From f365b91b7182e666ec4751544c965179fec45bcd Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Tue, 23 Jun 2026 08:36:30 +0800
Subject: [PATCH v1] Tighten opr_sanity check for variadic functions

The existing sanity check verified that provariadic matches the element type
of the last proargtypes entry, but it used != for the comparison. If the
last argument was not an array type at all, the element-type lookup returned
NULL, so the comparison did not evaluate to true and the bad row was missed.

Use IS DISTINCT FROM instead, so a missing element type is treated as a
mismatch. This catches variadic catalog entries whose final proargtypes entry
is a scalar type rather than the required array type.

Also fix the pg_get_*_ddl() entries added for PostgreSQL 19 to follow that
catalog convention by using _text for their variadic text argument.

Author: Chao Li <lic@highgo.com>
---
 src/include/catalog/pg_proc.dat          | 14 +++++++-------
 src/test/regress/expected/opr_sanity.out |  2 +-
 src/test/regress/sql/opr_sanity.sql      |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index be157a5fbe9..fa76c7923f0 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8593,26 +8593,26 @@
 { 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',
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index cfdc6b1a17a..80400a33734 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -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)
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index cd674d7dbca..5670bb14193 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -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.
-- 
2.50.1 (Apple Git-155)

