Fix bogus tab-completion rule for CREATE PUBLICATION.
authorTom Lane
Fri, 21 Sep 2018 19:58:37 +0000 (15:58 -0400)
committerTom Lane
Fri, 21 Sep 2018 19:58:37 +0000 (15:58 -0400)
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

src/bin/psql/tab-complete.c

index d5f0130f4429642fd0ea54b1d7b3b92da8b04339..2dda6f1bb4f799291dd3db9f98ab3ed25cee9f9f 100644 (file)
@@ -1600,6 +1600,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",
@@ -2646,8 +2661,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  FOR TABLE " */
-   else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR TABLE"))
+   /* Complete "CREATE PUBLICATION  FOR TABLE 
, ..." */
+   else if (HeadMatches5("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"))
        COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
    /* Complete "CREATE PUBLICATION  [...] WITH" */
    else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "("))