@@ -576,7 +576,9 @@ static const SchemaQuery Query_for_list_of_matviews = {
576576" SELECT pg_catalog.quote_ident(rolname) "\
577577" FROM pg_catalog.pg_roles "\
578578" WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\
579- " UNION ALL SELECT 'PUBLIC'"
579+ " UNION ALL SELECT 'PUBLIC'"\
580+ " UNION ALL SELECT 'CURRENT_USER'"\
581+ " UNION ALL SELECT 'SESSION_USER'"
580582
581583/* the silly-looking length condition is just to eat up the current word */
582584#define Query_for_table_owning_index \
@@ -888,7 +890,7 @@ psql_completion(const char *text, int start, int end)
888890 char * * matches = NULL ;
889891
890892 /* This array will contain some scannage of the input line. */
891- char * previous_words [6 ];
893+ char * previous_words [9 ];
892894
893895 /* For compactness, we use these macros to reference previous_words[]. */
894896#define prev_wd (previous_words[0])
@@ -897,6 +899,9 @@ psql_completion(const char *text, int start, int end)
897899#define prev4_wd (previous_words[3])
898900#define prev5_wd (previous_words[4])
899901#define prev6_wd (previous_words[5])
902+ #define prev7_wd (previous_words[6])
903+ #define prev8_wd (previous_words[7])
904+ #define prev9_wd (previous_words[8])
900905
901906 static const char * const sql_commands [] = {
902907 "ABORT" , "ALTER" , "ANALYZE" , "BEGIN" , "CHECKPOINT" , "CLOSE" , "CLUSTER" ,
@@ -3065,6 +3070,11 @@ psql_completion(const char *text, int start, int end)
30653070 pg_strcasecmp (prev_wd , "TABLE" ) == 0 )
30663071 COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_foreign_tables , NULL );
30673072
3073+ /* FOREIGN SERVER */
3074+ else if (pg_strcasecmp (prev2_wd , "FOREIGN" ) == 0 &&
3075+ pg_strcasecmp (prev_wd , "SERVER" ) == 0 )
3076+ COMPLETE_WITH_QUERY (Query_for_list_of_servers );
3077+
30683078/* GRANT && REVOKE */
30693079 /* Complete GRANT/REVOKE with a list of roles and privileges */
30703080 else if (pg_strcasecmp (prev_wd , "GRANT" ) == 0 ||
@@ -3118,20 +3128,23 @@ psql_completion(const char *text, int start, int end)
31183128 }
31193129
31203130 /*
3121- * Complete GRANT/REVOKE <sth> ON with a list of tables, views, sequences,
3122- * and indexes
3131+ * Complete GRANT/REVOKE <sth> ON with a list of tables, views, and
3132+ * sequences.
31233133 *
3124- * keywords DATABASE, FUNCTION, LANGUAGE, SCHEMA added to query result via
3125- * UNION; seems to work intuitively
3134+ * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to
3135+ * query result via UNION; seems to work intuitively.
31263136 *
31273137 * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
31283138 * here will only work if the privilege list contains exactly one
3129- * privilege
3139+ * privilege.
31303140 */
31313141 else if ((pg_strcasecmp (prev3_wd , "GRANT" ) == 0 ||
31323142 pg_strcasecmp (prev3_wd , "REVOKE" ) == 0 ) &&
31333143 pg_strcasecmp (prev_wd , "ON" ) == 0 )
31343144 COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tsvmf ,
3145+ " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
3146+ " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
3147+ " UNION SELECT 'ALL TABLES IN SCHEMA'"
31353148 " UNION SELECT 'DATABASE'"
31363149 " UNION SELECT 'DOMAIN'"
31373150 " UNION SELECT 'FOREIGN DATA WRAPPER'"
@@ -3140,8 +3153,23 @@ psql_completion(const char *text, int start, int end)
31403153 " UNION SELECT 'LANGUAGE'"
31413154 " UNION SELECT 'LARGE OBJECT'"
31423155 " UNION SELECT 'SCHEMA'"
3156+ " UNION SELECT 'SEQUENCE'"
3157+ " UNION SELECT 'TABLE'"
31433158 " UNION SELECT 'TABLESPACE'"
31443159 " UNION SELECT 'TYPE'" );
3160+
3161+ else if ((pg_strcasecmp (prev4_wd , "GRANT" ) == 0 ||
3162+ pg_strcasecmp (prev4_wd , "REVOKE" ) == 0 ) &&
3163+ pg_strcasecmp (prev2_wd , "ON" ) == 0 &&
3164+ pg_strcasecmp (prev_wd , "ALL" ) == 0 )
3165+ {
3166+ static const char * const list_privilege_all [] =
3167+ {"FUNCTIONS IN SCHEMA" , "SEQUENCES IN SCHEMA" , "TABLES IN SCHEMA" ,
3168+ NULL };
3169+
3170+ COMPLETE_WITH_LIST (list_privilege_all );
3171+ }
3172+
31453173 else if ((pg_strcasecmp (prev4_wd , "GRANT" ) == 0 ||
31463174 pg_strcasecmp (prev4_wd , "REVOKE" ) == 0 ) &&
31473175 pg_strcasecmp (prev2_wd , "ON" ) == 0 &&
@@ -3153,7 +3181,12 @@ psql_completion(const char *text, int start, int end)
31533181 COMPLETE_WITH_LIST (list_privilege_foreign );
31543182 }
31553183
3156- /* Complete "GRANT/REVOKE * ON * " with "TO/FROM" */
3184+ /*
3185+ * Complete "GRANT/REMOVE * ON DATABASE/DOMAIN/..." with a list of
3186+ * appropriate objects.
3187+ *
3188+ * Complete "GRANT/REVOKE * ON * " with "TO/FROM".
3189+ */
31573190 else if ((pg_strcasecmp (prev4_wd , "GRANT" ) == 0 ||
31583191 pg_strcasecmp (prev4_wd , "REVOKE" ) == 0 ) &&
31593192 pg_strcasecmp (prev2_wd , "ON" ) == 0 )
@@ -3168,6 +3201,10 @@ psql_completion(const char *text, int start, int end)
31683201 COMPLETE_WITH_QUERY (Query_for_list_of_languages );
31693202 else if (pg_strcasecmp (prev_wd , "SCHEMA" ) == 0 )
31703203 COMPLETE_WITH_QUERY (Query_for_list_of_schemas );
3204+ else if (pg_strcasecmp (prev_wd , "SEQUENCE" ) == 0 )
3205+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_sequences , NULL );
3206+ else if (pg_strcasecmp (prev_wd , "TABLE" ) == 0 )
3207+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tsvmf , NULL );
31713208 else if (pg_strcasecmp (prev_wd , "TABLESPACE" ) == 0 )
31723209 COMPLETE_WITH_QUERY (Query_for_list_of_tablespaces );
31733210 else if (pg_strcasecmp (prev_wd , "TYPE" ) == 0 )
@@ -3178,25 +3215,78 @@ psql_completion(const char *text, int start, int end)
31783215 COMPLETE_WITH_CONST ("FROM" );
31793216 }
31803217
3181- /* Complete "GRANT/REVOKE * ON * TO/FROM " with username, GROUP, or PUBLIC */
3218+ /* Complete "GRANT/REVOKE * ON * * " with TO/FROM */
31823219 else if (pg_strcasecmp (prev5_wd , "GRANT" ) == 0 &&
31833220 pg_strcasecmp (prev3_wd , "ON" ) == 0 )
3221+ COMPLETE_WITH_CONST ("TO" );
3222+
3223+ else if (pg_strcasecmp (prev5_wd , "REVOKE" ) == 0 &&
3224+ pg_strcasecmp (prev3_wd , "ON" ) == 0 )
3225+ COMPLETE_WITH_CONST ("FROM" );
3226+
3227+ /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
3228+ else if ((pg_strcasecmp (prev8_wd , "GRANT" ) == 0 ||
3229+ pg_strcasecmp (prev8_wd , "REVOKE" ) == 0 ) &&
3230+ pg_strcasecmp (prev6_wd , "ON" ) == 0 &&
3231+ pg_strcasecmp (prev5_wd , "ALL" ) == 0 &&
3232+ pg_strcasecmp (prev3_wd , "IN" ) == 0 &&
3233+ pg_strcasecmp (prev2_wd , "SCHEMA" ) == 0 )
31843234 {
3185- if (pg_strcasecmp (prev_wd , "TO " ) == 0 )
3186- COMPLETE_WITH_QUERY ( Query_for_list_of_grant_roles );
3235+ if (pg_strcasecmp (prev8_wd , "GRANT " ) == 0 )
3236+ COMPLETE_WITH_CONST ( "TO" );
31873237 else
3238+ COMPLETE_WITH_CONST ("FROM" );
3239+ }
3240+
3241+ /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
3242+ else if ((pg_strcasecmp (prev7_wd , "GRANT" ) == 0 ||
3243+ pg_strcasecmp (prev7_wd , "REVOKE" ) == 0 ) &&
3244+ pg_strcasecmp (prev5_wd , "ON" ) == 0 &&
3245+ pg_strcasecmp (prev4_wd , "FOREIGN" ) == 0 &&
3246+ pg_strcasecmp (prev3_wd , "DATA" ) == 0 &&
3247+ pg_strcasecmp (prev2_wd , "WRAPPER" ) == 0 )
3248+ {
3249+ if (pg_strcasecmp (prev7_wd , "GRANT" ) == 0 )
31883250 COMPLETE_WITH_CONST ("TO" );
3251+ else
3252+ COMPLETE_WITH_CONST ("FROM" );
31893253 }
3190- else if (pg_strcasecmp (prev5_wd , "REVOKE" ) == 0 &&
3191- pg_strcasecmp (prev3_wd , "ON" ) == 0 )
3254+
3255+ /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
3256+ else if ((pg_strcasecmp (prev6_wd , "GRANT" ) == 0 ||
3257+ pg_strcasecmp (prev6_wd , "REVOKE" ) == 0 ) &&
3258+ pg_strcasecmp (prev4_wd , "ON" ) == 0 &&
3259+ pg_strcasecmp (prev3_wd , "FOREIGN" ) == 0 &&
3260+ pg_strcasecmp (prev2_wd , "SERVER" ) == 0 )
31923261 {
3193- if (pg_strcasecmp (prev_wd , "FROM " ) == 0 )
3194- COMPLETE_WITH_QUERY ( Query_for_list_of_grant_roles );
3262+ if (pg_strcasecmp (prev6_wd , "GRANT " ) == 0 )
3263+ COMPLETE_WITH_CONST ( "TO" );
31953264 else
31963265 COMPLETE_WITH_CONST ("FROM" );
31973266 }
31983267
3199- /* Complete "GRANT/REVOKE * TO/FROM" with username, GROUP, or PUBLIC */
3268+ /*
3269+ * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
3270+ * CURRENT_USER, or SESSION_USER.
3271+ */
3272+ else if (((pg_strcasecmp (prev9_wd , "GRANT" ) == 0 ||
3273+ pg_strcasecmp (prev8_wd , "GRANT" ) == 0 ||
3274+ pg_strcasecmp (prev7_wd , "GRANT" ) == 0 ||
3275+ pg_strcasecmp (prev6_wd , "GRANT" ) == 0 ||
3276+ pg_strcasecmp (prev5_wd , "GRANT" ) == 0 ) &&
3277+ pg_strcasecmp (prev_wd , "TO" ) == 0 ) ||
3278+ ((pg_strcasecmp (prev9_wd , "REVOKE" ) == 0 ||
3279+ pg_strcasecmp (prev8_wd , "REVOKE" ) == 0 ||
3280+ pg_strcasecmp (prev7_wd , "REVOKE" ) == 0 ||
3281+ pg_strcasecmp (prev6_wd , "REVOKE" ) == 0 ||
3282+ pg_strcasecmp (prev5_wd , "REVOKE" ) == 0 ) &&
3283+ pg_strcasecmp (prev_wd , "FROM" ) == 0 ))
3284+ COMPLETE_WITH_QUERY (Query_for_list_of_grant_roles );
3285+
3286+ /*
3287+ * Complete "GRANT/REVOKE * TO/FROM" with username, PUBLIC,
3288+ * CURRENT_USER, or SESSION_USER.
3289+ */
32003290 else if (pg_strcasecmp (prev3_wd , "GRANT" ) == 0 &&
32013291 pg_strcasecmp (prev_wd , "TO" ) == 0 )
32023292 {
0 commit comments