From 2bcf744710589e88bfcdb370ba5c2b098cbdae9c Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Tue, 24 Mar 2026 20:59:26 -0700
Subject: [PATCH v4 2/2] POC: pass the list of publications to
 pg_get_publication_tables().

---
 src/backend/catalog/pg_publication.c        | 140 ++++++++++----------
 src/backend/replication/logical/tablesync.c |  26 ++--
 src/include/catalog/pg_proc.dat             |   6 +-
 src/test/regress/expected/publication.out   |  62 ++++++---
 src/test/regress/sql/publication.sql        |  49 ++++---
 5 files changed, 154 insertions(+), 129 deletions(-)

diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index f4649dbd8b9..181f999916c 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -1377,7 +1377,6 @@ is_table_publishable_in_publication(Oid relid, Publication *pub)
  * Helper function to get information of the tables in the given
  * publication(s).
  *
- * The parameters pubnames and {pubname, target_relid} are mutually exclusive.
  * If target_relid is provided, the function returns information only for that
  * specific table. Otherwise, if returns information for all tables within the
  * specified publications.
@@ -1386,7 +1385,7 @@ is_table_publishable_in_publication(Oid relid, Publication *pub)
  */
 static Datum
 pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames,
-						  text *pubname, Oid target_relid)
+						  Oid target_relid)
 {
 #define NUM_PUBLICATION_TABLES_ELEM	4
 	FuncCallContext *funcctx;
@@ -1397,6 +1396,10 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames,
 	{
 		TupleDesc	tupdesc;
 		MemoryContext oldcontext;
+		Datum	   *elems;
+		int			nelems,
+					i;
+		bool		viaroot = false;
 
 		/* create a function context for cross-call persistence */
 		funcctx = SRF_FIRSTCALL_INIT();
@@ -1404,49 +1407,37 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames,
 		/* switch to memory context appropriate for multiple function calls */
 		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-		if (pubname != NULL)
-		{
-			/* Try to retrieve the specified table information */
-			if (SearchSysCacheExists1(RELOID, target_relid))
-			{
-				Publication *pub;
-
-				pub = GetPublicationByName(text_to_cstring(pubname), false);
+		Assert(pubnames != NULL);
 
-				if (is_table_publishable_in_publication(target_relid, pub))
-				{
-					published_rel *table_info = palloc_object(published_rel);
+		/*
+		 * Deconstruct the parameter into elements where each element is a
+		 * publication name.
+		 */
+		deconstruct_array_builtin(pubnames, TEXTOID, &elems, NULL, &nelems);
 
-					table_info->relid = target_relid;
-					table_info->pubid = pub->oid;
-					table_infos = lappend(table_infos, table_info);
-				}
-			}
-		}
-		else
+		/* Get Oids of tables from each publication. */
+		for (i = 0; i < nelems; i++)
 		{
-			Datum	   *elems;
-			int			nelems,
-						i;
-			bool		viaroot = false;
+			Publication *pub_elem;
+			List	   *pub_elem_tables = NIL;
+			ListCell   *lc;
 
-			Assert(pubnames != NULL);
+			pub_elem = GetPublicationByName(TextDatumGetCString(elems[i]), true);
 
-			/*
-			 * Deconstruct the parameter into elements where each element is a
-			 * publication name.
-			 */
-			deconstruct_array_builtin(pubnames, TEXTOID, &elems, NULL, &nelems);
+			if (pub_elem == NULL)
+				continue;
 
-			/* Get Oids of tables from each publication. */
-			for (i = 0; i < nelems; i++)
+			if (OidIsValid(target_relid))
+			{
+				/* Try to retrieve the specified table information */
+				if (SearchSysCacheExists1(RELOID, target_relid) &&
+					is_table_publishable_in_publication(target_relid, pub_elem))
+				{
+					pub_elem_tables = list_make1_oid(target_relid);
+				}
+			}
+			else
 			{
-				Publication *pub_elem;
-				List	   *pub_elem_tables = NIL;
-				ListCell   *lc;
-
-				pub_elem = GetPublicationByName(TextDatumGetCString(elems[i]), false);
-
 				/*
 				 * Publications support partitioned tables. If
 				 * publish_via_partition_root is false, all changes are
@@ -1473,45 +1464,45 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames,
 																	PUBLICATION_PART_LEAF);
 					pub_elem_tables = list_concat_unique_oid(relids, schemarelids);
 				}
+			}
 
-				/*
-				 * Record the published table and the corresponding
-				 * publication so that we can get row filters and column lists
-				 * later.
-				 *
-				 * When a table is published by multiple publications, to
-				 * obtain all row filters and column lists, the structure
-				 * related to this table will be recorded multiple times.
-				 */
-				foreach(lc, pub_elem_tables)
-				{
-					published_rel *table_info = palloc_object(published_rel);
-
-					table_info->relid = lfirst_oid(lc);
-					table_info->pubid = pub_elem->oid;
-					table_infos = lappend(table_infos, table_info);
-				}
+			/*
+			 * Record the published table and the corresponding
+			 * publication so that we can get row filters and column lists
+			 * later.
+			 *
+			 * When a table is published by multiple publications, to
+			 * obtain all row filters and column lists, the structure
+			 * related to this table will be recorded multiple times.
+			 */
+			foreach(lc, pub_elem_tables)
+			{
+				published_rel *table_info = palloc_object(published_rel);
 
-				/*
-				 * At least one publication is using
-				 * publish_via_partition_root.
-				 */
-				if (pub_elem->pubviaroot)
-					viaroot = true;
+				table_info->relid = lfirst_oid(lc);
+				table_info->pubid = pub_elem->oid;
+				table_infos = lappend(table_infos, table_info);
 			}
 
 			/*
-			 * If the publication publishes partition changes via their
-			 * respective root partitioned tables, we must exclude partitions
-			 * in favor of including the root partitioned tables. Otherwise,
-			 * the function could return both the child and parent tables
-			 * which could cause data of the child table to be
-			 * double-published on the subscriber side.
+			 * At least one publication is using
+			 * publish_via_partition_root.
 			 */
-			if (viaroot)
-				filter_partitions(table_infos);
+			if (pub_elem->pubviaroot)
+				viaroot = true;
 		}
 
+		/*
+		 * If the publication publishes partition changes via their
+		 * respective root partitioned tables, we must exclude partitions
+		 * in favor of including the root partitioned tables. Otherwise,
+		 * the function could return both the child and parent tables
+		 * which could cause data of the child table to be
+		 * double-published on the subscriber side.
+		 */
+		if (viaroot)
+			filter_partitions(table_infos);
+
 		/* Construct a tuple descriptor for the result rows. */
 		tupdesc = CreateTemplateTupleDesc(NUM_PUBLICATION_TABLES_ELEM);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pubid",
@@ -1640,14 +1631,21 @@ Datum
 pg_get_publication_tables_a(PG_FUNCTION_ARGS)
 {
 	/* Get the information of the tables in the given publications */
-	return pg_get_publication_tables(fcinfo, PG_GETARG_ARRAYTYPE_P(0), NULL, InvalidOid);
+	return pg_get_publication_tables(fcinfo, PG_GETARG_ARRAYTYPE_P(0), InvalidOid);
 }
 
 Datum
 pg_get_publication_tables_b(PG_FUNCTION_ARGS)
 {
+	Oid relid = PG_GETARG_OID(1);
+
+	if (!OidIsValid(relid))
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("invalid relation OID %u", relid)));
+
 	/* Get the information of the specified table in the given publication */
-	return pg_get_publication_tables(fcinfo, NULL, PG_GETARG_TEXT_P(0), PG_GETARG_OID(1));
+	return pg_get_publication_tables(fcinfo, PG_GETARG_ARRAYTYPE_P(0), relid);
 }
 
 /*
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index ec8840ebf42..d70c172e0f5 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -802,20 +802,18 @@ fetch_remote_table_info(char *nspname, char *relname, LogicalRepRelation *lrel,
 		if (server_version >= 190000)
 		{
 			/*
-			 * We can pass relid to pg_get_publication_table() since version
-			 * 19.
+			 * We can pass both publication names and relid to
+			 * pg_get_publication_table() since version 19.
 			 */
 			appendStringInfo(&cmd,
 							 "SELECT DISTINCT"
 							 "  (CASE WHEN (array_length(gpt.attrs, 1) = c.relnatts)"
 							 "   THEN NULL ELSE gpt.attrs END)"
-							 "  FROM pg_publication p,"
-							 "  LATERAL pg_get_publication_tables(p.pubname, %u) gpt,"
+							 "  FROM pg_get_publication_tables(ARRAY[%s], %u) gpt,"
 							 "  pg_class c"
-							 " WHERE c.oid = gpt.relid"
-							 "   AND p.pubname IN ( %s )",
-							 lrel->remoteid,
-							 pub_names->data);
+							 " WHERE c.oid = gpt.relid",
+							 pub_names->data,
+							 lrel->remoteid);
 		}
 		else
 			appendStringInfo(&cmd,
@@ -1006,16 +1004,14 @@ fetch_remote_table_info(char *nspname, char *relname, LogicalRepRelation *lrel,
 		if (server_version >= 190000)
 		{
 			/*
-			 * We can pass relid to pg_get_publication_table() since version
-			 * 19.
+			 * We can pass both publication names and relid to
+			 * pg_get_publication_table() since version 19.
 			 */
 			appendStringInfo(&cmd,
 							 "SELECT DISTINCT pg_get_expr(gpt.qual, gpt.relid)"
-							 "  FROM pg_publication p,"
-							 "  LATERAL pg_get_publication_tables(p.pubname, %u) gpt"
-							 " WHERE p.pubname IN ( %s )",
-							 lrel->remoteid,
-							 pub_names->data);
+							 "  FROM pg_get_publication_tables(ARRAY[%s], %u) gpt",
+							 pub_names->data,
+							 lrel->remoteid);
 		}
 		else
 			appendStringInfo(&cmd,
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6c23f36495f..33729d9573a 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -12473,10 +12473,10 @@
   descr => 'get information of the specified table that is part of the specified publication',
   proname => 'pg_get_publication_tables', prorows => '1',
   proretset => 't', provolatile => 's',
-  prorettype => 'record', proargtypes => 'text oid',
-  proallargtypes => '{text,oid,oid,oid,int2vector,pg_node_tree}',
+  prorettype => 'record', proargtypes => '_text oid',
+  proallargtypes => '{_text,oid,oid,oid,int2vector,pg_node_tree}',
   proargmodes => '{i,i,o,o,o,o}',
-  proargnames => '{pubname,target_relid,pubid,relid,attrs,qual}',
+  proargnames => '{pubnames,target_relid,pubid,relid,attrs,qual}',
   prosrc => 'pg_get_publication_tables_b' },
 { oid => '8052', descr => 'get OIDs of sequences in a publication',
   proname => 'pg_get_publication_sequences', prorows => '1000', proretset => 't',
diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out
index 2c859de6c5e..c5f8e045307 100644
--- a/src/test/regress/expected/publication.out
+++ b/src/test/regress/expected/publication.out
@@ -2287,7 +2287,7 @@ CREATE PUBLICATION pub_part_leaf FOR TABLE tbl_part1 WITH (publish_via_partition
 CREATE PUBLICATION pub_part_parent FOR TABLE tbl_parent (id1, id2) WHERE (id1 = 10) WITH (publish_via_partition_root = true);
 CREATE PUBLICATION pub_part_parent_novia_root FOR TABLE tbl_parent WITH (publish_via_partition_root = false);
 RESET client_min_messages;
-CREATE FUNCTION test_gpt(pubname text, relname text)
+CREATE FUNCTION test_gpt(pubnames text[], relname text)
 RETURNS TABLE (
   pubname text,
   relname name,
@@ -2296,104 +2296,125 @@ RETURNS TABLE (
 )
 BEGIN ATOMIC
   SELECT p.pubname, c.relname, gpt.attrs::text, pg_get_expr(gpt.qual, gpt.relid)
-    FROM pg_get_publication_tables(pubname, relname::regclass::oid) gpt
+    FROM pg_get_publication_tables(pubnames, relname::regclass::oid) gpt
     JOIN pg_publication p ON p.oid = gpt.pubid
     JOIN pg_class c ON c.oid = gpt.relid
   ORDER BY p.pubname, c.relname;
 END;
-SELECT * FROM test_gpt('pub_normal', 'tbl_normal');
+SELECT * FROM test_gpt(ARRAY['pub_normal'], 'tbl_normal');
   pubname   |  relname   | attrs |   qual    
 ------------+------------+-------+-----------
  pub_normal | tbl_normal | 1     | (id < 10)
 (1 row)
 
-SELECT * FROM test_gpt('pub_normal', 'gpt_test_sch.tbl_sch'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_normal'], 'gpt_test_sch.tbl_sch'); -- no result
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_schema', 'gpt_test_sch.tbl_sch');
+SELECT * FROM test_gpt(ARRAY['pub_schema'], 'gpt_test_sch.tbl_sch');
   pubname   | relname | attrs | qual 
 ------------+---------+-------+------
  pub_schema | tbl_sch | 1     | 
 (1 row)
 
-SELECT * FROM test_gpt('pub_schema', 'tbl_normal'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_schema'], 'tbl_normal'); -- no result
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_part_parent', 'tbl_parent');
+SELECT * FROM test_gpt(ARRAY['pub_part_parent'], 'tbl_parent');
      pubname     |  relname   | attrs |    qual    
 -----------------+------------+-------+------------
  pub_part_parent | tbl_parent | 1 2   | (id1 = 10)
 (1 row)
 
-SELECT * FROM test_gpt('pub_part_parent', 'tbl_part1'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_part_parent'], 'tbl_part1'); -- no result
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_part_parent_novia_root', 'tbl_parent'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_part_parent_novia_root'], 'tbl_parent'); -- no result
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_part_parent_novia_root', 'tbl_part1');
+SELECT * FROM test_gpt(ARRAY['pub_part_parent_novia_root'], 'tbl_part1');
           pubname           |  relname  | attrs | qual 
 ----------------------------+-----------+-------+------
  pub_part_parent_novia_root | tbl_part1 | 1 2 3 | 
 (1 row)
 
-SELECT * FROM test_gpt('pub_part_leaf', 'tbl_parent'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_part_leaf'], 'tbl_parent'); -- no result
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_part_leaf', 'tbl_part1');
+SELECT * FROM test_gpt(ARRAY['pub_part_leaf'], 'tbl_part1');
     pubname    |  relname  | attrs | qual 
 ---------------+-----------+-------+------
  pub_part_leaf | tbl_part1 | 1 2 3 | 
 (1 row)
 
-SELECT * FROM test_gpt('pub_all', 'tbl_parent');
+SELECT * FROM test_gpt(ARRAY['pub_all'], 'tbl_parent');
  pubname |  relname   | attrs | qual 
 ---------+------------+-------+------
  pub_all | tbl_parent | 1 2 3 | 
 (1 row)
 
-SELECT * FROM test_gpt('pub_all', 'tbl_part1'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_all'], 'tbl_part1'); -- no result
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_all_except', 'tbl_normal');
+-- two rows with different row filter
+SELECT * FROM test_gpt(ARRAY['pub_all', 'pub_normal'], 'tbl_normal');
+  pubname   |  relname   | attrs |   qual    
+------------+------------+-------+-----------
+ pub_all    | tbl_normal | 1     | 
+ pub_normal | tbl_normal | 1     | (id < 10)
+(2 rows)
+
+-- one row with 'pub_part_parent'
+SELECT * FROM test_gpt(ARRAY['pub_part_parent', 'pub_part_parent_novia_root'], 'tbl_parent');
+     pubname     |  relname   | attrs |    qual    
+-----------------+------------+-------+------------
+ pub_part_parent | tbl_parent | 1 2   | (id1 = 10)
+(1 row)
+
+-- no result, partitions are excluded
+SELECT * FROM test_gpt(ARRAY['pub_part_parent', 'pub_all'], 'tbl_part1');
+ pubname | relname | attrs | qual 
+---------+---------+-------+------
+(0 rows)
+
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'tbl_normal');
     pubname     |  relname   | attrs | qual 
 ----------------+------------+-------+------
  pub_all_except | tbl_normal | 1     | 
 (1 row)
 
-SELECT * FROM test_gpt('pub_all_except', 'gpt_test_sch.tbl_sch'); -- no result (excluded)
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'gpt_test_sch.tbl_sch'); -- no result (excluded)
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_all_except', 'tbl_parent'); -- no result (excluded)
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'tbl_parent'); -- no result (excluded)
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_all_except', 'tbl_part1'); -- no result (excluded)
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'tbl_part1'); -- no result (excluded)
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_all_novia_root', 'tbl_parent'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_all_novia_root'], 'tbl_parent'); -- no result
  pubname | relname | attrs | qual 
 ---------+---------+-------+------
 (0 rows)
 
-SELECT * FROM test_gpt('pub_all_novia_root', 'tbl_part1');
+SELECT * FROM test_gpt(ARRAY['pub_all_novia_root'], 'tbl_part1');
       pubname       |  relname  | attrs | qual 
 --------------------+-----------+-------+------
  pub_all_novia_root | tbl_part1 | 1 2 3 | 
@@ -2401,6 +2422,7 @@ SELECT * FROM test_gpt('pub_all_novia_root', 'tbl_part1');
 
 -- Clean up
 DROP FUNCTION test_gpt(text, text);
+ERROR:  function test_gpt(text, text) does not exist
 DROP PUBLICATION pub_all;
 DROP PUBLICATION pub_all_novia_root;
 DROP PUBLICATION pub_all_except;
diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql
index c1c83f7d701..2016c0aac08 100644
--- a/src/test/regress/sql/publication.sql
+++ b/src/test/regress/sql/publication.sql
@@ -1447,7 +1447,7 @@ CREATE PUBLICATION pub_part_parent FOR TABLE tbl_parent (id1, id2) WHERE (id1 =
 CREATE PUBLICATION pub_part_parent_novia_root FOR TABLE tbl_parent WITH (publish_via_partition_root = false);
 RESET client_min_messages;
 
-CREATE FUNCTION test_gpt(pubname text, relname text)
+CREATE FUNCTION test_gpt(pubnames text[], relname text)
 RETURNS TABLE (
   pubname text,
   relname name,
@@ -1456,37 +1456,46 @@ RETURNS TABLE (
 )
 BEGIN ATOMIC
   SELECT p.pubname, c.relname, gpt.attrs::text, pg_get_expr(gpt.qual, gpt.relid)
-    FROM pg_get_publication_tables(pubname, relname::regclass::oid) gpt
+    FROM pg_get_publication_tables(pubnames, relname::regclass::oid) gpt
     JOIN pg_publication p ON p.oid = gpt.pubid
     JOIN pg_class c ON c.oid = gpt.relid
   ORDER BY p.pubname, c.relname;
 END;
 
-SELECT * FROM test_gpt('pub_normal', 'tbl_normal');
-SELECT * FROM test_gpt('pub_normal', 'gpt_test_sch.tbl_sch'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_normal'], 'tbl_normal');
+SELECT * FROM test_gpt(ARRAY['pub_normal'], 'gpt_test_sch.tbl_sch'); -- no result
 
-SELECT * FROM test_gpt('pub_schema', 'gpt_test_sch.tbl_sch');
-SELECT * FROM test_gpt('pub_schema', 'tbl_normal'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_schema'], 'gpt_test_sch.tbl_sch');
+SELECT * FROM test_gpt(ARRAY['pub_schema'], 'tbl_normal'); -- no result
 
-SELECT * FROM test_gpt('pub_part_parent', 'tbl_parent');
-SELECT * FROM test_gpt('pub_part_parent', 'tbl_part1'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_part_parent'], 'tbl_parent');
+SELECT * FROM test_gpt(ARRAY['pub_part_parent'], 'tbl_part1'); -- no result
 
-SELECT * FROM test_gpt('pub_part_parent_novia_root', 'tbl_parent'); -- no result
-SELECT * FROM test_gpt('pub_part_parent_novia_root', 'tbl_part1');
+SELECT * FROM test_gpt(ARRAY['pub_part_parent_novia_root'], 'tbl_parent'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_part_parent_novia_root'], 'tbl_part1');
 
-SELECT * FROM test_gpt('pub_part_leaf', 'tbl_parent'); -- no result
-SELECT * FROM test_gpt('pub_part_leaf', 'tbl_part1');
+SELECT * FROM test_gpt(ARRAY['pub_part_leaf'], 'tbl_parent'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_part_leaf'], 'tbl_part1');
 
-SELECT * FROM test_gpt('pub_all', 'tbl_parent');
-SELECT * FROM test_gpt('pub_all', 'tbl_part1'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_all'], 'tbl_parent');
+SELECT * FROM test_gpt(ARRAY['pub_all'], 'tbl_part1'); -- no result
 
-SELECT * FROM test_gpt('pub_all_except', 'tbl_normal');
-SELECT * FROM test_gpt('pub_all_except', 'gpt_test_sch.tbl_sch'); -- no result (excluded)
-SELECT * FROM test_gpt('pub_all_except', 'tbl_parent'); -- no result (excluded)
-SELECT * FROM test_gpt('pub_all_except', 'tbl_part1'); -- no result (excluded)
+-- two rows with different row filter
+SELECT * FROM test_gpt(ARRAY['pub_all', 'pub_normal'], 'tbl_normal');
 
-SELECT * FROM test_gpt('pub_all_novia_root', 'tbl_parent'); -- no result
-SELECT * FROM test_gpt('pub_all_novia_root', 'tbl_part1');
+-- one row with 'pub_part_parent'
+SELECT * FROM test_gpt(ARRAY['pub_part_parent', 'pub_part_parent_novia_root'], 'tbl_parent');
+
+-- no result, partitions are excluded
+SELECT * FROM test_gpt(ARRAY['pub_part_parent', 'pub_all'], 'tbl_part1');
+
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'tbl_normal');
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'gpt_test_sch.tbl_sch'); -- no result (excluded)
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'tbl_parent'); -- no result (excluded)
+SELECT * FROM test_gpt(ARRAY['pub_all_except'], 'tbl_part1'); -- no result (excluded)
+
+SELECT * FROM test_gpt(ARRAY['pub_all_novia_root'], 'tbl_parent'); -- no result
+SELECT * FROM test_gpt(ARRAY['pub_all_novia_root'], 'tbl_part1');
 
 -- Clean up
 DROP FUNCTION test_gpt(text, text);
-- 
2.53.0

