From 074add6ed286a02256a1b03137ff6dd7c8126f25 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 2 Jul 2019 13:35:14 -0400 Subject: [PATCH] Fix tab completion of "SET variable TO|=" to not offer bogus completions. Don't think that the context "UPDATE tab SET var =" is a GUC-setting command. If we have "SET var =" but the "var" is not a known GUC variable, don't offer any completions. The most likely explanation is that we've misparsed the context and it's not really a GUC-setting command. Per gripe from Ken Tanzer. Back-patch to 9.6. The issue exists further back, but before 9.6 the code looks very different and it doesn't actually know whether the "var" name matches anything, so I desisted from trying to fix it. Discussion: https://postgr.es/m/CAD3a31XpXzrZA9TT3BqLSHghdTK+=cXjNCE+oL2Zn4+oWoc=qA@mail.gmail.com --- src/bin/psql/tab-complete.c | 43 ++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 7817bd72d7..fe1b170a0e 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3532,8 +3532,13 @@ psql_completion(const char *text, int start, int end) else if (HeadMatches2("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") && TailMatches2("SET", MatchAny)) COMPLETE_WITH_LIST2("FROM CURRENT", "TO"); - /* Suggest possible variable values */ - else if (TailMatches3("SET", MatchAny, "TO|=")) + + /* + * Suggest possible variable values in SET variable TO|=, along with the + * preceding ALTER syntaxes. + */ + else if (TailMatches3("SET", MatchAny, "TO|=") && + !TailMatches5("UPDATE", MatchAny, "SET", MatchAny, "TO|=")) { /* special cased code for individual GUCs */ if (TailMatches2("DateStyle", "TO|=")) @@ -3556,21 +3561,29 @@ psql_completion(const char *text, int start, int end) /* generic, type based, GUC support */ char *guctype = get_guctype(prev2_wd); - if (guctype && strcmp(guctype, "enum") == 0) - { - char querybuf[1024]; - - snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd); - COMPLETE_WITH_QUERY(querybuf); - } - else if (guctype && strcmp(guctype, "bool") == 0) - COMPLETE_WITH_LIST9("on", "off", "true", "false", "yes", "no", - "1", "0", "DEFAULT"); - else - COMPLETE_WITH_CONST("DEFAULT"); - + /* + * Note: if we don't recognize the GUC name, it's important to not + * offer any completions, as most likely we've misinterpreted the + * context and this isn't a GUC-setting command at all. + */ if (guctype) + { + if (strcmp(guctype, "enum") == 0) + { + char querybuf[1024]; + + snprintf(querybuf, sizeof(querybuf), + Query_for_enum, prev2_wd); + COMPLETE_WITH_QUERY(querybuf); + } + else if (strcmp(guctype, "bool") == 0) + COMPLETE_WITH_LIST9("on", "off", "true", "false", + "yes", "no", "1", "0", "DEFAULT"); + else + COMPLETE_WITH_CONST("DEFAULT"); + free(guctype); + } } }