Обсуждение: [PATCH] Tab completion for ALTER TYPE … RENAMEVALUE …

Поиск
Список
Период
Сортировка

[PATCH] Tab completion for ALTER TYPE … RENAMEVALUE …

От
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Дата:
Hi hackers,

Here's a patch to add psql tab completion for the recently-added ALTER
TYPE … RENAME VALUE feature (thanks to Tom for fixing it up and
committing it).

It's modelled on the ALTER TYPE … RENAME ATTRIBUTE completion, but
tweaked to return string literals instead of identifiers.

- ilmari

>From f4fa474262e6e65f02095f9de09205bff7ea2a1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Mon, 12 Sep 2016 12:17:37 +0100
Subject: [PATCH] =?UTF-8?q?Add=20psql=20tab=20completion=20for=20ALTER=20T?=
 =?UTF-8?q?YPE=20=E2=80=A6=20RENAME=20VALUE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Modelled on the completion for attributes, tweaked to return string
literals intead of identifiers.
---
 src/bin/psql/tab-complete.c | 57 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 3e2f084..40790c9 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -202,6 +202,31 @@ do { \
     matches = completion_matches(text, complete_from_query); \
 } while (0)

+#define COMPLETE_WITH_ENUM_VALUE(type) \
+do { \
+    char   *_completion_schema; \
+    char   *_completion_type; \
+\
+    _completion_schema = strtokx(type, " \t\n\r", ".", "\"", 0, \
+                                 false, false, pset.encoding); \
+    (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
+                   false, false, pset.encoding); \
+    _completion_type = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
+                               false, false, pset.encoding);  \
+    if (_completion_type == NULL)\
+    { \
+        completion_charp = Query_for_list_of_enum_values; \
+        completion_info_charp = type; \
+    } \
+    else \
+    { \
+        completion_charp = Query_for_list_of_enum_values_with_schema; \
+        completion_info_charp = _completion_type; \
+        completion_info_charp2 = _completion_schema; \
+    } \
+    matches = completion_matches(text, complete_from_query); \
+} while (0)
+
 #define COMPLETE_WITH_FUNCTION_ARG(function) \
 do { \
     char   *_completion_schema; \
@@ -598,6 +623,26 @@ static const SchemaQuery Query_for_list_of_matviews = {
 "   AND (pg_catalog.quote_ident(nspname)='%s' "\
 "        OR '\"' || nspname || '\"' ='%s') "

+#define Query_for_list_of_enum_values \
+"SELECT pg_catalog.quote_literal(enumlabel) "\
+"  FROM pg_catalog.pg_enum e, pg_catalog.pg_type t "\
+" WHERE t.oid = e.enumtypid "\
+"   AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
+"   AND (pg_catalog.quote_ident(typname)='%s' "\
+"        OR '\"' || typname || '\"'='%s') "\
+"   AND pg_catalog.pg_type_is_visible(t.oid)"
+
+#define Query_for_list_of_enum_values_with_schema \
+"SELECT pg_catalog.quote_literal(enumlabel) "\
+"  FROM pg_catalog.pg_enum e, pg_catalog.pg_type t, pg_catalog.pg_namespace n "\
+" WHERE t.oid = e.enumtypid "\
+"   AND n.oid = t.typnamespace "\
+"   AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
+"   AND (pg_catalog.quote_ident(typname)='%s' "\
+"        OR '\"' || typname || '\"'='%s') "\
+"   AND (pg_catalog.quote_ident(nspname)='%s' "\
+"        OR '\"' || nspname || '\"' ='%s') "
+
 #define Query_for_list_of_template_databases \
 "SELECT pg_catalog.quote_ident(d.datname) "\
 "  FROM pg_catalog.pg_database d "\
@@ -1873,11 +1918,13 @@ psql_completion(const char *text, int start, int end)
         COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE");
     /* ALTER TYPE <foo> RENAME    */
     else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME"))
-        COMPLETE_WITH_LIST2("ATTRIBUTE", "TO");
+        COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE");
     /* ALTER TYPE xxx RENAME ATTRIBUTE yyy */
     else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE", MatchAny))
         COMPLETE_WITH_CONST("TO");
-
+    /* ALTER TYPE xxx RENAME VALUE yyy */
+    else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "VALUE", MatchAny))
+        COMPLETE_WITH_CONST("TO");
     /*
      * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
      * of attributes
@@ -1897,6 +1944,12 @@ psql_completion(const char *text, int start, int end)
     else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
         COMPLETE_WITH_QUERY(Query_for_list_of_roles);

+    /*
+     * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
+     */
+    else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
+        COMPLETE_WITH_ENUM_VALUE(prev3_wd);
+
 /* BEGIN */
     else if (Matches1("BEGIN"))
         COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
--
2.9.3


--
- Twitter seems more influential [than blogs] in the 'gets reported in
  the mainstream press' sense at least.               - Matt McLeod
- That'd be because the content of a tweet is easier to condense down
  to a mainstream media article.                      - Calle Dybedahl

Re: [PATCH] Tab completion for ALTER TYPE …RENAME VALUE …

От
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Дата:
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) writes:

> Hi hackers,
>
> Here's a patch to add psql tab completion for the recently-added ALTER
> TYPE … RENAME VALUE feature (thanks to Tom for fixing it up and
> committing it).

I've added it to the 2016-11 commit fest:
https://commitfest.postgresql.org/11/795/

- ilmari

--
"The surreality of the universe tends towards a maximum" -- Skud's Law
"Never formulate a law or axiom that you're not prepared to live with
 the consequences of."                              -- Skud's Meta-Law




Re: [HACKERS] Re: [PATCH] Tab completion for ALTER TYPE … RENAME VALUE …

От
Artur Zakirov
Дата:
Hello,

2016-09-12 16:16 GMT+03:00 Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>:
>
> I've added it to the 2016-11 commit fest:
> https://commitfest.postgresql.org/11/795/
>
> - ilmari

I've tested your patch.

Patch was applied to the master. It seems there is no need to rebase
it. PostgreSQL was compiled without errors with the patch.

I've tested the patch with type:

CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green',
'blue', 'purple');

And the following completions work as expected:

=> ALTER TYPE rainbow RENAME <tab>
ATTRIBUTE  TO         VALUE

=> ALTER TYPE rainbow RENAME VALUE <tab>
'blue'    'green'   'orange'  'purple'  'red'     'yellow'

It seems that the patch can be commited without any fixes. So I marked
it as "Ready for Committer".

--
Sincerely,
Artur Zakirov
Postgres Professional: http://www.postgrespro.com
Russian Postgres Company



Re: Re: [PATCH] Tab completion for ALTER TYPE… RENAME VALUE …

От
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Дата:
Artur Zakirov <a.zakirov@postgrespro.ru> writes:

> Hello,

Hi Artur,

> 2016-09-12 16:16 GMT+03:00 Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>:
>>
>> I've added it to the 2016-11 commit fest:
>> https://commitfest.postgresql.org/11/795/
>>
>> - ilmari
>
> I've tested your patch.
[...]
> It seems that the patch can be commited without any fixes. So I marked
> it as "Ready for Committer".

Thank you very much.  I just looked at the patch again and realised the
completion of "TO" after RENAME VALUE <name> can be merged with the one
for RENAME ATTRIBUTE <name>.  Attached is an updated and patch, which
only differs from the previous one as follows:

$ interdiff 0001-Add-psql-tab-completion-for-ALTER-TYPE-RENAME-VALUE{,-v2}.patch
diff -u b/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1918,11 +1918,8 @@ psql_completion(const char *text, int start, int end)
    /* ALTER TYPE <foo> RENAME  */
    else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME"))
        COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE");
-   /* ALTER TYPE xxx RENAME ATTRIBUTE yyy */
-   else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE", MatchAny))
-       COMPLETE_WITH_CONST("TO");
-   /* ALTER TYPE xxx RENAME VALUE yyy */
-   else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "VALUE", MatchAny))
+   /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
+   else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
        COMPLETE_WITH_CONST("TO");
    /*
     * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list

>From d8454b66a544d91bf779ca3bfb38d18e4cd504f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilmari@ilmari.org>
Date: Mon, 12 Sep 2016 12:17:37 +0100
Subject: [PATCH] =?UTF-8?q?Add=20psql=20tab=20completion=20for=20ALTER=20T?=
 =?UTF-8?q?YPE=20=E2=80=A6=20RENAME=20VALUE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Modelled on the completion for attributes, tweaked to return string
literals intead of identifiers.
---
 src/bin/psql/tab-complete.c | 58 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index a43bbc5..b556c00 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -202,6 +202,31 @@ do { \
     matches = completion_matches(text, complete_from_query); \
 } while (0)

+#define COMPLETE_WITH_ENUM_VALUE(type) \
+do { \
+    char   *_completion_schema; \
+    char   *_completion_type; \
+\
+    _completion_schema = strtokx(type, " \t\n\r", ".", "\"", 0, \
+                                 false, false, pset.encoding); \
+    (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
+                   false, false, pset.encoding); \
+    _completion_type = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
+                               false, false, pset.encoding);  \
+    if (_completion_type == NULL)\
+    { \
+        completion_charp = Query_for_list_of_enum_values; \
+        completion_info_charp = type; \
+    } \
+    else \
+    { \
+        completion_charp = Query_for_list_of_enum_values_with_schema; \
+        completion_info_charp = _completion_type; \
+        completion_info_charp2 = _completion_schema; \
+    } \
+    matches = completion_matches(text, complete_from_query); \
+} while (0)
+
 #define COMPLETE_WITH_FUNCTION_ARG(function) \
 do { \
     char   *_completion_schema; \
@@ -598,6 +623,26 @@ static const SchemaQuery Query_for_list_of_matviews = {
 "   AND (pg_catalog.quote_ident(nspname)='%s' "\
 "        OR '\"' || nspname || '\"' ='%s') "

+#define Query_for_list_of_enum_values \
+"SELECT pg_catalog.quote_literal(enumlabel) "\
+"  FROM pg_catalog.pg_enum e, pg_catalog.pg_type t "\
+" WHERE t.oid = e.enumtypid "\
+"   AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
+"   AND (pg_catalog.quote_ident(typname)='%s' "\
+"        OR '\"' || typname || '\"'='%s') "\
+"   AND pg_catalog.pg_type_is_visible(t.oid)"
+
+#define Query_for_list_of_enum_values_with_schema \
+"SELECT pg_catalog.quote_literal(enumlabel) "\
+"  FROM pg_catalog.pg_enum e, pg_catalog.pg_type t, pg_catalog.pg_namespace n "\
+" WHERE t.oid = e.enumtypid "\
+"   AND n.oid = t.typnamespace "\
+"   AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
+"   AND (pg_catalog.quote_ident(typname)='%s' "\
+"        OR '\"' || typname || '\"'='%s') "\
+"   AND (pg_catalog.quote_ident(nspname)='%s' "\
+"        OR '\"' || nspname || '\"' ='%s') "
+
 #define Query_for_list_of_template_databases \
 "SELECT pg_catalog.quote_ident(d.datname) "\
 "  FROM pg_catalog.pg_database d "\
@@ -1872,11 +1917,10 @@ psql_completion(const char *text, int start, int end)
         COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE");
     /* ALTER TYPE <foo> RENAME    */
     else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME"))
-        COMPLETE_WITH_LIST2("ATTRIBUTE", "TO");
-    /* ALTER TYPE xxx RENAME ATTRIBUTE yyy */
-    else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE", MatchAny))
+        COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE");
+    /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
+    else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
         COMPLETE_WITH_CONST("TO");
-
     /*
      * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
      * of attributes
@@ -1896,6 +1940,12 @@ psql_completion(const char *text, int start, int end)
     else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
         COMPLETE_WITH_QUERY(Query_for_list_of_roles);

+    /*
+     * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
+     */
+    else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
+        COMPLETE_WITH_ENUM_VALUE(prev3_wd);
+
 /* BEGIN */
     else if (Matches1("BEGIN"))
         COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
--
2.10.2


--
- Twitter seems more influential [than blogs] in the 'gets reported in
  the mainstream press' sense at least.               - Matt McLeod
- That'd be because the content of a tweet is easier to condense down
  to a mainstream media article.                      - Calle Dybedahl

Re: Re: [PATCH] Tab completion for ALTER TYPE… RENAME VALUE …

От
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker)
Дата:
Robert Haas <robertmhaas@gmail.com> writes:

> On Tue, Nov 8, 2016 at 8:53 AM, Dagfinn Ilmari Mannsåker
> <ilmari@ilmari.org> wrote:
>> Thank you very much.  I just looked at the patch again and realised the
>> completion of "TO" after RENAME VALUE <name> can be merged with the one
>> for RENAME ATTRIBUTE <name>.  Attached is an updated and patch
>
> Committed.

Thanks!

--
"The surreality of the universe tends towards a maximum" -- Skud's Law
"Never formulate a law or axiom that you're not prepared to live with
 the consequences of."                              -- Skud's Meta-Law



Re: [HACKERS] Re: [PATCH] Tab completion for ALTER TYPE … RENAME VALUE …

От
Robert Haas
Дата:
On Tue, Nov 8, 2016 at 8:53 AM, Dagfinn Ilmari Mannsåker
<ilmari@ilmari.org> wrote:
> Thank you very much.  I just looked at the patch again and realised the
> completion of "TO" after RENAME VALUE <name> can be merged with the one
> for RENAME ATTRIBUTE <name>.  Attached is an updated and patch

Committed.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company