Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nEeOZ-0005X4-UH for pgsql-hackers@arkaria.postgresql.org; Mon, 31 Jan 2022 21:39:32 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nEeOX-0000yW-CK for pgsql-hackers@arkaria.postgresql.org; Mon, 31 Jan 2022 21:39:29 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nEeOX-0000yN-34 for pgsql-hackers@lists.postgresql.org; Mon, 31 Jan 2022 21:39:29 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nEeOT-0000fa-61 for pgsql-hackers@lists.postgresql.org; Mon, 31 Jan 2022 21:39:28 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 20VLd1nd838382; Mon, 31 Jan 2022 16:39:01 -0500 From: Tom Lane To: =?utf-8?Q?Dagfinn_Ilmari_Manns=C3=A5ker?= cc: "tanghy.fnst@fujitsu.com" , Peter Eisentraut , Japin Li , Kyotaro Horiguchi , Laurenz Albe , "smithpb2250@gmail.com" , "david.zhang@highgo.ca" , "pgsql-hackers@lists.postgresql.org" Subject: Re: Support tab completion for upper character inputs in psql In-reply-to: <534641.1643594097@sss.pgh.pa.us> References: <80b093ae-88bd-8d8a-68b9-b535a3ab11be@enterprisedb.com> <54bd7839-f463-ef03-f2d2-ccb8184b9b27@enterprisedb.com> <1068530.1641480996@sss.pgh.pa.us> <3547066.1642272686@sss.pgh.pa.us> <2304294.1643152287@sss.pgh.pa.us> <2645164.1643315022@sss.pgh.pa.u! ! s> <2771362.1643385796@sss.pgh.pa.us> <2805502.1643405157@sss.pgh.pa.us> <2818574.1643408192@sss.pgh.pa.us> <324281.1643567679@sss.pgh.pa.us> <8735l41ynm.fsf@wibble.ilmari.org> <534641.1643594097@sss.pgh.pa.us> Comments: In-reply-to Tom Lane message dated "Sun, 30 Jan 2022 20:54:57 -0500" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <838367.1643665124.0@sss.pgh.pa.us> Date: Mon, 31 Jan 2022 16:39:01 -0500 Message-ID: <838381.1643665141@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <838367.1643665124.1@sss.pgh.pa.us> I wrote: > =?utf-8?Q?Dagfinn_Ilmari_Manns=C3=A5ker?= writes: >> First, as noted in the test, it doesn't preserve the case of the input >> for keywords appended to the query result. This is easily fixed by >> using `pg_strdup_keyword_case()`, per the first attached patch. > I thought about that, and intentionally didn't do it, because it > would also affect the menus produced by tab completion. > ... > We could do something hacky like matching case only when there's > no longer any matching object names, but that might be too magic. I experimented with that, and it actually doesn't seem as weird as I feared. See if you like this ... regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="respect-COMP_KEYWORD_CASE-v2.patch"; charset="us-ascii" Content-ID: <838367.1643665124.2@sss.pgh.pa.us> Content-Description: respect-COMP_KEYWORD_CASE-v2.patch Content-Transfer-Encoding: quoted-printable diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab= _completion.pl index c4f6552ac9..7a265e0676 100644 --- a/src/bin/psql/t/010_tab_completion.pl +++ b/src/bin/psql/t/010_tab_completion.pl @@ -40,7 +40,7 @@ $node->start; = # set up a few database objects $node->safe_psql('postgres', - "CREATE TABLE tab1 (f1 int primary key, f2 text);\n" + "CREATE TABLE tab1 (c1 int primary key, c2 text);\n" . "CREATE TABLE mytab123 (f1 int, f2 text);\n" . "CREATE TABLE mytab246 (f1 int, f2 text);\n" . "CREATE TABLE \"mixedName\" (f1 int, f2 text);\n" @@ -317,14 +317,30 @@ check_completion( = clear_line(); = -# check completion of a keyword offered in addition to object names -# (that code path currently doesn't preserve case of what's typed) -check_completion( - "comment on constraint foo on dom\t", - qr|DOMAIN|, - "offer keyword in addition to query result"); - -clear_query(); +# check completion of a keyword offered in addition to object names; +# such a keyword should obey COMP_KEYWORD_CASE once only keyword +# completions are possible +foreach ( + [ 'lower', 'CO', 'column' ], + [ 'upper', 'co', 'COLUMN' ], + [ 'preserve-lower', 'co', 'column' ], + [ 'preserve-upper', 'CO', 'COLUMN' ],) +{ + my ($case, $in, $out) =3D @$_; + + check_completion( + "\\set COMP_KEYWORD_CASE $case\n", + qr/postgres=3D#/, + "set completion case to '$case'"); + check_completion("alter table tab1 rename c\t\t", + qr|COLUMN|, + "offer keyword COLUMN for input c, COMP_KEYWORD_CASE =3D $case"); + clear_query(); + check_completion("alter table tab1 rename $in\t\t\t", + qr|$out|, + "offer keyword $out for input $in, COMP_KEYWORD_CASE =3D $case"); + clear_query(); +} = # send psql an explicit \q to shut it down, else pty won't close properly $timer->start(5); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index b2ec50b4f2..bdc9760fba 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -4742,7 +4742,8 @@ _complete_from_query(const char *simple_query, { static int list_index, num_schema_only, - num_other; + num_other, + num_keywords; static PGresult *result =3D NULL; static bool non_empty_object; static bool schemaquoted; @@ -4766,6 +4767,7 @@ _complete_from_query(const char *simple_query, list_index =3D 0; num_schema_only =3D 0; num_other =3D 0; + num_keywords =3D 0; PQclear(result); result =3D NULL; = @@ -4986,7 +4988,10 @@ _complete_from_query(const char *simple_query, = /* In verbatim mode, we return all the items as-is */ if (verbatim) + { + num_other++; return pg_strdup(item); + } = /* * In normal mode, a name requiring quoting will be returned only @@ -5031,8 +5036,12 @@ _complete_from_query(const char *simple_query, list_index++; if (pg_strncasecmp(text, item, strlen(text)) =3D=3D 0) { - num_other++; - return pg_strdup(item); + num_keywords++; + /* Match keyword case if we are returning only keywords */ + if (num_schema_only =3D=3D 0 && num_other =3D=3D 0) + return pg_strdup_keyword_case(item, text); + else + return pg_strdup(item); } } } @@ -5049,8 +5058,12 @@ _complete_from_query(const char *simple_query, list_index++; if (pg_strncasecmp(text, item, strlen(text)) =3D=3D 0) { - num_other++; - return pg_strdup(item); + num_keywords++; + /* Match keyword case if we are returning only keywords */ + if (num_schema_only =3D=3D 0 && num_other =3D=3D 0) + return pg_strdup_keyword_case(item, text); + else + return pg_strdup(item); } } } @@ -5062,7 +5075,7 @@ _complete_from_query(const char *simple_query, * completion subject text, which is not what we want. */ #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER - if (num_schema_only > 0 && num_other =3D=3D 0) + if (num_schema_only > 0 && num_other =3D=3D 0 && num_keywords =3D=3D 0) rl_completion_append_character =3D '\0'; #endif = ------- =_aaaaaaaaaa0--