Commit 0ec3e13c authored by Tom Lane's avatar Tom Lane

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
parent 4d6603f2
...@@ -3362,8 +3362,13 @@ psql_completion(const char *text, int start, int end) ...@@ -3362,8 +3362,13 @@ psql_completion(const char *text, int start, int end)
else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") && else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") &&
TailMatches("SET", MatchAny)) TailMatches("SET", MatchAny))
COMPLETE_WITH("FROM CURRENT", "TO"); 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 */ /* special cased code for individual GUCs */
if (TailMatches("DateStyle", "TO|=")) if (TailMatches("DateStyle", "TO|="))
...@@ -3381,23 +3386,31 @@ psql_completion(const char *text, int start, int end) ...@@ -3381,23 +3386,31 @@ psql_completion(const char *text, int start, int end)
/* generic, type based, GUC support */ /* generic, type based, GUC support */
char *guctype = get_guctype(prev2_wd); 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)
{
if (strcmp(guctype, "enum") == 0)
{ {
char querybuf[1024]; char querybuf[1024];
snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd); snprintf(querybuf, sizeof(querybuf),
Query_for_enum, prev2_wd);
COMPLETE_WITH_QUERY(querybuf); COMPLETE_WITH_QUERY(querybuf);
} }
else if (guctype && strcmp(guctype, "bool") == 0) else if (strcmp(guctype, "bool") == 0)
COMPLETE_WITH("on", "off", "true", "false", "yes", "no", COMPLETE_WITH("on", "off", "true", "false", "yes", "no",
"1", "0", "DEFAULT"); "1", "0", "DEFAULT");
else else
COMPLETE_WITH("DEFAULT"); COMPLETE_WITH("DEFAULT");
if (guctype)
free(guctype); free(guctype);
} }
} }
}
/* START TRANSACTION */ /* START TRANSACTION */
else if (Matches("START")) else if (Matches("START"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment