postgres.git / summary / log / commit / refs

commit    f3fd531a51df2a73d8517a542e6999e0186e586b
Author:   Stephen Frost <sfrost@snowman.net>
Date:     Sat Dec 24 02:01:29 2016 +0000

    Fix tab completion in psql for ALTER DEFAULT PRIVILEGES
    
    When providing tab completion for ALTER DEFAULT PRIVILEGES, we are
    including the list of roles as possible options for completion after the
    GRANT or REVOKE.  Further, we accept FOR ROLE/IN SCHEMA at the same time
    and in either order, but the tab completion was only working for one or
    the other.  Lastly, we weren't using the actual list of allowed kinds of
    objects for default privileges for completion after the 'GRANT X ON' but
    instead were completeing to what 'GRANT X ON' supports, which isn't the
    ssame at all.
    
    Address these issues by improving the forward tab-completion for ALTER
    DEFAULT PRIVILEGES and then constrain and correct how the tail
    completion is done when it is for ALTER DEFAULT PRIVILEGES.
    
    Back-patch the forward/tail tab-completion to 9.6, where we made it easy
    to handle such cases.
    
    For 9.5 and earlier, correct the initial tab-completion to at least be
    correct as far as it goes and then add a check for GRANT/REVOKE to only
    tab-complete when the GRANT/REVOKE is the start of the command, so we
    don't try to do tab-completion after we get to the GRANT/REVOKE part of
    the ALTER DEFAULT PRIVILEGES command, which is better than providing
    incorrect completions.
    
    Initial patch for master and 9.6 by Gilles Darold, though I cleaned it
    up and added a few comments.  All bugs in the 9.5 and earlier patch are
    mine.
    
    Discussion: https://www.postgresql.org/message-id/1614593c-e356-5b27-6dba-66320a9bc68b@dalibo.com


src/bin/psql/tab-complete.c | 57 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index cd64c39b7f0..02c8d60c297 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 <name> */ 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"); [parent: fe591f8bf68d]