@@ -576,7 +576,9 @@ static const SchemaQuery Query_for_list_of_matviews = {
576
576
" SELECT pg_catalog.quote_ident(rolname) "\
577
577
" FROM pg_catalog.pg_roles "\
578
578
" 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'"
580
582
581
583
/* the silly-looking length condition is just to eat up the current word */
582
584
#define Query_for_table_owning_index \
@@ -888,7 +890,7 @@ psql_completion(const char *text, int start, int end)
888
890
char * * matches = NULL ;
889
891
890
892
/* This array will contain some scannage of the input line. */
891
- char * previous_words [6 ];
893
+ char * previous_words [9 ];
892
894
893
895
/* For compactness, we use these macros to reference previous_words[]. */
894
896
#define prev_wd (previous_words[0])
@@ -897,6 +899,9 @@ psql_completion(const char *text, int start, int end)
897
899
#define prev4_wd (previous_words[3])
898
900
#define prev5_wd (previous_words[4])
899
901
#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])
900
905
901
906
static const char * const sql_commands [] = {
902
907
"ABORT" , "ALTER" , "ANALYZE" , "BEGIN" , "CHECKPOINT" , "CLOSE" , "CLUSTER" ,
@@ -3065,6 +3070,11 @@ psql_completion(const char *text, int start, int end)
3065
3070
pg_strcasecmp (prev_wd , "TABLE" ) == 0 )
3066
3071
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_foreign_tables , NULL );
3067
3072
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
+
3068
3078
/* GRANT && REVOKE */
3069
3079
/* Complete GRANT/REVOKE with a list of roles and privileges */
3070
3080
else if (pg_strcasecmp (prev_wd , "GRANT" ) == 0 ||
@@ -3118,20 +3128,23 @@ psql_completion(const char *text, int start, int end)
3118
3128
}
3119
3129
3120
3130
/*
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.
3123
3133
*
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.
3126
3136
*
3127
3137
* Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
3128
3138
* here will only work if the privilege list contains exactly one
3129
- * privilege
3139
+ * privilege.
3130
3140
*/
3131
3141
else if ((pg_strcasecmp (prev3_wd , "GRANT" ) == 0 ||
3132
3142
pg_strcasecmp (prev3_wd , "REVOKE" ) == 0 ) &&
3133
3143
pg_strcasecmp (prev_wd , "ON" ) == 0 )
3134
3144
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'"
3135
3148
" UNION SELECT 'DATABASE'"
3136
3149
" UNION SELECT 'DOMAIN'"
3137
3150
" UNION SELECT 'FOREIGN DATA WRAPPER'"
@@ -3140,8 +3153,23 @@ psql_completion(const char *text, int start, int end)
3140
3153
" UNION SELECT 'LANGUAGE'"
3141
3154
" UNION SELECT 'LARGE OBJECT'"
3142
3155
" UNION SELECT 'SCHEMA'"
3156
+ " UNION SELECT 'SEQUENCE'"
3157
+ " UNION SELECT 'TABLE'"
3143
3158
" UNION SELECT 'TABLESPACE'"
3144
3159
" 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
+
3145
3173
else if ((pg_strcasecmp (prev4_wd , "GRANT" ) == 0 ||
3146
3174
pg_strcasecmp (prev4_wd , "REVOKE" ) == 0 ) &&
3147
3175
pg_strcasecmp (prev2_wd , "ON" ) == 0 &&
@@ -3153,7 +3181,12 @@ psql_completion(const char *text, int start, int end)
3153
3181
COMPLETE_WITH_LIST (list_privilege_foreign );
3154
3182
}
3155
3183
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
+ */
3157
3190
else if ((pg_strcasecmp (prev4_wd , "GRANT" ) == 0 ||
3158
3191
pg_strcasecmp (prev4_wd , "REVOKE" ) == 0 ) &&
3159
3192
pg_strcasecmp (prev2_wd , "ON" ) == 0 )
@@ -3168,6 +3201,10 @@ psql_completion(const char *text, int start, int end)
3168
3201
COMPLETE_WITH_QUERY (Query_for_list_of_languages );
3169
3202
else if (pg_strcasecmp (prev_wd , "SCHEMA" ) == 0 )
3170
3203
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 );
3171
3208
else if (pg_strcasecmp (prev_wd , "TABLESPACE" ) == 0 )
3172
3209
COMPLETE_WITH_QUERY (Query_for_list_of_tablespaces );
3173
3210
else if (pg_strcasecmp (prev_wd , "TYPE" ) == 0 )
@@ -3178,25 +3215,78 @@ psql_completion(const char *text, int start, int end)
3178
3215
COMPLETE_WITH_CONST ("FROM" );
3179
3216
}
3180
3217
3181
- /* Complete "GRANT/REVOKE * ON * TO/FROM " with username, GROUP, or PUBLIC */
3218
+ /* Complete "GRANT/REVOKE * ON * * " with TO/FROM */
3182
3219
else if (pg_strcasecmp (prev5_wd , "GRANT" ) == 0 &&
3183
3220
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 )
3184
3234
{
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" );
3187
3237
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 )
3188
3250
COMPLETE_WITH_CONST ("TO" );
3251
+ else
3252
+ COMPLETE_WITH_CONST ("FROM" );
3189
3253
}
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 )
3192
3261
{
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" );
3195
3264
else
3196
3265
COMPLETE_WITH_CONST ("FROM" );
3197
3266
}
3198
3267
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
+ */
3200
3290
else if (pg_strcasecmp (prev3_wd , "GRANT" ) == 0 &&
3201
3291
pg_strcasecmp (prev_wd , "TO" ) == 0 )
3202
3292
{
0 commit comments