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 1702.1561478396@sss.pgh.pa.us
Whole thread Raw
In response to Re: psql UPDATE field [tab] expands to DEFAULT?  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
I wrote:
> I took a closer look and realized that this isn't some magic behavior of
> arcane parts of libreadline; it's more like self-inflicted damage.  It
> happens because tab-complete.c's complete_from_const() is doing exactly
> what its comment says it does:

> /*
>  * This function returns one fixed string the first time even if it doesn't
>  * match what's there, and nothing the second time. This should be used if
>  * there is only one possibility that can appear at a certain spot, so
>  * misspellings will be overwritten.  The string to be passed must be in
>  * completion_charp.
>  */

> This is unlike complete_from_list(), which will only return completions
> that match the text-string-so-far.

> I have to wonder whether complete_from_const()'s behavior is really
> a good idea; I think there might be an argument for getting rid of it
> and using complete_from_list() even for one-element lists.

I experimented with ripping out complete_from_const() altogether, and
soon found that there's still one place where we need it: down at the
end of psql_completion, where we've failed to find any useful completion.
If that instance of COMPLETE_WITH("") is implemented by complete_from_list
then readline will happily try to do filename completion :-(.
(I don't quite understand why we don't get the wiping-out behavior there;
maybe an empty-string result is treated differently from
not-empty-string?)

So I propose the attached instead, which doesn't get rid of
complete_from_const but ensures that it's only used in that one place.

This is independent of the other patch shown upthread.  I'm proposing
this one for HEAD only but would back-patch the other.

            regards, tom lane

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 7dcf342..d41f923 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -205,19 +205,22 @@ do { \
     matches = completion_matches(text, complete_from_versioned_schema_query); \
 } while (0)
 
+/*
+ * Caution: COMPLETE_WITH_CONST is not for general-purpose use; you probably
+ * want COMPLETE_WITH() with one element, instead.
+ */
+#define COMPLETE_WITH_CONST(cs, con) \
+do { \
+    completion_case_sensitive = (cs); \
+    completion_charp = (con); \
+    matches = completion_matches(text, complete_from_const); \
+} while (0)
+
 #define COMPLETE_WITH_LIST_INT(cs, list) \
 do { \
     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); \
-    } \
+    completion_charpp = (list); \
+    matches = completion_matches(text, complete_from_list); \
 } while (0)
 
 #define COMPLETE_WITH_LIST(list) COMPLETE_WITH_LIST_INT(false, list)
@@ -3745,7 +3748,7 @@ psql_completion(const char *text, int start, int end)
      */
     if (matches == NULL)
     {
-        COMPLETE_WITH("");
+        COMPLETE_WITH_CONST(true, "");
 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
         rl_completion_append_character = '\0';
 #endif
@@ -4177,8 +4180,10 @@ complete_from_list(const char *text, int state)
  * This function returns one fixed string the first time even if it doesn't
  * match what's there, and nothing the second time. This should be used if
  * there is only one possibility that can appear at a certain spot, so
- * misspellings will be overwritten.  The string to be passed must be in
- * completion_charp.
+ * misspellings will be overwritten.  (Caution: in practice that's almost
+ * never a good idea.  We currently use this function only for forcing
+ * readline to not attempt filename completion by default.)  The string
+ * to be passed must be in completion_charp.
  */
 static char *
 complete_from_const(const char *text, int state)

pgsql-hackers by date:

Previous
From: Liudmila Mantrova
Date:
Subject: Re: SQL/JSON path issues/questions
Next
From: Tomas Vondra
Date:
Subject: Re: [PATCH] Incremental sort (was: PoC: Partial sort)