Re: Dubious usage of TYPCATEGORY_STRING - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Dubious usage of TYPCATEGORY_STRING
Date
Msg-id 3573877.1638908686@sss.pgh.pa.us
Whole thread Raw
In response to Re: Dubious usage of TYPCATEGORY_STRING  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Dubious usage of TYPCATEGORY_STRING
List pgsql-hackers
I wrote:
> Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
>> Could we add explicit casts (like polcmd::text) here?  Or would it break 
>> too much?

> I assumed it'd break too much to consider doing that.  But I suppose
> that since a typcategory change would be initdb-forcing anyway, maybe
> it's not out of the question.  I'll investigate and see exactly how
> many places would need an explicit cast.

Um, I definitely gave up too easily there.  The one usage in \dp
seems to be the *only* thing that breaks in describe.c, and pg_dump
doesn't need any changes so far as check-world reveals.  So let's
just move "char" to another category, as attached.

            regards, tom lane

diff --git a/contrib/citext/expected/citext.out b/contrib/citext/expected/citext.out
index ec99aaed5d..3bac0534fb 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 75fd08b7cc..57fc863f7a 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 10232f5a9f..55fb1d11a6 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 c1d11be73f..216aa4510d 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -9305,6 +9305,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 ea721d963a..72d8547628 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/pg_type.dat b/src/include/catalog/pg_type.dat
index 41074c994b..f3d94f3cf5 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 e568e21dee..5e891a0596 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) */

pgsql-hackers by date:

Previous
From: Andrew Dunstan
Date:
Subject: Re: MSVC SSL test failure
Next
From: Robert Haas
Date:
Subject: Re: Why doesn't pgstat_report_analyze() focus on not-all-visible-page dead tuple counts, specifically?