From c77d9fd2dbe3148b4041e6d60374253a8793a67d Mon Sep 17 00:00:00 2001 From: Shi Yu Date: Wed, 28 Sep 2022 17:59:17 +0800 Subject: [PATCH v5 1/2] Fix tab completion for GRANT/REVOKE The result of tab completion for GRANT contains GRANT, but there's no such a privilege. This is because the tab completions for GRANT and REVOKE are the same. Fix it in this patch. Also add tab completion for GRANT/REVOKE ALL PRIVILEGES. --- src/bin/psql/tab-complete.c | 82 +++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 7b73886ce1..1f62ad401b 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -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')" +/* Privileges options of GRANT and REVOKE*/ +#define Privileges_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 @@ -3775,29 +3781,21 @@ 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("REVOKE", "GRANT")) + COMPLETE_WITH("OPTION FOR"); + else if (TailMatches("GRANT")) 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"); + Privileges_options_of_grant_and_revoke); + else if (TailMatches("REVOKE")) + COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles, + Privileges_options_of_grant_and_revoke, + "GRANT OPTION FOR", + "ADMIN OPTION FOR"); + else if (TailMatches("REVOKE", "GRANT", "OPTION", "FOR")) + COMPLETE_WITH(Privileges_options_of_grant_and_revoke); } - else if (TailMatches("REVOKE", "GRANT")) - COMPLETE_WITH("OPTION FOR"); else if (TailMatches("REVOKE", "GRANT", "OPTION")) COMPLETE_WITH("FOR"); @@ -3834,13 +3832,18 @@ psql_completion(const char *text, int start, int end) else if (TailMatches("GRANT|REVOKE", MatchAny) || TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny)) { - if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL")) + if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE")) COMPLETE_WITH("ON"); + else if (TailMatches("ALL")) + COMPLETE_WITH("ON", "PRIVILEGES"); else if (TailMatches("GRANT", MatchAny)) COMPLETE_WITH("TO"); else COMPLETE_WITH("FROM"); } + else if (TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES") || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALL", "PRIVILEGES")) + COMPLETE_WITH("ON"); /* * Complete GRANT/REVOKE ON with a list of appropriate relations. @@ -3850,7 +3853,9 @@ psql_completion(const char *text, int start, int end) * privilege. */ else if (TailMatches("GRANT|REVOKE", MatchAny, "ON") || - TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON")) + TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES", "ON") || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON") || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALL", "PRIVILEGES", "ON") ) { /* * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of @@ -3882,14 +3887,18 @@ psql_completion(const char *text, int start, int end) "TYPE"); } else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL") || - TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL")) + TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES", "ON", "ALL") || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL") || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALL", "PRIVILEGES", "ON", "ALL")) COMPLETE_WITH("FUNCTIONS IN SCHEMA", "PROCEDURES IN SCHEMA", "ROUTINES IN SCHEMA", "SEQUENCES IN SCHEMA", "TABLES IN SCHEMA"); else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN") || - TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN")) + TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES", "ON", "FOREIGN") || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN") || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALL", "PRIVILEGES", "ON", "FOREIGN")) COMPLETE_WITH("DATA WRAPPER", "SERVER"); /* @@ -3899,7 +3908,9 @@ psql_completion(const char *text, int start, int end) * Complete "GRANT/REVOKE * ON *" with "TO/FROM". */ else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny) || - TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", MatchAny)) + TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES", "ON", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALL", "PRIVILEGES", "ON", MatchAny)) { if (TailMatches("DATABASE")) COMPLETE_WITH_QUERY(Query_for_list_of_databases); @@ -3965,9 +3976,12 @@ psql_completion(const char *text, int start, int end) /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */ else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny) || - TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny)) + TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES", "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL", "ALL", "PRIVILEGES", "IN", "SCHEMA", MatchAny)) { - if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) || + TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) COMPLETE_WITH("TO"); else COMPLETE_WITH("FROM"); @@ -3975,9 +3989,12 @@ psql_completion(const char *text, int start, int end) /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */ else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny) || - TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny)) + TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES", "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALL", "PRIVILEGES", "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny)) { - if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) || + TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) COMPLETE_WITH("TO"); else COMPLETE_WITH("FROM"); @@ -3985,9 +4002,12 @@ psql_completion(const char *text, int start, int end) /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */ else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny) || - TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny)) + TailMatches("GRANT|REVOKE", "ALL", "PRIVILEGES", "ON", "FOREIGN", "SERVER", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny) || + TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALL", "PRIVILEGES", "ON", "FOREIGN", "SERVER", MatchAny)) { - if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) || + TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) COMPLETE_WITH("TO"); else COMPLETE_WITH("FROM"); -- 2.31.1