v8-0002-tab-complete-to-give-suggestions-in-case-of-multi.patch

application/x-patch

Filename: v8-0002-tab-complete-to-give-suggestions-in-case-of-multi.patch
Type: application/x-patch
Part: 1
Message: Re: Support EXCEPT for TABLES IN SCHEMA publications
From 52fc21fba3983485406565321e0607057fa8e48e Mon Sep 17 00:00:00 2001
From: Nisha Moond <nisha.moond412@gmail.com>
Date: Fri, 29 May 2026 19:50:12 +0530
Subject: [PATCH v8 2/4] tab complete to give suggestions in case of
 multi-schema.

---
 src/bin/psql/tab-complete.in.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index fe11dc619ac..831be27ad08 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -3791,24 +3791,40 @@ match_previous_words(int pattern_id,
 
 	/*
 	 * Complete "CREATE PUBLICATION <name> FOR TABLES IN SCHEMA <schema>, ..."
+	 *
+	 * Use HeadMatches+TailMatches instead of Matches for the EXCEPT sub-rules
+	 * so that a comma-separated schema list (e.g. "SCHEMA s1, s2") is handled
+	 * correctly: HeadMatches anchors the fixed prefix while TailMatches anchors
+	 * the fixed suffix, leaving any number of schema tokens in between.
 	 */
 	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA"))
 		COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas
 								 " AND nspname NOT LIKE E'pg\\\\_%%'",
 								 "CURRENT_SCHEMA");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny) && !ends_with(prev_wd, ','))
-		COMPLETE_WITH("EXCEPT ( TABLE", "WITH (");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny, "EXCEPT"))
+	else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA") &&
+			 TailMatches(MatchAny, "EXCEPT"))
 		COMPLETE_WITH("( TABLE");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny, "EXCEPT", "("))
+	else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA") &&
+			 TailMatches(MatchAny, "EXCEPT", "("))
 		COMPLETE_WITH("TABLE");
-	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny, "EXCEPT", "(", "TABLE"))
+	else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA") &&
+			 TailMatches(MatchAny, "EXCEPT", "(", "TABLE"))
 	{
 		set_completion_reference(prev4_wd);
 		COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_tables_in_schema);
 	}
+	/* Single-schema path: handles zero-or-more table names after TABLE */
 	else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny, "EXCEPT", "(", "TABLE", MatchAnyN) && !ends_with(prev_wd, ','))
 		COMPLETE_WITH(")");
+	/* Multi-schema path: covers exactly one table name after TABLE */
+	else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA") &&
+			 TailMatches("EXCEPT", "(", "TABLE", MatchAny) && !ends_with(prev_wd, ','))
+		COMPLETE_WITH(")");
+	else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA") &&
+			 (TailMatches("SCHEMA", MatchAny) || ends_with(prev2_wd, ',')) &&
+			 !ends_with(prev_wd, ',') && !ends_with(prev_wd, ')') &&
+			 !TailMatches(MatchAny, "=", MatchAny, MatchAny))
+		COMPLETE_WITH("EXCEPT ( TABLE", "WITH (");
 	/* Complete "CREATE PUBLICATION <name> [...] WITH" */
 	else if (Matches("CREATE", "PUBLICATION", MatchAnyN, "WITH", "("))
 		COMPLETE_WITH("publish", "publish_generated_columns", "publish_via_partition_root");
-- 
2.50.1 (Apple Git-155)