Re: psql UPDATE field [tab] expands to DEFAULT? - Mailing list pgsql-hackers

From Tom Lane
Subject Re: psql UPDATE field [tab] expands to DEFAULT?
Date
Msg-id 6787.1560955164@sss.pgh.pa.us
Whole thread Raw
Responses Re: psql UPDATE field [tab] expands to DEFAULT?
List pgsql-hackers
[ moving thread to -hackers ]

So I propose the attached patch for fixing the clear bugs that have
emerged in this discussion: don't confuse UPDATE ... SET ... with
GUC-setting commands, and don't offer just DEFAULT in contexts where
that's unlikely to be the only valid completion.

Nosing around in tab-complete.c, I notice a fair number of other
places where we're doing COMPLETE_WITH() with just a single possible
completion.  Knowing what we know now, in each one of those places
libreadline will suppose that that completion is the only syntactically
legal continuation, and throw away anything else the user might've typed.
We should probably inspect each of those places to see if that's really
desirable behavior ... but I didn't muster the energy to do that this
morning.

            regards, tom lane

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 5e38f46..3530570 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3361,8 +3361,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|="))
@@ -3390,8 +3395,18 @@ psql_completion(const char *text, int start, int end)
             else if (guctype && strcmp(guctype, "bool") == 0)
                 COMPLETE_WITH("on", "off", "true", "false", "yes", "no",
                               "1", "0", "DEFAULT");
-            else
-                COMPLETE_WITH("DEFAULT");
+
+            /*
+             * Note: if we didn'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 we
+             * did recognize the GUC but it's not enum or bool type, it still
+             * seems better to do nothing.  We used to offer (only) "DEFAULT"
+             * as a possible completion, but that turns out to be a bad idea,
+             * because with a single completion libreadline will decide that
+             * that's the only legal text and throw away whatever the user
+             * might've typed already.
+             */

             if (guctype)
                 free(guctype);

pgsql-hackers by date:

Previous
From: Rui Hai Jiang
Date:
Subject: Re: How to produce a Soft Block case of Deadlock Detection?
Next
From: David Fetter
Date:
Subject: Re: New EXPLAIN option: ALL