psql: Tab completion for renaming enum values.
authorRobert Haas <rhaas@postgresql.org>
Tue, 8 Nov 2016 21:27:09 +0000 (16:27 -0500)
committerRobert Haas <rhaas@postgresql.org>
Tue, 8 Nov 2016 21:30:51 +0000 (16:30 -0500)
For ALTER TYPE .. RENAME, add "VALUE" to the list of possible
completions.  Complete ALTER TYPE .. RENAME VALUE with possible
enum values.  After that, complete with "TO".

Dagfinn Ilmari MannsÃ¥ker, reviewed by Artur Zakirov.

src/bin/psql/tab-complete.c

index a43bbc519cf623cbf2e67cd98a41e9e4b1163aa4..b556c00b3154af7bb5248c6854d9c7ac8a4e1bf2 100644 (file)
@@ -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");