From 07f7237c2a3bcc2eebb554f812378188b07571bb Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 18 Nov 2022 11:26:49 +0900 Subject: [PATCH] psql: Improve tab completion for GRANT/REVOKE 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 | 53 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index a0e26bc295..13014f074f 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')" +/* 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, - "GRANT", - "SELECT", - "INSERT", - "UPDATE", - "DELETE", - "TRUNCATE", - "REFERENCES", - "TRIGGER", - "CREATE", - "CONNECT", - "TEMPORARY", - "EXECUTE", - "USAGE", - "SET", - "ALTER SYSTEM", - "ALL"); + Privilege_options_of_grant_and_revoke); + else if (TailMatches("REVOKE")) + COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles, + 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"))