]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix incorrect declarations of variadic pg_get_*_ddl() functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 23 Jun 2026 19:06:34 +0000 (15:06 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 23 Jun 2026 19:06:34 +0000 (15:06 -0400)
The final parameter of an ordinary variadic function should be an
array type.  CREATE FUNCTION won't accept a declaration that isn't
like that, but it's possible to put an incorrect combination into a
pg_proc.dat entry.  Sadly, the opr_sanity test that was supposed to
check that is broken and does not report functions with non-array
final parameters.  This allowed exactly such a thinko to sneak into
the recently-added pg_get_*_ddl() functions: their last argument
should be declared text[] but was declared text.  (We'd probably
have noticed eventually, when somebody tried to actually pass a
variadic array to one of those functions.  But their regression
tests do not do that.)

Fix those functions, and fix the opr_sanity test so we'll notice
next time.  Bump catversion for new pg_proc contents.

Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/D41A334E-ED9E-42EE-830D-28D4D36E9317@gmail.com

doc/src/sgml/func/func-info.sgml
src/include/catalog/catversion.h
src/include/catalog/pg_proc.dat
src/test/regress/expected/opr_sanity.out
src/test/regress/sql/opr_sanity.sql

index 8ffa7e832753e6f94f9af1d532e6ec5a36dd61c5..34f4019690f5d85df3d36811c0236beb166096ae 100644 (file)
@@ -3882,7 +3882,7 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         <function>pg_get_role_ddl</function>
         ( <parameter>role</parameter> <type>regrole</type>
         <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <type>text[]</type> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para>
@@ -3904,14 +3904,14 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         <function>pg_get_tablespace_ddl</function>
         ( <parameter>tablespace</parameter> <type>oid</type>
         <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <type>text[]</type> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para role="func_signature">
         <function>pg_get_tablespace_ddl</function>
         ( <parameter>tablespace</parameter> <type>name</type>
         <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <type>text[]</type> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para>
@@ -3932,7 +3932,7 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         <function>pg_get_database_ddl</function>
         ( <parameter>database</parameter> <type>regdatabase</type>
         <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <type>text[]</type> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para>
index c4e94a3a09e14d837d78c8428d25cefa64d465fb..fba78c20733814f60b41c2608e6e5e9e3a1e4f3e 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     202606091
+#define CATALOG_VERSION_NO     202606231
 
 #endif
index be157a5fbe90ccf6269f2e95233b35e2ea63abec..fa76c7923f0c38cdbf4dd019c88adf42aa8da6f2 100644 (file)
 { oid => '6501', descr => 'get DDL to recreate a role',
   proname => 'pg_get_role_ddl', prorows => '10', provariadic => 'text',
   proisstrict => 'f', proretset => 't', provolatile => 's',
-  pronargdefaults => '1', prorettype => 'text', proargtypes => 'regrole text',
-  proallargtypes => '{regrole,text}', proargmodes => '{i,v}',
+  pronargdefaults => '1', prorettype => 'text', proargtypes => 'regrole _text',
+  proallargtypes => '{regrole,_text}', proargmodes => '{i,v}',
   proargdefaults => '{NULL}', prosrc => 'pg_get_role_ddl' },
 { oid => '6499', descr => 'get DDL to recreate a tablespace',
   proname => 'pg_get_tablespace_ddl', prorows => '10', provariadic => 'text',
   proisstrict => 'f', proretset => 't', provolatile => 's',
-  pronargdefaults => '1', prorettype => 'text', proargtypes => 'oid text',
-  proallargtypes => '{oid,text}', proargmodes => '{i,v}',
+  pronargdefaults => '1', prorettype => 'text', proargtypes => 'oid _text',
+  proallargtypes => '{oid,_text}', proargmodes => '{i,v}',
   proargdefaults => '{NULL}', prosrc => 'pg_get_tablespace_ddl_oid' },
 { oid => '6500', descr => 'get DDL to recreate a tablespace',
   proname => 'pg_get_tablespace_ddl', prorows => '10', provariadic => 'text',
   proisstrict => 'f', proretset => 't', provolatile => 's',
-  pronargdefaults => '1', prorettype => 'text', proargtypes => 'name text',
-  proallargtypes => '{name,text}', proargmodes => '{i,v}',
+  pronargdefaults => '1', prorettype => 'text', proargtypes => 'name _text',
+  proallargtypes => '{name,_text}', proargmodes => '{i,v}',
   proargdefaults => '{NULL}', prosrc => 'pg_get_tablespace_ddl_name' },
 { oid => '6502', descr => 'get DDL to recreate a database',
   proname => 'pg_get_database_ddl', prorows => '10', provariadic => 'text',
   proisstrict => 'f', proretset => 't', provolatile => 's',
   pronargdefaults => '1', prorettype => 'text',
-  proargtypes => 'regdatabase text', proallargtypes => '{regdatabase,text}',
+  proargtypes => 'regdatabase _text', proallargtypes => '{regdatabase,_text}',
   proargmodes => '{i,v}', proargdefaults => '{NULL}',
   prosrc => 'pg_get_database_ddl' },
 { oid => '2509',
index cfdc6b1a17a2513fb11e69b59e22f5e3fb56aae6..80400a337347333f3b284db07a876be4bbc7c738 100644 (file)
@@ -487,7 +487,7 @@ AND case proargtypes[array_length(proargtypes, 1)-1]
        ELSE (SELECT t.oid
                  FROM pg_type t
                  WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1])
-       END  != provariadic;
+       END IS DISTINCT FROM provariadic;
  oid | provariadic | proargtypes 
 -----+-------------+-------------
 (0 rows)
index cd674d7dbca388db27317bddd4cbddbb4e22c81b..5670bb14193976eae1b4f50d9d378596bb666252 100644 (file)
@@ -360,7 +360,7 @@ AND case proargtypes[array_length(proargtypes, 1)-1]
        ELSE (SELECT t.oid
                  FROM pg_type t
                  WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1])
-       END  != provariadic;
+       END IS DISTINCT FROM provariadic;
 
 -- Check that all and only those functions with a variadic type have
 -- a variadic argument.