diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index cd64c39b7f..02c8d60c29 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1570,13 +1570,31 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_CONST("PASSWORD"); /* ALTER DEFAULT PRIVILEGES */ else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES")) - COMPLETE_WITH_LIST3("FOR ROLE", "FOR USER", "IN SCHEMA"); + COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA"); /* ALTER DEFAULT PRIVILEGES FOR */ else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR")) - COMPLETE_WITH_LIST2("ROLE", "USER"); - /* ALTER DEFAULT PRIVILEGES { FOR ROLE ... | IN SCHEMA ... } */ - else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", MatchAny) || - Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", MatchAny)) + COMPLETE_WITH_CONST("ROLE"); + /* ALTER DEFAULT PRIVILEGES IN */ + else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN")) + COMPLETE_WITH_CONST("SCHEMA"); + /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */ + else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", + MatchAny)) + COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA"); + /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */ + else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny)) + COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE"); + /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */ + else if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny, "FOR")) + COMPLETE_WITH_CONST("ROLE"); + /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */ + /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */ + else if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", + MatchAny, "IN", "SCHEMA", MatchAny) || + Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny, "FOR", "ROLE|USER", MatchAny)) COMPLETE_WITH_LIST2("GRANT", "REVOKE"); /* ALTER DOMAIN */ else if (Matches3("ALTER", "DOMAIN", MatchAny)) @@ -2566,10 +2584,22 @@ psql_completion(const char *text, int start, int end) else if (TailMatches2("FOREIGN", "SERVER")) COMPLETE_WITH_QUERY(Query_for_list_of_servers); -/* GRANT && REVOKE --- is allowed inside CREATE SCHEMA, so use TailMatches */ +/* + * GRANT and REVOKE are allowed inside CREATE SCHEMA and + * ALTER DEFAULT PRIVILEGES, so use TailMatches + */ /* Complete GRANT/REVOKE with a list of roles and privileges */ else if (TailMatches1("GRANT|REVOKE")) - COMPLETE_WITH_QUERY(Query_for_list_of_roles + /* + * With ALTER DEFAULT PRIVILEGES, restrict completion + * to grantable privileges (can't grant roles) + */ + if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES")) + COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE", + "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", + "EXECUTE", "USAGE", "ALL"); + else + COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'SELECT'" " UNION SELECT 'INSERT'" " UNION SELECT 'UPDATE'" @@ -2610,7 +2640,14 @@ psql_completion(const char *text, int start, int end) * privilege. */ else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, + /* + * With ALTER DEFAULT PRIVILEGES, restrict completion + * to the kinds of objects supported. + */ + if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES")) + COMPLETE_WITH_LIST4("TABLES", "SEQUENCES", "FUNCTIONS", "TYPES"); + else + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'" " UNION SELECT 'ALL SEQUENCES IN SCHEMA'" " UNION SELECT 'ALL TABLES IN SCHEMA'" @@ -2673,7 +2710,9 @@ psql_completion(const char *text, int start, int end) else if ((HeadMatches1("GRANT") && TailMatches1("TO")) || (HeadMatches1("REVOKE") && TailMatches1("FROM"))) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); - + /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */ + else if (HeadMatches3("ALTER","DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM")) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */ else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny)) COMPLETE_WITH_CONST("TO");