psql: Improve tab completion for GRANT/REVOKE
authorMichael Paquier <michael@paquier.xyz>
Fri, 18 Nov 2022 02:26:49 +0000 (11:26 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 18 Nov 2022 02:26:49 +0000 (11:26 +0900)
This commit improves the handling of the following clauses:
- Addition of "CREATE" for ALTER DEFAULT PRIVILEGES .. GRANT/REVOKE.
- Addition of GRANT|ADMIN|INHERIT OPTION FOR for REVOKE, with some
completion for roles, INHERIT being added recently by e3ce2de.
- Addition of GRANT WITH ADMIN|INHERIT.

The list of privilege options common to GRANT and REVOKE is refactored
to avoid its duplication.

Author: Shi Yu
Reviewed-by: Kyotaro Horiguchi, Michael Paquier, Peter Smith
Discussion: https://postgr.es/m/OSZPR01MB6310FCE8609185A56344EED2FD559@OSZPR01MB6310.jpnprd01.prod.outlook.com

src/bin/psql/tab-complete.c

index a0e26bc295894ccbb90c0c1d94e57592128a2a5c..13014f074f405f49e607538e56aa6bdde9bf9430 100644 (file)
@@ -1143,6 +1143,12 @@ static const SchemaQuery Query_for_trigger_of_table = {
 "  FROM pg_catalog.pg_timezone_names() "\
 " WHERE pg_catalog.quote_literal(pg_catalog.lower(name)) LIKE pg_catalog.lower('%s')"
 
+/* Privilege options shared between GRANT and REVOKE */
+#define Privilege_options_of_grant_and_revoke \
+"SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", \
+"CREATE", "CONNECT", "TEMPORARY", "EXECUTE", "USAGE", "SET", "ALTER SYSTEM", \
+"ALL"
+
 /*
  * These object types were introduced later than our support cutoff of
  * server version 9.2.  We use the VersionedQuery infrastructure so that
@@ -3767,7 +3773,7 @@ psql_completion(const char *text, int start, int end)
  */
    /* Complete GRANT/REVOKE with a list of roles and privileges */
    else if (TailMatches("GRANT|REVOKE") ||
-            TailMatches("REVOKE", "GRANT", "OPTION", "FOR"))
+            TailMatches("REVOKE", "ADMIN|GRANT|INHERIT", "OPTION", "FOR"))
    {
        /*
         * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable
@@ -3776,32 +3782,22 @@ psql_completion(const char *text, int start, int end)
        if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
            COMPLETE_WITH("SELECT", "INSERT", "UPDATE",
                          "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
-                         "EXECUTE", "USAGE", "ALL");
-       else
+                         "CREATE", "EXECUTE", "USAGE", "ALL");
+       else if (TailMatches("GRANT"))
+           COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
+                                    Privilege_options_of_grant_and_revoke);
+       else if (TailMatches("REVOKE"))
            COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
-                                    "GRANT",
-                                    "SELECT",
-                                    "INSERT",
-                                    "UPDATE",
-                                    "DELETE",
-                                    "TRUNCATE",
-                                    "REFERENCES",
-                                    "TRIGGER",
-                                    "CREATE",
-                                    "CONNECT",
-                                    "TEMPORARY",
-                                    "EXECUTE",
-                                    "USAGE",
-                                    "SET",
-                                    "ALTER SYSTEM",
-                                    "ALL");
+                                    Privilege_options_of_grant_and_revoke,
+                                    "GRANT OPTION FOR",
+                                    "ADMIN OPTION FOR",
+                                    "INHERIT OPTION FOR");
+       else if (TailMatches("REVOKE", "GRANT", "OPTION", "FOR"))
+           COMPLETE_WITH(Privilege_options_of_grant_and_revoke);
+       else if (TailMatches("REVOKE", "ADMIN|INHERIT", "OPTION", "FOR"))
+           COMPLETE_WITH_QUERY(Query_for_list_of_roles);
    }
 
-   else if (TailMatches("REVOKE", "GRANT"))
-       COMPLETE_WITH("OPTION FOR");
-   else if (TailMatches("REVOKE", "GRANT", "OPTION"))
-       COMPLETE_WITH("FOR");
-
    else if (TailMatches("GRANT|REVOKE", "ALTER") ||
             TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALTER"))
        COMPLETE_WITH("SYSTEM");
@@ -3943,12 +3939,17 @@ psql_completion(const char *text, int start, int end)
     * Offer grant options after that.
     */
    else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny))
-       COMPLETE_WITH("WITH ADMIN OPTION",
+       COMPLETE_WITH("WITH ADMIN",
+                     "WITH INHERIT",
                      "WITH GRANT OPTION",
                      "GRANTED BY");
    else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny, "WITH"))
-       COMPLETE_WITH("ADMIN OPTION",
+       COMPLETE_WITH("ADMIN",
+                     "INHERIT",
                      "GRANT OPTION");
+   else if (HeadMatches("GRANT") &&
+            (TailMatches("TO", MatchAny, "WITH", "ADMIN|INHERIT")))
+       COMPLETE_WITH("OPTION", "TRUE", "FALSE");
    else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny, "WITH", MatchAny, "OPTION"))
        COMPLETE_WITH("GRANTED BY");
    else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny, "WITH", MatchAny, "OPTION", "GRANTED", "BY"))