From: Tom Lane Date: Tue, 2 Jul 2019 17:35:14 +0000 (-0400) Subject: Fix tab completion of "SET variable TO|=" to not offer bogus completions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0ec3e13c69779117c8cfa39adcc6863631dedd44;p=postgresql 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 --- diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 7dcf342413..ca3a162bbf 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3362,8 +3362,13 @@ psql_completion(const char *text, int start, int end) else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") && TailMatches("SET", MatchAny)) COMPLETE_WITH("FROM CURRENT", "TO"); - /* Suggest possible variable values */ - else if (TailMatches("SET", MatchAny, "TO|=")) + + /* + * Suggest possible variable values in SET variable TO|=, along with the + * preceding ALTER syntaxes. + */ + else if (TailMatches("SET", MatchAny, "TO|=") && + !TailMatches("UPDATE", MatchAny, "SET", MatchAny, "TO|=")) { /* special cased code for individual GUCs */ if (TailMatches("DateStyle", "TO|=")) @@ -3381,21 +3386,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) + /* + * 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) { - char querybuf[1024]; + if (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("on", "off", "true", "false", "yes", "no", - "1", "0", "DEFAULT"); - else - COMPLETE_WITH("DEFAULT"); + snprintf(querybuf, sizeof(querybuf), + Query_for_enum, prev2_wd); + COMPLETE_WITH_QUERY(querybuf); + } + else if (strcmp(guctype, "bool") == 0) + COMPLETE_WITH("on", "off", "true", "false", "yes", "no", + "1", "0", "DEFAULT"); + else + COMPLETE_WITH("DEFAULT"); - if (guctype) free(guctype); + } } }