diff --git a/contrib/citext/Makefile b/contrib/citext/Makefile
index 267854b5de7a0aaff9b25117923fd6d5c5d9cb6d..61e04bce7ae72679391680dffe0114f26022e1be 100644
--- a/contrib/citext/Makefile
+++ b/contrib/citext/Makefile
@@ -3,7 +3,7 @@
 MODULES = citext
 
 EXTENSION = citext
-DATA = citext--1.0.sql citext--unpackaged--1.0.sql
+DATA = citext--1.1.sql citext--1.0--1.1.sql citext--unpackaged--1.0.sql
 PGFILEDESC = "citext - case-insensitive character string data type"
 
 REGRESS = citext
diff --git a/contrib/citext/citext--1.0--1.1.sql b/contrib/citext/citext--1.0--1.1.sql
new file mode 100644
index 0000000000000000000000000000000000000000..e06627e0258cc89845adb37b33fe14986eafb0ee
--- /dev/null
+++ b/contrib/citext/citext--1.0--1.1.sql
@@ -0,0 +1,21 @@
+/* contrib/citext/citext--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION citext UPDATE TO '1.1'" to load this file. \quit
+
+/* First we have to remove them from the extension */
+ALTER EXTENSION citext DROP FUNCTION regexp_matches( citext, citext );
+ALTER EXTENSION citext DROP FUNCTION regexp_matches( citext, citext, text );
+
+/* Then we can drop them */
+DROP FUNCTION regexp_matches( citext, citext );
+DROP FUNCTION regexp_matches( citext, citext, text );
+
+/* Now redefine */
+CREATE FUNCTION regexp_matches( citext, citext ) RETURNS SETOF TEXT[] AS $$
+    SELECT pg_catalog.regexp_matches( $1::pg_catalog.text, $2::pg_catalog.text, 'i' );
+$$ LANGUAGE SQL IMMUTABLE STRICT ROWS 1;
+
+CREATE FUNCTION regexp_matches( citext, citext, text ) RETURNS SETOF TEXT[] AS $$
+    SELECT pg_catalog.regexp_matches( $1::pg_catalog.text, $2::pg_catalog.text, CASE WHEN pg_catalog.strpos($3, 'c') = 0 THEN  $3 || 'i' ELSE $3 END );
+$$ LANGUAGE SQL IMMUTABLE STRICT ROWS 10;
diff --git a/contrib/citext/citext--1.0.sql b/contrib/citext/citext--1.1.sql
similarity index 97%
rename from contrib/citext/citext--1.0.sql
rename to contrib/citext/citext--1.1.sql
index 7db2e8d0aec9cca5843ff070be2630fcac9f64d7..9ea7c64709a1093cce0cd0ef40f340b6906bec0d 100644
--- a/contrib/citext/citext--1.0.sql
+++ b/contrib/citext/citext--1.1.sql
@@ -1,4 +1,4 @@
-/* contrib/citext/citext--1.0.sql */
+/* contrib/citext/citext--1.1.sql */
 
 -- complain if script is sourced in psql, rather than via CREATE EXTENSION
 \echo Use "CREATE EXTENSION citext" to load this file. \quit
@@ -440,13 +440,13 @@ CREATE OPERATOR !~~* (
 -- XXX TODO Ideally these would be implemented in C.
 --
 
-CREATE FUNCTION regexp_matches( citext, citext ) RETURNS TEXT[] AS $$
+CREATE FUNCTION regexp_matches( citext, citext ) RETURNS SETOF TEXT[] AS $$
     SELECT pg_catalog.regexp_matches( $1::pg_catalog.text, $2::pg_catalog.text, 'i' );
-$$ LANGUAGE SQL IMMUTABLE STRICT;
+$$ LANGUAGE SQL IMMUTABLE STRICT ROWS 1;
 
-CREATE FUNCTION regexp_matches( citext, citext, text ) RETURNS TEXT[] AS $$
+CREATE FUNCTION regexp_matches( citext, citext, text ) RETURNS SETOF TEXT[] AS $$
     SELECT pg_catalog.regexp_matches( $1::pg_catalog.text, $2::pg_catalog.text, CASE WHEN pg_catalog.strpos($3, 'c') = 0 THEN  $3 || 'i' ELSE $3 END );
-$$ LANGUAGE SQL IMMUTABLE STRICT;
+$$ LANGUAGE SQL IMMUTABLE STRICT ROWS 10;
 
 CREATE FUNCTION regexp_replace( citext, citext, text ) returns TEXT AS $$
     SELECT pg_catalog.regexp_replace( $1::pg_catalog.text, $2::pg_catalog.text, $3, 'i');
diff --git a/contrib/citext/citext.control b/contrib/citext/citext.control
index 3eb01a3360861472a62d6a59a3c03b18c3d8dcb3..ef90a97bc981907855ad2233d262a423cada9142 100644
--- a/contrib/citext/citext.control
+++ b/contrib/citext/citext.control
@@ -1,5 +1,5 @@
 # citext extension
 comment = 'data type for case-insensitive character strings'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/citext'
 relocatable = true
diff --git a/contrib/citext/expected/citext.out b/contrib/citext/expected/citext.out
index 411b689b4b9a95dacf62b89203afd38cab9e58fa..373fe6da545d0bb5b9f268896f08e4e4a34efac0 100644
--- a/contrib/citext/expected/citext.out
+++ b/contrib/citext/expected/citext.out
@@ -1846,11 +1846,18 @@ SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, ''::cite
 (1 row)
 
 -- c forces case-sensitive
-SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citext) = ARRAY[ 'bar', 'beque' ] AS "null";
- null 
-------
- 
-(1 row)
+SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citext) = ARRAY[ 'bar', 'beque' ] AS "no rows";
+ no rows 
+---------
+(0 rows)
+
+-- g allows multiple output rows
+SELECT regexp_matches('foobarbequebazmorebarbequetoo'::citext, '(BAR)(BEQUE)'::citext, 'g'::citext) AS "two rows";
+  two rows   
+-------------
+ {bar,beque}
+ {bar,beque}
+(2 rows)
 
 SELECT regexp_replace('Thomas'::citext, '.[mN]a.',         'M') = 'ThM' AS t;
  t 
diff --git a/contrib/citext/expected/citext_1.out b/contrib/citext/expected/citext_1.out
index da3862f49bac1df43d7917f84bd9a8ba9e65f327..fcadd8d3929ff6e54a3a9d9d150f36592e0d2486 100644
--- a/contrib/citext/expected/citext_1.out
+++ b/contrib/citext/expected/citext_1.out
@@ -1846,11 +1846,18 @@ SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, ''::cite
 (1 row)
 
 -- c forces case-sensitive
-SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citext) = ARRAY[ 'bar', 'beque' ] AS "null";
- null 
-------
- 
-(1 row)
+SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citext) = ARRAY[ 'bar', 'beque' ] AS "no rows";
+ no rows 
+---------
+(0 rows)
+
+-- g allows multiple output rows
+SELECT regexp_matches('foobarbequebazmorebarbequetoo'::citext, '(BAR)(BEQUE)'::citext, 'g'::citext) AS "two rows";
+  two rows   
+-------------
+ {bar,beque}
+ {bar,beque}
+(2 rows)
 
 SELECT regexp_replace('Thomas'::citext, '.[mN]a.',         'M') = 'ThM' AS t;
  t 
diff --git a/contrib/citext/sql/citext.sql b/contrib/citext/sql/citext.sql
index 27678fab5df669c01c6bb3868a2bbcf5c9f07206..950895baea7998e6ee6d2ec83f0767c754ee2caf 100644
--- a/contrib/citext/sql/citext.sql
+++ b/contrib/citext/sql/citext.sql
@@ -601,7 +601,9 @@ SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)', '') = ARRAY[ 'ba
 SELECT regexp_matches('foobarbequebaz', '(BAR)(BEQUE)'::citext, '') = ARRAY[ 'bar', 'beque' ] AS t;
 SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, ''::citext) = ARRAY[ 'bar', 'beque' ] AS t;
 -- c forces case-sensitive
-SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citext) = ARRAY[ 'bar', 'beque' ] AS "null";
+SELECT regexp_matches('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citext) = ARRAY[ 'bar', 'beque' ] AS "no rows";
+-- g allows multiple output rows
+SELECT regexp_matches('foobarbequebazmorebarbequetoo'::citext, '(BAR)(BEQUE)'::citext, 'g'::citext) AS "two rows";
 
 SELECT regexp_replace('Thomas'::citext, '.[mN]a.',         'M') = 'ThM' AS t;
 SELECT regexp_replace('Thomas'::citext, '.[MN]A.',         'M') = 'ThM' AS t;