diff --git a/contrib/citext/expected/citext.out b/contrib/citext/expected/citext.out
index ec99aaed5dc..3bac0534fb8 100644
--- a/contrib/citext/expected/citext.out
+++ b/contrib/citext/expected/citext.out
@@ -1089,7 +1089,12 @@ INSERT INTO caster (char) VALUES ('f'::citext);
INSERT INTO caster (citext) VALUES ('f'::char);
INSERT INTO caster (chr) VALUES ('f'::text);
INSERT INTO caster (text) VALUES ('f'::"char");
-INSERT INTO caster (chr) VALUES ('f'::citext);
+INSERT INTO caster (chr) VALUES ('f'::citext); -- requires cast
+ERROR: column "chr" is of type "char" but expression is of type citext
+LINE 1: INSERT INTO caster (chr) VALUES ('f'::citext);
+ ^
+HINT: You will need to rewrite or cast the expression.
+INSERT INTO caster (chr) VALUES ('f'::citext::text);
INSERT INTO caster (citext) VALUES ('f'::"char");
INSERT INTO caster (name) VALUES ('foo'::text);
INSERT INTO caster (text) VALUES ('foo'::name);
diff --git a/contrib/citext/expected/citext_1.out b/contrib/citext/expected/citext_1.out
index 75fd08b7cc4..57fc863f7a5 100644
--- a/contrib/citext/expected/citext_1.out
+++ b/contrib/citext/expected/citext_1.out
@@ -1089,7 +1089,12 @@ INSERT INTO caster (char) VALUES ('f'::citext);
INSERT INTO caster (citext) VALUES ('f'::char);
INSERT INTO caster (chr) VALUES ('f'::text);
INSERT INTO caster (text) VALUES ('f'::"char");
-INSERT INTO caster (chr) VALUES ('f'::citext);
+INSERT INTO caster (chr) VALUES ('f'::citext); -- requires cast
+ERROR: column "chr" is of type "char" but expression is of type citext
+LINE 1: INSERT INTO caster (chr) VALUES ('f'::citext);
+ ^
+HINT: You will need to rewrite or cast the expression.
+INSERT INTO caster (chr) VALUES ('f'::citext::text);
INSERT INTO caster (citext) VALUES ('f'::"char");
INSERT INTO caster (name) VALUES ('foo'::text);
INSERT INTO caster (text) VALUES ('foo'::name);
diff --git a/contrib/citext/sql/citext.sql b/contrib/citext/sql/citext.sql
index 10232f5a9f4..55fb1d11a6f 100644
--- a/contrib/citext/sql/citext.sql
+++ b/contrib/citext/sql/citext.sql
@@ -361,7 +361,8 @@ INSERT INTO caster (citext) VALUES ('f'::char);
INSERT INTO caster (chr) VALUES ('f'::text);
INSERT INTO caster (text) VALUES ('f'::"char");
-INSERT INTO caster (chr) VALUES ('f'::citext);
+INSERT INTO caster (chr) VALUES ('f'::citext); -- requires cast
+INSERT INTO caster (chr) VALUES ('f'::citext::text);
INSERT INTO caster (citext) VALUES ('f'::"char");
INSERT INTO caster (name) VALUES ('foo'::text);
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 025db987633..03e2537b07d 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -9317,6 +9317,10 @@ SCRAM-SHA-256$<iteration count>:&l
X
unknown type
+
+ Z
+ Internal-use types
+
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index ea721d963a7..72d8547628a 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -1142,7 +1142,7 @@ permissionsList(const char *pattern)
",\n pg_catalog.array_to_string(ARRAY(\n"
" SELECT polname\n"
" || CASE WHEN polcmd != '*' THEN\n"
- " E' (' || polcmd || E'):'\n"
+ " E' (' || polcmd::pg_catalog.text || E'):'\n"
" ELSE E':'\n"
" END\n"
" || CASE WHEN polqual IS NOT NULL THEN\n"
@@ -1176,7 +1176,7 @@ permissionsList(const char *pattern)
" E' (RESTRICTIVE)'\n"
" ELSE '' END\n"
" || CASE WHEN polcmd != '*' THEN\n"
- " E' (' || polcmd || E'):'\n"
+ " E' (' || polcmd::pg_catalog.text || E'):'\n"
" ELSE E':'\n"
" END\n"
" || CASE WHEN polqual IS NOT NULL THEN\n"
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index c8259b833bc..6b19ffddde9 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202112081
+#define CATALOG_VERSION_NO 202112111
#endif
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index 41074c994b1..f3d94f3cf5d 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -42,7 +42,7 @@
typinput => 'byteain', typoutput => 'byteaout', typreceive => 'bytearecv',
typsend => 'byteasend', typalign => 'i', typstorage => 'x' },
{ oid => '18', array_type_oid => '1002', descr => 'single character',
- typname => 'char', typlen => '1', typbyval => 't', typcategory => 'S',
+ typname => 'char', typlen => '1', typbyval => 't', typcategory => 'Z',
typinput => 'charin', typoutput => 'charout', typreceive => 'charrecv',
typsend => 'charsend', typalign => 'c' },
{ oid => '19', array_type_oid => '1003',
@@ -145,24 +145,24 @@
typsend => 'xml_send', typalign => 'i', typstorage => 'x' },
{ oid => '194', descr => 'string representing an internal node tree',
typname => 'pg_node_tree', typlen => '-1', typbyval => 'f',
- typcategory => 'S', typinput => 'pg_node_tree_in',
+ typcategory => 'Z', typinput => 'pg_node_tree_in',
typoutput => 'pg_node_tree_out', typreceive => 'pg_node_tree_recv',
typsend => 'pg_node_tree_send', typalign => 'i', typstorage => 'x',
typcollation => 'default' },
{ oid => '3361', descr => 'multivariate ndistinct coefficients',
typname => 'pg_ndistinct', typlen => '-1', typbyval => 'f',
- typcategory => 'S', typinput => 'pg_ndistinct_in',
+ typcategory => 'Z', typinput => 'pg_ndistinct_in',
typoutput => 'pg_ndistinct_out', typreceive => 'pg_ndistinct_recv',
typsend => 'pg_ndistinct_send', typalign => 'i', typstorage => 'x',
typcollation => 'default' },
{ oid => '3402', descr => 'multivariate dependencies',
typname => 'pg_dependencies', typlen => '-1', typbyval => 'f',
- typcategory => 'S', typinput => 'pg_dependencies_in',
+ typcategory => 'Z', typinput => 'pg_dependencies_in',
typoutput => 'pg_dependencies_out', typreceive => 'pg_dependencies_recv',
typsend => 'pg_dependencies_send', typalign => 'i', typstorage => 'x',
typcollation => 'default' },
{ oid => '5017', descr => 'multivariate MCV list',
- typname => 'pg_mcv_list', typlen => '-1', typbyval => 'f', typcategory => 'S',
+ typname => 'pg_mcv_list', typlen => '-1', typbyval => 'f', typcategory => 'Z',
typinput => 'pg_mcv_list_in', typoutput => 'pg_mcv_list_out',
typreceive => 'pg_mcv_list_recv', typsend => 'pg_mcv_list_send',
typalign => 'i', typstorage => 'x', typcollation => 'default' },
@@ -681,13 +681,13 @@
typalign => 'd', typstorage => 'x' },
{ oid => '4600', descr => 'BRIN bloom summary',
typname => 'pg_brin_bloom_summary', typlen => '-1', typbyval => 'f',
- typcategory => 'S', typinput => 'brin_bloom_summary_in',
+ typcategory => 'Z', typinput => 'brin_bloom_summary_in',
typoutput => 'brin_bloom_summary_out',
typreceive => 'brin_bloom_summary_recv', typsend => 'brin_bloom_summary_send',
typalign => 'i', typstorage => 'x', typcollation => 'default' },
{ oid => '4601', descr => 'BRIN minmax-multi summary',
typname => 'pg_brin_minmax_multi_summary', typlen => '-1', typbyval => 'f',
- typcategory => 'S', typinput => 'brin_minmax_multi_summary_in',
+ typcategory => 'Z', typinput => 'brin_minmax_multi_summary_in',
typoutput => 'brin_minmax_multi_summary_out',
typreceive => 'brin_minmax_multi_summary_recv',
typsend => 'brin_minmax_multi_summary_send', typalign => 'i',
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index e568e21dee6..5e891a05962 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -294,6 +294,7 @@ DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index, 2704, TypeNameNspIndexId, on pg_
#define TYPCATEGORY_USER 'U'
#define TYPCATEGORY_BITSTRING 'V' /* er ... "varbit"? */
#define TYPCATEGORY_UNKNOWN 'X'
+#define TYPCATEGORY_INTERNAL 'Z'
#define TYPALIGN_CHAR 'c' /* char alignment (i.e. unaligned) */
#define TYPALIGN_SHORT 's' /* short alignment (typically 2 bytes) */