psql: Add tab completion for view options.
authorDean Rasheed <[email protected]>
Tue, 28 Nov 2023 09:50:17 +0000 (09:50 +0000)
committerDean Rasheed <[email protected]>
Tue, 28 Nov 2023 09:50:17 +0000 (09:50 +0000)
Add support for tab completion of WITH (...) options to CREATE VIEW,
and for the corresponding SET/RESET (...) options in ALTER VIEW.

Christoph Heiss, reviewed by Melih Mutlu, Vignesh C, Jim Jones,
Mikhail Gribkov, David Zhang, Shubham Khanna, and me.

Discussion: https://postgr.es/m/a2075c5a-66f9-a564-f038-9ac044b03117@c8h4.io

src/bin/psql/tab-complete.c

index 006e10f5d2d9b3fa1e6fd1d4279fa2506f7efa33..049801186c3779c082d13b13a3f1864fda8d3fc6 100644 (file)
@@ -1329,6 +1329,13 @@ static const char *const table_storage_parameters[] = {
    NULL
 };
 
+/* Optional parameters for CREATE VIEW and ALTER VIEW */
+static const char *const view_optional_parameters[] = {
+   "check_option",
+   "security_barrier",
+   "security_invoker",
+   NULL
+};
 
 /* Forward declaration of functions */
 static char **psql_completion(const char *text, int start, int end);
@@ -2216,8 +2223,7 @@ psql_completion(const char *text, int start, int end)
        COMPLETE_WITH("TO");
    /* ALTER VIEW <name> */
    else if (Matches("ALTER", "VIEW", MatchAny))
-       COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME",
-                     "SET SCHEMA");
+       COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME", "RESET", "SET");
    /* ALTER VIEW xxx RENAME */
    else if (Matches("ALTER", "VIEW", MatchAny, "RENAME"))
        COMPLETE_WITH_ATTR_PLUS(prev2_wd, "COLUMN", "TO");
@@ -2233,6 +2239,21 @@ psql_completion(const char *text, int start, int end)
    /* ALTER VIEW xxx RENAME COLUMN yyy */
    else if (Matches("ALTER", "VIEW", MatchAny, "RENAME", "COLUMN", MatchAnyExcept("TO")))
        COMPLETE_WITH("TO");
+   /* ALTER VIEW xxx RESET ( */
+   else if (Matches("ALTER", "VIEW", MatchAny, "RESET"))
+       COMPLETE_WITH("(");
+   /* Complete ALTER VIEW xxx SET with "(" or "SCHEMA" */
+   else if (Matches("ALTER", "VIEW", MatchAny, "SET"))
+       COMPLETE_WITH("(", "SCHEMA");
+   /* ALTER VIEW xxx SET|RESET ( yyy [= zzz] ) */
+   else if (Matches("ALTER", "VIEW", MatchAny, "SET|RESET", "("))
+       COMPLETE_WITH_LIST(view_optional_parameters);
+   else if (Matches("ALTER", "VIEW", MatchAny, "SET", "(", MatchAny))
+       COMPLETE_WITH("=");
+   else if (Matches("ALTER", "VIEW", MatchAny, "SET", "(", "check_option", "="))
+       COMPLETE_WITH("local", "cascaded");
+   else if (Matches("ALTER", "VIEW", MatchAny, "SET", "(", "security_barrier|security_invoker", "="))
+       COMPLETE_WITH("true", "false");
 
    /* ALTER MATERIALIZED VIEW <name> */
    else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny))
@@ -3531,14 +3552,35 @@ psql_completion(const char *text, int start, int end)
    }
 
 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
-   /* Complete CREATE [ OR REPLACE ] VIEW <name> with AS */
+   /* Complete CREATE [ OR REPLACE ] VIEW <name> with AS or WITH */
    else if (TailMatches("CREATE", "VIEW", MatchAny) ||
             TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny))
-       COMPLETE_WITH("AS");
+       COMPLETE_WITH("AS", "WITH");
    /* Complete "CREATE [ OR REPLACE ] VIEW <sth> AS with "SELECT" */
    else if (TailMatches("CREATE", "VIEW", MatchAny, "AS") ||
             TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "AS"))
        COMPLETE_WITH("SELECT");
+   /* CREATE [ OR REPLACE ] VIEW <name> WITH ( yyy [= zzz] ) */
+   else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH") ||
+            TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH"))
+       COMPLETE_WITH("(");
+   else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(") ||
+            TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "("))
+       COMPLETE_WITH_LIST(view_optional_parameters);
+   else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option") ||
+            TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option"))
+       COMPLETE_WITH("=");
+   else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option", "=") ||
+            TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option", "="))
+       COMPLETE_WITH("local", "cascaded");
+   /* CREATE [ OR REPLACE ] VIEW <name> WITH ( ... ) AS */
+   else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)") ||
+            TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)"))
+       COMPLETE_WITH("AS");
+   /* CREATE [ OR REPLACE ] VIEW <name> WITH ( ... ) AS SELECT */
+   else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)", "AS") ||
+            TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)", "AS"))
+       COMPLETE_WITH("SELECT");
 
 /* CREATE MATERIALIZED VIEW */
    else if (Matches("CREATE", "MATERIALIZED"))