Skip to content

Commit dc61580

Browse files
committed
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
1 parent a377c8d commit dc61580

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

src/bin/psql/tab-complete.c

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,13 +1502,31 @@ psql_completion(const char *text, int start, int end)
15021502
COMPLETE_WITH_CONST("PASSWORD");
15031503
/* ALTER DEFAULT PRIVILEGES */
15041504
else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES"))
1505-
COMPLETE_WITH_LIST3("FOR ROLE", "FOR USER", "IN SCHEMA");
1505+
COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA");
15061506
/* ALTER DEFAULT PRIVILEGES FOR */
15071507
else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
1508-
COMPLETE_WITH_LIST2("ROLE", "USER");
1509-
/* ALTER DEFAULT PRIVILEGES { FOR ROLE ... | IN SCHEMA ... } */
1510-
else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", MatchAny) ||
1511-
Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", MatchAny))
1508+
COMPLETE_WITH_CONST("ROLE");
1509+
/* ALTER DEFAULT PRIVILEGES IN */
1510+
else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
1511+
COMPLETE_WITH_CONST("SCHEMA");
1512+
/* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
1513+
else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1514+
MatchAny))
1515+
COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA");
1516+
/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
1517+
else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1518+
MatchAny))
1519+
COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE");
1520+
/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
1521+
else if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1522+
MatchAny, "FOR"))
1523+
COMPLETE_WITH_CONST("ROLE");
1524+
/* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
1525+
/* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
1526+
else if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1527+
MatchAny, "IN", "SCHEMA", MatchAny) ||
1528+
Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1529+
MatchAny, "FOR", "ROLE|USER", MatchAny))
15121530
COMPLETE_WITH_LIST2("GRANT", "REVOKE");
15131531
/* ALTER DOMAIN <name> */
15141532
else if (Matches3("ALTER", "DOMAIN", MatchAny))
@@ -2431,10 +2449,22 @@ psql_completion(const char *text, int start, int end)
24312449
else if (TailMatches2("FOREIGN", "SERVER"))
24322450
COMPLETE_WITH_QUERY(Query_for_list_of_servers);
24332451

2434-
/* GRANT && REVOKE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2452+
/*
2453+
* GRANT and REVOKE are allowed inside CREATE SCHEMA and
2454+
* ALTER DEFAULT PRIVILEGES, so use TailMatches
2455+
*/
24352456
/* Complete GRANT/REVOKE with a list of roles and privileges */
24362457
else if (TailMatches1("GRANT|REVOKE"))
2437-
COMPLETE_WITH_QUERY(Query_for_list_of_roles
2458+
/*
2459+
* With ALTER DEFAULT PRIVILEGES, restrict completion
2460+
* to grantable privileges (can't grant roles)
2461+
*/
2462+
if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2463+
COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE",
2464+
"DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2465+
"EXECUTE", "USAGE", "ALL");
2466+
else
2467+
COMPLETE_WITH_QUERY(Query_for_list_of_roles
24382468
" UNION SELECT 'SELECT'"
24392469
" UNION SELECT 'INSERT'"
24402470
" UNION SELECT 'UPDATE'"
@@ -2475,7 +2505,14 @@ psql_completion(const char *text, int start, int end)
24752505
* privilege.
24762506
*/
24772507
else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON"))
2478-
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf,
2508+
/*
2509+
* With ALTER DEFAULT PRIVILEGES, restrict completion
2510+
* to the kinds of objects supported.
2511+
*/
2512+
if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2513+
COMPLETE_WITH_LIST4("TABLES", "SEQUENCES", "FUNCTIONS", "TYPES");
2514+
else
2515+
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf,
24792516
" UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
24802517
" UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
24812518
" UNION SELECT 'ALL TABLES IN SCHEMA'"
@@ -2538,7 +2575,9 @@ psql_completion(const char *text, int start, int end)
25382575
else if ((HeadMatches1("GRANT") && TailMatches1("TO")) ||
25392576
(HeadMatches1("REVOKE") && TailMatches1("FROM")))
25402577
COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2541-
2578+
/* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
2579+
else if (HeadMatches3("ALTER","DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM"))
2580+
COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
25422581
/* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
25432582
else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny))
25442583
COMPLETE_WITH_CONST("TO");

0 commit comments

Comments
 (0)