From: Tom Lane Date: Sat, 22 Sep 2018 00:50:18 +0000 (-0400) Subject: Get rid of explicit argument-count markings in tab-complete.c. X-Git-Tag: REL_12_BETA1~1529 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f3b38fe2bde72d59b7eab593ff72e0cebd9ecc6;p=postgresql Get rid of explicit argument-count markings in tab-complete.c. This replaces the "TailMatchesN" macros with just "TailMatches", and likewise "HeadMatchesN" becomes "HeadMatches" and "MatchesN" becomes "Matches". The various COMPLETE_WITH_LISTn macros are reduced to COMPLETE_WITH, and the single-item COMPLETE_WITH_CONST also gets folded into that. This eliminates a lot of minor annoyance in writing tab-completion rules. Usefully, the compiled code also gets a bit smaller (10% or so, on my machine). The implementation depends on variadic macros, so we couldn't have done this before we required C99. Andres Freund and Thomas Munro; some cosmetic cleanup by me. Discussion: https://postgr.es/m/d8jo9djvm7h.fsf@dalvik.ping.uio.no --- diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 4c6b0fa09a..299600652f 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -173,10 +173,10 @@ static bool completion_case_sensitive; /* completion is case sensitive */ * 2) The results from a schema query you pass it. * We support both simple and versioned schema queries. * 3) The items from a null-pointer-terminated list (with or without - * case-sensitive comparison; see also COMPLETE_WITH_LISTn, below). - * 4) A string constant. - * 5) The list of attributes of the given table (possibly schema-qualified). - * 6/ The list of arguments to the given function (possibly schema-qualified). + * case-sensitive comparison); if the list is constant you can build it + * with COMPLETE_WITH() or COMPLETE_WITH_CS(). + * 4) The list of attributes of the given table (possibly schema-qualified). + * 5) The list of arguments to the given function (possibly schema-qualified). */ #define COMPLETE_WITH_QUERY(query) \ do { \ @@ -204,25 +204,34 @@ do { \ matches = completion_matches(text, complete_from_versioned_schema_query); \ } while (0) -#define COMPLETE_WITH_LIST_CS(list) \ +#define COMPLETE_WITH_LIST_INT(cs, list) \ do { \ - completion_charpp = list; \ - completion_case_sensitive = true; \ - matches = completion_matches(text, complete_from_list); \ + completion_case_sensitive = (cs); \ + if (!(list)[1]) \ + { \ + completion_charp = (list)[0]; \ + matches = completion_matches(text, complete_from_const); \ + } \ + else \ + { \ + completion_charpp = (list); \ + matches = completion_matches(text, complete_from_list); \ + } \ } while (0) -#define COMPLETE_WITH_LIST(list) \ +#define COMPLETE_WITH_LIST(list) COMPLETE_WITH_LIST_INT(false, list) +#define COMPLETE_WITH_LIST_CS(list) COMPLETE_WITH_LIST_INT(true, list) + +#define COMPLETE_WITH(...) \ do { \ - completion_charpp = list; \ - completion_case_sensitive = false; \ - matches = completion_matches(text, complete_from_list); \ + static const char *const list[] = { __VA_ARGS__, NULL }; \ + COMPLETE_WITH_LIST(list); \ } while (0) -#define COMPLETE_WITH_CONST(string) \ +#define COMPLETE_WITH_CS(...) \ do { \ - completion_charp = string; \ - completion_case_sensitive = false; \ - matches = completion_matches(text, complete_from_const); \ + static const char *const list[] = { __VA_ARGS__, NULL }; \ + COMPLETE_WITH_LIST_CS(list); \ } while (0) #define COMPLETE_WITH_ATTR(relation, addon) \ @@ -300,91 +309,6 @@ do { \ matches = completion_matches(text, complete_from_query); \ } while (0) -/* - * These macros simplify use of COMPLETE_WITH_LIST for short, fixed lists. - * There is no COMPLETE_WITH_LIST1; use COMPLETE_WITH_CONST for that case. - */ -#define COMPLETE_WITH_LIST2(s1, s2) \ -do { \ - static const char *const list[] = { s1, s2, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST3(s1, s2, s3) \ -do { \ - static const char *const list[] = { s1, s2, s3, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST4(s1, s2, s3, s4) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST5(s1, s2, s3, s4, s5) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST6(s1, s2, s3, s4, s5, s6) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST7(s1, s2, s3, s4, s5, s6, s7) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST8(s1, s2, s3, s4, s5, s6, s7, s8) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST9(s1, s2, s3, s4, s5, s6, s7, s8, s9) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST10(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -/* - * Likewise for COMPLETE_WITH_LIST_CS. - */ -#define COMPLETE_WITH_LIST_CS2(s1, s2) \ -do { \ - static const char *const list[] = { s1, s2, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - -#define COMPLETE_WITH_LIST_CS3(s1, s2, s3) \ -do { \ - static const char *const list[] = { s1, s2, s3, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - -#define COMPLETE_WITH_LIST_CS4(s1, s2, s3, s4) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - -#define COMPLETE_WITH_LIST_CS5(s1, s2, s3, s4, s5) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - /* * Assembly instructions for schema queries */ @@ -1142,9 +1066,9 @@ initialize_readline(void) #define MatchAnyExcept(pattern) ("!" pattern) static bool -word_matches_internal(const char *pattern, - const char *word, - bool case_sensitive) +word_matches(const char *pattern, + const char *word, + bool case_sensitive) { size_t wordlen; @@ -1157,7 +1081,7 @@ word_matches_internal(const char *pattern, /* Handle negated patterns from the MatchAnyExcept macro. */ if (*pattern == '!') - return !word_matches_internal(pattern + 1, word, case_sensitive); + return !word_matches(pattern + 1, word, case_sensitive); /* Else consider each alternative in the pattern. */ wordlen = strlen(word); @@ -1204,24 +1128,105 @@ word_matches_internal(const char *pattern, } /* - * There are enough matching calls below that it seems worth having these two - * interface routines rather than including a third parameter in every call. + * Implementation of TailMatches and TailMatchesCS macros: do the last N words + * in previous_words match the variadic arguments? * - * word_matches --- match case-insensitively. + * The array indexing might look backwards, but remember that + * previous_words[0] contains the *last* word on the line, not the first. */ static bool -word_matches(const char *pattern, const char *word) +TailMatchesImpl(bool case_sensitive, + int previous_words_count, char **previous_words, + int narg,...) { - return word_matches_internal(pattern, word, false); + va_list args; + + if (previous_words_count < narg) + return false; + + va_start(args, narg); + + for (int argno = 0; argno < narg; argno++) + { + const char *arg = va_arg(args, const char *); + + if (!word_matches(arg, previous_words[narg - argno - 1], + case_sensitive)) + { + va_end(args); + return false; + } + } + + va_end(args); + + return true; +} + +/* + * Implementation of Matches and MatchesCS macros: do all of the words + * in previous_words match the variadic arguments? + */ +static bool +MatchesImpl(bool case_sensitive, + int previous_words_count, char **previous_words, + int narg,...) +{ + va_list args; + + if (previous_words_count != narg) + return false; + + va_start(args, narg); + + for (int argno = 0; argno < narg; argno++) + { + const char *arg = va_arg(args, const char *); + + if (!word_matches(arg, previous_words[narg - argno - 1], + case_sensitive)) + { + va_end(args); + return false; + } + } + + va_end(args); + + return true; } /* - * word_matches_cs --- match case-sensitively. + * Implementation of HeadMatches and HeadMatchesCS macros: do the first N + * words in previous_words match the variadic arguments? */ static bool -word_matches_cs(const char *pattern, const char *word) +HeadMatchesImpl(bool case_sensitive, + int previous_words_count, char **previous_words, + int narg,...) { - return word_matches_internal(pattern, word, true); + va_list args; + + if (previous_words_count < narg) + return false; + + va_start(args, narg); + + for (int argno = 0; argno < narg; argno++) + { + const char *arg = va_arg(args, const char *); + + if (!word_matches(arg, previous_words[previous_words_count - argno - 1], + case_sensitive)) + { + va_end(args); + return false; + } + } + + va_end(args); + + return true; } /* @@ -1275,164 +1280,35 @@ psql_completion(const char *text, int start, int end) #define prev8_wd (previous_words[7]) #define prev9_wd (previous_words[8]) - /* Macros for matching the last N words before point, case-insensitively. */ -#define TailMatches1(p1) \ - (previous_words_count >= 1 && \ - word_matches(p1, prev_wd)) - -#define TailMatches2(p2, p1) \ - (previous_words_count >= 2 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd)) - -#define TailMatches3(p3, p2, p1) \ - (previous_words_count >= 3 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd)) - -#define TailMatches4(p4, p3, p2, p1) \ - (previous_words_count >= 4 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd)) - -#define TailMatches5(p5, p4, p3, p2, p1) \ - (previous_words_count >= 5 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd)) - -#define TailMatches6(p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 6 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd)) - -#define TailMatches7(p7, p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 7 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd) && \ - word_matches(p7, prev7_wd)) - -#define TailMatches8(p8, p7, p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 8 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd) && \ - word_matches(p7, prev7_wd) && \ - word_matches(p8, prev8_wd)) - -#define TailMatches9(p9, p8, p7, p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 9 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd) && \ - word_matches(p7, prev7_wd) && \ - word_matches(p8, prev8_wd) && \ - word_matches(p9, prev9_wd)) - - /* Macros for matching the last N words before point, case-sensitively. */ -#define TailMatchesCS1(p1) \ - (previous_words_count >= 1 && \ - word_matches_cs(p1, prev_wd)) -#define TailMatchesCS2(p2, p1) \ - (previous_words_count >= 2 && \ - word_matches_cs(p1, prev_wd) && \ - word_matches_cs(p2, prev2_wd)) -#define TailMatchesCS3(p3, p2, p1) \ - (previous_words_count >= 3 && \ - word_matches_cs(p1, prev_wd) && \ - word_matches_cs(p2, prev2_wd) && \ - word_matches_cs(p3, prev3_wd)) -#define TailMatchesCS4(p4, p3, p2, p1) \ - (previous_words_count >= 4 && \ - word_matches_cs(p1, prev_wd) && \ - word_matches_cs(p2, prev2_wd) && \ - word_matches_cs(p3, prev3_wd) && \ - word_matches_cs(p4, prev4_wd)) + /* Match the last N words before point, case-insensitively. */ +#define TailMatches(...) \ + TailMatchesImpl(false, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) - /* - * Macros for matching N words beginning at the start of the line, - * case-insensitively. - */ -#define Matches1(p1) \ - (previous_words_count == 1 && \ - TailMatches1(p1)) -#define Matches2(p1, p2) \ - (previous_words_count == 2 && \ - TailMatches2(p1, p2)) -#define Matches3(p1, p2, p3) \ - (previous_words_count == 3 && \ - TailMatches3(p1, p2, p3)) -#define Matches4(p1, p2, p3, p4) \ - (previous_words_count == 4 && \ - TailMatches4(p1, p2, p3, p4)) -#define Matches5(p1, p2, p3, p4, p5) \ - (previous_words_count == 5 && \ - TailMatches5(p1, p2, p3, p4, p5)) -#define Matches6(p1, p2, p3, p4, p5, p6) \ - (previous_words_count == 6 && \ - TailMatches6(p1, p2, p3, p4, p5, p6)) -#define Matches7(p1, p2, p3, p4, p5, p6, p7) \ - (previous_words_count == 7 && \ - TailMatches7(p1, p2, p3, p4, p5, p6, p7)) -#define Matches8(p1, p2, p3, p4, p5, p6, p7, p8) \ - (previous_words_count == 8 && \ - TailMatches8(p1, p2, p3, p4, p5, p6, p7, p8)) -#define Matches9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \ - (previous_words_count == 9 && \ - TailMatches9(p1, p2, p3, p4, p5, p6, p7, p8, p9)) + /* Match the last N words before point, case-sensitively. */ +#define TailMatchesCS(...) \ + TailMatchesImpl(true, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) - /* - * Macros for matching N words at the start of the line, regardless of - * what is after them, case-insensitively. - */ -#define HeadMatches1(p1) \ - (previous_words_count >= 1 && \ - word_matches(p1, previous_words[previous_words_count - 1])) - -#define HeadMatches2(p1, p2) \ - (previous_words_count >= 2 && \ - word_matches(p1, previous_words[previous_words_count - 1]) && \ - word_matches(p2, previous_words[previous_words_count - 2])) - -#define HeadMatches3(p1, p2, p3) \ - (previous_words_count >= 3 && \ - 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])) - -#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])) + /* Match N words representing all of the line, case-insensitively. */ +#define Matches(...) \ + MatchesImpl(false, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + + /* Match N words representing all of the line, case-sensitively. */ +#define MatchesCS(...) \ + MatchesImpl(true, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + + /* Match the first N words on the line, case-insensitively. */ +#define HeadMatches(...) \ + HeadMatchesImpl(false, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + + /* Match the first N words on the line, case-sensitively. */ +#define HeadMatchesCS(...) \ + HeadMatchesImpl(true, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) /* Known command-starting keywords. */ static const char *const sql_commands[] = { @@ -1522,369 +1398,350 @@ psql_completion(const char *text, int start, int end) /* CREATE */ /* complete with something you can create */ - else if (TailMatches1("CREATE")) + else if (TailMatches("CREATE")) matches = completion_matches(text, create_command_generator); /* DROP, but not DROP embedded in other commands */ /* complete with something you can drop */ - else if (Matches1("DROP")) + else if (Matches("DROP")) matches = completion_matches(text, drop_command_generator); /* ALTER */ /* ALTER TABLE */ - else if (Matches2("ALTER", "TABLE")) + else if (Matches("ALTER", "TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "UNION SELECT 'ALL IN TABLESPACE'"); /* ALTER something */ - else if (Matches1("ALTER")) + else if (Matches("ALTER")) matches = completion_matches(text, alter_command_generator); /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */ - else if (TailMatches4("ALL", "IN", "TABLESPACE", MatchAny)) - COMPLETE_WITH_LIST2("SET TABLESPACE", "OWNED BY"); + else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny)) + COMPLETE_WITH("SET TABLESPACE", "OWNED BY"); /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */ - else if (TailMatches6("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY")) + else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */ - else if (TailMatches7("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny)) - COMPLETE_WITH_CONST("SET TABLESPACE"); + else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny)) + COMPLETE_WITH("SET TABLESPACE"); /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE */ - else if (Matches3("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) + COMPLETE_WITH("("); /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE (...) */ - else if (Matches4("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny)) + else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny)) { if (ends_with(prev_wd, ')')) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); else COMPLETE_WITH_FUNCTION_ARG(prev2_wd); } /* ALTER PUBLICATION */ - else if (Matches3("ALTER", "PUBLICATION", MatchAny)) - COMPLETE_WITH_LIST5("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET"); + else if (Matches("ALTER", "PUBLICATION", MatchAny)) + COMPLETE_WITH("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET"); /* ALTER PUBLICATION SET */ - else if (Matches4("ALTER", "PUBLICATION", MatchAny, "SET")) - COMPLETE_WITH_LIST2("(", "TABLE"); + else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET")) + COMPLETE_WITH("(", "TABLE"); /* ALTER PUBLICATION SET ( */ - else if (HeadMatches3("ALTER", "PUBLICATION", MatchAny) && TailMatches2("SET", "(")) - COMPLETE_WITH_CONST("publish"); + else if (HeadMatches("ALTER", "PUBLICATION", MatchAny) && TailMatches("SET", "(")) + COMPLETE_WITH("publish"); /* ALTER SUBSCRIPTION */ - else if (Matches3("ALTER", "SUBSCRIPTION", MatchAny)) - COMPLETE_WITH_LIST7("CONNECTION", "ENABLE", "DISABLE", "OWNER TO", - "RENAME TO", "REFRESH PUBLICATION", "SET"); + else if (Matches("ALTER", "SUBSCRIPTION", MatchAny)) + COMPLETE_WITH("CONNECTION", "ENABLE", "DISABLE", "OWNER TO", + "RENAME TO", "REFRESH PUBLICATION", "SET"); /* ALTER SUBSCRIPTION REFRESH PUBLICATION */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches2("REFRESH", "PUBLICATION")) - COMPLETE_WITH_CONST("WITH ("); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("REFRESH", "PUBLICATION")) + COMPLETE_WITH("WITH ("); /* ALTER SUBSCRIPTION REFRESH PUBLICATION WITH ( */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches4("REFRESH", "PUBLICATION", "WITH", "(")) - COMPLETE_WITH_CONST("copy_data"); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("REFRESH", "PUBLICATION", "WITH", "(")) + COMPLETE_WITH("copy_data"); /* ALTER SUBSCRIPTION SET */ - else if (Matches4("ALTER", "SUBSCRIPTION", MatchAny, "SET")) - COMPLETE_WITH_LIST2("(", "PUBLICATION"); + else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, "SET")) + COMPLETE_WITH("(", "PUBLICATION"); /* ALTER SUBSCRIPTION SET ( */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("SET", "(")) - COMPLETE_WITH_LIST2("slot_name", "synchronous_commit"); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "(")) + COMPLETE_WITH("slot_name", "synchronous_commit"); /* ALTER SUBSCRIPTION SET PUBLICATION */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("SET", "PUBLICATION")) + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "PUBLICATION")) { /* complete with nothing here as this refers to remote publications */ } /* ALTER SUBSCRIPTION SET PUBLICATION */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches3("SET", "PUBLICATION", MatchAny)) - COMPLETE_WITH_CONST("WITH ("); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("SET", "PUBLICATION", MatchAny)) + COMPLETE_WITH("WITH ("); /* ALTER SUBSCRIPTION SET PUBLICATION WITH ( */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches5("SET", "PUBLICATION", MatchAny, "WITH", "(")) - COMPLETE_WITH_LIST2("copy_data", "refresh"); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("SET", "PUBLICATION", MatchAny, "WITH", "(")) + COMPLETE_WITH("copy_data", "refresh"); /* ALTER SCHEMA */ - else if (Matches3("ALTER", "SCHEMA", MatchAny)) - COMPLETE_WITH_LIST2("OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "SCHEMA", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO"); /* ALTER COLLATION */ - else if (Matches3("ALTER", "COLLATION", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "COLLATION", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); /* ALTER CONVERSION */ - else if (Matches3("ALTER", "CONVERSION", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "CONVERSION", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); /* ALTER DATABASE */ - else if (Matches3("ALTER", "DATABASE", MatchAny)) - COMPLETE_WITH_LIST7("RESET", "SET", "OWNER TO", "RENAME TO", - "IS_TEMPLATE", "ALLOW_CONNECTIONS", - "CONNECTION LIMIT"); + else if (Matches("ALTER", "DATABASE", MatchAny)) + COMPLETE_WITH("RESET", "SET", "OWNER TO", "RENAME TO", + "IS_TEMPLATE", "ALLOW_CONNECTIONS", + "CONNECTION LIMIT"); /* ALTER DATABASE SET TABLESPACE */ - else if (Matches5("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE")) + else if (Matches("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE")) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); /* ALTER EVENT TRIGGER */ - else if (Matches3("ALTER", "EVENT", "TRIGGER")) + else if (Matches("ALTER", "EVENT", "TRIGGER")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); /* ALTER EVENT TRIGGER */ - else if (Matches4("ALTER", "EVENT", "TRIGGER", MatchAny)) - COMPLETE_WITH_LIST4("DISABLE", "ENABLE", "OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny)) + COMPLETE_WITH("DISABLE", "ENABLE", "OWNER TO", "RENAME TO"); /* ALTER EVENT TRIGGER ENABLE */ - else if (Matches5("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE")) - COMPLETE_WITH_LIST2("REPLICA", "ALWAYS"); + else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE")) + COMPLETE_WITH("REPLICA", "ALWAYS"); /* ALTER EXTENSION */ - else if (Matches3("ALTER", "EXTENSION", MatchAny)) - COMPLETE_WITH_LIST4("ADD", "DROP", "UPDATE", "SET SCHEMA"); + else if (Matches("ALTER", "EXTENSION", MatchAny)) + COMPLETE_WITH("ADD", "DROP", "UPDATE", "SET SCHEMA"); /* ALTER EXTENSION UPDATE */ - else if (Matches4("ALTER", "EXTENSION", MatchAny, "UPDATE")) + else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO); } /* ALTER EXTENSION UPDATE TO */ - else if (Matches5("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO")) + else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions); } /* ALTER FOREIGN */ - else if (Matches2("ALTER", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); + else if (Matches("ALTER", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); /* ALTER FOREIGN DATA WRAPPER */ - else if (Matches5("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny)) - COMPLETE_WITH_LIST5("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny)) + COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO"); /* ALTER FOREIGN TABLE */ - else if (Matches4("ALTER", "FOREIGN", "TABLE", MatchAny)) - { - static const char *const list_ALTER_FOREIGN_TABLE[] = - {"ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE", "INHERIT", - "NO INHERIT", "OPTIONS", "OWNER TO", "RENAME", "SET", - "VALIDATE CONSTRAINT", NULL}; - - COMPLETE_WITH_LIST(list_ALTER_FOREIGN_TABLE); - } + else if (Matches("ALTER", "FOREIGN", "TABLE", MatchAny)) + COMPLETE_WITH("ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE", + "INHERIT", "NO INHERIT", "OPTIONS", "OWNER TO", + "RENAME", "SET", "VALIDATE CONSTRAINT"); /* ALTER INDEX */ - else if (Matches2("ALTER", "INDEX")) + else if (Matches("ALTER", "INDEX")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, "UNION SELECT 'ALL IN TABLESPACE'"); /* ALTER INDEX */ - else if (Matches3("ALTER", "INDEX", MatchAny)) - COMPLETE_WITH_LIST6("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET", - "RESET", "ATTACH PARTITION"); - else if (Matches4("ALTER", "INDEX", MatchAny, "ATTACH")) - COMPLETE_WITH_CONST("PARTITION"); - else if (Matches5("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION")) + else if (Matches("ALTER", "INDEX", MatchAny)) + COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET", + "RESET", "ATTACH PARTITION"); + else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH")) + COMPLETE_WITH("PARTITION"); + else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); /* ALTER INDEX ALTER COLUMN */ - else if (Matches6("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny)) - COMPLETE_WITH_CONST("SET STATISTICS"); + else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny)) + COMPLETE_WITH("SET STATISTICS"); /* ALTER INDEX SET */ - else if (Matches4("ALTER", "INDEX", MatchAny, "SET")) - COMPLETE_WITH_LIST2("(", "TABLESPACE"); + else if (Matches("ALTER", "INDEX", MatchAny, "SET")) + COMPLETE_WITH("(", "TABLESPACE"); /* ALTER INDEX RESET */ - else if (Matches4("ALTER", "INDEX", MatchAny, "RESET")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "INDEX", MatchAny, "RESET")) + COMPLETE_WITH("("); /* ALTER INDEX SET|RESET ( */ - else if (Matches5("ALTER", "INDEX", MatchAny, "RESET", "(")) - COMPLETE_WITH_LIST8("fillfactor", "recheck_on_update", - "vacuum_cleanup_index_scale_factor", /* BTREE */ - "fastupdate", "gin_pending_list_limit", /* GIN */ - "buffering", /* GiST */ - "pages_per_range", "autosummarize" /* BRIN */ + else if (Matches("ALTER", "INDEX", MatchAny, "RESET", "(")) + COMPLETE_WITH("fillfactor", "recheck_on_update", + "vacuum_cleanup_index_scale_factor", /* BTREE */ + "fastupdate", "gin_pending_list_limit", /* GIN */ + "buffering", /* GiST */ + "pages_per_range", "autosummarize" /* BRIN */ ); - else if (Matches5("ALTER", "INDEX", MatchAny, "SET", "(")) - COMPLETE_WITH_LIST8("fillfactor =", "recheck_on_update =", - "vacuum_cleanup_index_scale_factor =", /* BTREE */ - "fastupdate =", "gin_pending_list_limit =", /* GIN */ - "buffering =", /* GiST */ - "pages_per_range =", "autosummarize =" /* BRIN */ + else if (Matches("ALTER", "INDEX", MatchAny, "SET", "(")) + COMPLETE_WITH("fillfactor =", "recheck_on_update =", + "vacuum_cleanup_index_scale_factor =", /* BTREE */ + "fastupdate =", "gin_pending_list_limit =", /* GIN */ + "buffering =", /* GiST */ + "pages_per_range =", "autosummarize =" /* BRIN */ ); /* ALTER LANGUAGE */ - else if (Matches3("ALTER", "LANGUAGE", MatchAny)) - COMPLETE_WITH_LIST2("OWNER_TO", "RENAME TO"); + else if (Matches("ALTER", "LANGUAGE", MatchAny)) + COMPLETE_WITH("OWNER_TO", "RENAME TO"); /* ALTER LARGE OBJECT */ - else if (Matches4("ALTER", "LARGE", "OBJECT", MatchAny)) - COMPLETE_WITH_CONST("OWNER TO"); + else if (Matches("ALTER", "LARGE", "OBJECT", MatchAny)) + COMPLETE_WITH("OWNER TO"); /* ALTER MATERIALIZED VIEW */ - else if (Matches3("ALTER", "MATERIALIZED", "VIEW")) + else if (Matches("ALTER", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, "UNION SELECT 'ALL IN TABLESPACE'"); /* ALTER USER,ROLE */ - else if (Matches3("ALTER", "USER|ROLE", MatchAny) && - !TailMatches2("USER", "MAPPING")) - { - static const char *const list_ALTERUSER[] = - {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO", - "REPLICATION", "RESET", "SET", "SUPERUSER", - "VALID UNTIL", "WITH", NULL}; - - COMPLETE_WITH_LIST(list_ALTERUSER); - } + else if (Matches("ALTER", "USER|ROLE", MatchAny) && + !TailMatches("USER", "MAPPING")) + COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", + "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER", + "VALID UNTIL", "WITH"); /* ALTER USER,ROLE WITH */ - else if (Matches4("ALTER", "USER|ROLE", MatchAny, "WITH")) - { + else if (Matches("ALTER", "USER|ROLE", MatchAny, "WITH")) /* Similar to the above, but don't complete "WITH" again. */ - static const char *const list_ALTERUSER_WITH[] = - {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO", - "REPLICATION", "RESET", "SET", "SUPERUSER", - "VALID UNTIL", NULL}; - - COMPLETE_WITH_LIST(list_ALTERUSER_WITH); - } + COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", + "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER", + "VALID UNTIL"); /* ALTER DEFAULT PRIVILEGES */ - else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES")) - COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES")) + COMPLETE_WITH("FOR ROLE", "IN SCHEMA"); /* ALTER DEFAULT PRIVILEGES FOR */ - else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR")) - COMPLETE_WITH_CONST("ROLE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR")) + COMPLETE_WITH("ROLE"); /* ALTER DEFAULT PRIVILEGES IN */ - else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN")) - COMPLETE_WITH_CONST("SCHEMA"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN")) + COMPLETE_WITH("SCHEMA"); /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */ - else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", - MatchAny)) - COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", + MatchAny)) + COMPLETE_WITH("GRANT", "REVOKE", "IN SCHEMA"); /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */ - else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", - MatchAny)) - COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny)) + COMPLETE_WITH("GRANT", "REVOKE", "FOR ROLE"); /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */ - else if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", - MatchAny, "FOR")) - COMPLETE_WITH_CONST("ROLE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny, "FOR")) + COMPLETE_WITH("ROLE"); /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */ /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */ - else if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", - MatchAny, "IN", "SCHEMA", MatchAny) || - Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", - MatchAny, "FOR", "ROLE|USER", MatchAny)) - COMPLETE_WITH_LIST2("GRANT", "REVOKE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", + MatchAny, "IN", "SCHEMA", MatchAny) || + Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny, "FOR", "ROLE|USER", MatchAny)) + COMPLETE_WITH("GRANT", "REVOKE"); /* ALTER DOMAIN */ - else if (Matches3("ALTER", "DOMAIN", MatchAny)) - COMPLETE_WITH_LIST6("ADD", "DROP", "OWNER TO", "RENAME", "SET", - "VALIDATE CONSTRAINT"); + else if (Matches("ALTER", "DOMAIN", MatchAny)) + COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME", "SET", + "VALIDATE CONSTRAINT"); /* ALTER DOMAIN DROP */ - else if (Matches4("ALTER", "DOMAIN", MatchAny, "DROP")) - COMPLETE_WITH_LIST3("CONSTRAINT", "DEFAULT", "NOT NULL"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP")) + COMPLETE_WITH("CONSTRAINT", "DEFAULT", "NOT NULL"); /* ALTER DOMAIN DROP|RENAME|VALIDATE CONSTRAINT */ - else if (Matches5("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT")) + else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_constraint_of_type); } /* ALTER DOMAIN RENAME */ - else if (Matches4("ALTER", "DOMAIN", MatchAny, "RENAME")) - COMPLETE_WITH_LIST2("CONSTRAINT", "TO"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME")) + COMPLETE_WITH("CONSTRAINT", "TO"); /* ALTER DOMAIN RENAME CONSTRAINT */ - else if (Matches6("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny)) + COMPLETE_WITH("TO"); /* ALTER DOMAIN SET */ - else if (Matches4("ALTER", "DOMAIN", MatchAny, "SET")) - COMPLETE_WITH_LIST3("DEFAULT", "NOT NULL", "SCHEMA"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "SET")) + COMPLETE_WITH("DEFAULT", "NOT NULL", "SCHEMA"); /* ALTER SEQUENCE */ - else if (Matches3("ALTER", "SEQUENCE", MatchAny)) - { - static const char *const list_ALTERSEQUENCE[] = - {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE", - "SET SCHEMA", "OWNED BY", "OWNER TO", "RENAME TO", NULL}; - - COMPLETE_WITH_LIST(list_ALTERSEQUENCE); - } + else if (Matches("ALTER", "SEQUENCE", MatchAny)) + COMPLETE_WITH("INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", + "CACHE", "CYCLE", "SET SCHEMA", "OWNED BY", "OWNER TO", + "RENAME TO"); /* ALTER SEQUENCE NO */ - else if (Matches4("ALTER", "SEQUENCE", MatchAny, "NO")) - COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE"); + else if (Matches("ALTER", "SEQUENCE", MatchAny, "NO")) + COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE"); /* ALTER SERVER */ - else if (Matches3("ALTER", "SERVER", MatchAny)) - COMPLETE_WITH_LIST4("VERSION", "OPTIONS", "OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "SERVER", MatchAny)) + COMPLETE_WITH("VERSION", "OPTIONS", "OWNER TO", "RENAME TO"); /* ALTER SERVER VERSION */ - else if (Matches5("ALTER", "SERVER", MatchAny, "VERSION", MatchAny)) - COMPLETE_WITH_CONST("OPTIONS"); + else if (Matches("ALTER", "SERVER", MatchAny, "VERSION", MatchAny)) + COMPLETE_WITH("OPTIONS"); /* ALTER SYSTEM SET, RESET, RESET ALL */ - else if (Matches2("ALTER", "SYSTEM")) - COMPLETE_WITH_LIST2("SET", "RESET"); - else if (Matches3("ALTER", "SYSTEM", "SET|RESET")) + else if (Matches("ALTER", "SYSTEM")) + COMPLETE_WITH("SET", "RESET"); + else if (Matches("ALTER", "SYSTEM", "SET|RESET")) COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars); - else if (Matches4("ALTER", "SYSTEM", "SET", MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "SYSTEM", "SET", MatchAny)) + COMPLETE_WITH("TO"); /* ALTER VIEW */ - else if (Matches3("ALTER", "VIEW", MatchAny)) - COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO", - "SET SCHEMA"); + else if (Matches("ALTER", "VIEW", MatchAny)) + COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", + "SET SCHEMA"); /* ALTER MATERIALIZED VIEW */ - else if (Matches4("ALTER", "MATERIALIZED", "VIEW", MatchAny)) - COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO", - "SET SCHEMA"); + else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny)) + COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", + "SET SCHEMA"); /* ALTER POLICY */ - else if (Matches2("ALTER", "POLICY")) + else if (Matches("ALTER", "POLICY")) COMPLETE_WITH_QUERY(Query_for_list_of_policies); /* ALTER POLICY ON */ - else if (Matches3("ALTER", "POLICY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("ALTER", "POLICY", MatchAny)) + COMPLETE_WITH("ON"); /* ALTER POLICY ON */ - else if (Matches4("ALTER", "POLICY", MatchAny, "ON")) + else if (Matches("ALTER", "POLICY", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy); } /* ALTER POLICY ON
- show options */ - else if (Matches5("ALTER", "POLICY", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST4("RENAME TO", "TO", "USING (", "WITH CHECK ("); + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("RENAME TO", "TO", "USING (", "WITH CHECK ("); /* ALTER POLICY ON
TO */ - else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO")) + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* ALTER POLICY ON
USING ( */ - else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING")) + COMPLETE_WITH("("); /* ALTER POLICY ON
WITH CHECK ( */ - else if (Matches7("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK")) + COMPLETE_WITH("("); /* ALTER RULE , add ON */ - else if (Matches3("ALTER", "RULE", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("ALTER", "RULE", MatchAny)) + COMPLETE_WITH("ON"); /* If we have ALTER RULE ON, then add the correct tablename */ - else if (Matches4("ALTER", "RULE", MatchAny, "ON")) + else if (Matches("ALTER", "RULE", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule); } /* ALTER RULE ON */ - else if (Matches5("ALTER", "RULE", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_CONST("RENAME TO"); + else if (Matches("ALTER", "RULE", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("RENAME TO"); /* ALTER STATISTICS */ - else if (Matches3("ALTER", "STATISTICS", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "STATISTICS", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); /* ALTER TRIGGER , add ON */ - else if (Matches3("ALTER", "TRIGGER", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("ALTER", "TRIGGER", MatchAny)) + COMPLETE_WITH("ON"); - else if (Matches4("ALTER", "TRIGGER", MatchAny, MatchAny)) + else if (Matches("ALTER", "TRIGGER", MatchAny, MatchAny)) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger); @@ -1893,155 +1750,151 @@ psql_completion(const char *text, int start, int end) /* * If we have ALTER TRIGGER ON, then add the correct tablename */ - else if (Matches4("ALTER", "TRIGGER", MatchAny, "ON")) + else if (Matches("ALTER", "TRIGGER", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* ALTER TRIGGER ON */ - else if (Matches5("ALTER", "TRIGGER", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_CONST("RENAME TO"); + else if (Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("RENAME TO"); /* * If we detect ALTER TABLE , suggest sub commands */ - else if (Matches3("ALTER", "TABLE", MatchAny)) - { - static const char *const list_ALTER2[] = - {"ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", "ENABLE", "INHERIT", - "NO INHERIT", "RENAME", "RESET", "OWNER TO", "SET", - "VALIDATE CONSTRAINT", "REPLICA IDENTITY", "ATTACH PARTITION", - "DETACH PARTITION", NULL}; - - COMPLETE_WITH_LIST(list_ALTER2); - } + else if (Matches("ALTER", "TABLE", MatchAny)) + COMPLETE_WITH("ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", + "ENABLE", "INHERIT", "NO INHERIT", "RENAME", "RESET", + "OWNER TO", "SET", "VALIDATE CONSTRAINT", + "REPLICA IDENTITY", "ATTACH PARTITION", + "DETACH PARTITION"); /* ALTER TABLE xxx ENABLE */ - else if (Matches4("ALTER", "TABLE", MatchAny, "ENABLE")) - COMPLETE_WITH_LIST5("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE", - "TRIGGER"); - else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS")) - COMPLETE_WITH_LIST2("RULE", "TRIGGER"); - else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "RULE")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE")) + COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE", + "TRIGGER"); + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS")) + COMPLETE_WITH("RULE", "TRIGGER"); + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_rule_of_table); } - else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE")) { completion_info_charp = prev4_wd; COMPLETE_WITH_QUERY(Query_for_rule_of_table); } - else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_trigger_of_table); } - else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER")) { completion_info_charp = prev4_wd; COMPLETE_WITH_QUERY(Query_for_trigger_of_table); } /* ALTER TABLE xxx INHERIT */ - else if (Matches4("ALTER", "TABLE", MatchAny, "INHERIT")) + else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* ALTER TABLE xxx NO INHERIT */ - else if (Matches5("ALTER", "TABLE", MatchAny, "NO", "INHERIT")) + else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* ALTER TABLE xxx DISABLE */ - else if (Matches4("ALTER", "TABLE", MatchAny, "DISABLE")) - COMPLETE_WITH_LIST3("ROW LEVEL SECURITY", "RULE", "TRIGGER"); - else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "RULE")) + else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE")) + COMPLETE_WITH("ROW LEVEL SECURITY", "RULE", "TRIGGER"); + else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_rule_of_table); } - else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER")) + else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_trigger_of_table); } /* ALTER TABLE xxx ALTER */ - else if (Matches4("ALTER", "TABLE", MatchAny, "ALTER")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER")) COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'"); /* ALTER TABLE xxx RENAME */ - else if (Matches4("ALTER", "TABLE", MatchAny, "RENAME")) + else if (Matches("ALTER", "TABLE", MatchAny, "RENAME")) COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'"); - else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* ALTER TABLE xxx RENAME yyy */ - else if (Matches5("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO"))) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO"))) + COMPLETE_WITH("TO"); /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */ - else if (Matches6("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO"))) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO"))) + COMPLETE_WITH("TO"); /* If we have ALTER TABLE DROP, provide COLUMN or CONSTRAINT */ - else if (Matches4("ALTER", "TABLE", MatchAny, "DROP")) - COMPLETE_WITH_LIST2("COLUMN", "CONSTRAINT"); + else if (Matches("ALTER", "TABLE", MatchAny, "DROP")) + COMPLETE_WITH("COLUMN", "CONSTRAINT"); /* If we have ALTER TABLE DROP COLUMN, provide list of columns */ - else if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN")) + else if (Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* * If we have ALTER TABLE ALTER|DROP|RENAME|VALIDATE CONSTRAINT, * provide list of constraints */ - else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_constraint_of_table); } /* ALTER TABLE ALTER [COLUMN] */ - else if (Matches6("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) || - Matches5("ALTER", "TABLE", MatchAny, "ALTER", MatchAny)) - COMPLETE_WITH_LIST6("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny)) + COMPLETE_WITH("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP"); /* ALTER TABLE ALTER [COLUMN] SET */ - else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") || - Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET")) - COMPLETE_WITH_LIST5("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET")) + COMPLETE_WITH("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE"); /* ALTER TABLE ALTER [COLUMN] SET ( */ - else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") || - Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "(")) - COMPLETE_WITH_LIST2("n_distinct", "n_distinct_inherited"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "(")) + COMPLETE_WITH("n_distinct", "n_distinct_inherited"); /* ALTER TABLE ALTER [COLUMN] SET STORAGE */ - else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") || - Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE")) - COMPLETE_WITH_LIST4("PLAIN", "EXTERNAL", "EXTENDED", "MAIN"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE")) + COMPLETE_WITH("PLAIN", "EXTERNAL", "EXTENDED", "MAIN"); /* ALTER TABLE ALTER [COLUMN] DROP */ - else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") || - Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP")) - COMPLETE_WITH_LIST3("DEFAULT", "IDENTITY", "NOT NULL"); - else if (Matches4("ALTER", "TABLE", MatchAny, "CLUSTER")) - COMPLETE_WITH_CONST("ON"); - else if (Matches5("ALTER", "TABLE", MatchAny, "CLUSTER", "ON")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP")) + COMPLETE_WITH("DEFAULT", "IDENTITY", "NOT NULL"); + else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER")) + COMPLETE_WITH("ON"); + else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } /* If we have ALTER TABLE SET, provide list of attributes and '(' */ - else if (Matches4("ALTER", "TABLE", MatchAny, "SET")) - COMPLETE_WITH_LIST7("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED", - "WITH", "WITHOUT"); + else if (Matches("ALTER", "TABLE", MatchAny, "SET")) + COMPLETE_WITH("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED", + "WITH", "WITHOUT"); /* * If we have ALTER TABLE SET TABLESPACE provide a list of * tablespaces */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE")) + else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE")) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); /* If we have ALTER TABLE SET WITH provide OIDS */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITH")) - COMPLETE_WITH_CONST("OIDS"); + else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITH")) + COMPLETE_WITH("OIDS"); /* If we have ALTER TABLE SET WITHOUT provide CLUSTER or OIDS */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITHOUT")) - COMPLETE_WITH_LIST2("CLUSTER", "OIDS"); + else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT")) + COMPLETE_WITH("CLUSTER", "OIDS"); /* ALTER TABLE RESET */ - else if (Matches4("ALTER", "TABLE", MatchAny, "RESET")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "TABLE", MatchAny, "RESET")) + COMPLETE_WITH("("); /* ALTER TABLE SET|RESET ( */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET|RESET", "(")) + else if (Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "(")) { static const char *const list_TABLEOPTIONS[] = { @@ -2080,101 +1933,101 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_LIST(list_TABLEOPTIONS); } - else if (Matches7("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX")) + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX")) { completion_info_charp = prev5_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } - else if (Matches6("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING")) - COMPLETE_WITH_CONST("INDEX"); - else if (Matches5("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY")) - COMPLETE_WITH_LIST4("FULL", "NOTHING", "DEFAULT", "USING"); - else if (Matches4("ALTER", "TABLE", MatchAny, "REPLICA")) - COMPLETE_WITH_CONST("IDENTITY"); + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING")) + COMPLETE_WITH("INDEX"); + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY")) + COMPLETE_WITH("FULL", "NOTHING", "DEFAULT", "USING"); + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA")) + COMPLETE_WITH("IDENTITY"); /* * If we have ALTER TABLE ATTACH PARTITION, provide a list of * tables. */ - else if (Matches5("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION")) + else if (Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* Limited completion support for partition bound specification */ - else if (TailMatches3("ATTACH", "PARTITION", MatchAny)) - COMPLETE_WITH_LIST2("FOR VALUES", "DEFAULT"); - else if (TailMatches2("FOR", "VALUES")) - COMPLETE_WITH_LIST3("FROM (", "IN (", "WITH ("); + else if (TailMatches("ATTACH", "PARTITION", MatchAny)) + COMPLETE_WITH("FOR VALUES", "DEFAULT"); + else if (TailMatches("FOR", "VALUES")) + COMPLETE_WITH("FROM (", "IN (", "WITH ("); /* * If we have ALTER TABLE DETACH PARTITION, provide a list of * partitions of . */ - else if (Matches5("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION")) + else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_partition_of_table); } /* ALTER TABLESPACE with RENAME TO, OWNER TO, SET, RESET */ - else if (Matches3("ALTER", "TABLESPACE", MatchAny)) - COMPLETE_WITH_LIST4("RENAME TO", "OWNER TO", "SET", "RESET"); + else if (Matches("ALTER", "TABLESPACE", MatchAny)) + COMPLETE_WITH("RENAME TO", "OWNER TO", "SET", "RESET"); /* ALTER TABLESPACE SET|RESET */ - else if (Matches4("ALTER", "TABLESPACE", MatchAny, "SET|RESET")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET")) + COMPLETE_WITH("("); /* ALTER TABLESPACE SET|RESET ( */ - else if (Matches5("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "(")) - COMPLETE_WITH_LIST3("seq_page_cost", "random_page_cost", - "effective_io_concurrency"); + else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "(")) + COMPLETE_WITH("seq_page_cost", "random_page_cost", + "effective_io_concurrency"); /* ALTER TEXT SEARCH */ - else if (Matches3("ALTER", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (Matches5("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny)) - COMPLETE_WITH_LIST2("RENAME TO", "SET SCHEMA"); - else if (Matches5("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); - else if (Matches5("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) - COMPLETE_WITH_LIST6("ADD MAPPING FOR", "ALTER MAPPING", - "DROP MAPPING FOR", - "OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny)) + COMPLETE_WITH("RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) + COMPLETE_WITH("ADD MAPPING FOR", "ALTER MAPPING", + "DROP MAPPING FOR", + "OWNER TO", "RENAME TO", "SET SCHEMA"); /* complete ALTER TYPE with actions */ - else if (Matches3("ALTER", "TYPE", MatchAny)) - COMPLETE_WITH_LIST7("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE", - "DROP ATTRIBUTE", - "OWNER TO", "RENAME", "SET SCHEMA"); + else if (Matches("ALTER", "TYPE", MatchAny)) + COMPLETE_WITH("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE", + "DROP ATTRIBUTE", + "OWNER TO", "RENAME", "SET SCHEMA"); /* complete ALTER TYPE ADD with actions */ - else if (Matches4("ALTER", "TYPE", MatchAny, "ADD")) - COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE"); + else if (Matches("ALTER", "TYPE", MatchAny, "ADD")) + COMPLETE_WITH("ATTRIBUTE", "VALUE"); /* ALTER TYPE RENAME */ - else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME")) - COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE"); + else if (Matches("ALTER", "TYPE", MatchAny, "RENAME")) + COMPLETE_WITH("ATTRIBUTE", "TO", "VALUE"); /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */ - else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny)) + COMPLETE_WITH("TO"); /* * If we have ALTER TYPE ALTER/DROP/RENAME ATTRIBUTE, provide list * of attributes */ - else if (Matches5("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE")) + else if (Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* ALTER TYPE ALTER ATTRIBUTE */ - else if (Matches6("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny)) - COMPLETE_WITH_CONST("TYPE"); + else if (Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny)) + COMPLETE_WITH("TYPE"); /* complete ALTER GROUP */ - else if (Matches3("ALTER", "GROUP", MatchAny)) - COMPLETE_WITH_LIST3("ADD USER", "DROP USER", "RENAME TO"); + else if (Matches("ALTER", "GROUP", MatchAny)) + COMPLETE_WITH("ADD USER", "DROP USER", "RENAME TO"); /* complete ALTER GROUP ADD|DROP with USER */ - else if (Matches4("ALTER", "GROUP", MatchAny, "ADD|DROP")) - COMPLETE_WITH_CONST("USER"); + else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP")) + COMPLETE_WITH("USER"); /* complete ALTER GROUP ADD|DROP USER with a user name */ - else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER")) + else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* * If we have ALTER TYPE RENAME VALUE, provide list of enum values */ - else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE")) + else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE")) COMPLETE_WITH_ENUM_VALUE(prev3_wd); /* @@ -2184,97 +2037,93 @@ psql_completion(const char *text, int start, int end) * Currently the only allowed option is VERBOSE, so we can be skimpier on * the option processing than VACUUM has to be. */ - else if (Matches1("ANALYZE")) + else if (Matches("ANALYZE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables, " UNION SELECT 'VERBOSE'"); - else if (Matches2("ANALYZE", "(")) - COMPLETE_WITH_CONST("VERBOSE)"); - else if (HeadMatches1("ANALYZE") && TailMatches1("(")) + else if (Matches("ANALYZE", "(")) + COMPLETE_WITH("VERBOSE)"); + else if (HeadMatches("ANALYZE") && TailMatches("(")) /* "ANALYZE (" should be caught above, so assume we want columns */ COMPLETE_WITH_ATTR(prev2_wd, ""); - else if (HeadMatches1("ANALYZE")) + else if (HeadMatches("ANALYZE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables, NULL); /* BEGIN */ - else if (Matches1("BEGIN")) - COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); + else if (Matches("BEGIN")) + COMPLETE_WITH("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); /* END, ABORT */ - else if (Matches1("END|ABORT")) - COMPLETE_WITH_LIST2("WORK", "TRANSACTION"); + else if (Matches("END|ABORT")) + COMPLETE_WITH("WORK", "TRANSACTION"); /* COMMIT */ - else if (Matches1("COMMIT")) - COMPLETE_WITH_LIST3("WORK", "TRANSACTION", "PREPARED"); + else if (Matches("COMMIT")) + COMPLETE_WITH("WORK", "TRANSACTION", "PREPARED"); /* RELEASE SAVEPOINT */ - else if (Matches1("RELEASE")) - COMPLETE_WITH_CONST("SAVEPOINT"); + else if (Matches("RELEASE")) + COMPLETE_WITH("SAVEPOINT"); /* ROLLBACK */ - else if (Matches1("ROLLBACK")) - COMPLETE_WITH_LIST4("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED"); + else if (Matches("ROLLBACK")) + COMPLETE_WITH("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED"); /* CALL */ - else if (Matches1("CALL")) + else if (Matches("CALL")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL); - else if (Matches2("CALL", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (Matches("CALL", MatchAny)) + COMPLETE_WITH("("); /* CLUSTER */ - else if (Matches1("CLUSTER")) + else if (Matches("CLUSTER")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'"); - else if (Matches2("CLUSTER", "VERBOSE")) + else if (Matches("CLUSTER", "VERBOSE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL); /* If we have CLUSTER , then add "USING" */ - else if (Matches2("CLUSTER", MatchAnyExcept("VERBOSE|ON"))) - COMPLETE_WITH_CONST("USING"); + else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON"))) + COMPLETE_WITH("USING"); /* If we have CLUSTER VERBOSE , then add "USING" */ - else if (Matches3("CLUSTER", "VERBOSE", MatchAny)) - COMPLETE_WITH_CONST("USING"); + else if (Matches("CLUSTER", "VERBOSE", MatchAny)) + COMPLETE_WITH("USING"); /* If we have CLUSTER USING, then add the index as well */ - else if (Matches3("CLUSTER", MatchAny, "USING") || - Matches4("CLUSTER", "VERBOSE", MatchAny, "USING")) + else if (Matches("CLUSTER", MatchAny, "USING") || + Matches("CLUSTER", "VERBOSE", MatchAny, "USING")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } /* COMMENT */ - else if (Matches1("COMMENT")) - COMPLETE_WITH_CONST("ON"); - else if (Matches2("COMMENT", "ON")) - { - static const char *const list_COMMENT[] = - {"ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", "DATABASE", - "EVENT TRIGGER", "EXTENSION", - "FOREIGN DATA WRAPPER", "FOREIGN TABLE", - "SERVER", "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE", - "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION", - "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION", - "PROCEDURE", "ROUTINE", - "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", - "TABLESPACE", "TEXT SEARCH", "ROLE", NULL}; - - COMPLETE_WITH_LIST(list_COMMENT); - } - else if (Matches4("COMMENT", "ON", "ACCESS", "METHOD")) + else if (Matches("COMMENT")) + COMPLETE_WITH("ON"); + else if (Matches("COMMENT", "ON")) + COMPLETE_WITH("ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", + "DATABASE", "EVENT TRIGGER", "EXTENSION", + "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "SERVER", + "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE", + "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION", + "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", + "COLUMN", "AGGREGATE", "FUNCTION", + "PROCEDURE", "ROUTINE", + "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", + "LARGE OBJECT", "TABLESPACE", "TEXT SEARCH", "ROLE"); + else if (Matches("COMMENT", "ON", "ACCESS", "METHOD")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); - else if (Matches3("COMMENT", "ON", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); - else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (Matches3("COMMENT", "ON", "CONSTRAINT")) + else if (Matches("COMMENT", "ON", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); + else if (Matches("COMMENT", "ON", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("COMMENT", "ON", "CONSTRAINT")) COMPLETE_WITH_QUERY(Query_for_all_table_constraints); - else if (Matches4("COMMENT", "ON", "CONSTRAINT", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches5("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON")) + else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint); } - else if (Matches4("COMMENT", "ON", "MATERIALIZED", "VIEW")) + else if (Matches("COMMENT", "ON", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); - else if (Matches4("COMMENT", "ON", "EVENT", "TRIGGER")) + else if (Matches("COMMENT", "ON", "EVENT", "TRIGGER")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); - else if (Matches4("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) || - Matches5("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) || - Matches6("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS"))) - COMPLETE_WITH_CONST("IS"); + else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) || + Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) || + Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS"))) + COMPLETE_WITH("IS"); /* COPY */ @@ -2282,92 +2131,92 @@ psql_completion(const char *text, int start, int end) * If we have COPY, offer list of tables or "(" (Also cover the analogous * backslash command). */ - else if (Matches1("COPY|\\copy")) + else if (Matches("COPY|\\copy")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, " UNION ALL SELECT '('"); /* If we have COPY BINARY, complete with list of tables */ - else if (Matches2("COPY", "BINARY")) + else if (Matches("COPY", "BINARY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* If we have COPY (, complete it with legal commands */ - else if (Matches2("COPY|\\copy", "(")) - COMPLETE_WITH_LIST7("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH"); + else if (Matches("COPY|\\copy", "(")) + COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH"); /* If we have COPY [BINARY] , complete it with "TO" or "FROM" */ - else if (Matches2("COPY|\\copy", MatchAny) || - Matches3("COPY", "BINARY", MatchAny)) - COMPLETE_WITH_LIST2("FROM", "TO"); + else if (Matches("COPY|\\copy", MatchAny) || + Matches("COPY", "BINARY", MatchAny)) + COMPLETE_WITH("FROM", "TO"); /* If we have COPY [BINARY] FROM|TO, complete with filename */ - else if (Matches3("COPY|\\copy", MatchAny, "FROM|TO") || - Matches4("COPY", "BINARY", MatchAny, "FROM|TO")) + else if (Matches("COPY|\\copy", MatchAny, "FROM|TO") || + Matches("COPY", "BINARY", MatchAny, "FROM|TO")) { completion_charp = ""; matches = completion_matches(text, complete_from_files); } /* Handle COPY [BINARY] FROM|TO filename */ - else if (Matches4("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) || - Matches5("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny)) - COMPLETE_WITH_LIST6("BINARY", "OIDS", "DELIMITER", "NULL", "CSV", - "ENCODING"); + else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) || + Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny)) + COMPLETE_WITH("BINARY", "OIDS", "DELIMITER", "NULL", "CSV", + "ENCODING"); /* Handle COPY [BINARY] FROM|TO filename CSV */ - else if (Matches5("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") || - Matches6("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV")) - COMPLETE_WITH_LIST5("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", - "FORCE NOT NULL"); + else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") || + Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV")) + COMPLETE_WITH("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", + "FORCE NOT NULL"); /* CREATE ACCESS METHOD */ /* Complete "CREATE ACCESS METHOD " */ - else if (Matches4("CREATE", "ACCESS", "METHOD", MatchAny)) - COMPLETE_WITH_CONST("TYPE"); + else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny)) + COMPLETE_WITH("TYPE"); /* Complete "CREATE ACCESS METHOD TYPE" */ - else if (Matches5("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE")) - COMPLETE_WITH_CONST("INDEX"); + else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE")) + COMPLETE_WITH("INDEX"); /* Complete "CREATE ACCESS METHOD TYPE " */ - else if (Matches6("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny)) - COMPLETE_WITH_CONST("HANDLER"); + else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny)) + COMPLETE_WITH("HANDLER"); /* CREATE DATABASE */ - else if (Matches3("CREATE", "DATABASE", MatchAny)) - COMPLETE_WITH_LIST9("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", - "IS_TEMPLATE", - "ALLOW_CONNECTIONS", "CONNECTION LIMIT", - "LC_COLLATE", "LC_CTYPE"); + else if (Matches("CREATE", "DATABASE", MatchAny)) + COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", + "IS_TEMPLATE", + "ALLOW_CONNECTIONS", "CONNECTION LIMIT", + "LC_COLLATE", "LC_CTYPE"); - else if (Matches4("CREATE", "DATABASE", MatchAny, "TEMPLATE")) + else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE")) COMPLETE_WITH_QUERY(Query_for_list_of_template_databases); /* CREATE EXTENSION */ /* Complete with available extensions rather than installed ones. */ - else if (Matches2("CREATE", "EXTENSION")) + else if (Matches("CREATE", "EXTENSION")) COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions); /* CREATE EXTENSION */ - else if (Matches3("CREATE", "EXTENSION", MatchAny)) - COMPLETE_WITH_LIST3("WITH SCHEMA", "CASCADE", "VERSION"); + else if (Matches("CREATE", "EXTENSION", MatchAny)) + COMPLETE_WITH("WITH SCHEMA", "CASCADE", "VERSION"); /* CREATE EXTENSION VERSION */ - else if (Matches4("CREATE", "EXTENSION", MatchAny, "VERSION")) + else if (Matches("CREATE", "EXTENSION", MatchAny, "VERSION")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions); } /* CREATE FOREIGN */ - else if (Matches2("CREATE", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); + else if (Matches("CREATE", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); /* CREATE FOREIGN DATA WRAPPER */ - else if (Matches5("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny)) - COMPLETE_WITH_LIST3("HANDLER", "VALIDATOR", "OPTIONS"); + else if (Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny)) + COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS"); /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */ /* First off we complete CREATE UNIQUE with "INDEX" */ - else if (TailMatches2("CREATE", "UNIQUE")) - COMPLETE_WITH_CONST("INDEX"); + else if (TailMatches("CREATE", "UNIQUE")) + COMPLETE_WITH("INDEX"); /* * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and * existing indexes */ - else if (TailMatches2("CREATE|UNIQUE", "INDEX")) + else if (TailMatches("CREATE|UNIQUE", "INDEX")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, " UNION SELECT 'ON'" " UNION SELECT 'CONCURRENTLY'"); @@ -2376,493 +2225,485 @@ psql_completion(const char *text, int start, int end) * Complete ... INDEX|CONCURRENTLY [] ON with a list of relations * that indexes can be created on */ - else if (TailMatches3("INDEX|CONCURRENTLY", MatchAny, "ON") || - TailMatches2("INDEX|CONCURRENTLY", "ON")) + else if (TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON") || + TailMatches("INDEX|CONCURRENTLY", "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL); /* * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing * indexes */ - else if (TailMatches3("CREATE|UNIQUE", "INDEX", "CONCURRENTLY")) + else if (TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, " UNION SELECT 'ON'"); /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] with "ON" */ - else if (TailMatches3("CREATE|UNIQUE", "INDEX", MatchAny) || - TailMatches4("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (TailMatches("CREATE|UNIQUE", "INDEX", MatchAny) || + TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny)) + COMPLETE_WITH("ON"); /* * Complete INDEX ON
with a list of table columns (which * should really be in parens) */ - else if (TailMatches4("INDEX", MatchAny, "ON", MatchAny) || - TailMatches3("INDEX|CONCURRENTLY", "ON", MatchAny)) - COMPLETE_WITH_LIST2("(", "USING"); - else if (TailMatches5("INDEX", MatchAny, "ON", MatchAny, "(") || - TailMatches4("INDEX|CONCURRENTLY", "ON", MatchAny, "(")) + else if (TailMatches("INDEX", MatchAny, "ON", MatchAny) || + TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny)) + COMPLETE_WITH("(", "USING"); + else if (TailMatches("INDEX", MatchAny, "ON", MatchAny, "(") || + TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "(")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* same if you put in USING */ - else if (TailMatches5("ON", MatchAny, "USING", MatchAny, "(")) + else if (TailMatches("ON", MatchAny, "USING", MatchAny, "(")) COMPLETE_WITH_ATTR(prev4_wd, ""); /* Complete USING with an index method */ - else if (TailMatches6("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") || - TailMatches5("INDEX", MatchAny, "ON", MatchAny, "USING") || - TailMatches4("INDEX", "ON", MatchAny, "USING")) + else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") || + TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") || + TailMatches("INDEX", "ON", MatchAny, "USING")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); - else if (TailMatches4("ON", MatchAny, "USING", MatchAny) && - !TailMatches6("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) && - !TailMatches4("FOR", MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("("); + else if (TailMatches("ON", MatchAny, "USING", MatchAny) && + !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) && + !TailMatches("FOR", MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("("); /* CREATE POLICY */ /* Complete "CREATE POLICY ON" */ - else if (Matches3("CREATE", "POLICY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("CREATE", "POLICY", MatchAny)) + COMPLETE_WITH("ON"); /* Complete "CREATE POLICY ON
" */ - else if (Matches4("CREATE", "POLICY", MatchAny, "ON")) + else if (Matches("CREATE", "POLICY", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* Complete "CREATE POLICY ON
AS|FOR|TO|USING|WITH CHECK" */ - else if (Matches5("CREATE", "POLICY", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST5("AS", "FOR", "TO", "USING (", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("AS", "FOR", "TO", "USING (", "WITH CHECK ("); /* CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS")) - COMPLETE_WITH_LIST2("PERMISSIVE", "RESTRICTIVE"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS")) + COMPLETE_WITH("PERMISSIVE", "RESTRICTIVE"); /* * CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE * FOR|TO|USING|WITH CHECK */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny)) - COMPLETE_WITH_LIST4("FOR", "TO", "USING", "WITH CHECK"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny)) + COMPLETE_WITH("FOR", "TO", "USING", "WITH CHECK"); /* CREATE POLICY ON
FOR ALL|SELECT|INSERT|UPDATE|DELETE */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR")) - COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR")) + COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); /* Complete "CREATE POLICY ON
FOR INSERT TO|WITH CHECK" */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT")) - COMPLETE_WITH_LIST2("TO", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT")) + COMPLETE_WITH("TO", "WITH CHECK ("); /* Complete "CREATE POLICY ON
FOR SELECT|DELETE TO|USING" */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE")) - COMPLETE_WITH_LIST2("TO", "USING ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE")) + COMPLETE_WITH("TO", "USING ("); /* CREATE POLICY ON
FOR ALL|UPDATE TO|USING|WITH CHECK */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE")) - COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE")) + COMPLETE_WITH("TO", "USING (", "WITH CHECK ("); /* Complete "CREATE POLICY ON
TO " */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO")) + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* Complete "CREATE POLICY ON
USING (" */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING")) - COMPLETE_WITH_CONST("("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING")) + COMPLETE_WITH("("); /* * CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * ALL|SELECT|INSERT|UPDATE|DELETE */ - else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR")) - COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR")) + COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * INSERT TO|WITH CHECK" */ - else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT")) - COMPLETE_WITH_LIST2("TO", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT")) + COMPLETE_WITH("TO", "WITH CHECK ("); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * SELECT|DELETE TO|USING" */ - else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE")) - COMPLETE_WITH_LIST2("TO", "USING ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE")) + COMPLETE_WITH("TO", "USING ("); /* * CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * ALL|UPDATE TO|USING|WITH CHECK */ - else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE")) - COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE")) + COMPLETE_WITH("TO", "USING (", "WITH CHECK ("); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE TO * " */ - else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO")) + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE * USING (" */ - else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING")) - COMPLETE_WITH_CONST("("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING")) + COMPLETE_WITH("("); /* CREATE PUBLICATION */ - else if (Matches3("CREATE", "PUBLICATION", MatchAny)) - COMPLETE_WITH_LIST3("FOR TABLE", "FOR ALL TABLES", "WITH ("); - else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR")) - COMPLETE_WITH_LIST2("TABLE", "ALL TABLES"); + else if (Matches("CREATE", "PUBLICATION", MatchAny)) + COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "WITH ("); + else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR")) + COMPLETE_WITH("TABLE", "ALL TABLES"); /* Complete "CREATE PUBLICATION FOR TABLE
, ..." */ - else if (HeadMatches5("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE")) + else if (HeadMatches("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", "(")) - COMPLETE_WITH_CONST("publish"); + else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "(")) + COMPLETE_WITH("publish"); /* CREATE RULE */ /* Complete "CREATE RULE " with "AS ON" */ - else if (Matches3("CREATE", "RULE", MatchAny)) - COMPLETE_WITH_CONST("AS ON"); + else if (Matches("CREATE", "RULE", MatchAny)) + COMPLETE_WITH("AS ON"); /* Complete "CREATE RULE AS" with "ON" */ - else if (Matches4("CREATE", "RULE", MatchAny, "AS")) - COMPLETE_WITH_CONST("ON"); + else if (Matches("CREATE", "RULE", MatchAny, "AS")) + COMPLETE_WITH("ON"); /* Complete "CREATE RULE AS ON" with SELECT|UPDATE|INSERT|DELETE */ - else if (Matches5("CREATE", "RULE", MatchAny, "AS", "ON")) - COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE"); + else if (Matches("CREATE", "RULE", MatchAny, "AS", "ON")) + COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE"); /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */ - else if (TailMatches3("AS", "ON", "SELECT|UPDATE|INSERT|DELETE")) - COMPLETE_WITH_CONST("TO"); + else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE")) + COMPLETE_WITH("TO"); /* Complete "AS ON TO" with a table name */ - else if (TailMatches4("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO")) + else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */ - else if (TailMatches3("CREATE", "SEQUENCE", MatchAny) || - TailMatches4("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny)) - COMPLETE_WITH_LIST8("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE", - "CYCLE", "OWNED BY", "START WITH"); - else if (TailMatches4("CREATE", "SEQUENCE", MatchAny, "NO") || - TailMatches5("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO")) - COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE"); + else if (TailMatches("CREATE", "SEQUENCE", MatchAny) || + TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny)) + COMPLETE_WITH("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE", + "CYCLE", "OWNED BY", "START WITH"); + else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "NO") || + TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO")) + COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE"); /* CREATE SERVER */ - else if (Matches3("CREATE", "SERVER", MatchAny)) - COMPLETE_WITH_LIST3("TYPE", "VERSION", "FOREIGN DATA WRAPPER"); + else if (Matches("CREATE", "SERVER", MatchAny)) + COMPLETE_WITH("TYPE", "VERSION", "FOREIGN DATA WRAPPER"); /* CREATE STATISTICS */ - else if (Matches3("CREATE", "STATISTICS", MatchAny)) - COMPLETE_WITH_LIST2("(", "ON"); - else if (Matches4("CREATE", "STATISTICS", MatchAny, "(")) - COMPLETE_WITH_LIST2("ndistinct", "dependencies"); - else if (HeadMatches3("CREATE", "STATISTICS", MatchAny) && + else if (Matches("CREATE", "STATISTICS", MatchAny)) + COMPLETE_WITH("(", "ON"); + else if (Matches("CREATE", "STATISTICS", MatchAny, "(")) + COMPLETE_WITH("ndistinct", "dependencies"); + else if (HeadMatches("CREATE", "STATISTICS", MatchAny) && previous_words[0][0] == '(' && previous_words[0][strlen(previous_words[0]) - 1] == ')') - COMPLETE_WITH_CONST("ON"); - else if (HeadMatches3("CREATE", "STATISTICS", MatchAny) && - TailMatches1("FROM")) + COMPLETE_WITH("ON"); + else if (HeadMatches("CREATE", "STATISTICS", MatchAny) && + TailMatches("FROM")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */ /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */ - else if (TailMatches2("CREATE", "TEMP|TEMPORARY")) - COMPLETE_WITH_LIST3("SEQUENCE", "TABLE", "VIEW"); + else if (TailMatches("CREATE", "TEMP|TEMPORARY")) + COMPLETE_WITH("SEQUENCE", "TABLE", "VIEW"); /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */ - else if (TailMatches2("CREATE", "UNLOGGED")) - COMPLETE_WITH_LIST2("TABLE", "MATERIALIZED VIEW"); + else if (TailMatches("CREATE", "UNLOGGED")) + COMPLETE_WITH("TABLE", "MATERIALIZED VIEW"); /* Complete PARTITION BY with RANGE ( or LIST ( or ... */ - else if (TailMatches2("PARTITION", "BY")) - COMPLETE_WITH_LIST3("RANGE (", "LIST (", "HASH ("); + else if (TailMatches("PARTITION", "BY")) + COMPLETE_WITH("RANGE (", "LIST (", "HASH ("); /* If we have xxx PARTITION OF, provide a list of partitioned tables */ - else if (TailMatches2("PARTITION", "OF")) + else if (TailMatches("PARTITION", "OF")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, ""); /* Limited completion support for partition bound specification */ - else if (TailMatches3("PARTITION", "OF", MatchAny)) - COMPLETE_WITH_LIST2("FOR VALUES", "DEFAULT"); + else if (TailMatches("PARTITION", "OF", MatchAny)) + COMPLETE_WITH("FOR VALUES", "DEFAULT"); /* CREATE TABLESPACE */ - else if (Matches3("CREATE", "TABLESPACE", MatchAny)) - COMPLETE_WITH_LIST2("OWNER", "LOCATION"); + else if (Matches("CREATE", "TABLESPACE", MatchAny)) + COMPLETE_WITH("OWNER", "LOCATION"); /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */ - else if (Matches5("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny)) - COMPLETE_WITH_CONST("LOCATION"); + else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny)) + COMPLETE_WITH("LOCATION"); /* CREATE TEXT SEARCH */ - else if (Matches3("CREATE", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (Matches5("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (Matches("CREATE", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) + COMPLETE_WITH("("); /* CREATE SUBSCRIPTION */ - else if (Matches3("CREATE", "SUBSCRIPTION", MatchAny)) - COMPLETE_WITH_CONST("CONNECTION"); - else if (Matches5("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny)) - COMPLETE_WITH_CONST("PUBLICATION"); - else if (Matches6("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", - MatchAny, "PUBLICATION")) + else if (Matches("CREATE", "SUBSCRIPTION", MatchAny)) + COMPLETE_WITH("CONNECTION"); + else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny)) + COMPLETE_WITH("PUBLICATION"); + else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", + MatchAny, "PUBLICATION")) { /* complete with nothing here as this refers to remote publications */ } - else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("PUBLICATION", MatchAny)) - COMPLETE_WITH_CONST("WITH ("); + else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("PUBLICATION", MatchAny)) + COMPLETE_WITH("WITH ("); /* Complete "CREATE SUBSCRIPTION ... WITH ( " */ - else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("WITH", "(")) - COMPLETE_WITH_LIST6("copy_data", "connect", "create_slot", "enabled", - "slot_name", "synchronous_commit"); + else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("WITH", "(")) + COMPLETE_WITH("copy_data", "connect", "create_slot", "enabled", + "slot_name", "synchronous_commit"); /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */ /* complete CREATE TRIGGER with BEFORE,AFTER,INSTEAD OF */ - else if (TailMatches3("CREATE", "TRIGGER", MatchAny)) - COMPLETE_WITH_LIST3("BEFORE", "AFTER", "INSTEAD OF"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny)) + COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF"); /* complete CREATE TRIGGER BEFORE,AFTER with an event */ - else if (TailMatches4("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER")) - COMPLETE_WITH_LIST4("INSERT", "DELETE", "UPDATE", "TRUNCATE"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER")) + COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE"); /* complete CREATE TRIGGER INSTEAD OF with an event */ - else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF")) - COMPLETE_WITH_LIST3("INSERT", "DELETE", "UPDATE"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF")) + COMPLETE_WITH("INSERT", "DELETE", "UPDATE"); /* complete CREATE TRIGGER BEFORE,AFTER sth with OR,ON */ - else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) || - TailMatches6("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny)) - COMPLETE_WITH_LIST2("ON", "OR"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) || + TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny)) + COMPLETE_WITH("ON", "OR"); /* * complete CREATE TRIGGER BEFORE,AFTER event ON with a list of * tables */ - else if (TailMatches6("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON")) + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */ - else if (TailMatches7("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON")) + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("ON", MatchAny)) - COMPLETE_WITH_LIST7("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY", - "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches1("DEFERRABLE") || TailMatches2("INITIALLY", "IMMEDIATE|DEFERRED"))) - COMPLETE_WITH_LIST4("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("REFERENCING")) - COMPLETE_WITH_LIST2("OLD TABLE", "NEW TABLE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("OLD|NEW", "TABLE")) - COMPLETE_WITH_CONST("AS"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches5("REFERENCING", "OLD", "TABLE", "AS", MatchAny) || - TailMatches4("REFERENCING", "OLD", "TABLE", MatchAny))) - COMPLETE_WITH_LIST4("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches5("REFERENCING", "NEW", "TABLE", "AS", MatchAny) || - TailMatches4("REFERENCING", "NEW", "TABLE", MatchAny))) - COMPLETE_WITH_LIST4("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches9("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || - TailMatches8("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || - TailMatches8("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) || - TailMatches7("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny))) - COMPLETE_WITH_LIST3("FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("FOR")) - COMPLETE_WITH_LIST3("EACH", "ROW", "STATEMENT"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("FOR", "EACH")) - COMPLETE_WITH_LIST2("ROW", "STATEMENT"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches3("FOR", "EACH", "ROW|STATEMENT") || - TailMatches2("FOR", "ROW|STATEMENT"))) - COMPLETE_WITH_LIST2("WHEN (", "EXECUTE PROCEDURE"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("ON", MatchAny)) + COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY", + "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("DEFERRABLE") || TailMatches("INITIALLY", "IMMEDIATE|DEFERRED"))) + COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("REFERENCING")) + COMPLETE_WITH("OLD TABLE", "NEW TABLE"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("OLD|NEW", "TABLE")) + COMPLETE_WITH("AS"); + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("REFERENCING", "OLD", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "OLD", "TABLE", MatchAny))) + COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("REFERENCING", "NEW", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "NEW", "TABLE", MatchAny))) + COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) || + TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny))) + COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR")) + COMPLETE_WITH("EACH", "ROW", "STATEMENT"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR", "EACH")) + COMPLETE_WITH("ROW", "STATEMENT"); + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("FOR", "EACH", "ROW|STATEMENT") || + TailMatches("FOR", "ROW|STATEMENT"))) + COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE"); /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE */ - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("EXECUTE")) - COMPLETE_WITH_CONST("PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("EXECUTE", "PROCEDURE")) + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("EXECUTE")) + COMPLETE_WITH("PROCEDURE"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("EXECUTE", "PROCEDURE")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); /* CREATE ROLE,USER,GROUP */ - else if (Matches3("CREATE", "ROLE|GROUP|USER", MatchAny) && - !TailMatches2("USER", "MAPPING")) - { - static const char *const list_CREATEROLE[] = - {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", - "REPLICATION", "ROLE", "SUPERUSER", "SYSID", - "VALID UNTIL", "WITH", NULL}; - - COMPLETE_WITH_LIST(list_CREATEROLE); - } + else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny) && + !TailMatches("USER", "MAPPING")) + COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", + "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT", + "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "REPLICATION", "ROLE", "SUPERUSER", "SYSID", + "VALID UNTIL", "WITH"); /* CREATE ROLE,USER,GROUP WITH */ - else if (Matches4("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH")) - { + else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH")) /* Similar to the above, but don't complete "WITH" again. */ - static const char *const list_CREATEROLE_WITH[] = - {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", - "REPLICATION", "ROLE", "SUPERUSER", "SYSID", - "VALID UNTIL", NULL}; - - COMPLETE_WITH_LIST(list_CREATEROLE_WITH); - } + COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", + "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT", + "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "REPLICATION", "ROLE", "SUPERUSER", "SYSID", + "VALID UNTIL"); /* complete CREATE ROLE,USER,GROUP IN with ROLE,GROUP */ - else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "IN")) - COMPLETE_WITH_LIST2("GROUP", "ROLE"); + else if (Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN")) + COMPLETE_WITH("GROUP", "ROLE"); /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */ /* Complete CREATE VIEW with AS */ - else if (TailMatches3("CREATE", "VIEW", MatchAny)) - COMPLETE_WITH_CONST("AS"); + else if (TailMatches("CREATE", "VIEW", MatchAny)) + COMPLETE_WITH("AS"); /* Complete "CREATE VIEW AS with "SELECT" */ - else if (TailMatches4("CREATE", "VIEW", MatchAny, "AS")) - COMPLETE_WITH_CONST("SELECT"); + else if (TailMatches("CREATE", "VIEW", MatchAny, "AS")) + COMPLETE_WITH("SELECT"); /* CREATE MATERIALIZED VIEW */ - else if (Matches2("CREATE", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); + else if (Matches("CREATE", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); /* Complete CREATE MATERIALIZED VIEW with AS */ - else if (Matches4("CREATE", "MATERIALIZED", "VIEW", MatchAny)) - COMPLETE_WITH_CONST("AS"); + else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny)) + COMPLETE_WITH("AS"); /* Complete "CREATE MATERIALIZED VIEW AS with "SELECT" */ - else if (Matches5("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS")) - COMPLETE_WITH_CONST("SELECT"); + else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS")) + COMPLETE_WITH("SELECT"); /* CREATE EVENT TRIGGER */ - else if (Matches2("CREATE", "EVENT")) - COMPLETE_WITH_CONST("TRIGGER"); + else if (Matches("CREATE", "EVENT")) + COMPLETE_WITH("TRIGGER"); /* Complete CREATE EVENT TRIGGER with ON */ - else if (Matches4("CREATE", "EVENT", "TRIGGER", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny)) + COMPLETE_WITH("ON"); /* Complete CREATE EVENT TRIGGER ON with event_type */ - else if (Matches5("CREATE", "EVENT", "TRIGGER", MatchAny, "ON")) - COMPLETE_WITH_LIST3("ddl_command_start", "ddl_command_end", "sql_drop"); + else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON")) + COMPLETE_WITH("ddl_command_start", "ddl_command_end", "sql_drop"); /* DEALLOCATE */ - else if (Matches1("DEALLOCATE")) + else if (Matches("DEALLOCATE")) COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements); /* DECLARE */ - else if (Matches2("DECLARE", MatchAny)) - COMPLETE_WITH_LIST5("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", - "CURSOR"); - else if (HeadMatches1("DECLARE") && TailMatches1("CURSOR")) - COMPLETE_WITH_LIST3("WITH HOLD", "WITHOUT HOLD", "FOR"); + else if (Matches("DECLARE", MatchAny)) + COMPLETE_WITH("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", + "CURSOR"); + else if (HeadMatches("DECLARE") && TailMatches("CURSOR")) + COMPLETE_WITH("WITH HOLD", "WITHOUT HOLD", "FOR"); /* DELETE --- can be inside EXPLAIN, RULE, etc */ /* ... despite which, only complete DELETE with FROM at start of line */ - else if (Matches1("DELETE")) - COMPLETE_WITH_CONST("FROM"); + else if (Matches("DELETE")) + COMPLETE_WITH("FROM"); /* Complete DELETE FROM with a list of tables */ - else if (TailMatches2("DELETE", "FROM")) + else if (TailMatches("DELETE", "FROM")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL); /* Complete DELETE FROM
*/ - else if (TailMatches3("DELETE", "FROM", MatchAny)) - COMPLETE_WITH_LIST2("USING", "WHERE"); + else if (TailMatches("DELETE", "FROM", MatchAny)) + COMPLETE_WITH("USING", "WHERE"); /* XXX: implement tab completion for DELETE ... USING */ /* DISCARD */ - else if (Matches1("DISCARD")) - COMPLETE_WITH_LIST4("ALL", "PLANS", "SEQUENCES", "TEMP"); + else if (Matches("DISCARD")) + COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP"); /* DO */ - else if (Matches1("DO")) - COMPLETE_WITH_CONST("LANGUAGE"); + else if (Matches("DO")) + COMPLETE_WITH("LANGUAGE"); /* DROP */ /* Complete DROP object with CASCADE / RESTRICT */ - else if (Matches3("DROP", - "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW", - MatchAny) || - Matches4("DROP", "ACCESS", "METHOD", MatchAny) || - (Matches4("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) && + else if (Matches("DROP", + "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW", + MatchAny) || + Matches("DROP", "ACCESS", "METHOD", MatchAny) || + (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) && ends_with(prev_wd, ')')) || - Matches4("DROP", "EVENT", "TRIGGER", MatchAny) || - Matches5("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) || - Matches4("DROP", "FOREIGN", "TABLE", MatchAny) || - Matches5("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + Matches("DROP", "EVENT", "TRIGGER", MatchAny) || + Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) || + Matches("DROP", "FOREIGN", "TABLE", MatchAny) || + Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* help completing some of the variants */ - else if (Matches3("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) - COMPLETE_WITH_CONST("("); - else if (Matches4("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "(")) + else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) + COMPLETE_WITH("("); + else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "(")) COMPLETE_WITH_FUNCTION_ARG(prev2_wd); - else if (Matches2("DROP", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); + else if (Matches("DROP", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); /* DROP INDEX */ - else if (Matches2("DROP", "INDEX")) + else if (Matches("DROP", "INDEX")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, " UNION SELECT 'CONCURRENTLY'"); - else if (Matches3("DROP", "INDEX", "CONCURRENTLY")) + else if (Matches("DROP", "INDEX", "CONCURRENTLY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); - else if (Matches3("DROP", "INDEX", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); - else if (Matches4("DROP", "INDEX", "CONCURRENTLY", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + else if (Matches("DROP", "INDEX", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); + else if (Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* DROP MATERIALIZED VIEW */ - else if (Matches2("DROP", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); - else if (Matches3("DROP", "MATERIALIZED", "VIEW")) + else if (Matches("DROP", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); + else if (Matches("DROP", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); /* DROP OWNED BY */ - else if (Matches2("DROP", "OWNED")) - COMPLETE_WITH_CONST("BY"); - else if (Matches3("DROP", "OWNED", "BY")) + else if (Matches("DROP", "OWNED")) + COMPLETE_WITH("BY"); + else if (Matches("DROP", "OWNED", "BY")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* DROP TEXT SEARCH */ - else if (Matches3("DROP", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("DROP", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); /* DROP TRIGGER */ - else if (Matches3("DROP", "TRIGGER", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches4("DROP", "TRIGGER", MatchAny, "ON")) + else if (Matches("DROP", "TRIGGER", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("DROP", "TRIGGER", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger); } - else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + else if (Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* DROP ACCESS METHOD */ - else if (Matches2("DROP", "ACCESS")) - COMPLETE_WITH_CONST("METHOD"); - else if (Matches3("DROP", "ACCESS", "METHOD")) + else if (Matches("DROP", "ACCESS")) + COMPLETE_WITH("METHOD"); + else if (Matches("DROP", "ACCESS", "METHOD")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); /* DROP EVENT TRIGGER */ - else if (Matches2("DROP", "EVENT")) - COMPLETE_WITH_CONST("TRIGGER"); - else if (Matches3("DROP", "EVENT", "TRIGGER")) + else if (Matches("DROP", "EVENT")) + COMPLETE_WITH("TRIGGER"); + else if (Matches("DROP", "EVENT", "TRIGGER")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); /* DROP POLICY */ - else if (Matches2("DROP", "POLICY")) + else if (Matches("DROP", "POLICY")) COMPLETE_WITH_QUERY(Query_for_list_of_policies); /* DROP POLICY ON */ - else if (Matches3("DROP", "POLICY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("DROP", "POLICY", MatchAny)) + COMPLETE_WITH("ON"); /* DROP POLICY ON
*/ - else if (Matches4("DROP", "POLICY", MatchAny, "ON")) + else if (Matches("DROP", "POLICY", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy); } /* DROP RULE */ - else if (Matches3("DROP", "RULE", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches4("DROP", "RULE", MatchAny, "ON")) + else if (Matches("DROP", "RULE", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("DROP", "RULE", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule); } - else if (Matches5("DROP", "RULE", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + else if (Matches("DROP", "RULE", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* EXECUTE */ - else if (Matches1("EXECUTE")) + else if (Matches("EXECUTE")) COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements); /* * EXPLAIN [ ( option [, ...] ) ] statement * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement */ - else if (Matches1("EXPLAIN")) - COMPLETE_WITH_LIST7("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", - "ANALYZE", "VERBOSE"); - else if (HeadMatches2("EXPLAIN", "(*") && - !HeadMatches2("EXPLAIN", "(*)")) + else if (Matches("EXPLAIN")) + COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", + "ANALYZE", "VERBOSE"); + else if (HeadMatches("EXPLAIN", "(*") && + !HeadMatches("EXPLAIN", "(*)")) { /* * This fires if we're in an unfinished parenthesized option list. @@ -2870,54 +2711,54 @@ psql_completion(const char *text, int start, int end) * one word, so the above test is correct. */ if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) - COMPLETE_WITH_LIST7("ANALYZE", "VERBOSE", "COSTS", "BUFFERS", - "TIMING", "SUMMARY", "FORMAT"); - else if (TailMatches1("ANALYZE|VERBOSE|COSTS|BUFFERS|TIMING|SUMMARY")) - COMPLETE_WITH_LIST2("ON", "OFF"); - else if (TailMatches1("FORMAT")) - COMPLETE_WITH_LIST4("TEXT", "XML", "JSON", "YAML"); + COMPLETE_WITH("ANALYZE", "VERBOSE", "COSTS", "BUFFERS", + "TIMING", "SUMMARY", "FORMAT"); + else if (TailMatches("ANALYZE|VERBOSE|COSTS|BUFFERS|TIMING|SUMMARY")) + COMPLETE_WITH("ON", "OFF"); + else if (TailMatches("FORMAT")) + COMPLETE_WITH("TEXT", "XML", "JSON", "YAML"); } - else if (Matches2("EXPLAIN", "ANALYZE")) - COMPLETE_WITH_LIST6("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", - "VERBOSE"); - else if (Matches2("EXPLAIN", "(*)") || - Matches2("EXPLAIN", "VERBOSE") || - Matches3("EXPLAIN", "ANALYZE", "VERBOSE")) - COMPLETE_WITH_LIST5("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE"); + else if (Matches("EXPLAIN", "ANALYZE")) + COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", + "VERBOSE"); + else if (Matches("EXPLAIN", "(*)") || + Matches("EXPLAIN", "VERBOSE") || + Matches("EXPLAIN", "ANALYZE", "VERBOSE")) + COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE"); /* FETCH && MOVE */ /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */ - else if (Matches1("FETCH|MOVE")) - COMPLETE_WITH_LIST4("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE"); + else if (Matches("FETCH|MOVE")) + COMPLETE_WITH("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE"); /* Complete FETCH with one of ALL, NEXT, PRIOR */ - else if (Matches2("FETCH|MOVE", MatchAny)) - COMPLETE_WITH_LIST3("ALL", "NEXT", "PRIOR"); + else if (Matches("FETCH|MOVE", MatchAny)) + COMPLETE_WITH("ALL", "NEXT", "PRIOR"); /* * Complete FETCH with "FROM" or "IN". These are equivalent, * but we may as well tab-complete both: perhaps some users prefer one * variant or the other. */ - else if (Matches3("FETCH|MOVE", MatchAny, MatchAny)) - COMPLETE_WITH_LIST2("FROM", "IN"); + else if (Matches("FETCH|MOVE", MatchAny, MatchAny)) + COMPLETE_WITH("FROM", "IN"); /* FOREIGN DATA WRAPPER */ /* applies in ALTER/DROP FDW and in CREATE SERVER */ - else if (TailMatches3("FOREIGN", "DATA", "WRAPPER") && - !TailMatches4("CREATE", MatchAny, MatchAny, MatchAny)) + else if (TailMatches("FOREIGN", "DATA", "WRAPPER") && + !TailMatches("CREATE", MatchAny, MatchAny, MatchAny)) COMPLETE_WITH_QUERY(Query_for_list_of_fdws); /* applies in CREATE SERVER */ - else if (TailMatches4("FOREIGN", "DATA", "WRAPPER", MatchAny) && - HeadMatches2("CREATE", "SERVER")) - COMPLETE_WITH_CONST("OPTIONS"); + else if (TailMatches("FOREIGN", "DATA", "WRAPPER", MatchAny) && + HeadMatches("CREATE", "SERVER")) + COMPLETE_WITH("OPTIONS"); /* FOREIGN TABLE */ - else if (TailMatches2("FOREIGN", "TABLE") && - !TailMatches3("CREATE", MatchAny, MatchAny)) + else if (TailMatches("FOREIGN", "TABLE") && + !TailMatches("CREATE", MatchAny, MatchAny)) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL); /* FOREIGN SERVER */ - else if (TailMatches2("FOREIGN", "SERVER")) + else if (TailMatches("FOREIGN", "SERVER")) COMPLETE_WITH_QUERY(Query_for_list_of_servers); /* @@ -2925,16 +2766,16 @@ psql_completion(const char *text, int start, int end) * ALTER DEFAULT PRIVILEGES, so use TailMatches */ /* Complete GRANT/REVOKE with a list of roles and privileges */ - else if (TailMatches1("GRANT|REVOKE")) + else if (TailMatches("GRANT|REVOKE")) { /* * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable * privileges (can't grant roles) */ - if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES")) - COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE", - "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", - "EXECUTE", "USAGE", "ALL"); + if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES")) + COMPLETE_WITH("SELECT", "INSERT", "UPDATE", + "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", + "EXECUTE", "USAGE", "ALL"); else COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'SELECT'" @@ -2956,14 +2797,14 @@ psql_completion(const char *text, int start, int end) * Complete GRANT/REVOKE with "ON", GRANT/REVOKE with * TO/FROM */ - else if (TailMatches2("GRANT|REVOKE", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny)) { - if (TailMatches1("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL")) - COMPLETE_WITH_CONST("ON"); - else if (TailMatches2("GRANT", MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL")) + COMPLETE_WITH("ON"); + else if (TailMatches("GRANT", MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* @@ -2976,14 +2817,14 @@ psql_completion(const char *text, int start, int end) * here will only work if the privilege list contains exactly one * privilege. */ - else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON")) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON")) { /* * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of * objects supported. */ - if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES")) - COMPLETE_WITH_LIST7("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS"); + if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES")) + COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS"); else COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'" @@ -3006,14 +2847,14 @@ psql_completion(const char *text, int start, int end) " UNION SELECT 'TABLESPACE'" " UNION SELECT 'TYPE'"); } - else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "ALL")) - COMPLETE_WITH_LIST5("FUNCTIONS IN SCHEMA", - "PROCEDURES IN SCHEMA", - "ROUTINES IN SCHEMA", - "SEQUENCES IN SCHEMA", - "TABLES IN SCHEMA"); - else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "SERVER"); + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL")) + COMPLETE_WITH("FUNCTIONS IN SCHEMA", + "PROCEDURES IN SCHEMA", + "ROUTINES IN SCHEMA", + "SEQUENCES IN SCHEMA", + "TABLES IN SCHEMA"); + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "SERVER"); /* * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of @@ -3021,183 +2862,183 @@ psql_completion(const char *text, int start, int end) * * Complete "GRANT/REVOKE * ON *" with "TO/FROM". */ - else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny)) { - if (TailMatches1("DATABASE")) + if (TailMatches("DATABASE")) COMPLETE_WITH_QUERY(Query_for_list_of_databases); - else if (TailMatches1("DOMAIN")) + else if (TailMatches("DOMAIN")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); - else if (TailMatches1("FUNCTION")) + else if (TailMatches("FUNCTION")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); - else if (TailMatches1("LANGUAGE")) + else if (TailMatches("LANGUAGE")) COMPLETE_WITH_QUERY(Query_for_list_of_languages); - else if (TailMatches1("PROCEDURE")) + else if (TailMatches("PROCEDURE")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL); - else if (TailMatches1("ROUTINE")) + else if (TailMatches("ROUTINE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL); - else if (TailMatches1("SCHEMA")) + else if (TailMatches("SCHEMA")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); - else if (TailMatches1("SEQUENCE")) + else if (TailMatches("SEQUENCE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); - else if (TailMatches1("TABLE")) + else if (TailMatches("TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL); - else if (TailMatches1("TABLESPACE")) + else if (TailMatches("TABLESPACE")) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); - else if (TailMatches1("TYPE")) + else if (TailMatches("TYPE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); - else if (TailMatches4("GRANT", MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC, * CURRENT_USER, or SESSION_USER. */ - else if ((HeadMatches1("GRANT") && TailMatches1("TO")) || - (HeadMatches1("REVOKE") && TailMatches1("FROM"))) + else if ((HeadMatches("GRANT") && TailMatches("TO")) || + (HeadMatches("REVOKE") && TailMatches("FROM"))) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */ - else if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM")) + else if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches("TO|FROM")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */ - else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); - else if (HeadMatches1("REVOKE") && TailMatches3("ON", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("FROM"); + else if (HeadMatches("GRANT") && TailMatches("ON", MatchAny, MatchAny)) + COMPLETE_WITH("TO"); + else if (HeadMatches("REVOKE") && TailMatches("ON", MatchAny, MatchAny)) + COMPLETE_WITH("FROM"); /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */ - else if (TailMatches8("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny)) { - if (TailMatches8("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */ - else if (TailMatches7("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny)) { - if (TailMatches7("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */ - else if (TailMatches6("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny)) { - if (TailMatches6("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* GROUP BY */ - else if (TailMatches3("FROM", MatchAny, "GROUP")) - COMPLETE_WITH_CONST("BY"); + else if (TailMatches("FROM", MatchAny, "GROUP")) + COMPLETE_WITH("BY"); /* IMPORT FOREIGN SCHEMA */ - else if (Matches1("IMPORT")) - COMPLETE_WITH_CONST("FOREIGN SCHEMA"); - else if (Matches2("IMPORT", "FOREIGN")) - COMPLETE_WITH_CONST("SCHEMA"); + else if (Matches("IMPORT")) + COMPLETE_WITH("FOREIGN SCHEMA"); + else if (Matches("IMPORT", "FOREIGN")) + COMPLETE_WITH("SCHEMA"); /* INSERT --- can be inside EXPLAIN, RULE, etc */ /* Complete INSERT with "INTO" */ - else if (TailMatches1("INSERT")) - COMPLETE_WITH_CONST("INTO"); + else if (TailMatches("INSERT")) + COMPLETE_WITH("INTO"); /* Complete INSERT INTO with table names */ - else if (TailMatches2("INSERT", "INTO")) + else if (TailMatches("INSERT", "INTO")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL); /* Complete "INSERT INTO
(" with attribute names */ - else if (TailMatches4("INSERT", "INTO", MatchAny, "(")) + else if (TailMatches("INSERT", "INTO", MatchAny, "(")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* * Complete INSERT INTO
with "(" or "VALUES" or "SELECT" or * "TABLE" or "DEFAULT VALUES" or "OVERRIDING" */ - else if (TailMatches3("INSERT", "INTO", MatchAny)) - COMPLETE_WITH_LIST6("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING"); + else if (TailMatches("INSERT", "INTO", MatchAny)) + COMPLETE_WITH("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING"); /* * Complete INSERT INTO
(attribs) with "VALUES" or "SELECT" or * "TABLE" or "OVERRIDING" */ - else if (TailMatches4("INSERT", "INTO", MatchAny, MatchAny) && + else if (TailMatches("INSERT", "INTO", MatchAny, MatchAny) && ends_with(prev_wd, ')')) - COMPLETE_WITH_LIST4("SELECT", "TABLE", "VALUES", "OVERRIDING"); + COMPLETE_WITH("SELECT", "TABLE", "VALUES", "OVERRIDING"); /* Complete OVERRIDING */ - else if (TailMatches1("OVERRIDING")) - COMPLETE_WITH_LIST2("SYSTEM VALUE", "USER VALUE"); + else if (TailMatches("OVERRIDING")) + COMPLETE_WITH("SYSTEM VALUE", "USER VALUE"); /* Complete after OVERRIDING clause */ - else if (TailMatches3("OVERRIDING", MatchAny, "VALUE")) - COMPLETE_WITH_LIST3("SELECT", "TABLE", "VALUES"); + else if (TailMatches("OVERRIDING", MatchAny, "VALUE")) + COMPLETE_WITH("SELECT", "TABLE", "VALUES"); /* Insert an open parenthesis after "VALUES" */ - else if (TailMatches1("VALUES") && !TailMatches2("DEFAULT", "VALUES")) - COMPLETE_WITH_CONST("("); + else if (TailMatches("VALUES") && !TailMatches("DEFAULT", "VALUES")) + COMPLETE_WITH("("); /* LOCK */ /* Complete LOCK [TABLE] with a list of tables */ - else if (Matches1("LOCK")) + else if (Matches("LOCK")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, " UNION SELECT 'TABLE'"); - else if (Matches2("LOCK", "TABLE")) + else if (Matches("LOCK", "TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* For the following, handle the case of a single table only for now */ /* Complete LOCK [TABLE]
with "IN" */ - else if (Matches2("LOCK", MatchAnyExcept("TABLE")) || - Matches3("LOCK", "TABLE", MatchAny)) - COMPLETE_WITH_CONST("IN"); + else if (Matches("LOCK", MatchAnyExcept("TABLE")) || + Matches("LOCK", "TABLE", MatchAny)) + COMPLETE_WITH("IN"); /* Complete LOCK [TABLE]
IN with a lock mode */ - else if (Matches3("LOCK", MatchAny, "IN") || - Matches4("LOCK", "TABLE", MatchAny, "IN")) - COMPLETE_WITH_LIST8("ACCESS SHARE MODE", - "ROW SHARE MODE", "ROW EXCLUSIVE MODE", - "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE", - "SHARE ROW EXCLUSIVE MODE", - "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE"); + else if (Matches("LOCK", MatchAny, "IN") || + Matches("LOCK", "TABLE", MatchAny, "IN")) + COMPLETE_WITH("ACCESS SHARE MODE", + "ROW SHARE MODE", "ROW EXCLUSIVE MODE", + "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE", + "SHARE ROW EXCLUSIVE MODE", + "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE"); /* Complete LOCK [TABLE]
IN ACCESS|ROW with rest of lock mode */ - else if (Matches4("LOCK", MatchAny, "IN", "ACCESS|ROW") || - Matches5("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW")) - COMPLETE_WITH_LIST2("EXCLUSIVE MODE", "SHARE MODE"); + else if (Matches("LOCK", MatchAny, "IN", "ACCESS|ROW") || + Matches("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW")) + COMPLETE_WITH("EXCLUSIVE MODE", "SHARE MODE"); /* Complete LOCK [TABLE]
IN SHARE with rest of lock mode */ - else if (Matches4("LOCK", MatchAny, "IN", "SHARE") || - Matches5("LOCK", "TABLE", MatchAny, "IN", "SHARE")) - COMPLETE_WITH_LIST3("MODE", "ROW EXCLUSIVE MODE", - "UPDATE EXCLUSIVE MODE"); + else if (Matches("LOCK", MatchAny, "IN", "SHARE") || + Matches("LOCK", "TABLE", MatchAny, "IN", "SHARE")) + COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE", + "UPDATE EXCLUSIVE MODE"); /* NOTIFY --- can be inside EXPLAIN, RULE, etc */ - else if (TailMatches1("NOTIFY")) + else if (TailMatches("NOTIFY")) COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(channel) FROM pg_catalog.pg_listening_channels() AS channel WHERE substring(pg_catalog.quote_ident(channel),1,%d)='%s'"); /* OPTIONS */ - else if (TailMatches1("OPTIONS")) - COMPLETE_WITH_CONST("("); + else if (TailMatches("OPTIONS")) + COMPLETE_WITH("("); /* OWNER TO - complete with available roles */ - else if (TailMatches2("OWNER", "TO")) + else if (TailMatches("OWNER", "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* ORDER BY */ - else if (TailMatches3("FROM", MatchAny, "ORDER")) - COMPLETE_WITH_CONST("BY"); - else if (TailMatches4("FROM", MatchAny, "ORDER", "BY")) + else if (TailMatches("FROM", MatchAny, "ORDER")) + COMPLETE_WITH("BY"); + else if (TailMatches("FROM", MatchAny, "ORDER", "BY")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* PREPARE xx AS */ - else if (Matches3("PREPARE", MatchAny, "AS")) - COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE FROM"); + else if (Matches("PREPARE", MatchAny, "AS")) + COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE FROM"); /* * PREPARE TRANSACTION is missing on purpose. It's intended for transaction @@ -3205,158 +3046,149 @@ psql_completion(const char *text, int start, int end) */ /* REASSIGN OWNED BY xxx TO yyy */ - else if (Matches1("REASSIGN")) - COMPLETE_WITH_CONST("OWNED BY"); - else if (Matches2("REASSIGN", "OWNED")) - COMPLETE_WITH_CONST("BY"); - else if (Matches3("REASSIGN", "OWNED", "BY")) + else if (Matches("REASSIGN")) + COMPLETE_WITH("OWNED BY"); + else if (Matches("REASSIGN", "OWNED")) + COMPLETE_WITH("BY"); + else if (Matches("REASSIGN", "OWNED", "BY")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); - else if (Matches4("REASSIGN", "OWNED", "BY", MatchAny)) - COMPLETE_WITH_CONST("TO"); - else if (Matches5("REASSIGN", "OWNED", "BY", MatchAny, "TO")) + else if (Matches("REASSIGN", "OWNED", "BY", MatchAny)) + COMPLETE_WITH("TO"); + else if (Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* REFRESH MATERIALIZED VIEW */ - else if (Matches1("REFRESH")) - COMPLETE_WITH_CONST("MATERIALIZED VIEW"); - else if (Matches2("REFRESH", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); - else if (Matches3("REFRESH", "MATERIALIZED", "VIEW")) + else if (Matches("REFRESH")) + COMPLETE_WITH("MATERIALIZED VIEW"); + else if (Matches("REFRESH", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, " UNION SELECT 'CONCURRENTLY'"); - else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY")) + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); - else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", MatchAny)) - COMPLETE_WITH_CONST("WITH"); - else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny)) - COMPLETE_WITH_CONST("WITH"); - else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH")) - COMPLETE_WITH_LIST2("NO DATA", "DATA"); - else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH")) - COMPLETE_WITH_LIST2("NO DATA", "DATA"); - else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO")) - COMPLETE_WITH_CONST("DATA"); - else if (Matches7("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO")) - COMPLETE_WITH_CONST("DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny)) + COMPLETE_WITH("WITH"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny)) + COMPLETE_WITH("WITH"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH")) + COMPLETE_WITH("NO DATA", "DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH")) + COMPLETE_WITH("NO DATA", "DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO")) + COMPLETE_WITH("DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO")) + COMPLETE_WITH("DATA"); /* REINDEX */ - else if (Matches1("REINDEX")) - COMPLETE_WITH_LIST5("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE"); - else if (Matches2("REINDEX", "TABLE")) + else if (Matches("REINDEX")) + COMPLETE_WITH("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE"); + else if (Matches("REINDEX", "TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL); - else if (Matches2("REINDEX", "INDEX")) + else if (Matches("REINDEX", "INDEX")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); - else if (Matches2("REINDEX", "SCHEMA")) + else if (Matches("REINDEX", "SCHEMA")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); - else if (Matches2("REINDEX", "SYSTEM|DATABASE")) + else if (Matches("REINDEX", "SYSTEM|DATABASE")) COMPLETE_WITH_QUERY(Query_for_list_of_databases); /* SECURITY LABEL */ - else if (Matches1("SECURITY")) - COMPLETE_WITH_CONST("LABEL"); - else if (Matches2("SECURITY", "LABEL")) - COMPLETE_WITH_LIST2("ON", "FOR"); - else if (Matches4("SECURITY", "LABEL", "FOR", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches3("SECURITY", "LABEL", "ON") || - Matches5("SECURITY", "LABEL", "FOR", MatchAny, "ON")) - { - static const char *const list_SECURITY_LABEL[] = - {"TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN", - "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", "LARGE OBJECT", - "MATERIALIZED VIEW", "LANGUAGE", "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA", - "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW", NULL}; - - COMPLETE_WITH_LIST(list_SECURITY_LABEL); - } - else if (Matches5("SECURITY", "LABEL", "ON", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("IS"); + else if (Matches("SECURITY")) + COMPLETE_WITH("LABEL"); + else if (Matches("SECURITY", "LABEL")) + COMPLETE_WITH("ON", "FOR"); + else if (Matches("SECURITY", "LABEL", "FOR", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("SECURITY", "LABEL", "ON") || + Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON")) + COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN", + "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", + "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE", + "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA", + "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW"); + else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny)) + COMPLETE_WITH("IS"); /* SELECT */ /* naah . . . */ /* SET, RESET, SHOW */ /* Complete with a variable name */ - else if (TailMatches1("SET|RESET") && !TailMatches3("UPDATE", MatchAny, "SET")) + else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET")) COMPLETE_WITH_QUERY(Query_for_list_of_set_vars); - else if (Matches1("SHOW")) + else if (Matches("SHOW")) COMPLETE_WITH_QUERY(Query_for_list_of_show_vars); /* Complete "SET TRANSACTION" */ - else if (Matches2("SET", "TRANSACTION")) - COMPLETE_WITH_LIST5("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); - else if (Matches2("BEGIN|START", "TRANSACTION") || - Matches2("BEGIN", "WORK") || - Matches1("BEGIN") || - Matches5("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION")) - COMPLETE_WITH_LIST4("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); - else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") || - Matches2("BEGIN", "NOT") || - Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT")) - COMPLETE_WITH_CONST("DEFERRABLE"); - else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") || - Matches2("BEGIN", "ISOLATION") || - Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION")) - COMPLETE_WITH_CONST("LEVEL"); - else if (Matches4("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") || - Matches3("BEGIN", "ISOLATION", "LEVEL") || - Matches7("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL")) - COMPLETE_WITH_LIST3("READ", "REPEATABLE READ", "SERIALIZABLE"); - else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") || - Matches4("BEGIN", "ISOLATION", "LEVEL", "READ") || - Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ")) - COMPLETE_WITH_LIST2("UNCOMMITTED", "COMMITTED"); - else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") || - Matches4("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") || - Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE")) - COMPLETE_WITH_CONST("READ"); - else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "READ") || - Matches2("BEGIN", "READ") || - Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ")) - COMPLETE_WITH_LIST2("ONLY", "WRITE"); + else if (Matches("SET", "TRANSACTION")) + COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); + else if (Matches("BEGIN|START", "TRANSACTION") || + Matches("BEGIN", "WORK") || + Matches("BEGIN") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION")) + COMPLETE_WITH("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") || + Matches("BEGIN", "NOT") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT")) + COMPLETE_WITH("DEFERRABLE"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") || + Matches("BEGIN", "ISOLATION") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION")) + COMPLETE_WITH("LEVEL"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") || + Matches("BEGIN", "ISOLATION", "LEVEL") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL")) + COMPLETE_WITH("READ", "REPEATABLE READ", "SERIALIZABLE"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") || + Matches("BEGIN", "ISOLATION", "LEVEL", "READ") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ")) + COMPLETE_WITH("UNCOMMITTED", "COMMITTED"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") || + Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE")) + COMPLETE_WITH("READ"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ") || + Matches("BEGIN", "READ") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ")) + COMPLETE_WITH("ONLY", "WRITE"); /* SET CONSTRAINTS */ - else if (Matches2("SET", "CONSTRAINTS")) + else if (Matches("SET", "CONSTRAINTS")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'"); /* Complete SET CONSTRAINTS with DEFERRED|IMMEDIATE */ - else if (Matches3("SET", "CONSTRAINTS", MatchAny)) - COMPLETE_WITH_LIST2("DEFERRED", "IMMEDIATE"); + else if (Matches("SET", "CONSTRAINTS", MatchAny)) + COMPLETE_WITH("DEFERRED", "IMMEDIATE"); /* Complete SET ROLE */ - else if (Matches2("SET", "ROLE")) + else if (Matches("SET", "ROLE")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */ - else if (Matches2("SET", "SESSION")) - COMPLETE_WITH_LIST2("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION"); + else if (Matches("SET", "SESSION")) + COMPLETE_WITH("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION"); /* Complete SET SESSION AUTHORIZATION with username */ - else if (Matches3("SET", "SESSION", "AUTHORIZATION")) + else if (Matches("SET", "SESSION", "AUTHORIZATION")) COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'"); /* Complete RESET SESSION with AUTHORIZATION */ - else if (Matches2("RESET", "SESSION")) - COMPLETE_WITH_CONST("AUTHORIZATION"); + else if (Matches("RESET", "SESSION")) + COMPLETE_WITH("AUTHORIZATION"); /* Complete SET with "TO" */ - else if (Matches2("SET", MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (Matches("SET", MatchAny)) + COMPLETE_WITH("TO"); /* * Complete ALTER DATABASE|FUNCTION||PROCEDURE|ROLE|ROUTINE|USER ... SET * */ - else if (HeadMatches2("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") && - TailMatches2("SET", MatchAny)) - COMPLETE_WITH_LIST2("FROM CURRENT", "TO"); + else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") && + TailMatches("SET", MatchAny)) + COMPLETE_WITH("FROM CURRENT", "TO"); /* Suggest possible variable values */ - else if (TailMatches3("SET", MatchAny, "TO|=")) + else if (TailMatches("SET", MatchAny, "TO|=")) { /* special cased code for individual GUCs */ - if (TailMatches2("DateStyle", "TO|=")) - { - static const char *const my_list[] = - {"ISO", "SQL", "Postgres", "German", - "YMD", "DMY", "MDY", - "US", "European", "NonEuropean", - "DEFAULT", NULL}; - - COMPLETE_WITH_LIST(my_list); - } - else if (TailMatches2("search_path", "TO|=")) + if (TailMatches("DateStyle", "TO|=")) + COMPLETE_WITH("ISO", "SQL", "Postgres", "German", + "YMD", "DMY", "MDY", + "US", "European", "NonEuropean", + "DEFAULT"); + else if (TailMatches("search_path", "TO|=")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas " AND nspname not like 'pg\\_toast%%' " " AND nspname not like 'pg\\_temp%%' " @@ -3374,10 +3206,10 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_QUERY(querybuf); } else if (guctype && strcmp(guctype, "bool") == 0) - COMPLETE_WITH_LIST9("on", "off", "true", "false", "yes", "no", - "1", "0", "DEFAULT"); + COMPLETE_WITH("on", "off", "true", "false", "yes", "no", + "1", "0", "DEFAULT"); else - COMPLETE_WITH_CONST("DEFAULT"); + COMPLETE_WITH("DEFAULT"); if (guctype) free(guctype); @@ -3385,83 +3217,83 @@ psql_completion(const char *text, int start, int end) } /* START TRANSACTION */ - else if (Matches1("START")) - COMPLETE_WITH_CONST("TRANSACTION"); + else if (Matches("START")) + COMPLETE_WITH("TRANSACTION"); /* TABLE, but not TABLE embedded in other commands */ - else if (Matches1("TABLE")) + else if (Matches("TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL); /* TABLESAMPLE */ - else if (TailMatches1("TABLESAMPLE")) + else if (TailMatches("TABLESAMPLE")) COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods); - else if (TailMatches2("TABLESAMPLE", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (TailMatches("TABLESAMPLE", MatchAny)) + COMPLETE_WITH("("); /* TRUNCATE */ - else if (Matches1("TRUNCATE")) + else if (Matches("TRUNCATE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* UNLISTEN */ - else if (Matches1("UNLISTEN")) + else if (Matches("UNLISTEN")) COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(channel) FROM pg_catalog.pg_listening_channels() AS channel WHERE substring(pg_catalog.quote_ident(channel),1,%d)='%s' UNION SELECT '*'"); /* UPDATE --- can be inside EXPLAIN, RULE, etc */ /* If prev. word is UPDATE suggest a list of tables */ - else if (TailMatches1("UPDATE")) + else if (TailMatches("UPDATE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL); /* Complete UPDATE
with "SET" */ - else if (TailMatches2("UPDATE", MatchAny)) - COMPLETE_WITH_CONST("SET"); + else if (TailMatches("UPDATE", MatchAny)) + COMPLETE_WITH("SET"); /* Complete UPDATE
SET with list of attributes */ - else if (TailMatches3("UPDATE", MatchAny, "SET")) + else if (TailMatches("UPDATE", MatchAny, "SET")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* UPDATE
SET = */ - else if (TailMatches4("UPDATE", MatchAny, "SET", MatchAny)) - COMPLETE_WITH_CONST("="); + else if (TailMatches("UPDATE", MatchAny, "SET", MatchAny)) + COMPLETE_WITH("="); /* USER MAPPING */ - else if (Matches3("ALTER|CREATE|DROP", "USER", "MAPPING")) - COMPLETE_WITH_CONST("FOR"); - else if (Matches4("CREATE", "USER", "MAPPING", "FOR")) + else if (Matches("ALTER|CREATE|DROP", "USER", "MAPPING")) + COMPLETE_WITH("FOR"); + else if (Matches("CREATE", "USER", "MAPPING", "FOR")) COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'CURRENT_USER'" " UNION SELECT 'PUBLIC'" " UNION SELECT 'USER'"); - else if (Matches4("ALTER|DROP", "USER", "MAPPING", "FOR")) + else if (Matches("ALTER|DROP", "USER", "MAPPING", "FOR")) COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings); - else if (Matches5("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny)) - COMPLETE_WITH_CONST("SERVER"); - else if (Matches7("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny)) - COMPLETE_WITH_CONST("OPTIONS"); + else if (Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny)) + COMPLETE_WITH("SERVER"); + else if (Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny)) + COMPLETE_WITH("OPTIONS"); /* * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ] * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] */ - else if (Matches1("VACUUM")) + else if (Matches("VACUUM")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, " UNION SELECT 'FULL'" " UNION SELECT 'FREEZE'" " UNION SELECT 'ANALYZE'" " UNION SELECT 'VERBOSE'"); - else if (Matches2("VACUUM", "FULL")) + else if (Matches("VACUUM", "FULL")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, " UNION SELECT 'FREEZE'" " UNION SELECT 'ANALYZE'" " UNION SELECT 'VERBOSE'"); - else if (Matches2("VACUUM", "FREEZE") || - Matches3("VACUUM", "FULL", "FREEZE")) + else if (Matches("VACUUM", "FREEZE") || + Matches("VACUUM", "FULL", "FREEZE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, " UNION SELECT 'VERBOSE'" " UNION SELECT 'ANALYZE'"); - else if (Matches2("VACUUM", "VERBOSE") || - Matches3("VACUUM", "FULL|FREEZE", "VERBOSE") || - Matches4("VACUUM", "FULL", "FREEZE", "VERBOSE")) + else if (Matches("VACUUM", "VERBOSE") || + Matches("VACUUM", "FULL|FREEZE", "VERBOSE") || + Matches("VACUUM", "FULL", "FREEZE", "VERBOSE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, " UNION SELECT 'ANALYZE'"); - else if (HeadMatches2("VACUUM", "(*") && - !HeadMatches2("VACUUM", "(*)")) + else if (HeadMatches("VACUUM", "(*") && + !HeadMatches("VACUUM", "(*)")) { /* * This fires if we're in an unfinished parenthesized option list. @@ -3469,13 +3301,13 @@ psql_completion(const char *text, int start, int end) * one word, so the above test is correct. */ if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) - COMPLETE_WITH_LIST5("FULL", "FREEZE", "ANALYZE", "VERBOSE", - "DISABLE_PAGE_SKIPPING"); + COMPLETE_WITH("FULL", "FREEZE", "ANALYZE", "VERBOSE", + "DISABLE_PAGE_SKIPPING"); } - else if (HeadMatches1("VACUUM") && TailMatches1("(")) + else if (HeadMatches("VACUUM") && TailMatches("(")) /* "VACUUM (" should be caught above, so assume we want columns */ COMPLETE_WITH_ATTR(prev2_wd, ""); - else if (HeadMatches1("VACUUM")) + else if (HeadMatches("VACUUM")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, NULL); /* WITH [RECURSIVE] */ @@ -3484,109 +3316,109 @@ psql_completion(const char *text, int start, int end) * Only match when WITH is the first word, as WITH may appear in many * other contexts. */ - else if (Matches1("WITH")) - COMPLETE_WITH_CONST("RECURSIVE"); + else if (Matches("WITH")) + COMPLETE_WITH("RECURSIVE"); /* WHERE */ /* Simple case of the word before the where being the table name */ - else if (TailMatches2(MatchAny, "WHERE")) + else if (TailMatches(MatchAny, "WHERE")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* ... FROM ... */ /* TODO: also include SRF ? */ - else if (TailMatches1("FROM") && !Matches3("COPY|\\copy", MatchAny, "FROM")) + else if (TailMatches("FROM") && !Matches("COPY|\\copy", MatchAny, "FROM")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL); /* ... JOIN ... */ - else if (TailMatches1("JOIN")) + else if (TailMatches("JOIN")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL); /* Backslash commands */ /* TODO: \dc \dd \dl */ - else if (TailMatchesCS1("\\?")) - COMPLETE_WITH_LIST_CS3("commands", "options", "variables"); - else if (TailMatchesCS1("\\connect|\\c")) + else if (TailMatchesCS("\\?")) + COMPLETE_WITH_CS("commands", "options", "variables"); + else if (TailMatchesCS("\\connect|\\c")) { if (!recognized_connection_string(text)) COMPLETE_WITH_QUERY(Query_for_list_of_databases); } - else if (TailMatchesCS2("\\connect|\\c", MatchAny)) + else if (TailMatchesCS("\\connect|\\c", MatchAny)) { if (!recognized_connection_string(prev_wd)) COMPLETE_WITH_QUERY(Query_for_list_of_roles); } - else if (TailMatchesCS1("\\da*")) + else if (TailMatchesCS("\\da*")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); - else if (TailMatchesCS1("\\dA*")) + else if (TailMatchesCS("\\dA*")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); - else if (TailMatchesCS1("\\db*")) + else if (TailMatchesCS("\\db*")) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); - else if (TailMatchesCS1("\\dD*")) + else if (TailMatchesCS("\\dD*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); - else if (TailMatchesCS1("\\des*")) + else if (TailMatchesCS("\\des*")) COMPLETE_WITH_QUERY(Query_for_list_of_servers); - else if (TailMatchesCS1("\\deu*")) + else if (TailMatchesCS("\\deu*")) COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings); - else if (TailMatchesCS1("\\dew*")) + else if (TailMatchesCS("\\dew*")) COMPLETE_WITH_QUERY(Query_for_list_of_fdws); - else if (TailMatchesCS1("\\df*")) + else if (TailMatchesCS("\\df*")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); - else if (TailMatchesCS1("\\dFd*")) + else if (TailMatchesCS("\\dFd*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries); - else if (TailMatchesCS1("\\dFp*")) + else if (TailMatchesCS("\\dFp*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers); - else if (TailMatchesCS1("\\dFt*")) + else if (TailMatchesCS("\\dFt*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates); /* must be at end of \dF alternatives: */ - else if (TailMatchesCS1("\\dF*")) + else if (TailMatchesCS("\\dF*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations); - else if (TailMatchesCS1("\\di*")) + else if (TailMatchesCS("\\di*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); - else if (TailMatchesCS1("\\dL*")) + else if (TailMatchesCS("\\dL*")) COMPLETE_WITH_QUERY(Query_for_list_of_languages); - else if (TailMatchesCS1("\\dn*")) + else if (TailMatchesCS("\\dn*")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); - else if (TailMatchesCS1("\\dp") || TailMatchesCS1("\\z")) + else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL); - else if (TailMatchesCS1("\\ds*")) + else if (TailMatchesCS("\\ds*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); - else if (TailMatchesCS1("\\dt*")) + else if (TailMatchesCS("\\dt*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - else if (TailMatchesCS1("\\dT*")) + else if (TailMatchesCS("\\dT*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); - else if (TailMatchesCS1("\\du*") || TailMatchesCS1("\\dg*")) + else if (TailMatchesCS("\\du*") || TailMatchesCS("\\dg*")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); - else if (TailMatchesCS1("\\dv*")) + else if (TailMatchesCS("\\dv*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (TailMatchesCS1("\\dx*")) + else if (TailMatchesCS("\\dx*")) COMPLETE_WITH_QUERY(Query_for_list_of_extensions); - else if (TailMatchesCS1("\\dm*")) + else if (TailMatchesCS("\\dm*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); - else if (TailMatchesCS1("\\dE*")) + else if (TailMatchesCS("\\dE*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL); - else if (TailMatchesCS1("\\dy*")) + else if (TailMatchesCS("\\dy*")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); /* must be at end of \d alternatives: */ - else if (TailMatchesCS1("\\d*")) + else if (TailMatchesCS("\\d*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL); - else if (TailMatchesCS1("\\ef")) + else if (TailMatchesCS("\\ef")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL); - else if (TailMatchesCS1("\\ev")) + else if (TailMatchesCS("\\ev")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (TailMatchesCS1("\\encoding")) + else if (TailMatchesCS("\\encoding")) COMPLETE_WITH_QUERY(Query_for_list_of_encodings); - else if (TailMatchesCS1("\\h|\\help")) + else if (TailMatchesCS("\\h|\\help")) COMPLETE_WITH_LIST(sql_commands); - else if (TailMatchesCS2("\\h|\\help", MatchAny)) + else if (TailMatchesCS("\\h|\\help", MatchAny)) { - if (TailMatches1("DROP")) + if (TailMatches("DROP")) matches = completion_matches(text, drop_command_generator); - else if (TailMatches1("ALTER")) + else if (TailMatches("ALTER")) matches = completion_matches(text, alter_command_generator); /* @@ -3594,101 +3426,96 @@ psql_completion(const char *text, int start, int end) * repeated here */ } - else if (TailMatchesCS3("\\h|\\help", MatchAny, MatchAny)) + else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny)) { - if (TailMatches2("CREATE|DROP", "ACCESS")) - COMPLETE_WITH_CONST("METHOD"); - else if (TailMatches2("ALTER", "DEFAULT")) - COMPLETE_WITH_CONST("PRIVILEGES"); - else if (TailMatches2("CREATE|ALTER|DROP", "EVENT")) - COMPLETE_WITH_CONST("TRIGGER"); - else if (TailMatches2("CREATE|ALTER|DROP", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); - else if (TailMatches2("ALTER", "LARGE")) - COMPLETE_WITH_CONST("OBJECT"); - else if (TailMatches2("CREATE|ALTER|DROP", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); - else if (TailMatches2("CREATE|ALTER|DROP", "TEXT")) - COMPLETE_WITH_CONST("SEARCH"); - else if (TailMatches2("CREATE|ALTER|DROP", "USER")) - COMPLETE_WITH_CONST("MAPPING FOR"); + if (TailMatches("CREATE|DROP", "ACCESS")) + COMPLETE_WITH("METHOD"); + else if (TailMatches("ALTER", "DEFAULT")) + COMPLETE_WITH("PRIVILEGES"); + else if (TailMatches("CREATE|ALTER|DROP", "EVENT")) + COMPLETE_WITH("TRIGGER"); + else if (TailMatches("CREATE|ALTER|DROP", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); + else if (TailMatches("ALTER", "LARGE")) + COMPLETE_WITH("OBJECT"); + else if (TailMatches("CREATE|ALTER|DROP", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); + else if (TailMatches("CREATE|ALTER|DROP", "TEXT")) + COMPLETE_WITH("SEARCH"); + else if (TailMatches("CREATE|ALTER|DROP", "USER")) + COMPLETE_WITH("MAPPING FOR"); } - else if (TailMatchesCS4("\\h|\\help", MatchAny, MatchAny, MatchAny)) + else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny)) { - if (TailMatches3("CREATE|ALTER|DROP", "FOREIGN", "DATA")) - COMPLETE_WITH_CONST("WRAPPER"); - else if (TailMatches3("CREATE|ALTER|DROP", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (TailMatches3("CREATE|ALTER|DROP", "USER", "MAPPING")) - COMPLETE_WITH_CONST("FOR"); + if (TailMatches("CREATE|ALTER|DROP", "FOREIGN", "DATA")) + COMPLETE_WITH("WRAPPER"); + else if (TailMatches("CREATE|ALTER|DROP", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (TailMatches("CREATE|ALTER|DROP", "USER", "MAPPING")) + COMPLETE_WITH("FOR"); } - else if (TailMatchesCS1("\\l*") && !TailMatchesCS1("\\lo*")) + else if (TailMatchesCS("\\l*") && !TailMatchesCS("\\lo*")) COMPLETE_WITH_QUERY(Query_for_list_of_databases); - else if (TailMatchesCS1("\\password")) + else if (TailMatchesCS("\\password")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); - else if (TailMatchesCS1("\\pset")) - { - static const char *const my_list[] = - {"border", "columns", "expanded", "fieldsep", "fieldsep_zero", - "footer", "format", "linestyle", "null", "numericlocale", - "pager", "pager_min_lines", "recordsep", "recordsep_zero", - "tableattr", "title", "tuples_only", "unicode_border_linestyle", - "unicode_column_linestyle", "unicode_header_linestyle", NULL}; - - COMPLETE_WITH_LIST_CS(my_list); - } - else if (TailMatchesCS2("\\pset", MatchAny)) + else if (TailMatchesCS("\\pset")) + COMPLETE_WITH_CS("border", "columns", "expanded", + "fieldsep", "fieldsep_zero", "footer", "format", + "linestyle", "null", "numericlocale", + "pager", "pager_min_lines", + "recordsep", "recordsep_zero", + "tableattr", "title", "tuples_only", + "unicode_border_linestyle", + "unicode_column_linestyle", + "unicode_header_linestyle"); + else if (TailMatchesCS("\\pset", MatchAny)) { - if (TailMatchesCS1("format")) - { - static const char *const my_list[] = - {"unaligned", "aligned", "wrapped", "html", "asciidoc", - "latex", "latex-longtable", "troff-ms", NULL}; - - COMPLETE_WITH_LIST_CS(my_list); - } - else if (TailMatchesCS1("linestyle")) - COMPLETE_WITH_LIST_CS3("ascii", "old-ascii", "unicode"); - else if (TailMatchesCS1("pager")) - COMPLETE_WITH_LIST_CS3("on", "off", "always"); - else if (TailMatchesCS1("unicode_border_linestyle|" - "unicode_column_linestyle|" - "unicode_header_linestyle")) - COMPLETE_WITH_LIST_CS2("single", "double"); + if (TailMatchesCS("format")) + COMPLETE_WITH_CS("unaligned", "aligned", "wrapped", "html", + "asciidoc", "latex", "latex-longtable", + "troff-ms"); + else if (TailMatchesCS("linestyle")) + COMPLETE_WITH_CS("ascii", "old-ascii", "unicode"); + else if (TailMatchesCS("pager")) + COMPLETE_WITH_CS("on", "off", "always"); + else if (TailMatchesCS("unicode_border_linestyle|" + "unicode_column_linestyle|" + "unicode_header_linestyle")) + COMPLETE_WITH_CS("single", "double"); } - else if (TailMatchesCS1("\\unset")) + else if (TailMatchesCS("\\unset")) matches = complete_from_variables(text, "", "", true); - else if (TailMatchesCS1("\\set")) + else if (TailMatchesCS("\\set")) matches = complete_from_variables(text, "", "", false); - else if (TailMatchesCS2("\\set", MatchAny)) + else if (TailMatchesCS("\\set", MatchAny)) { - if (TailMatchesCS1("AUTOCOMMIT|ON_ERROR_STOP|QUIET|" - "SINGLELINE|SINGLESTEP")) - COMPLETE_WITH_LIST_CS2("on", "off"); - else if (TailMatchesCS1("COMP_KEYWORD_CASE")) - COMPLETE_WITH_LIST_CS4("lower", "upper", - "preserve-lower", "preserve-upper"); - else if (TailMatchesCS1("ECHO")) - COMPLETE_WITH_LIST_CS4("errors", "queries", "all", "none"); - else if (TailMatchesCS1("ECHO_HIDDEN")) - COMPLETE_WITH_LIST_CS3("noexec", "off", "on"); - else if (TailMatchesCS1("HISTCONTROL")) - COMPLETE_WITH_LIST_CS4("ignorespace", "ignoredups", - "ignoreboth", "none"); - else if (TailMatchesCS1("ON_ERROR_ROLLBACK")) - COMPLETE_WITH_LIST_CS3("on", "off", "interactive"); - else if (TailMatchesCS1("SHOW_CONTEXT")) - COMPLETE_WITH_LIST_CS3("never", "errors", "always"); - else if (TailMatchesCS1("VERBOSITY")) - COMPLETE_WITH_LIST_CS3("default", "verbose", "terse"); + if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|" + "SINGLELINE|SINGLESTEP")) + COMPLETE_WITH_CS("on", "off"); + else if (TailMatchesCS("COMP_KEYWORD_CASE")) + COMPLETE_WITH_CS("lower", "upper", + "preserve-lower", "preserve-upper"); + else if (TailMatchesCS("ECHO")) + COMPLETE_WITH_CS("errors", "queries", "all", "none"); + else if (TailMatchesCS("ECHO_HIDDEN")) + COMPLETE_WITH_CS("noexec", "off", "on"); + else if (TailMatchesCS("HISTCONTROL")) + COMPLETE_WITH_CS("ignorespace", "ignoredups", + "ignoreboth", "none"); + else if (TailMatchesCS("ON_ERROR_ROLLBACK")) + COMPLETE_WITH_CS("on", "off", "interactive"); + else if (TailMatchesCS("SHOW_CONTEXT")) + COMPLETE_WITH_CS("never", "errors", "always"); + else if (TailMatchesCS("VERBOSITY")) + COMPLETE_WITH_CS("default", "verbose", "terse"); } - else if (TailMatchesCS1("\\sf*")) + else if (TailMatchesCS("\\sf*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL); - else if (TailMatchesCS1("\\sv*")) + else if (TailMatchesCS("\\sv*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (TailMatchesCS1("\\cd|\\e|\\edit|\\g|\\i|\\include|" - "\\ir|\\include_relative|\\o|\\out|" - "\\s|\\w|\\write|\\lo_import")) + else if (TailMatchesCS("\\cd|\\e|\\edit|\\g|\\i|\\include|" + "\\ir|\\include_relative|\\o|\\out|" + "\\s|\\w|\\write|\\lo_import")) { completion_charp = "\\"; matches = completion_matches(text, complete_from_files); @@ -3726,7 +3553,7 @@ psql_completion(const char *text, int start, int end) */ if (matches == NULL) { - COMPLETE_WITH_CONST(""); + COMPLETE_WITH(""); #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER rl_completion_append_character = '\0'; #endif diff --git a/src/include/c.h b/src/include/c.h index 901d791198..13c794d8ea 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -224,6 +224,39 @@ #define CppAsString2(x) CppAsString(x) #define CppConcat(x, y) x##y +/* + * VA_ARGS_NARGS + * Returns the number of macro arguments it is passed. + * + * An empty argument still counts as an argument, so effectively, this is + * "one more than the number of commas in the argument list". + * + * This works for up to 63 arguments. Internally, VA_ARGS_NARGS_() is passed + * 64+N arguments, and the C99 standard only requires macros to allow up to + * 127 arguments, so we can't portably go higher. The implementation is + * pretty trivial: VA_ARGS_NARGS_() returns its 64th argument, and we set up + * the call so that that is the appropriate one of the list of constants. + * This idea is due to Laurent Deniau. + */ +#define VA_ARGS_NARGS(...) \ + VA_ARGS_NARGS_(__VA_ARGS__, \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define VA_ARGS_NARGS_( \ + _01,_02,_03,_04,_05,_06,_07,_08,_09,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63, N, ...) \ + (N) + /* * dummyret is used to set return values in macros that use ?: to make * assignments. gcc wants these to be void, other compilers like char