diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2021-12-11 14:10:51 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2021-12-11 14:10:51 -0500 |
commit | 07eee5a0dc642d26f44d65c4e6263304208e8583 (patch) | |
tree | d1e1dfa452a2e7d032b2b6226fe38478139927f3 | |
parent | fe60b67250a31cd1ac2a4882f12e199e30abd316 (diff) | |
download | postgresql-07eee5a0dc642d26f44d65c4e6263304208e8583.tar.gz postgresql-07eee5a0dc642d26f44d65c4e6263304208e8583.zip |
Create a new type category for "internal use" types.
Historically we've put type "char" into the S (String) typcategory,
although calling it a string is a stretch considering it can only
store one byte. (In our actual usage, it's more like an enum.)
This choice now seems wrong in view of the special heuristics
that parse_func.c and parse_coerce.c have for TYPCATEGORY_STRING:
it's not a great idea for "char" to have those preferential casting
behaviors.
Worse than that, recent patches inventing special-purpose types
like pg_node_tree have assigned typcategory S to those types,
meaning they also get preferential casting treatment that's designed
on the assumption that they can hold arbitrary text.
To fix, invent a new category TYPCATEGORY_INTERNAL for internal-use
types, and assign that to all these types. I used code 'Z' for
lack of a better idea ('I' was already taken).
This change breaks one query in psql/describe.c, which now needs to
explicitly cast a catalog "char" column to text before concatenating
it with an undecorated literal. Also, a test case in contrib/citext
now needs an explicit cast to convert citext to "char". Since the
point of this change is to not have "char" be a surprisingly-available
cast target, these breakages seem OK.
Per report from Ian Campbell.
Discussion: https://postgr.es/m/2216388.1638480141@sss.pgh.pa.us
-rw-r--r-- | contrib/citext/expected/citext.out | 7 | ||||
-rw-r--r-- | contrib/citext/expected/citext_1.out | 7 | ||||
-rw-r--r-- | contrib/citext/sql/citext.sql | 3 | ||||
-rw-r--r-- | doc/src/sgml/catalogs.sgml | 4 | ||||
-rw-r--r-- | src/bin/psql/describe.c | 4 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_type.dat | 14 | ||||
-rw-r--r-- | src/include/catalog/pg_type.h | 1 |
8 files changed, 29 insertions, 13 deletions
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$<replaceable><iteration count></replaceable>:<replaceable>&l <entry><literal>X</literal></entry> <entry><type>unknown</type> type</entry> </row> + <row> + <entry><literal>Z</literal></entry> + <entry>Internal-use types</entry> + </row> </tbody> </tgroup> </table> 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) */ |