aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-09-21 15:58:37 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2018-09-21 15:58:37 -0400
commite8fe426baa9c242d8dbd4eab1d963e952c9172f4 (patch)
treef673541fcd387777daaa724e2204ca96c44228a8
parent121213d9d8527f880f153e4a032ee1a4cd43833f (diff)
downloadpostgresql-e8fe426baa9c242d8dbd4eab1d963e952c9172f4.tar.gz
postgresql-e8fe426baa9c242d8dbd4eab1d963e952c9172f4.zip
Fix bogus tab-completion rule for CREATE PUBLICATION.
You can't use "FOR TABLE" as a single Matches argument, because readline will consider that input to be two words not one. It's necessary to make the pattern contain two arguments. The case accidentally worked anyway because the words_after_create test fired ... but only for the first such table name. Noted by Edmund Horner, though this isn't exactly his proposed fix. Backpatch to v10 where the faulty code came in. Discussion: https://postgr.es/m/CAMyN-kDe=gBmHgxWwUUaXuwK+p+7g1vChR7foPHRDLE592nJPQ@mail.gmail.com
-rw-r--r--src/bin/psql/tab-complete.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index a4863487175..4c6b0fa09a2 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1419,6 +1419,21 @@ psql_completion(const char *text, int start, int end)
word_matches(p2, previous_words[previous_words_count - 2]) && \
word_matches(p3, previous_words[previous_words_count - 3]))
+#define HeadMatches4(p1, p2, p3, p4) \
+ (previous_words_count >= 4 && \
+ word_matches(p1, previous_words[previous_words_count - 1]) && \
+ word_matches(p2, previous_words[previous_words_count - 2]) && \
+ word_matches(p3, previous_words[previous_words_count - 3]) && \
+ word_matches(p4, previous_words[previous_words_count - 4]))
+
+#define HeadMatches5(p1, p2, p3, p4, p5) \
+ (previous_words_count >= 5 && \
+ word_matches(p1, previous_words[previous_words_count - 1]) && \
+ word_matches(p2, previous_words[previous_words_count - 2]) && \
+ word_matches(p3, previous_words[previous_words_count - 3]) && \
+ word_matches(p4, previous_words[previous_words_count - 4]) && \
+ word_matches(p5, previous_words[previous_words_count - 5]))
+
/* Known command-starting keywords. */
static const char *const sql_commands[] = {
"ABORT", "ALTER", "ANALYZE", "BEGIN", "CALL", "CHECKPOINT", "CLOSE", "CLUSTER",
@@ -2487,8 +2502,8 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST3("FOR TABLE", "FOR ALL TABLES", "WITH (");
else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR"))
COMPLETE_WITH_LIST2("TABLE", "ALL TABLES");
- /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>" */
- else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR TABLE"))
+ /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>, ..." */
+ else if (HeadMatches5("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
/* Complete "CREATE PUBLICATION <name> [...] WITH" */
else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "("))