diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 816deda..c00308d 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -888,7 +888,7 @@ psql_completion(const char *text, int start, int end) char **matches = NULL; /* This array will contain some scannage of the input line. */ - char *previous_words[6]; + char *previous_words[9]; /* For compactness, we use these macros to reference previous_words[]. */ #define prev_wd (previous_words[0]) @@ -897,6 +897,9 @@ psql_completion(const char *text, int start, int end) #define prev4_wd (previous_words[3]) #define prev5_wd (previous_words[4]) #define prev6_wd (previous_words[5]) +#define prev7_wd (previous_words[6]) +#define prev8_wd (previous_words[7]) +#define prev9_wd (previous_words[8]) static const char *const sql_commands[] = { "ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", @@ -3132,6 +3135,9 @@ psql_completion(const char *text, int start, int end) pg_strcasecmp(prev3_wd, "REVOKE") == 0) && pg_strcasecmp(prev_wd, "ON") == 0) 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'" " UNION SELECT 'DATABASE'" " UNION SELECT 'DOMAIN'" " UNION SELECT 'FOREIGN DATA WRAPPER'" @@ -3140,11 +3146,24 @@ psql_completion(const char *text, int start, int end) " UNION SELECT 'LANGUAGE'" " UNION SELECT 'LARGE OBJECT'" " UNION SELECT 'SCHEMA'" + " UNION SELECT 'SEQUENCE'" + " UNION SELECT 'TABLE'" " UNION SELECT 'TABLESPACE'" " UNION SELECT 'TYPE'"); else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 || pg_strcasecmp(prev4_wd, "REVOKE") == 0) && pg_strcasecmp(prev2_wd, "ON") == 0 && + pg_strcasecmp(prev_wd, "ALL") == 0) + { + static const char *const list_privilege_all[] = + {"FUNCTIONS IN SCHEMA", "SEQUENCES IN SCHEMA", "TABLES IN SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_privilege_all); + } + + else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 || + pg_strcasecmp(prev4_wd, "REVOKE") == 0) && + pg_strcasecmp(prev2_wd, "ON") == 0 && pg_strcasecmp(prev_wd, "FOREIGN") == 0) { static const char *const list_privilege_foreign[] = @@ -3153,7 +3172,19 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_LIST(list_privilege_foreign); } - /* Complete "GRANT/REVOKE * ON * " with "TO/FROM" */ + /* Complete "GRANT/REVOKE * ON FOREIGN DATA" with WRAPPER */ + else if ((pg_strcasecmp(prev5_wd, "GRANT") == 0 || pg_strcasecmp(prev5_wd, "REVOKE") == 0) && + pg_strcasecmp(prev3_wd, "ON") == 0 && + pg_strcasecmp(prev2_wd, "FOREIGN") == 0 && + pg_strcasecmp(prev_wd, "DATA") == 0) + COMPLETE_WITH_CONST("WRAPPER"); + + /* + * Complete "GRANT/REMOVE * ON DATABASE/DOMAIN/..." with a list of + * appropriate objects. + * + * Complete "GRANT/REVOKE * ON * " with "TO/FROM". + */ else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 || pg_strcasecmp(prev4_wd, "REVOKE") == 0) && pg_strcasecmp(prev2_wd, "ON") == 0) @@ -3168,6 +3199,10 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_QUERY(Query_for_list_of_languages); else if (pg_strcasecmp(prev_wd, "SCHEMA") == 0) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (pg_strcasecmp(prev_wd, "SEQUENCE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); + else if (pg_strcasecmp(prev_wd, "TABLE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); else if (pg_strcasecmp(prev_wd, "TABLESPACE") == 0) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); else if (pg_strcasecmp(prev_wd, "TYPE") == 0) @@ -3178,20 +3213,109 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_CONST("FROM"); } - /* Complete "GRANT/REVOKE * ON * TO/FROM" with username, GROUP, or PUBLIC */ - else if (pg_strcasecmp(prev5_wd, "GRANT") == 0 && + /* + * Complete "GRANT/REVOKE * ON ALL * IN SCHEMA * TO/FROM" with username, + * GROUP, or PUBLIC. + */ + else if (((pg_strcasecmp(prev9_wd, "GRANT") == 0 && pg_strcasecmp(prev_wd, "TO") == 0) || + (pg_strcasecmp(prev9_wd, "REVOKE") == 0 && pg_strcasecmp(prev_wd, "FROM") == 0)) && + pg_strcasecmp(prev7_wd, "ON") == 0 && + pg_strcasecmp(prev6_wd, "ALL") == 0 && + pg_strcasecmp(prev4_wd, "IN") == 0 && + pg_strcasecmp(prev3_wd, "SCHEMA") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + + /* Complete "GRANT/REVOKE * ON FOREIGN SERVER" with server names. */ + else if ((pg_strcasecmp(prev5_wd, "GRANT") == 0 || pg_strcasecmp(prev5_wd, "REVOKE")) && + pg_strcasecmp(prev3_wd, "ON") == 0 && + pg_strcasecmp(prev2_wd, "FOREIGN") == 0 && + pg_strcasecmp(prev_wd, "SERVER") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_servers); + + /* + * Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER * TO/FROM" with username, + * GROUP, or PUBLIC. + */ + else if (((pg_strcasecmp(prev8_wd, "GRANT") == 0 && pg_strcasecmp(prev_wd, "TO") == 0) || + (pg_strcasecmp(prev8_wd, "REVOKE") == 0 && pg_strcasecmp(prev_wd, "FROM") == 0)) && + pg_strcasecmp(prev6_wd, "ON") == 0 && + pg_strcasecmp(prev5_wd, "FOREIGN") == 0 && + pg_strcasecmp(prev4_wd, "DATA") == 0 && + pg_strcasecmp(prev3_wd, "WRAPPER") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + + /* + * Complete "GRANT/REVOKE * ON FOREIGN SERVER * TO/FROM" with username, + * GROUP, or PUBLIC. + */ + else if (((pg_strcasecmp(prev7_wd, "GRANT") == 0 && pg_strcasecmp(prev_wd, "TO") == 0) || + (pg_strcasecmp(prev7_wd, "REVOKE") == 0 && pg_strcasecmp(prev_wd, "FROM") == 0)) && + pg_strcasecmp(prev5_wd, "ON") == 0 && + pg_strcasecmp(prev4_wd, "FOREIGN") == 0 && + pg_strcasecmp(prev3_wd, "SERVER") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + + /* + * Complete "GRANT/REVOKE * ON * * TO/FROM" with username, GROUP, or + * PUBLIC. + */ + else if (((pg_strcasecmp(prev6_wd, "GRANT") == 0 && pg_strcasecmp(prev_wd, "TO") == 0) || + (pg_strcasecmp(prev6_wd, "REVOKE") == 0 && pg_strcasecmp(prev_wd, "FROM") == 0)) && + pg_strcasecmp(prev4_wd, "ON") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + + /* + * Complete "GRANT/REVOKE * ON * TO/FROM" with username, GROUP, or PUBLIC. + */ + else if (((pg_strcasecmp(prev5_wd, "GRANT") == 0 && pg_strcasecmp(prev_wd, "TO") == 0) || + (pg_strcasecmp(prev5_wd, "REVOKE") == 0 && pg_strcasecmp(prev_wd, "FROM") == 0)) && + pg_strcasecmp(prev3_wd, "ON") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + + /* Complete "GRANT/REVOKE * ON * *" with TO or FROM */ + else if ((pg_strcasecmp(prev5_wd, "GRANT") == 0 || pg_strcasecmp(prev5_wd, "REVOKE") == 0) && pg_strcasecmp(prev3_wd, "ON") == 0) { - if (pg_strcasecmp(prev_wd, "TO") == 0) - COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + if (pg_strcasecmp(prev5_wd, "GRANT") == 0) + COMPLETE_WITH_CONST("TO"); else + COMPLETE_WITH_CONST("FROM"); + } + + /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO or FROM */ + else if ((pg_strcasecmp(prev8_wd, "GRANT") == 0 || pg_strcasecmp(prev8_wd, "REVOKE") == 0) && + pg_strcasecmp(prev6_wd, "ON") == 0 && + pg_strcasecmp(prev5_wd, "ALL") == 0 && + pg_strcasecmp(prev3_wd, "IN") == 0 && + pg_strcasecmp(prev2_wd, "SCHEMA") == 0) + { + if (pg_strcasecmp(prev8_wd, "GRANT") == 0) COMPLETE_WITH_CONST("TO"); + else + COMPLETE_WITH_CONST("FROM"); } - else if (pg_strcasecmp(prev5_wd, "REVOKE") == 0 && - pg_strcasecmp(prev3_wd, "ON") == 0) + + /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO or FROM */ + else if ((pg_strcasecmp(prev7_wd, "GRANT") == 0 || pg_strcasecmp(prev7_wd, "REVOKE") == 0) && + pg_strcasecmp(prev5_wd, "ON") == 0 && + pg_strcasecmp(prev4_wd, "FOREIGN") == 0 && + pg_strcasecmp(prev3_wd, "DATA") == 0 && + pg_strcasecmp(prev2_wd, "WRAPPER") == 0) { - if (pg_strcasecmp(prev_wd, "FROM") == 0) - COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + if (pg_strcasecmp(prev7_wd, "GRANT") == 0) + COMPLETE_WITH_CONST("TO"); + else + COMPLETE_WITH_CONST("FROM"); + } + + /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO or FROM */ + else if ((pg_strcasecmp(prev6_wd, "GRANT") == 0 || pg_strcasecmp(prev6_wd, "REVOKE") == 0) && + pg_strcasecmp(prev4_wd, "ON") == 0 && + pg_strcasecmp(prev3_wd, "FOREIGN") == 0 && + pg_strcasecmp(prev2_wd, "SERVER") == 0) + { + if (pg_strcasecmp(prev6_wd, "GRANT") == 0) + COMPLETE_WITH_CONST("TO"); else COMPLETE_WITH_CONST("FROM"); }