]> granicus.if.org Git - postgresql/blob - src/bin/psql/tab-complete.c
Use C99 designated initializers for some structs
[postgresql] / src / bin / psql / tab-complete.c
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2018, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/tab-complete.c
7  */
8
9 /*----------------------------------------------------------------------
10  * This file implements a somewhat more sophisticated readline "TAB
11  * completion" in psql. It is not intended to be AI, to replace
12  * learning SQL, or to relieve you from thinking about what you're
13  * doing. Also it does not always give you all the syntactically legal
14  * completions, only those that are the most common or the ones that
15  * the programmer felt most like implementing.
16  *
17  * CAVEAT: Tab completion causes queries to be sent to the backend.
18  * The number of tuples returned gets limited, in most default
19  * installations to 1000, but if you still don't like this prospect,
20  * you can turn off tab completion in your ~/.inputrc (or else
21  * ${INPUTRC}) file so:
22  *
23  *       $if psql
24  *       set disable-completion on
25  *       $endif
26  *
27  * See `man 3 readline' or `info readline' for the full details.
28  *
29  * BUGS:
30  * - Quotes, parentheses, and other funny characters are not handled
31  *       all that gracefully.
32  *----------------------------------------------------------------------
33  */
34
35 #include "postgres_fe.h"
36 #include "tab-complete.h"
37 #include "input.h"
38
39 /* If we don't have this, we might as well forget about the whole thing: */
40 #ifdef USE_READLINE
41
42 #include <ctype.h>
43
44 #include "catalog/pg_class_d.h"
45
46 #include "libpq-fe.h"
47 #include "pqexpbuffer.h"
48 #include "common.h"
49 #include "settings.h"
50 #include "stringutils.h"
51
52 #ifdef HAVE_RL_FILENAME_COMPLETION_FUNCTION
53 #define filename_completion_function rl_filename_completion_function
54 #else
55 /* missing in some header files */
56 extern char *filename_completion_function();
57 #endif
58
59 #ifdef HAVE_RL_COMPLETION_MATCHES
60 #define completion_matches rl_completion_matches
61 #endif
62
63 /* word break characters */
64 #define WORD_BREAKS             "\t\n@$><=;|&{() "
65
66 /*
67  * Since readline doesn't let us pass any state through to the tab completion
68  * callback, we have to use this global variable to let get_previous_words()
69  * get at the previous lines of the current command.  Ick.
70  */
71 PQExpBuffer tab_completion_query_buf = NULL;
72
73 /*
74  * In some situations, the query to find out what names are available to
75  * complete with must vary depending on server version.  We handle this by
76  * storing a list of queries, each tagged with the minimum server version
77  * it will work for.  Each list must be stored in descending server version
78  * order, so that the first satisfactory query is the one to use.
79  *
80  * When the query string is otherwise constant, an array of VersionedQuery
81  * suffices.  Terminate the array with an entry having min_server_version = 0.
82  * That entry's query string can be a query that works in all supported older
83  * server versions, or NULL to give up and do no completion.
84  */
85 typedef struct VersionedQuery
86 {
87         int                     min_server_version;
88         const char *query;
89 } VersionedQuery;
90
91 /*
92  * This struct is used to define "schema queries", which are custom-built
93  * to obtain possibly-schema-qualified names of database objects.  There is
94  * enough similarity in the structure that we don't want to repeat it each
95  * time.  So we put the components of each query into this struct and
96  * assemble them with the common boilerplate in _complete_from_query().
97  *
98  * As with VersionedQuery, we can use an array of these if the query details
99  * must vary across versions.
100  */
101 typedef struct SchemaQuery
102 {
103         /*
104          * If not zero, minimum server version this struct applies to.  If not
105          * zero, there should be a following struct with a smaller minimum server
106          * version; use catname == NULL in the last entry if we should do nothing.
107          */
108         int                     min_server_version;
109
110         /*
111          * Name of catalog or catalogs to be queried, with alias, eg.
112          * "pg_catalog.pg_class c".  Note that "pg_namespace n" will be added.
113          */
114         const char *catname;
115
116         /*
117          * Selection condition --- only rows meeting this condition are candidates
118          * to display.  If catname mentions multiple tables, include the necessary
119          * join condition here.  For example, this might look like "c.relkind = "
120          * CppAsString2(RELKIND_RELATION).  Write NULL (not an empty string) if
121          * not needed.
122          */
123         const char *selcondition;
124
125         /*
126          * Visibility condition --- which rows are visible without schema
127          * qualification?  For example, "pg_catalog.pg_table_is_visible(c.oid)".
128          */
129         const char *viscondition;
130
131         /*
132          * Namespace --- name of field to join to pg_namespace.oid. For example,
133          * "c.relnamespace".
134          */
135         const char *namespace;
136
137         /*
138          * Result --- the appropriately-quoted name to return, in the case of an
139          * unqualified name.  For example, "pg_catalog.quote_ident(c.relname)".
140          */
141         const char *result;
142
143         /*
144          * In some cases a different result must be used for qualified names.
145          * Enter that here, or write NULL if result can be used.
146          */
147         const char *qualresult;
148 } SchemaQuery;
149
150
151 /* Store maximum number of records we want from database queries
152  * (implemented via SELECT ... LIMIT xx).
153  */
154 static int      completion_max_records;
155
156 /*
157  * Communication variables set by COMPLETE_WITH_FOO macros and then used by
158  * the completion callback functions.  Ugly but there is no better way.
159  */
160 static const char *completion_charp;    /* to pass a string */
161 static const char *const *completion_charpp;    /* to pass a list of strings */
162 static const char *completion_info_charp;       /* to pass a second string */
163 static const char *completion_info_charp2;      /* to pass a third string */
164 static const VersionedQuery *completion_vquery; /* to pass a VersionedQuery */
165 static const SchemaQuery *completion_squery;    /* to pass a SchemaQuery */
166 static bool completion_case_sensitive;  /* completion is case sensitive */
167
168 /*
169  * A few macros to ease typing. You can use these to complete the given
170  * string with
171  * 1) The results from a query you pass it. (Perhaps one of those below?)
172  *        We support both simple and versioned queries.
173  * 2) The results from a schema query you pass it.
174  *        We support both simple and versioned schema queries.
175  * 3) The items from a null-pointer-terminated list (with or without
176  *        case-sensitive comparison; see also COMPLETE_WITH_LISTn, below).
177  * 4) A string constant.
178  * 5) The list of attributes of the given table (possibly schema-qualified).
179  * 6/ The list of arguments to the given function (possibly schema-qualified).
180  */
181 #define COMPLETE_WITH_QUERY(query) \
182 do { \
183         completion_charp = query; \
184         matches = completion_matches(text, complete_from_query); \
185 } while (0)
186
187 #define COMPLETE_WITH_VERSIONED_QUERY(query) \
188 do { \
189         completion_vquery = query; \
190         matches = completion_matches(text, complete_from_versioned_query); \
191 } while (0)
192
193 #define COMPLETE_WITH_SCHEMA_QUERY(query, addon) \
194 do { \
195         completion_squery = &(query); \
196         completion_charp = addon; \
197         matches = completion_matches(text, complete_from_schema_query); \
198 } while (0)
199
200 #define COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(query, addon) \
201 do { \
202         completion_squery = query; \
203         completion_vquery = addon; \
204         matches = completion_matches(text, complete_from_versioned_schema_query); \
205 } while (0)
206
207 #define COMPLETE_WITH_LIST_CS(list) \
208 do { \
209         completion_charpp = list; \
210         completion_case_sensitive = true; \
211         matches = completion_matches(text, complete_from_list); \
212 } while (0)
213
214 #define COMPLETE_WITH_LIST(list) \
215 do { \
216         completion_charpp = list; \
217         completion_case_sensitive = false; \
218         matches = completion_matches(text, complete_from_list); \
219 } while (0)
220
221 #define COMPLETE_WITH_CONST(string) \
222 do { \
223         completion_charp = string; \
224         completion_case_sensitive = false; \
225         matches = completion_matches(text, complete_from_const); \
226 } while (0)
227
228 #define COMPLETE_WITH_ATTR(relation, addon) \
229 do { \
230         char   *_completion_schema; \
231         char   *_completion_table; \
232 \
233         _completion_schema = strtokx(relation, " \t\n\r", ".", "\"", 0, \
234                                                                  false, false, pset.encoding); \
235         (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
236                                    false, false, pset.encoding); \
237         _completion_table = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
238                                                                 false, false, pset.encoding); \
239         if (_completion_table == NULL) \
240         { \
241                 completion_charp = Query_for_list_of_attributes  addon; \
242                 completion_info_charp = relation; \
243         } \
244         else \
245         { \
246                 completion_charp = Query_for_list_of_attributes_with_schema  addon; \
247                 completion_info_charp = _completion_table; \
248                 completion_info_charp2 = _completion_schema; \
249         } \
250         matches = completion_matches(text, complete_from_query); \
251 } while (0)
252
253 #define COMPLETE_WITH_ENUM_VALUE(type) \
254 do { \
255         char   *_completion_schema; \
256         char   *_completion_type; \
257 \
258         _completion_schema = strtokx(type, " \t\n\r", ".", "\"", 0, \
259                                                                  false, false, pset.encoding); \
260         (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
261                                    false, false, pset.encoding); \
262         _completion_type = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
263                                                            false, false, pset.encoding);  \
264         if (_completion_type == NULL)\
265         { \
266                 completion_charp = Query_for_list_of_enum_values; \
267                 completion_info_charp = type; \
268         } \
269         else \
270         { \
271                 completion_charp = Query_for_list_of_enum_values_with_schema; \
272                 completion_info_charp = _completion_type; \
273                 completion_info_charp2 = _completion_schema; \
274         } \
275         matches = completion_matches(text, complete_from_query); \
276 } while (0)
277
278 #define COMPLETE_WITH_FUNCTION_ARG(function) \
279 do { \
280         char   *_completion_schema; \
281         char   *_completion_function; \
282 \
283         _completion_schema = strtokx(function, " \t\n\r", ".", "\"", 0, \
284                                                                  false, false, pset.encoding); \
285         (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
286                                    false, false, pset.encoding); \
287         _completion_function = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
288                                                                    false, false, pset.encoding); \
289         if (_completion_function == NULL) \
290         { \
291                 completion_charp = Query_for_list_of_arguments; \
292                 completion_info_charp = function; \
293         } \
294         else \
295         { \
296                 completion_charp = Query_for_list_of_arguments_with_schema; \
297                 completion_info_charp = _completion_function; \
298                 completion_info_charp2 = _completion_schema; \
299         } \
300         matches = completion_matches(text, complete_from_query); \
301 } while (0)
302
303 /*
304  * These macros simplify use of COMPLETE_WITH_LIST for short, fixed lists.
305  * There is no COMPLETE_WITH_LIST1; use COMPLETE_WITH_CONST for that case.
306  */
307 #define COMPLETE_WITH_LIST2(s1, s2) \
308 do { \
309         static const char *const list[] = { s1, s2, NULL }; \
310         COMPLETE_WITH_LIST(list); \
311 } while (0)
312
313 #define COMPLETE_WITH_LIST3(s1, s2, s3) \
314 do { \
315         static const char *const list[] = { s1, s2, s3, NULL }; \
316         COMPLETE_WITH_LIST(list); \
317 } while (0)
318
319 #define COMPLETE_WITH_LIST4(s1, s2, s3, s4) \
320 do { \
321         static const char *const list[] = { s1, s2, s3, s4, NULL }; \
322         COMPLETE_WITH_LIST(list); \
323 } while (0)
324
325 #define COMPLETE_WITH_LIST5(s1, s2, s3, s4, s5) \
326 do { \
327         static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \
328         COMPLETE_WITH_LIST(list); \
329 } while (0)
330
331 #define COMPLETE_WITH_LIST6(s1, s2, s3, s4, s5, s6) \
332 do { \
333         static const char *const list[] = { s1, s2, s3, s4, s5, s6, NULL }; \
334         COMPLETE_WITH_LIST(list); \
335 } while (0)
336
337 #define COMPLETE_WITH_LIST7(s1, s2, s3, s4, s5, s6, s7) \
338 do { \
339         static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, NULL }; \
340         COMPLETE_WITH_LIST(list); \
341 } while (0)
342
343 #define COMPLETE_WITH_LIST8(s1, s2, s3, s4, s5, s6, s7, s8) \
344 do { \
345         static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, NULL }; \
346         COMPLETE_WITH_LIST(list); \
347 } while (0)
348
349 #define COMPLETE_WITH_LIST9(s1, s2, s3, s4, s5, s6, s7, s8, s9) \
350 do { \
351         static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, NULL }; \
352         COMPLETE_WITH_LIST(list); \
353 } while (0)
354
355 #define COMPLETE_WITH_LIST10(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
356 do { \
357         static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, NULL }; \
358         COMPLETE_WITH_LIST(list); \
359 } while (0)
360
361 /*
362  * Likewise for COMPLETE_WITH_LIST_CS.
363  */
364 #define COMPLETE_WITH_LIST_CS2(s1, s2) \
365 do { \
366         static const char *const list[] = { s1, s2, NULL }; \
367         COMPLETE_WITH_LIST_CS(list); \
368 } while (0)
369
370 #define COMPLETE_WITH_LIST_CS3(s1, s2, s3) \
371 do { \
372         static const char *const list[] = { s1, s2, s3, NULL }; \
373         COMPLETE_WITH_LIST_CS(list); \
374 } while (0)
375
376 #define COMPLETE_WITH_LIST_CS4(s1, s2, s3, s4) \
377 do { \
378         static const char *const list[] = { s1, s2, s3, s4, NULL }; \
379         COMPLETE_WITH_LIST_CS(list); \
380 } while (0)
381
382 #define COMPLETE_WITH_LIST_CS5(s1, s2, s3, s4, s5) \
383 do { \
384         static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \
385         COMPLETE_WITH_LIST_CS(list); \
386 } while (0)
387
388 /*
389  * Assembly instructions for schema queries
390  */
391
392 static const SchemaQuery Query_for_list_of_aggregates[] = {
393         {
394                 .min_server_version = 110000,
395                 .catname = "pg_catalog.pg_proc p",
396                 .selcondition = "p.prokind = 'a'",
397                 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
398                 .namespace = "p.pronamespace",
399                 .result = "pg_catalog.quote_ident(p.proname)",
400         },
401         {
402                 .catname = "pg_catalog.pg_proc p",
403                 .selcondition = "p.proisagg",
404                 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
405                 .namespace = "p.pronamespace",
406                 .result = "pg_catalog.quote_ident(p.proname)",
407         }
408 };
409
410 static const SchemaQuery Query_for_list_of_datatypes = {
411         .catname = "pg_catalog.pg_type t",
412         /* selcondition --- ignore table rowtypes and array types */
413         .selcondition = "(t.typrelid = 0 "
414         " OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
415         "     FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) "
416         "AND t.typname !~ '^_'",
417         .viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
418         .namespace = "t.typnamespace",
419         .result = "pg_catalog.format_type(t.oid, NULL)",
420         .qualresult = "pg_catalog.quote_ident(t.typname)",
421 };
422
423 static const SchemaQuery Query_for_list_of_domains = {
424         .catname = "pg_catalog.pg_type t",
425         .selcondition = "t.typtype = 'd'",
426         .viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
427         .namespace = "t.typnamespace",
428         .result = "pg_catalog.quote_ident(t.typname)",
429 };
430
431 /* Note: this intentionally accepts aggregates as well as plain functions */
432 static const SchemaQuery Query_for_list_of_functions[] = {
433         {
434                 .min_server_version = 110000,
435                 .catname = "pg_catalog.pg_proc p",
436                 .selcondition = "p.prokind != 'p'",
437                 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
438                 .namespace = "p.pronamespace",
439                 .result = "pg_catalog.quote_ident(p.proname)",
440         },
441         {
442                 .catname = "pg_catalog.pg_proc p",
443                 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
444                 .namespace = "p.pronamespace",
445                 .result = "pg_catalog.quote_ident(p.proname)",
446         }
447 };
448
449 static const SchemaQuery Query_for_list_of_indexes = {
450         .catname = "pg_catalog.pg_class c",
451         .selcondition =
452         "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", "
453         CppAsString2(RELKIND_PARTITIONED_INDEX) ")",
454         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
455         .namespace = "c.relnamespace",
456         .result = "pg_catalog.quote_ident(c.relname)",
457 };
458
459 static const SchemaQuery Query_for_list_of_procedures[] = {
460         {
461                 .min_server_version = 110000,
462                 .catname = "pg_catalog.pg_proc p",
463                 .selcondition = "p.prokind = 'p'",
464                 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
465                 .namespace = "p.pronamespace",
466                 .result = "pg_catalog.quote_ident(p.proname)",
467         },
468         {
469                 /* not supported in older versions */
470                 .catname = NULL,
471         }
472 };
473
474 static const SchemaQuery Query_for_list_of_routines = {
475         .catname = "pg_catalog.pg_proc p",
476         .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
477         .namespace = "p.pronamespace",
478         .result = "pg_catalog.quote_ident(p.proname)",
479 };
480
481 static const SchemaQuery Query_for_list_of_sequences = {
482         .catname = "pg_catalog.pg_class c",
483         .selcondition = "c.relkind IN (" CppAsString2(RELKIND_SEQUENCE) ")",
484         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
485         .namespace = "c.relnamespace",
486         .result = "pg_catalog.quote_ident(c.relname)",
487 };
488
489 static const SchemaQuery Query_for_list_of_foreign_tables = {
490         .catname = "pg_catalog.pg_class c",
491         .selcondition = "c.relkind IN (" CppAsString2(RELKIND_FOREIGN_TABLE) ")",
492         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
493         .namespace = "c.relnamespace",
494         .result = "pg_catalog.quote_ident(c.relname)",
495 };
496
497 static const SchemaQuery Query_for_list_of_tables = {
498         .catname = "pg_catalog.pg_class c",
499         .selcondition =
500         "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
501         CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
502         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
503         .namespace = "c.relnamespace",
504         .result = "pg_catalog.quote_ident(c.relname)",
505 };
506
507 static const SchemaQuery Query_for_list_of_partitioned_tables = {
508         .catname = "pg_catalog.pg_class c",
509         .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
510         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
511         .namespace = "c.relnamespace",
512         .result = "pg_catalog.quote_ident(c.relname)",
513 };
514
515 static const SchemaQuery Query_for_list_of_constraints_with_schema = {
516         .catname = "pg_catalog.pg_constraint c",
517         .selcondition = "c.conrelid <> 0",
518         .viscondition = "true",         /* there is no pg_constraint_is_visible */
519         .namespace = "c.connamespace",
520         .result = "pg_catalog.quote_ident(c.conname)",
521 };
522
523 /* Relations supporting INSERT, UPDATE or DELETE */
524 static const SchemaQuery Query_for_list_of_updatables = {
525         .catname = "pg_catalog.pg_class c",
526         .selcondition =
527         "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
528         CppAsString2(RELKIND_FOREIGN_TABLE) ", "
529         CppAsString2(RELKIND_VIEW) ", "
530         CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
531         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
532         .namespace = "c.relnamespace",
533         .result = "pg_catalog.quote_ident(c.relname)",
534 };
535
536 static const SchemaQuery Query_for_list_of_relations = {
537         .catname = "pg_catalog.pg_class c",
538         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
539         .namespace = "c.relnamespace",
540         .result = "pg_catalog.quote_ident(c.relname)",
541 };
542
543 static const SchemaQuery Query_for_list_of_tsvmf = {
544         .catname = "pg_catalog.pg_class c",
545         .selcondition =
546         "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
547         CppAsString2(RELKIND_SEQUENCE) ", "
548         CppAsString2(RELKIND_VIEW) ", "
549         CppAsString2(RELKIND_MATVIEW) ", "
550         CppAsString2(RELKIND_FOREIGN_TABLE) ", "
551         CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
552         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
553         .namespace = "c.relnamespace",
554         .result = "pg_catalog.quote_ident(c.relname)",
555 };
556
557 static const SchemaQuery Query_for_list_of_tmf = {
558         .catname = "pg_catalog.pg_class c",
559         .selcondition =
560         "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
561         CppAsString2(RELKIND_MATVIEW) ", "
562         CppAsString2(RELKIND_FOREIGN_TABLE) ")",
563         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
564         .namespace = "c.relnamespace",
565         .result = "pg_catalog.quote_ident(c.relname)",
566 };
567
568 static const SchemaQuery Query_for_list_of_tpm = {
569         .catname = "pg_catalog.pg_class c",
570         .selcondition =
571         "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
572         CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
573         CppAsString2(RELKIND_MATVIEW) ")",
574         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
575         .namespace = "c.relnamespace",
576         .result = "pg_catalog.quote_ident(c.relname)",
577 };
578
579 static const SchemaQuery Query_for_list_of_tm = {
580         .catname = "pg_catalog.pg_class c",
581         .selcondition =
582         "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
583         CppAsString2(RELKIND_MATVIEW) ")",
584         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
585         .namespace = "c.relnamespace",
586         .result = "pg_catalog.quote_ident(c.relname)",
587 };
588
589 static const SchemaQuery Query_for_list_of_views = {
590         .catname = "pg_catalog.pg_class c",
591         .selcondition = "c.relkind IN (" CppAsString2(RELKIND_VIEW) ")",
592         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
593         .namespace = "c.relnamespace",
594         .result = "pg_catalog.quote_ident(c.relname)",
595 };
596
597 static const SchemaQuery Query_for_list_of_matviews = {
598         .catname = "pg_catalog.pg_class c",
599         .selcondition = "c.relkind IN (" CppAsString2(RELKIND_MATVIEW) ")",
600         .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
601         .namespace = "c.relnamespace",
602         .result = "pg_catalog.quote_ident(c.relname)",
603 };
604
605 static const SchemaQuery Query_for_list_of_statistics = {
606         .catname = "pg_catalog.pg_statistic_ext s",
607         .viscondition = "pg_catalog.pg_statistics_obj_is_visible(s.oid)",
608         .namespace = "s.stxnamespace",
609         .result = "pg_catalog.quote_ident(s.stxname)",
610 };
611
612
613 /*
614  * Queries to get lists of names of various kinds of things, possibly
615  * restricted to names matching a partially entered name.  In these queries,
616  * the first %s will be replaced by the text entered so far (suitably escaped
617  * to become a SQL literal string).  %d will be replaced by the length of the
618  * string (in unescaped form).  A second and third %s, if present, will be
619  * replaced by a suitably-escaped version of the string provided in
620  * completion_info_charp.  A fourth and fifth %s are similarly replaced by
621  * completion_info_charp2.
622  *
623  * Beware that the allowed sequences of %s and %d are determined by
624  * _complete_from_query().
625  */
626
627 #define Query_for_list_of_attributes \
628 "SELECT pg_catalog.quote_ident(attname) "\
629 "  FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\
630 " WHERE c.oid = a.attrelid "\
631 "   AND a.attnum > 0 "\
632 "   AND NOT a.attisdropped "\
633 "   AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\
634 "   AND (pg_catalog.quote_ident(relname)='%s' "\
635 "        OR '\"' || relname || '\"'='%s') "\
636 "   AND pg_catalog.pg_table_is_visible(c.oid)"
637
638 #define Query_for_list_of_attributes_with_schema \
639 "SELECT pg_catalog.quote_ident(attname) "\
640 "  FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c, pg_catalog.pg_namespace n "\
641 " WHERE c.oid = a.attrelid "\
642 "   AND n.oid = c.relnamespace "\
643 "   AND a.attnum > 0 "\
644 "   AND NOT a.attisdropped "\
645 "   AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\
646 "   AND (pg_catalog.quote_ident(relname)='%s' "\
647 "        OR '\"' || relname || '\"' ='%s') "\
648 "   AND (pg_catalog.quote_ident(nspname)='%s' "\
649 "        OR '\"' || nspname || '\"' ='%s') "
650
651 #define Query_for_list_of_enum_values \
652 "SELECT pg_catalog.quote_literal(enumlabel) "\
653 "  FROM pg_catalog.pg_enum e, pg_catalog.pg_type t "\
654 " WHERE t.oid = e.enumtypid "\
655 "   AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
656 "   AND (pg_catalog.quote_ident(typname)='%s' "\
657 "        OR '\"' || typname || '\"'='%s') "\
658 "   AND pg_catalog.pg_type_is_visible(t.oid)"
659
660 #define Query_for_list_of_enum_values_with_schema \
661 "SELECT pg_catalog.quote_literal(enumlabel) "\
662 "  FROM pg_catalog.pg_enum e, pg_catalog.pg_type t, pg_catalog.pg_namespace n "\
663 " WHERE t.oid = e.enumtypid "\
664 "   AND n.oid = t.typnamespace "\
665 "   AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
666 "   AND (pg_catalog.quote_ident(typname)='%s' "\
667 "        OR '\"' || typname || '\"'='%s') "\
668 "   AND (pg_catalog.quote_ident(nspname)='%s' "\
669 "        OR '\"' || nspname || '\"' ='%s') "
670
671 #define Query_for_list_of_template_databases \
672 "SELECT pg_catalog.quote_ident(d.datname) "\
673 "  FROM pg_catalog.pg_database d "\
674 " WHERE substring(pg_catalog.quote_ident(d.datname),1,%d)='%s' "\
675 "   AND (d.datistemplate OR pg_catalog.pg_has_role(d.datdba, 'USAGE'))"
676
677 #define Query_for_list_of_databases \
678 "SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\
679 " WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'"
680
681 #define Query_for_list_of_tablespaces \
682 "SELECT pg_catalog.quote_ident(spcname) FROM pg_catalog.pg_tablespace "\
683 " WHERE substring(pg_catalog.quote_ident(spcname),1,%d)='%s'"
684
685 #define Query_for_list_of_encodings \
686 " SELECT DISTINCT pg_catalog.pg_encoding_to_char(conforencoding) "\
687 "   FROM pg_catalog.pg_conversion "\
688 "  WHERE substring(pg_catalog.pg_encoding_to_char(conforencoding),1,%d)=UPPER('%s')"
689
690 #define Query_for_list_of_languages \
691 "SELECT pg_catalog.quote_ident(lanname) "\
692 "  FROM pg_catalog.pg_language "\
693 " WHERE lanname != 'internal' "\
694 "   AND substring(pg_catalog.quote_ident(lanname),1,%d)='%s'"
695
696 #define Query_for_list_of_schemas \
697 "SELECT pg_catalog.quote_ident(nspname) FROM pg_catalog.pg_namespace "\
698 " WHERE substring(pg_catalog.quote_ident(nspname),1,%d)='%s'"
699
700 #define Query_for_list_of_alter_system_set_vars \
701 "SELECT name FROM "\
702 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
703 "  WHERE context != 'internal' "\
704 "  UNION ALL SELECT 'all') ss "\
705 " WHERE substring(name,1,%d)='%s'"
706
707 #define Query_for_list_of_set_vars \
708 "SELECT name FROM "\
709 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
710 "  WHERE context IN ('user', 'superuser') "\
711 "  UNION ALL SELECT 'constraints' "\
712 "  UNION ALL SELECT 'transaction' "\
713 "  UNION ALL SELECT 'session' "\
714 "  UNION ALL SELECT 'role' "\
715 "  UNION ALL SELECT 'tablespace' "\
716 "  UNION ALL SELECT 'all') ss "\
717 " WHERE substring(name,1,%d)='%s'"
718
719 #define Query_for_list_of_show_vars \
720 "SELECT name FROM "\
721 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
722 "  UNION ALL SELECT 'session authorization' "\
723 "  UNION ALL SELECT 'all') ss "\
724 " WHERE substring(name,1,%d)='%s'"
725
726 #define Query_for_list_of_roles \
727 " SELECT pg_catalog.quote_ident(rolname) "\
728 "   FROM pg_catalog.pg_roles "\
729 "  WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"
730
731 #define Query_for_list_of_grant_roles \
732 " SELECT pg_catalog.quote_ident(rolname) "\
733 "   FROM pg_catalog.pg_roles "\
734 "  WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\
735 " UNION ALL SELECT 'PUBLIC'"\
736 " UNION ALL SELECT 'CURRENT_USER'"\
737 " UNION ALL SELECT 'SESSION_USER'"
738
739 /* the silly-looking length condition is just to eat up the current word */
740 #define Query_for_table_owning_index \
741 "SELECT pg_catalog.quote_ident(c1.relname) "\
742 "  FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
743 " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
744 "       and (%d = pg_catalog.length('%s'))"\
745 "       and pg_catalog.quote_ident(c2.relname)='%s'"\
746 "       and pg_catalog.pg_table_is_visible(c2.oid)"
747
748 /* the silly-looking length condition is just to eat up the current word */
749 #define Query_for_index_of_table \
750 "SELECT pg_catalog.quote_ident(c2.relname) "\
751 "  FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
752 " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
753 "       and (%d = pg_catalog.length('%s'))"\
754 "       and pg_catalog.quote_ident(c1.relname)='%s'"\
755 "       and pg_catalog.pg_table_is_visible(c2.oid)"
756
757 /* the silly-looking length condition is just to eat up the current word */
758 #define Query_for_constraint_of_table \
759 "SELECT pg_catalog.quote_ident(conname) "\
760 "  FROM pg_catalog.pg_class c1, pg_catalog.pg_constraint con "\
761 " WHERE c1.oid=conrelid and (%d = pg_catalog.length('%s'))"\
762 "       and pg_catalog.quote_ident(c1.relname)='%s'"\
763 "       and pg_catalog.pg_table_is_visible(c1.oid)"
764
765 #define Query_for_all_table_constraints \
766 "SELECT pg_catalog.quote_ident(conname) "\
767 "  FROM pg_catalog.pg_constraint c "\
768 " WHERE c.conrelid <> 0 "
769
770 /* the silly-looking length condition is just to eat up the current word */
771 #define Query_for_constraint_of_type \
772 "SELECT pg_catalog.quote_ident(conname) "\
773 "  FROM pg_catalog.pg_type t, pg_catalog.pg_constraint con "\
774 " WHERE t.oid=contypid and (%d = pg_catalog.length('%s'))"\
775 "       and pg_catalog.quote_ident(t.typname)='%s'"\
776 "       and pg_catalog.pg_type_is_visible(t.oid)"
777
778 /* the silly-looking length condition is just to eat up the current word */
779 #define Query_for_list_of_tables_for_constraint \
780 "SELECT pg_catalog.quote_ident(relname) "\
781 "  FROM pg_catalog.pg_class"\
782 " WHERE (%d = pg_catalog.length('%s'))"\
783 "   AND oid IN "\
784 "       (SELECT conrelid FROM pg_catalog.pg_constraint "\
785 "         WHERE pg_catalog.quote_ident(conname)='%s')"
786
787 /* the silly-looking length condition is just to eat up the current word */
788 #define Query_for_rule_of_table \
789 "SELECT pg_catalog.quote_ident(rulename) "\
790 "  FROM pg_catalog.pg_class c1, pg_catalog.pg_rewrite "\
791 " WHERE c1.oid=ev_class and (%d = pg_catalog.length('%s'))"\
792 "       and pg_catalog.quote_ident(c1.relname)='%s'"\
793 "       and pg_catalog.pg_table_is_visible(c1.oid)"
794
795 /* the silly-looking length condition is just to eat up the current word */
796 #define Query_for_list_of_tables_for_rule \
797 "SELECT pg_catalog.quote_ident(relname) "\
798 "  FROM pg_catalog.pg_class"\
799 " WHERE (%d = pg_catalog.length('%s'))"\
800 "   AND oid IN "\
801 "       (SELECT ev_class FROM pg_catalog.pg_rewrite "\
802 "         WHERE pg_catalog.quote_ident(rulename)='%s')"
803
804 /* the silly-looking length condition is just to eat up the current word */
805 #define Query_for_trigger_of_table \
806 "SELECT pg_catalog.quote_ident(tgname) "\
807 "  FROM pg_catalog.pg_class c1, pg_catalog.pg_trigger "\
808 " WHERE c1.oid=tgrelid and (%d = pg_catalog.length('%s'))"\
809 "       and pg_catalog.quote_ident(c1.relname)='%s'"\
810 "       and pg_catalog.pg_table_is_visible(c1.oid)"\
811 "       and not tgisinternal"
812
813 /* the silly-looking length condition is just to eat up the current word */
814 #define Query_for_list_of_tables_for_trigger \
815 "SELECT pg_catalog.quote_ident(relname) "\
816 "  FROM pg_catalog.pg_class"\
817 " WHERE (%d = pg_catalog.length('%s'))"\
818 "   AND oid IN "\
819 "       (SELECT tgrelid FROM pg_catalog.pg_trigger "\
820 "         WHERE pg_catalog.quote_ident(tgname)='%s')"
821
822 #define Query_for_list_of_ts_configurations \
823 "SELECT pg_catalog.quote_ident(cfgname) FROM pg_catalog.pg_ts_config "\
824 " WHERE substring(pg_catalog.quote_ident(cfgname),1,%d)='%s'"
825
826 #define Query_for_list_of_ts_dictionaries \
827 "SELECT pg_catalog.quote_ident(dictname) FROM pg_catalog.pg_ts_dict "\
828 " WHERE substring(pg_catalog.quote_ident(dictname),1,%d)='%s'"
829
830 #define Query_for_list_of_ts_parsers \
831 "SELECT pg_catalog.quote_ident(prsname) FROM pg_catalog.pg_ts_parser "\
832 " WHERE substring(pg_catalog.quote_ident(prsname),1,%d)='%s'"
833
834 #define Query_for_list_of_ts_templates \
835 "SELECT pg_catalog.quote_ident(tmplname) FROM pg_catalog.pg_ts_template "\
836 " WHERE substring(pg_catalog.quote_ident(tmplname),1,%d)='%s'"
837
838 #define Query_for_list_of_fdws \
839 " SELECT pg_catalog.quote_ident(fdwname) "\
840 "   FROM pg_catalog.pg_foreign_data_wrapper "\
841 "  WHERE substring(pg_catalog.quote_ident(fdwname),1,%d)='%s'"
842
843 #define Query_for_list_of_servers \
844 " SELECT pg_catalog.quote_ident(srvname) "\
845 "   FROM pg_catalog.pg_foreign_server "\
846 "  WHERE substring(pg_catalog.quote_ident(srvname),1,%d)='%s'"
847
848 #define Query_for_list_of_user_mappings \
849 " SELECT pg_catalog.quote_ident(usename) "\
850 "   FROM pg_catalog.pg_user_mappings "\
851 "  WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'"
852
853 #define Query_for_list_of_access_methods \
854 " SELECT pg_catalog.quote_ident(amname) "\
855 "   FROM pg_catalog.pg_am "\
856 "  WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'"
857
858 /* the silly-looking length condition is just to eat up the current word */
859 #define Query_for_list_of_arguments \
860 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
861 "  FROM pg_catalog.pg_proc "\
862 " WHERE (%d = pg_catalog.length('%s'))"\
863 "   AND (pg_catalog.quote_ident(proname)='%s'"\
864 "        OR '\"' || proname || '\"'='%s') "\
865 "   AND (pg_catalog.pg_function_is_visible(pg_proc.oid))"
866
867 /* the silly-looking length condition is just to eat up the current word */
868 #define Query_for_list_of_arguments_with_schema \
869 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
870 "  FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "\
871 " WHERE (%d = pg_catalog.length('%s'))"\
872 "   AND n.oid = p.pronamespace "\
873 "   AND (pg_catalog.quote_ident(proname)='%s' "\
874 "        OR '\"' || proname || '\"' ='%s') "\
875 "   AND (pg_catalog.quote_ident(nspname)='%s' "\
876 "        OR '\"' || nspname || '\"' ='%s') "
877
878 #define Query_for_list_of_extensions \
879 " SELECT pg_catalog.quote_ident(extname) "\
880 "   FROM pg_catalog.pg_extension "\
881 "  WHERE substring(pg_catalog.quote_ident(extname),1,%d)='%s'"
882
883 #define Query_for_list_of_available_extensions \
884 " SELECT pg_catalog.quote_ident(name) "\
885 "   FROM pg_catalog.pg_available_extensions "\
886 "  WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s' AND installed_version IS NULL"
887
888 /* the silly-looking length condition is just to eat up the current word */
889 #define Query_for_list_of_available_extension_versions \
890 " SELECT pg_catalog.quote_ident(version) "\
891 "   FROM pg_catalog.pg_available_extension_versions "\
892 "  WHERE (%d = pg_catalog.length('%s'))"\
893 "    AND pg_catalog.quote_ident(name)='%s'"
894
895 /* the silly-looking length condition is just to eat up the current word */
896 #define Query_for_list_of_available_extension_versions_with_TO \
897 " SELECT 'TO ' || pg_catalog.quote_ident(version) "\
898 "   FROM pg_catalog.pg_available_extension_versions "\
899 "  WHERE (%d = pg_catalog.length('%s'))"\
900 "    AND pg_catalog.quote_ident(name)='%s'"
901
902 #define Query_for_list_of_prepared_statements \
903 " SELECT pg_catalog.quote_ident(name) "\
904 "   FROM pg_catalog.pg_prepared_statements "\
905 "  WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s'"
906
907 #define Query_for_list_of_event_triggers \
908 " SELECT pg_catalog.quote_ident(evtname) "\
909 "   FROM pg_catalog.pg_event_trigger "\
910 "  WHERE substring(pg_catalog.quote_ident(evtname),1,%d)='%s'"
911
912 #define Query_for_list_of_tablesample_methods \
913 " SELECT pg_catalog.quote_ident(proname) "\
914 "   FROM pg_catalog.pg_proc "\
915 "  WHERE prorettype = 'pg_catalog.tsm_handler'::pg_catalog.regtype AND "\
916 "        proargtypes[0] = 'pg_catalog.internal'::pg_catalog.regtype AND "\
917 "        substring(pg_catalog.quote_ident(proname),1,%d)='%s'"
918
919 #define Query_for_list_of_policies \
920 " SELECT pg_catalog.quote_ident(polname) "\
921 "   FROM pg_catalog.pg_policy "\
922 "  WHERE substring(pg_catalog.quote_ident(polname),1,%d)='%s'"
923
924 #define Query_for_list_of_tables_for_policy \
925 "SELECT pg_catalog.quote_ident(relname) "\
926 "  FROM pg_catalog.pg_class"\
927 " WHERE (%d = pg_catalog.length('%s'))"\
928 "   AND oid IN "\
929 "       (SELECT polrelid FROM pg_catalog.pg_policy "\
930 "         WHERE pg_catalog.quote_ident(polname)='%s')"
931
932 #define Query_for_enum \
933 " SELECT name FROM ( "\
934 "   SELECT pg_catalog.quote_ident(pg_catalog.unnest(enumvals)) AS name "\
935 "     FROM pg_catalog.pg_settings "\
936 "    WHERE pg_catalog.lower(name)=pg_catalog.lower('%s') "\
937 "    UNION ALL " \
938 "   SELECT 'DEFAULT' ) ss "\
939 "  WHERE pg_catalog.substring(name,1,%%d)='%%s'"
940
941 /* the silly-looking length condition is just to eat up the current word */
942 #define Query_for_partition_of_table \
943 "SELECT pg_catalog.quote_ident(c2.relname) "\
944 "  FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_inherits i"\
945 " WHERE c1.oid=i.inhparent and i.inhrelid=c2.oid"\
946 "       and (%d = pg_catalog.length('%s'))"\
947 "       and pg_catalog.quote_ident(c1.relname)='%s'"\
948 "       and pg_catalog.pg_table_is_visible(c2.oid)"\
949 "       and c2.relispartition = 'true'"
950
951 /*
952  * These object types were introduced later than our support cutoff of
953  * server version 7.4.  We use the VersionedQuery infrastructure so that
954  * we don't send certain-to-fail queries to older servers.
955  */
956
957 static const VersionedQuery Query_for_list_of_publications[] = {
958         {100000,
959                 " SELECT pg_catalog.quote_ident(pubname) "
960                 "   FROM pg_catalog.pg_publication "
961                 "  WHERE substring(pg_catalog.quote_ident(pubname),1,%d)='%s'"
962         },
963         {0, NULL}
964 };
965
966 static const VersionedQuery Query_for_list_of_subscriptions[] = {
967         {100000,
968                 " SELECT pg_catalog.quote_ident(s.subname) "
969                 "   FROM pg_catalog.pg_subscription s, pg_catalog.pg_database d "
970                 "  WHERE substring(pg_catalog.quote_ident(s.subname),1,%d)='%s' "
971                 "    AND d.datname = pg_catalog.current_database() "
972                 "    AND s.subdbid = d.oid"
973         },
974         {0, NULL}
975 };
976
977 /*
978  * This is a list of all "things" in Pgsql, which can show up after CREATE or
979  * DROP; and there is also a query to get a list of them.
980  */
981
982 typedef struct
983 {
984         const char *name;
985         const char *query;                      /* simple query, or NULL */
986         const VersionedQuery *vquery;   /* versioned query, or NULL */
987         const SchemaQuery *squery;      /* schema query, or NULL */
988         const bits32 flags;                     /* visibility flags, see below */
989 } pgsql_thing_t;
990
991 #define THING_NO_CREATE         (1 << 0)        /* should not show up after CREATE */
992 #define THING_NO_DROP           (1 << 1)        /* should not show up after DROP */
993 #define THING_NO_ALTER          (1 << 2)        /* should not show up after ALTER */
994 #define THING_NO_SHOW           (THING_NO_CREATE | THING_NO_DROP | THING_NO_ALTER)
995
996 static const pgsql_thing_t words_after_create[] = {
997         {"ACCESS METHOD", NULL, NULL, NULL, THING_NO_ALTER},
998         {"AGGREGATE", NULL, NULL, Query_for_list_of_aggregates},
999         {"CAST", NULL, NULL, NULL}, /* Casts have complex structures for names, so
1000                                                                  * skip it */
1001         {"COLLATION", "SELECT pg_catalog.quote_ident(collname) FROM pg_catalog.pg_collation WHERE collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding())) AND substring(pg_catalog.quote_ident(collname),1,%d)='%s'"},
1002
1003         /*
1004          * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
1005          * to be used only by pg_dump.
1006          */
1007         {"CONFIGURATION", Query_for_list_of_ts_configurations, NULL, NULL, THING_NO_SHOW},
1008         {"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"},
1009         {"DATABASE", Query_for_list_of_databases},
1010         {"DEFAULT PRIVILEGES", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
1011         {"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, NULL, THING_NO_SHOW},
1012         {"DOMAIN", NULL, NULL, &Query_for_list_of_domains},
1013         {"EVENT TRIGGER", NULL, NULL, NULL},
1014         {"EXTENSION", Query_for_list_of_extensions},
1015         {"FOREIGN DATA WRAPPER", NULL, NULL, NULL},
1016         {"FOREIGN TABLE", NULL, NULL, NULL},
1017         {"FUNCTION", NULL, NULL, Query_for_list_of_functions},
1018         {"GROUP", Query_for_list_of_roles},
1019         {"INDEX", NULL, NULL, &Query_for_list_of_indexes},
1020         {"LANGUAGE", Query_for_list_of_languages},
1021         {"LARGE OBJECT", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
1022         {"MATERIALIZED VIEW", NULL, NULL, &Query_for_list_of_matviews},
1023         {"OPERATOR", NULL, NULL, NULL}, /* Querying for this is probably not such
1024                                                                          * a good idea. */
1025         {"OWNED", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_ALTER},  /* for DROP OWNED BY ... */
1026         {"PARSER", Query_for_list_of_ts_parsers, NULL, NULL, THING_NO_SHOW},
1027         {"POLICY", NULL, NULL, NULL},
1028         {"PROCEDURE", NULL, NULL, Query_for_list_of_procedures},
1029         {"PUBLICATION", NULL, Query_for_list_of_publications},
1030         {"ROLE", Query_for_list_of_roles},
1031         {"ROUTINE", NULL, NULL, &Query_for_list_of_routines, THING_NO_CREATE},
1032         {"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
1033         {"SCHEMA", Query_for_list_of_schemas},
1034         {"SEQUENCE", NULL, NULL, &Query_for_list_of_sequences},
1035         {"SERVER", Query_for_list_of_servers},
1036         {"STATISTICS", NULL, NULL, &Query_for_list_of_statistics},
1037         {"SUBSCRIPTION", NULL, Query_for_list_of_subscriptions},
1038         {"SYSTEM", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
1039         {"TABLE", NULL, NULL, &Query_for_list_of_tables},
1040         {"TABLESPACE", Query_for_list_of_tablespaces},
1041         {"TEMP", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMP TABLE
1042                                                                                                                                  * ... */
1043         {"TEMPLATE", Query_for_list_of_ts_templates, NULL, NULL, THING_NO_SHOW},
1044         {"TEMPORARY", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER},        /* for CREATE TEMPORARY
1045                                                                                                                                                  * TABLE ... */
1046         {"TEXT SEARCH", NULL, NULL, NULL},
1047         {"TRANSFORM", NULL, NULL, NULL},
1048         {"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s' AND NOT tgisinternal"},
1049         {"TYPE", NULL, NULL, &Query_for_list_of_datatypes},
1050         {"UNIQUE", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER},   /* for CREATE UNIQUE
1051                                                                                                                                          * INDEX ... */
1052         {"UNLOGGED", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNLOGGED
1053                                                                                                                                          * TABLE ... */
1054         {"USER", Query_for_list_of_roles " UNION SELECT 'MAPPING FOR'"},
1055         {"USER MAPPING FOR", NULL, NULL, NULL},
1056         {"VIEW", NULL, NULL, &Query_for_list_of_views},
1057         {NULL}                                          /* end of list */
1058 };
1059
1060
1061 /* Forward declaration of functions */
1062 static char **psql_completion(const char *text, int start, int end);
1063 static char *create_command_generator(const char *text, int state);
1064 static char *drop_command_generator(const char *text, int state);
1065 static char *alter_command_generator(const char *text, int state);
1066 static char *complete_from_query(const char *text, int state);
1067 static char *complete_from_versioned_query(const char *text, int state);
1068 static char *complete_from_schema_query(const char *text, int state);
1069 static char *complete_from_versioned_schema_query(const char *text, int state);
1070 static char *_complete_from_query(const char *simple_query,
1071                                          const SchemaQuery *schema_query,
1072                                          const char *text, int state);
1073 static char *complete_from_list(const char *text, int state);
1074 static char *complete_from_const(const char *text, int state);
1075 static void append_variable_names(char ***varnames, int *nvars,
1076                                           int *maxvars, const char *varname,
1077                                           const char *prefix, const char *suffix);
1078 static char **complete_from_variables(const char *text,
1079                                                 const char *prefix, const char *suffix, bool need_value);
1080 static char *complete_from_files(const char *text, int state);
1081
1082 static char *pg_strdup_keyword_case(const char *s, const char *ref);
1083 static char *escape_string(const char *text);
1084 static PGresult *exec_query(const char *query);
1085
1086 static char **get_previous_words(int point, char **buffer, int *nwords);
1087
1088 static char *get_guctype(const char *varname);
1089
1090 #ifdef NOT_USED
1091 static char *quote_file_name(char *text, int match_type, char *quote_pointer);
1092 static char *dequote_file_name(char *text, char quote_char);
1093 #endif
1094
1095
1096 /*
1097  * Initialize the readline library for our purposes.
1098  */
1099 void
1100 initialize_readline(void)
1101 {
1102         rl_readline_name = (char *) pset.progname;
1103         rl_attempted_completion_function = psql_completion;
1104
1105         rl_basic_word_break_characters = WORD_BREAKS;
1106
1107         completion_max_records = 1000;
1108
1109         /*
1110          * There is a variable rl_completion_query_items for this but apparently
1111          * it's not defined everywhere.
1112          */
1113 }
1114
1115 /*
1116  * Check if 'word' matches any of the '|'-separated strings in 'pattern',
1117  * using case-insensitive or case-sensitive comparisons.
1118  *
1119  * If pattern is NULL, it's a wild card that matches any word.
1120  * If pattern begins with '!', the result is negated, ie we check that 'word'
1121  * does *not* match any alternative appearing in the rest of 'pattern'.
1122  * Any alternative can end with '*' which is a wild card, i.e., it means
1123  * match any word that matches the characters so far.  (We do not currently
1124  * support '*' elsewhere than the end of an alternative.)
1125  *
1126  * For readability, callers should use the macros MatchAny and MatchAnyExcept
1127  * to invoke those two special cases for 'pattern'.  (But '|' and '*' must
1128  * just be written directly in patterns.)
1129  */
1130 #define MatchAny  NULL
1131 #define MatchAnyExcept(pattern)  ("!" pattern)
1132
1133 static bool
1134 word_matches_internal(const char *pattern,
1135                                           const char *word,
1136                                           bool case_sensitive)
1137 {
1138         size_t          wordlen,
1139                                 patternlen;
1140
1141         /* NULL pattern matches anything. */
1142         if (pattern == NULL)
1143                 return true;
1144
1145         /* Handle negated patterns from the MatchAnyExcept macro. */
1146         if (*pattern == '!')
1147                 return !word_matches_internal(pattern + 1, word, case_sensitive);
1148
1149         /* Else consider each alternative in the pattern. */
1150         wordlen = strlen(word);
1151         for (;;)
1152         {
1153                 const char *c;
1154
1155                 /* Find end of current alternative. */
1156                 c = pattern;
1157                 while (*c != '\0' && *c != '|')
1158                         c++;
1159                 /* Was there a wild card?  (Assumes first alternative is not empty) */
1160                 if (c[-1] == '*')
1161                 {
1162                         /* Yes, wildcard match? */
1163                         patternlen = c - pattern - 1;
1164                         if (wordlen >= patternlen &&
1165                                 (case_sensitive ?
1166                                  strncmp(word, pattern, patternlen) == 0 :
1167                                  pg_strncasecmp(word, pattern, patternlen) == 0))
1168                                 return true;
1169                 }
1170                 else
1171                 {
1172                         /* No, plain match? */
1173                         patternlen = c - pattern;
1174                         if (wordlen == patternlen &&
1175                                 (case_sensitive ?
1176                                  strncmp(word, pattern, wordlen) == 0 :
1177                                  pg_strncasecmp(word, pattern, wordlen) == 0))
1178                                 return true;
1179                 }
1180                 /* Out of alternatives? */
1181                 if (*c == '\0')
1182                         break;
1183                 /* Nope, try next alternative. */
1184                 pattern = c + 1;
1185         }
1186
1187         return false;
1188 }
1189
1190 /*
1191  * There are enough matching calls below that it seems worth having these two
1192  * interface routines rather than including a third parameter in every call.
1193  *
1194  * word_matches --- match case-insensitively.
1195  */
1196 static bool
1197 word_matches(const char *pattern, const char *word)
1198 {
1199         return word_matches_internal(pattern, word, false);
1200 }
1201
1202 /*
1203  * word_matches_cs --- match case-sensitively.
1204  */
1205 static bool
1206 word_matches_cs(const char *pattern, const char *word)
1207 {
1208         return word_matches_internal(pattern, word, true);
1209 }
1210
1211 /*
1212  * Check if the final character of 's' is 'c'.
1213  */
1214 static bool
1215 ends_with(const char *s, char c)
1216 {
1217         size_t          length = strlen(s);
1218
1219         return (length > 0 && s[length - 1] == c);
1220 }
1221
1222 /*
1223  * The completion function.
1224  *
1225  * According to readline spec this gets passed the text entered so far and its
1226  * start and end positions in the readline buffer. The return value is some
1227  * partially obscure list format that can be generated by readline's
1228  * completion_matches() function, so we don't have to worry about it.
1229  */
1230 static char **
1231 psql_completion(const char *text, int start, int end)
1232 {
1233         /* This is the variable we'll return. */
1234         char      **matches = NULL;
1235
1236         /* Workspace for parsed words. */
1237         char       *words_buffer;
1238
1239         /* This array will contain pointers to parsed words. */
1240         char      **previous_words;
1241
1242         /* The number of words found on the input line. */
1243         int                     previous_words_count;
1244
1245         /*
1246          * For compactness, we use these macros to reference previous_words[].
1247          * Caution: do not access a previous_words[] entry without having checked
1248          * previous_words_count to be sure it's valid.  In most cases below, that
1249          * check is implicit in a TailMatches() or similar macro, but in some
1250          * places we have to check it explicitly.
1251          */
1252 #define prev_wd   (previous_words[0])
1253 #define prev2_wd  (previous_words[1])
1254 #define prev3_wd  (previous_words[2])
1255 #define prev4_wd  (previous_words[3])
1256 #define prev5_wd  (previous_words[4])
1257 #define prev6_wd  (previous_words[5])
1258 #define prev7_wd  (previous_words[6])
1259 #define prev8_wd  (previous_words[7])
1260 #define prev9_wd  (previous_words[8])
1261
1262         /* Macros for matching the last N words before point, case-insensitively. */
1263 #define TailMatches1(p1) \
1264         (previous_words_count >= 1 && \
1265          word_matches(p1, prev_wd))
1266
1267 #define TailMatches2(p2, p1) \
1268         (previous_words_count >= 2 && \
1269          word_matches(p1, prev_wd) && \
1270          word_matches(p2, prev2_wd))
1271
1272 #define TailMatches3(p3, p2, p1) \
1273         (previous_words_count >= 3 && \
1274          word_matches(p1, prev_wd) && \
1275          word_matches(p2, prev2_wd) && \
1276          word_matches(p3, prev3_wd))
1277
1278 #define TailMatches4(p4, p3, p2, p1) \
1279         (previous_words_count >= 4 && \
1280          word_matches(p1, prev_wd) && \
1281          word_matches(p2, prev2_wd) && \
1282          word_matches(p3, prev3_wd) && \
1283          word_matches(p4, prev4_wd))
1284
1285 #define TailMatches5(p5, p4, p3, p2, p1) \
1286         (previous_words_count >= 5 && \
1287          word_matches(p1, prev_wd) && \
1288          word_matches(p2, prev2_wd) && \
1289          word_matches(p3, prev3_wd) && \
1290          word_matches(p4, prev4_wd) && \
1291          word_matches(p5, prev5_wd))
1292
1293 #define TailMatches6(p6, p5, p4, p3, p2, p1) \
1294         (previous_words_count >= 6 && \
1295          word_matches(p1, prev_wd) && \
1296          word_matches(p2, prev2_wd) && \
1297          word_matches(p3, prev3_wd) && \
1298          word_matches(p4, prev4_wd) && \
1299          word_matches(p5, prev5_wd) && \
1300          word_matches(p6, prev6_wd))
1301
1302 #define TailMatches7(p7, p6, p5, p4, p3, p2, p1) \
1303         (previous_words_count >= 7 && \
1304          word_matches(p1, prev_wd) && \
1305          word_matches(p2, prev2_wd) && \
1306          word_matches(p3, prev3_wd) && \
1307          word_matches(p4, prev4_wd) && \
1308          word_matches(p5, prev5_wd) && \
1309          word_matches(p6, prev6_wd) && \
1310          word_matches(p7, prev7_wd))
1311
1312 #define TailMatches8(p8, p7, p6, p5, p4, p3, p2, p1) \
1313         (previous_words_count >= 8 && \
1314          word_matches(p1, prev_wd) && \
1315          word_matches(p2, prev2_wd) && \
1316          word_matches(p3, prev3_wd) && \
1317          word_matches(p4, prev4_wd) && \
1318          word_matches(p5, prev5_wd) && \
1319          word_matches(p6, prev6_wd) && \
1320          word_matches(p7, prev7_wd) && \
1321          word_matches(p8, prev8_wd))
1322
1323 #define TailMatches9(p9, p8, p7, p6, p5, p4, p3, p2, p1) \
1324         (previous_words_count >= 9 && \
1325          word_matches(p1, prev_wd) && \
1326          word_matches(p2, prev2_wd) && \
1327          word_matches(p3, prev3_wd) && \
1328          word_matches(p4, prev4_wd) && \
1329          word_matches(p5, prev5_wd) && \
1330          word_matches(p6, prev6_wd) && \
1331          word_matches(p7, prev7_wd) && \
1332          word_matches(p8, prev8_wd) && \
1333          word_matches(p9, prev9_wd))
1334
1335         /* Macros for matching the last N words before point, case-sensitively. */
1336 #define TailMatchesCS1(p1) \
1337         (previous_words_count >= 1 && \
1338          word_matches_cs(p1, prev_wd))
1339 #define TailMatchesCS2(p2, p1) \
1340         (previous_words_count >= 2 && \
1341          word_matches_cs(p1, prev_wd) && \
1342          word_matches_cs(p2, prev2_wd))
1343 #define TailMatchesCS3(p3, p2, p1) \
1344         (previous_words_count >= 3 && \
1345          word_matches_cs(p1, prev_wd) && \
1346          word_matches_cs(p2, prev2_wd) && \
1347          word_matches_cs(p3, prev3_wd))
1348 #define TailMatchesCS4(p4, p3, p2, p1) \
1349         (previous_words_count >= 4 && \
1350          word_matches_cs(p1, prev_wd) && \
1351          word_matches_cs(p2, prev2_wd) && \
1352          word_matches_cs(p3, prev3_wd) && \
1353          word_matches_cs(p4, prev4_wd))
1354
1355         /*
1356          * Macros for matching N words beginning at the start of the line,
1357          * case-insensitively.
1358          */
1359 #define Matches1(p1) \
1360         (previous_words_count == 1 && \
1361          TailMatches1(p1))
1362 #define Matches2(p1, p2) \
1363         (previous_words_count == 2 && \
1364          TailMatches2(p1, p2))
1365 #define Matches3(p1, p2, p3) \
1366         (previous_words_count == 3 && \
1367          TailMatches3(p1, p2, p3))
1368 #define Matches4(p1, p2, p3, p4) \
1369         (previous_words_count == 4 && \
1370          TailMatches4(p1, p2, p3, p4))
1371 #define Matches5(p1, p2, p3, p4, p5) \
1372         (previous_words_count == 5 && \
1373          TailMatches5(p1, p2, p3, p4, p5))
1374 #define Matches6(p1, p2, p3, p4, p5, p6) \
1375         (previous_words_count == 6 && \
1376          TailMatches6(p1, p2, p3, p4, p5, p6))
1377 #define Matches7(p1, p2, p3, p4, p5, p6, p7) \
1378         (previous_words_count == 7 && \
1379          TailMatches7(p1, p2, p3, p4, p5, p6, p7))
1380 #define Matches8(p1, p2, p3, p4, p5, p6, p7, p8) \
1381         (previous_words_count == 8 && \
1382          TailMatches8(p1, p2, p3, p4, p5, p6, p7, p8))
1383 #define Matches9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \
1384         (previous_words_count == 9 && \
1385          TailMatches9(p1, p2, p3, p4, p5, p6, p7, p8, p9))
1386
1387         /*
1388          * Macros for matching N words at the start of the line, regardless of
1389          * what is after them, case-insensitively.
1390          */
1391 #define HeadMatches1(p1) \
1392         (previous_words_count >= 1 && \
1393          word_matches(p1, previous_words[previous_words_count - 1]))
1394
1395 #define HeadMatches2(p1, p2) \
1396         (previous_words_count >= 2 && \
1397          word_matches(p1, previous_words[previous_words_count - 1]) && \
1398          word_matches(p2, previous_words[previous_words_count - 2]))
1399
1400 #define HeadMatches3(p1, p2, p3) \
1401         (previous_words_count >= 3 && \
1402          word_matches(p1, previous_words[previous_words_count - 1]) && \
1403          word_matches(p2, previous_words[previous_words_count - 2]) && \
1404          word_matches(p3, previous_words[previous_words_count - 3]))
1405
1406         /* Known command-starting keywords. */
1407         static const char *const sql_commands[] = {
1408                 "ABORT", "ALTER", "ANALYZE", "BEGIN", "CALL", "CHECKPOINT", "CLOSE", "CLUSTER",
1409                 "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
1410                 "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
1411                 "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK",
1412                 "MOVE", "NOTIFY", "PREPARE",
1413                 "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
1414                 "RESET", "REVOKE", "ROLLBACK",
1415                 "SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
1416                 "TABLE", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", "VALUES", "WITH",
1417                 NULL
1418         };
1419
1420         /* psql's backslash commands. */
1421         static const char *const backslash_commands[] = {
1422                 "\\a",
1423                 "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
1424                 "\\copyright", "\\crosstabview",
1425                 "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
1426                 "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
1427                 "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
1428                 "\\dm", "\\dn", "\\do", "\\dO", "\\dp",
1429                 "\\drds", "\\dRs", "\\dRp", "\\ds", "\\dS",
1430                 "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
1431                 "\\e", "\\echo", "\\ef", "\\elif", "\\else", "\\encoding",
1432                 "\\endif", "\\errverbose", "\\ev",
1433                 "\\f",
1434                 "\\g", "\\gdesc", "\\gexec", "\\gset", "\\gx",
1435                 "\\h", "\\help", "\\H",
1436                 "\\i", "\\if", "\\ir",
1437                 "\\l", "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
1438                 "\\o",
1439                 "\\p", "\\password", "\\prompt", "\\pset",
1440                 "\\q", "\\qecho",
1441                 "\\r",
1442                 "\\s", "\\set", "\\setenv", "\\sf", "\\sv",
1443                 "\\t", "\\T", "\\timing",
1444                 "\\unset",
1445                 "\\x",
1446                 "\\w", "\\watch",
1447                 "\\z",
1448                 "\\!", "\\?",
1449                 NULL
1450         };
1451
1452         (void) end;                                     /* "end" is not used */
1453
1454 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1455         rl_completion_append_character = ' ';
1456 #endif
1457
1458         /* Clear a few things. */
1459         completion_charp = NULL;
1460         completion_charpp = NULL;
1461         completion_info_charp = NULL;
1462         completion_info_charp2 = NULL;
1463
1464         /*
1465          * Scan the input line to extract the words before our current position.
1466          * According to those we'll make some smart decisions on what the user is
1467          * probably intending to type.
1468          */
1469         previous_words = get_previous_words(start,
1470                                                                                 &words_buffer,
1471                                                                                 &previous_words_count);
1472
1473         /* If current word is a backslash command, offer completions for that */
1474         if (text[0] == '\\')
1475                 COMPLETE_WITH_LIST_CS(backslash_commands);
1476
1477         /* If current word is a variable interpolation, handle that case */
1478         else if (text[0] == ':' && text[1] != ':')
1479         {
1480                 if (text[1] == '\'')
1481                         matches = complete_from_variables(text, ":'", "'", true);
1482                 else if (text[1] == '"')
1483                         matches = complete_from_variables(text, ":\"", "\"", true);
1484                 else
1485                         matches = complete_from_variables(text, ":", "", true);
1486         }
1487
1488         /* If no previous word, suggest one of the basic sql commands */
1489         else if (previous_words_count == 0)
1490                 COMPLETE_WITH_LIST(sql_commands);
1491
1492 /* CREATE */
1493         /* complete with something you can create */
1494         else if (TailMatches1("CREATE"))
1495                 matches = completion_matches(text, create_command_generator);
1496
1497 /* DROP, but not DROP embedded in other commands */
1498         /* complete with something you can drop */
1499         else if (Matches1("DROP"))
1500                 matches = completion_matches(text, drop_command_generator);
1501
1502 /* ALTER */
1503
1504         /* ALTER TABLE */
1505         else if (Matches2("ALTER", "TABLE"))
1506                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
1507                                                                    "UNION SELECT 'ALL IN TABLESPACE'");
1508
1509         /* ALTER something */
1510         else if (Matches1("ALTER"))
1511                 matches = completion_matches(text, alter_command_generator);
1512         /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */
1513         else if (TailMatches4("ALL", "IN", "TABLESPACE", MatchAny))
1514                 COMPLETE_WITH_LIST2("SET TABLESPACE", "OWNED BY");
1515         /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */
1516         else if (TailMatches6("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"))
1517                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1518         /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */
1519         else if (TailMatches7("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny))
1520                 COMPLETE_WITH_CONST("SET TABLESPACE");
1521         /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> */
1522         else if (Matches3("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
1523                 COMPLETE_WITH_CONST("(");
1524         /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> (...) */
1525         else if (Matches4("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny))
1526         {
1527                 if (ends_with(prev_wd, ')'))
1528                         COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1529                 else
1530                         COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
1531         }
1532         /* ALTER PUBLICATION <name> */
1533         else if (Matches3("ALTER", "PUBLICATION", MatchAny))
1534                 COMPLETE_WITH_LIST5("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET");
1535         /* ALTER PUBLICATION <name> SET */
1536         else if (Matches4("ALTER", "PUBLICATION", MatchAny, "SET"))
1537                 COMPLETE_WITH_LIST2("(", "TABLE");
1538         /* ALTER PUBLICATION <name> SET ( */
1539         else if (HeadMatches3("ALTER", "PUBLICATION", MatchAny) && TailMatches2("SET", "("))
1540                 COMPLETE_WITH_CONST("publish");
1541         /* ALTER SUBSCRIPTION <name> */
1542         else if (Matches3("ALTER", "SUBSCRIPTION", MatchAny))
1543                 COMPLETE_WITH_LIST7("CONNECTION", "ENABLE", "DISABLE", "OWNER TO",
1544                                                         "RENAME TO", "REFRESH PUBLICATION", "SET");
1545         /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION */
1546         else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) &&
1547                          TailMatches2("REFRESH", "PUBLICATION"))
1548                 COMPLETE_WITH_CONST("WITH (");
1549         /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION WITH ( */
1550         else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) &&
1551                          TailMatches4("REFRESH", "PUBLICATION", "WITH", "("))
1552                 COMPLETE_WITH_CONST("copy_data");
1553         /* ALTER SUBSCRIPTION <name> SET */
1554         else if (Matches4("ALTER", "SUBSCRIPTION", MatchAny, "SET"))
1555                 COMPLETE_WITH_LIST2("(", "PUBLICATION");
1556         /* ALTER SUBSCRIPTION <name> SET ( */
1557         else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("SET", "("))
1558                 COMPLETE_WITH_LIST2("slot_name", "synchronous_commit");
1559         /* ALTER SUBSCRIPTION <name> SET PUBLICATION */
1560         else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("SET", "PUBLICATION"))
1561         {
1562                 /* complete with nothing here as this refers to remote publications */
1563         }
1564         /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> */
1565         else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) &&
1566                          TailMatches3("SET", "PUBLICATION", MatchAny))
1567                 COMPLETE_WITH_CONST("WITH (");
1568         /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> WITH ( */
1569         else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) &&
1570                          TailMatches5("SET", "PUBLICATION", MatchAny, "WITH", "("))
1571                 COMPLETE_WITH_LIST2("copy_data", "refresh");
1572         /* ALTER SCHEMA <name> */
1573         else if (Matches3("ALTER", "SCHEMA", MatchAny))
1574                 COMPLETE_WITH_LIST2("OWNER TO", "RENAME TO");
1575
1576         /* ALTER COLLATION <name> */
1577         else if (Matches3("ALTER", "COLLATION", MatchAny))
1578                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1579
1580         /* ALTER CONVERSION <name> */
1581         else if (Matches3("ALTER", "CONVERSION", MatchAny))
1582                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1583
1584         /* ALTER DATABASE <name> */
1585         else if (Matches3("ALTER", "DATABASE", MatchAny))
1586                 COMPLETE_WITH_LIST7("RESET", "SET", "OWNER TO", "RENAME TO",
1587                                                         "IS_TEMPLATE", "ALLOW_CONNECTIONS",
1588                                                         "CONNECTION LIMIT");
1589
1590         /* ALTER EVENT TRIGGER */
1591         else if (Matches3("ALTER", "EVENT", "TRIGGER"))
1592                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
1593
1594         /* ALTER EVENT TRIGGER <name> */
1595         else if (Matches4("ALTER", "EVENT", "TRIGGER", MatchAny))
1596                 COMPLETE_WITH_LIST4("DISABLE", "ENABLE", "OWNER TO", "RENAME TO");
1597
1598         /* ALTER EVENT TRIGGER <name> ENABLE */
1599         else if (Matches5("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"))
1600                 COMPLETE_WITH_LIST2("REPLICA", "ALWAYS");
1601
1602         /* ALTER EXTENSION <name> */
1603         else if (Matches3("ALTER", "EXTENSION", MatchAny))
1604                 COMPLETE_WITH_LIST4("ADD", "DROP", "UPDATE", "SET SCHEMA");
1605
1606         /* ALTER EXTENSION <name> UPDATE */
1607         else if (Matches4("ALTER", "EXTENSION", MatchAny, "UPDATE"))
1608         {
1609                 completion_info_charp = prev2_wd;
1610                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO);
1611         }
1612
1613         /* ALTER EXTENSION <name> UPDATE TO */
1614         else if (Matches5("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"))
1615         {
1616                 completion_info_charp = prev3_wd;
1617                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
1618         }
1619
1620         /* ALTER FOREIGN */
1621         else if (Matches2("ALTER", "FOREIGN"))
1622                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
1623
1624         /* ALTER FOREIGN DATA WRAPPER <name> */
1625         else if (Matches5("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
1626                 COMPLETE_WITH_LIST5("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO");
1627
1628         /* ALTER FOREIGN TABLE <name> */
1629         else if (Matches4("ALTER", "FOREIGN", "TABLE", MatchAny))
1630         {
1631                 static const char *const list_ALTER_FOREIGN_TABLE[] =
1632                 {"ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE", "INHERIT",
1633                         "NO INHERIT", "OPTIONS", "OWNER TO", "RENAME", "SET",
1634                 "VALIDATE CONSTRAINT", NULL};
1635
1636                 COMPLETE_WITH_LIST(list_ALTER_FOREIGN_TABLE);
1637         }
1638
1639         /* ALTER INDEX */
1640         else if (Matches2("ALTER", "INDEX"))
1641                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
1642                                                                    "UNION SELECT 'ALL IN TABLESPACE'");
1643         /* ALTER INDEX <name> */
1644         else if (Matches3("ALTER", "INDEX", MatchAny))
1645                 COMPLETE_WITH_LIST6("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET",
1646                                                         "RESET", "ATTACH PARTITION");
1647         else if (Matches4("ALTER", "INDEX", MatchAny, "ATTACH"))
1648                 COMPLETE_WITH_CONST("PARTITION");
1649         else if (Matches5("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION"))
1650                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
1651         /* ALTER INDEX <name> ALTER COLUMN <colnum> */
1652         else if (Matches6("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny))
1653                 COMPLETE_WITH_CONST("SET STATISTICS");
1654         /* ALTER INDEX <name> SET */
1655         else if (Matches4("ALTER", "INDEX", MatchAny, "SET"))
1656                 COMPLETE_WITH_LIST2("(", "TABLESPACE");
1657         /* ALTER INDEX <name> RESET */
1658         else if (Matches4("ALTER", "INDEX", MatchAny, "RESET"))
1659                 COMPLETE_WITH_CONST("(");
1660         /* ALTER INDEX <foo> SET|RESET ( */
1661         else if (Matches5("ALTER", "INDEX", MatchAny, "RESET", "("))
1662                 COMPLETE_WITH_LIST8("fillfactor", "recheck_on_update",
1663                                                         "vacuum_cleanup_index_scale_factor",    /* BTREE */
1664                                                         "fastupdate", "gin_pending_list_limit", /* GIN */
1665                                                         "buffering",    /* GiST */
1666                                                         "pages_per_range", "autosummarize"      /* BRIN */
1667                         );
1668         else if (Matches5("ALTER", "INDEX", MatchAny, "SET", "("))
1669                 COMPLETE_WITH_LIST8("fillfactor =", "recheck_on_update =",
1670                                                         "vacuum_cleanup_index_scale_factor =",  /* BTREE */
1671                                                         "fastupdate =", "gin_pending_list_limit =", /* GIN */
1672                                                         "buffering =",  /* GiST */
1673                                                         "pages_per_range =", "autosummarize ="  /* BRIN */
1674                         );
1675
1676         /* ALTER LANGUAGE <name> */
1677         else if (Matches3("ALTER", "LANGUAGE", MatchAny))
1678                 COMPLETE_WITH_LIST2("OWNER_TO", "RENAME TO");
1679
1680         /* ALTER LARGE OBJECT <oid> */
1681         else if (Matches4("ALTER", "LARGE", "OBJECT", MatchAny))
1682                 COMPLETE_WITH_CONST("OWNER TO");
1683
1684         /* ALTER MATERIALIZED VIEW */
1685         else if (Matches3("ALTER", "MATERIALIZED", "VIEW"))
1686                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
1687                                                                    "UNION SELECT 'ALL IN TABLESPACE'");
1688
1689         /* ALTER USER,ROLE <name> */
1690         else if (Matches3("ALTER", "USER|ROLE", MatchAny) &&
1691                          !TailMatches2("USER", "MAPPING"))
1692         {
1693                 static const char *const list_ALTERUSER[] =
1694                 {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1695                         "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1696                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1697                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
1698                         "REPLICATION", "RESET", "SET", "SUPERUSER",
1699                 "VALID UNTIL", "WITH", NULL};
1700
1701                 COMPLETE_WITH_LIST(list_ALTERUSER);
1702         }
1703
1704         /* ALTER USER,ROLE <name> WITH */
1705         else if (Matches4("ALTER", "USER|ROLE", MatchAny, "WITH"))
1706         {
1707                 /* Similar to the above, but don't complete "WITH" again. */
1708                 static const char *const list_ALTERUSER_WITH[] =
1709                 {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1710                         "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1711                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1712                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
1713                         "REPLICATION", "RESET", "SET", "SUPERUSER",
1714                 "VALID UNTIL", NULL};
1715
1716                 COMPLETE_WITH_LIST(list_ALTERUSER_WITH);
1717         }
1718
1719         /* ALTER DEFAULT PRIVILEGES */
1720         else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES"))
1721                 COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA");
1722         /* ALTER DEFAULT PRIVILEGES FOR */
1723         else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
1724                 COMPLETE_WITH_CONST("ROLE");
1725         /* ALTER DEFAULT PRIVILEGES IN */
1726         else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
1727                 COMPLETE_WITH_CONST("SCHEMA");
1728         /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
1729         else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1730                                           MatchAny))
1731                 COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA");
1732         /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
1733         else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1734                                           MatchAny))
1735                 COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE");
1736         /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
1737         else if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1738                                           MatchAny, "FOR"))
1739                 COMPLETE_WITH_CONST("ROLE");
1740         /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
1741         /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
1742         else if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1743                                           MatchAny, "IN", "SCHEMA", MatchAny) ||
1744                          Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1745                                           MatchAny, "FOR", "ROLE|USER", MatchAny))
1746                 COMPLETE_WITH_LIST2("GRANT", "REVOKE");
1747         /* ALTER DOMAIN <name> */
1748         else if (Matches3("ALTER", "DOMAIN", MatchAny))
1749                 COMPLETE_WITH_LIST6("ADD", "DROP", "OWNER TO", "RENAME", "SET",
1750                                                         "VALIDATE CONSTRAINT");
1751         /* ALTER DOMAIN <sth> DROP */
1752         else if (Matches4("ALTER", "DOMAIN", MatchAny, "DROP"))
1753                 COMPLETE_WITH_LIST3("CONSTRAINT", "DEFAULT", "NOT NULL");
1754         /* ALTER DOMAIN <sth> DROP|RENAME|VALIDATE CONSTRAINT */
1755         else if (Matches5("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
1756         {
1757                 completion_info_charp = prev3_wd;
1758                 COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
1759         }
1760         /* ALTER DOMAIN <sth> RENAME */
1761         else if (Matches4("ALTER", "DOMAIN", MatchAny, "RENAME"))
1762                 COMPLETE_WITH_LIST2("CONSTRAINT", "TO");
1763         /* ALTER DOMAIN <sth> RENAME CONSTRAINT <sth> */
1764         else if (Matches6("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny))
1765                 COMPLETE_WITH_CONST("TO");
1766
1767         /* ALTER DOMAIN <sth> SET */
1768         else if (Matches4("ALTER", "DOMAIN", MatchAny, "SET"))
1769                 COMPLETE_WITH_LIST3("DEFAULT", "NOT NULL", "SCHEMA");
1770         /* ALTER SEQUENCE <name> */
1771         else if (Matches3("ALTER", "SEQUENCE", MatchAny))
1772         {
1773                 static const char *const list_ALTERSEQUENCE[] =
1774                 {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE",
1775                 "SET SCHEMA", "OWNED BY", "OWNER TO", "RENAME TO", NULL};
1776
1777                 COMPLETE_WITH_LIST(list_ALTERSEQUENCE);
1778         }
1779         /* ALTER SEQUENCE <name> NO */
1780         else if (Matches4("ALTER", "SEQUENCE", MatchAny, "NO"))
1781                 COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE");
1782         /* ALTER SERVER <name> */
1783         else if (Matches3("ALTER", "SERVER", MatchAny))
1784                 COMPLETE_WITH_LIST4("VERSION", "OPTIONS", "OWNER TO", "RENAME TO");
1785         /* ALTER SERVER <name> VERSION <version> */
1786         else if (Matches5("ALTER", "SERVER", MatchAny, "VERSION", MatchAny))
1787                 COMPLETE_WITH_CONST("OPTIONS");
1788         /* ALTER SYSTEM SET, RESET, RESET ALL */
1789         else if (Matches2("ALTER", "SYSTEM"))
1790                 COMPLETE_WITH_LIST2("SET", "RESET");
1791         else if (Matches3("ALTER", "SYSTEM", "SET|RESET"))
1792                 COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars);
1793         else if (Matches4("ALTER", "SYSTEM", "SET", MatchAny))
1794                 COMPLETE_WITH_CONST("TO");
1795         /* ALTER VIEW <name> */
1796         else if (Matches3("ALTER", "VIEW", MatchAny))
1797                 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1798                                                         "SET SCHEMA");
1799         /* ALTER MATERIALIZED VIEW <name> */
1800         else if (Matches4("ALTER", "MATERIALIZED", "VIEW", MatchAny))
1801                 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1802                                                         "SET SCHEMA");
1803
1804         /* ALTER POLICY <name> */
1805         else if (Matches2("ALTER", "POLICY"))
1806                 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
1807         /* ALTER POLICY <name> ON */
1808         else if (Matches3("ALTER", "POLICY", MatchAny))
1809                 COMPLETE_WITH_CONST("ON");
1810         /* ALTER POLICY <name> ON <table> */
1811         else if (Matches4("ALTER", "POLICY", MatchAny, "ON"))
1812         {
1813                 completion_info_charp = prev2_wd;
1814                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
1815         }
1816         /* ALTER POLICY <name> ON <table> - show options */
1817         else if (Matches5("ALTER", "POLICY", MatchAny, "ON", MatchAny))
1818                 COMPLETE_WITH_LIST4("RENAME TO", "TO", "USING (", "WITH CHECK (");
1819         /* ALTER POLICY <name> ON <table> TO <role> */
1820         else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
1821                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
1822         /* ALTER POLICY <name> ON <table> USING ( */
1823         else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
1824                 COMPLETE_WITH_CONST("(");
1825         /* ALTER POLICY <name> ON <table> WITH CHECK ( */
1826         else if (Matches7("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
1827                 COMPLETE_WITH_CONST("(");
1828
1829         /* ALTER RULE <name>, add ON */
1830         else if (Matches3("ALTER", "RULE", MatchAny))
1831                 COMPLETE_WITH_CONST("ON");
1832
1833         /* If we have ALTER RULE <name> ON, then add the correct tablename */
1834         else if (Matches4("ALTER", "RULE", MatchAny, "ON"))
1835         {
1836                 completion_info_charp = prev2_wd;
1837                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1838         }
1839
1840         /* ALTER RULE <name> ON <name> */
1841         else if (Matches5("ALTER", "RULE", MatchAny, "ON", MatchAny))
1842                 COMPLETE_WITH_CONST("RENAME TO");
1843
1844         /* ALTER STATISTICS <name> */
1845         else if (Matches3("ALTER", "STATISTICS", MatchAny))
1846                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1847
1848         /* ALTER TRIGGER <name>, add ON */
1849         else if (Matches3("ALTER", "TRIGGER", MatchAny))
1850                 COMPLETE_WITH_CONST("ON");
1851
1852         else if (Matches4("ALTER", "TRIGGER", MatchAny, MatchAny))
1853         {
1854                 completion_info_charp = prev2_wd;
1855                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
1856         }
1857
1858         /*
1859          * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
1860          */
1861         else if (Matches4("ALTER", "TRIGGER", MatchAny, "ON"))
1862                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
1863
1864         /* ALTER TRIGGER <name> ON <name> */
1865         else if (Matches5("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
1866                 COMPLETE_WITH_CONST("RENAME TO");
1867
1868         /*
1869          * If we detect ALTER TABLE <name>, suggest sub commands
1870          */
1871         else if (Matches3("ALTER", "TABLE", MatchAny))
1872         {
1873                 static const char *const list_ALTER2[] =
1874                 {"ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", "ENABLE", "INHERIT",
1875                         "NO INHERIT", "RENAME", "RESET", "OWNER TO", "SET",
1876                         "VALIDATE CONSTRAINT", "REPLICA IDENTITY", "ATTACH PARTITION",
1877                 "DETACH PARTITION", NULL};
1878
1879                 COMPLETE_WITH_LIST(list_ALTER2);
1880         }
1881         /* ALTER TABLE xxx ENABLE */
1882         else if (Matches4("ALTER", "TABLE", MatchAny, "ENABLE"))
1883                 COMPLETE_WITH_LIST5("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
1884                                                         "TRIGGER");
1885         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
1886                 COMPLETE_WITH_LIST2("RULE", "TRIGGER");
1887         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
1888         {
1889                 completion_info_charp = prev3_wd;
1890                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1891         }
1892         else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
1893         {
1894                 completion_info_charp = prev4_wd;
1895                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1896         }
1897         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
1898         {
1899                 completion_info_charp = prev3_wd;
1900                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1901         }
1902         else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
1903         {
1904                 completion_info_charp = prev4_wd;
1905                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1906         }
1907         /* ALTER TABLE xxx INHERIT */
1908         else if (Matches4("ALTER", "TABLE", MatchAny, "INHERIT"))
1909                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1910         /* ALTER TABLE xxx NO INHERIT */
1911         else if (Matches5("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
1912                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1913         /* ALTER TABLE xxx DISABLE */
1914         else if (Matches4("ALTER", "TABLE", MatchAny, "DISABLE"))
1915                 COMPLETE_WITH_LIST3("ROW LEVEL SECURITY", "RULE", "TRIGGER");
1916         else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
1917         {
1918                 completion_info_charp = prev3_wd;
1919                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1920         }
1921         else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
1922         {
1923                 completion_info_charp = prev3_wd;
1924                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1925         }
1926
1927         /* ALTER TABLE xxx ALTER */
1928         else if (Matches4("ALTER", "TABLE", MatchAny, "ALTER"))
1929                 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'");
1930
1931         /* ALTER TABLE xxx RENAME */
1932         else if (Matches4("ALTER", "TABLE", MatchAny, "RENAME"))
1933                 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'");
1934         else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
1935                 COMPLETE_WITH_ATTR(prev3_wd, "");
1936
1937         /* ALTER TABLE xxx RENAME yyy */
1938         else if (Matches5("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
1939                 COMPLETE_WITH_CONST("TO");
1940
1941         /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
1942         else if (Matches6("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
1943                 COMPLETE_WITH_CONST("TO");
1944
1945         /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
1946         else if (Matches4("ALTER", "TABLE", MatchAny, "DROP"))
1947                 COMPLETE_WITH_LIST2("COLUMN", "CONSTRAINT");
1948         /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
1949         else if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
1950                 COMPLETE_WITH_ATTR(prev3_wd, "");
1951
1952         /*
1953          * If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
1954          * provide list of constraints
1955          */
1956         else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
1957         {
1958                 completion_info_charp = prev3_wd;
1959                 COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
1960         }
1961         /* ALTER TABLE ALTER [COLUMN] <foo> */
1962         else if (Matches6("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
1963                          Matches5("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
1964                 COMPLETE_WITH_LIST6("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP");
1965         /* ALTER TABLE ALTER [COLUMN] <foo> SET */
1966         else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
1967                          Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
1968                 COMPLETE_WITH_LIST5("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE");
1969         /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
1970         else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
1971                          Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
1972                 COMPLETE_WITH_LIST2("n_distinct", "n_distinct_inherited");
1973         /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
1974         else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
1975                          Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
1976                 COMPLETE_WITH_LIST4("PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
1977         /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
1978         else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
1979                          Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
1980                 COMPLETE_WITH_LIST3("DEFAULT", "IDENTITY", "NOT NULL");
1981         else if (Matches4("ALTER", "TABLE", MatchAny, "CLUSTER"))
1982                 COMPLETE_WITH_CONST("ON");
1983         else if (Matches5("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
1984         {
1985                 completion_info_charp = prev3_wd;
1986                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1987         }
1988         /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
1989         else if (Matches4("ALTER", "TABLE", MatchAny, "SET"))
1990                 COMPLETE_WITH_LIST7("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED",
1991                                                         "WITH", "WITHOUT");
1992
1993         /*
1994          * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
1995          * tablespaces
1996          */
1997         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
1998                 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1999         /* If we have ALTER TABLE <sth> SET WITH provide OIDS */
2000         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITH"))
2001                 COMPLETE_WITH_CONST("OIDS");
2002         /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
2003         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
2004                 COMPLETE_WITH_LIST2("CLUSTER", "OIDS");
2005         /* ALTER TABLE <foo> RESET */
2006         else if (Matches4("ALTER", "TABLE", MatchAny, "RESET"))
2007                 COMPLETE_WITH_CONST("(");
2008         /* ALTER TABLE <foo> SET|RESET ( */
2009         else if (Matches5("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
2010         {
2011                 static const char *const list_TABLEOPTIONS[] =
2012                 {
2013                         "autovacuum_analyze_scale_factor",
2014                         "autovacuum_analyze_threshold",
2015                         "autovacuum_enabled",
2016                         "autovacuum_freeze_max_age",
2017                         "autovacuum_freeze_min_age",
2018                         "autovacuum_freeze_table_age",
2019                         "autovacuum_multixact_freeze_max_age",
2020                         "autovacuum_multixact_freeze_min_age",
2021                         "autovacuum_multixact_freeze_table_age",
2022                         "autovacuum_vacuum_cost_delay",
2023                         "autovacuum_vacuum_cost_limit",
2024                         "autovacuum_vacuum_scale_factor",
2025                         "autovacuum_vacuum_threshold",
2026                         "fillfactor",
2027                         "parallel_workers",
2028                         "log_autovacuum_min_duration",
2029                         "toast.autovacuum_enabled",
2030                         "toast.autovacuum_freeze_max_age",
2031                         "toast.autovacuum_freeze_min_age",
2032                         "toast.autovacuum_freeze_table_age",
2033                         "toast.autovacuum_multixact_freeze_max_age",
2034                         "toast.autovacuum_multixact_freeze_min_age",
2035                         "toast.autovacuum_multixact_freeze_table_age",
2036                         "toast.autovacuum_vacuum_cost_delay",
2037                         "toast.autovacuum_vacuum_cost_limit",
2038                         "toast.autovacuum_vacuum_scale_factor",
2039                         "toast.autovacuum_vacuum_threshold",
2040                         "toast.log_autovacuum_min_duration",
2041                         "user_catalog_table",
2042                         NULL
2043                 };
2044
2045                 COMPLETE_WITH_LIST(list_TABLEOPTIONS);
2046         }
2047         else if (Matches7("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
2048         {
2049                 completion_info_charp = prev5_wd;
2050                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
2051         }
2052         else if (Matches6("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
2053                 COMPLETE_WITH_CONST("INDEX");
2054         else if (Matches5("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
2055                 COMPLETE_WITH_LIST4("FULL", "NOTHING", "DEFAULT", "USING");
2056         else if (Matches4("ALTER", "TABLE", MatchAny, "REPLICA"))
2057                 COMPLETE_WITH_CONST("IDENTITY");
2058
2059         /*
2060          * If we have ALTER TABLE <foo> ATTACH PARTITION, provide a list of
2061          * tables.
2062          */
2063         else if (Matches5("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION"))
2064                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
2065         /* Limited completion support for partition bound specification */
2066         else if (TailMatches3("ATTACH", "PARTITION", MatchAny))
2067                 COMPLETE_WITH_LIST2("FOR VALUES", "DEFAULT");
2068         else if (TailMatches2("FOR", "VALUES"))
2069                 COMPLETE_WITH_LIST3("FROM (", "IN (", "WITH (");
2070
2071         /*
2072          * If we have ALTER TABLE <foo> DETACH PARTITION, provide a list of
2073          * partitions of <foo>.
2074          */
2075         else if (Matches5("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION"))
2076         {
2077                 completion_info_charp = prev3_wd;
2078                 COMPLETE_WITH_QUERY(Query_for_partition_of_table);
2079         }
2080
2081         /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
2082         else if (Matches3("ALTER", "TABLESPACE", MatchAny))
2083                 COMPLETE_WITH_LIST4("RENAME TO", "OWNER TO", "SET", "RESET");
2084         /* ALTER TABLESPACE <foo> SET|RESET */
2085         else if (Matches4("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
2086                 COMPLETE_WITH_CONST("(");
2087         /* ALTER TABLESPACE <foo> SET|RESET ( */
2088         else if (Matches5("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
2089                 COMPLETE_WITH_LIST3("seq_page_cost", "random_page_cost",
2090                                                         "effective_io_concurrency");
2091
2092         /* ALTER TEXT SEARCH */
2093         else if (Matches3("ALTER", "TEXT", "SEARCH"))
2094                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2095         else if (Matches5("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
2096                 COMPLETE_WITH_LIST2("RENAME TO", "SET SCHEMA");
2097         else if (Matches5("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
2098                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
2099         else if (Matches5("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2100                 COMPLETE_WITH_LIST6("ADD MAPPING FOR", "ALTER MAPPING",
2101                                                         "DROP MAPPING FOR",
2102                                                         "OWNER TO", "RENAME TO", "SET SCHEMA");
2103
2104         /* complete ALTER TYPE <foo> with actions */
2105         else if (Matches3("ALTER", "TYPE", MatchAny))
2106                 COMPLETE_WITH_LIST7("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
2107                                                         "DROP ATTRIBUTE",
2108                                                         "OWNER TO", "RENAME", "SET SCHEMA");
2109         /* complete ALTER TYPE <foo> ADD with actions */
2110         else if (Matches4("ALTER", "TYPE", MatchAny, "ADD"))
2111                 COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE");
2112         /* ALTER TYPE <foo> RENAME      */
2113         else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME"))
2114                 COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE");
2115         /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
2116         else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
2117                 COMPLETE_WITH_CONST("TO");
2118
2119         /*
2120          * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
2121          * of attributes
2122          */
2123         else if (Matches5("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
2124                 COMPLETE_WITH_ATTR(prev3_wd, "");
2125         /* ALTER TYPE ALTER ATTRIBUTE <foo> */
2126         else if (Matches6("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
2127                 COMPLETE_WITH_CONST("TYPE");
2128         /* complete ALTER GROUP <foo> */
2129         else if (Matches3("ALTER", "GROUP", MatchAny))
2130                 COMPLETE_WITH_LIST3("ADD USER", "DROP USER", "RENAME TO");
2131         /* complete ALTER GROUP <foo> ADD|DROP with USER */
2132         else if (Matches4("ALTER", "GROUP", MatchAny, "ADD|DROP"))
2133                 COMPLETE_WITH_CONST("USER");
2134         /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
2135         else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
2136                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2137
2138         /*
2139          * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
2140          */
2141         else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
2142                 COMPLETE_WITH_ENUM_VALUE(prev3_wd);
2143
2144 /* BEGIN */
2145         else if (Matches1("BEGIN"))
2146                 COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2147 /* END, ABORT */
2148         else if (Matches1("END|ABORT"))
2149                 COMPLETE_WITH_LIST2("WORK", "TRANSACTION");
2150 /* COMMIT */
2151         else if (Matches1("COMMIT"))
2152                 COMPLETE_WITH_LIST3("WORK", "TRANSACTION", "PREPARED");
2153 /* RELEASE SAVEPOINT */
2154         else if (Matches1("RELEASE"))
2155                 COMPLETE_WITH_CONST("SAVEPOINT");
2156 /* ROLLBACK */
2157         else if (Matches1("ROLLBACK"))
2158                 COMPLETE_WITH_LIST4("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
2159 /* CALL */
2160         else if (Matches1("CALL"))
2161                 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
2162         else if (Matches2("CALL", MatchAny))
2163                 COMPLETE_WITH_CONST("(");
2164 /* CLUSTER */
2165         else if (Matches1("CLUSTER"))
2166                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, "UNION SELECT 'VERBOSE'");
2167         else if (Matches2("CLUSTER", "VERBOSE"))
2168                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2169         /* If we have CLUSTER <sth>, then add "USING" */
2170         else if (Matches2("CLUSTER", MatchAnyExcept("VERBOSE|ON")))
2171                 COMPLETE_WITH_CONST("USING");
2172         /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
2173         else if (Matches3("CLUSTER", "VERBOSE", MatchAny))
2174                 COMPLETE_WITH_CONST("USING");
2175         /* If we have CLUSTER <sth> USING, then add the index as well */
2176         else if (Matches3("CLUSTER", MatchAny, "USING") ||
2177                          Matches4("CLUSTER", "VERBOSE", MatchAny, "USING"))
2178         {
2179                 completion_info_charp = prev2_wd;
2180                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
2181         }
2182
2183 /* COMMENT */
2184         else if (Matches1("COMMENT"))
2185                 COMPLETE_WITH_CONST("ON");
2186         else if (Matches2("COMMENT", "ON"))
2187         {
2188                 static const char *const list_COMMENT[] =
2189                 {"ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", "DATABASE",
2190                         "EVENT TRIGGER", "EXTENSION",
2191                         "FOREIGN DATA WRAPPER", "FOREIGN TABLE",
2192                         "SERVER", "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE",
2193                         "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION",
2194                         "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
2195                         "PROCEDURE", "ROUTINE",
2196                         "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
2197                 "TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
2198
2199                 COMPLETE_WITH_LIST(list_COMMENT);
2200         }
2201         else if (Matches4("COMMENT", "ON", "ACCESS", "METHOD"))
2202                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2203         else if (Matches3("COMMENT", "ON", "FOREIGN"))
2204                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2205         else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH"))
2206                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2207         else if (Matches3("COMMENT", "ON", "CONSTRAINT"))
2208                 COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2209         else if (Matches4("COMMENT", "ON", "CONSTRAINT", MatchAny))
2210                 COMPLETE_WITH_CONST("ON");
2211         else if (Matches5("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2212         {
2213                 completion_info_charp = prev2_wd;
2214                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint);
2215         }
2216         else if (Matches4("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2217                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2218         else if (Matches4("COMMENT", "ON", "EVENT", "TRIGGER"))
2219                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2220         else if (Matches4("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2221                          Matches5("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2222                          Matches6("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2223                 COMPLETE_WITH_CONST("IS");
2224
2225 /* COPY */
2226
2227         /*
2228          * If we have COPY, offer list of tables or "(" (Also cover the analogous
2229          * backslash command).
2230          */
2231         else if (Matches1("COPY|\\copy"))
2232                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2233                                                                    " UNION ALL SELECT '('");
2234         /* If we have COPY BINARY, complete with list of tables */
2235         else if (Matches2("COPY", "BINARY"))
2236                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2237         /* If we have COPY (, complete it with legal commands */
2238         else if (Matches2("COPY|\\copy", "("))
2239                 COMPLETE_WITH_LIST7("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH");
2240         /* If we have COPY [BINARY] <sth>, complete it with "TO" or "FROM" */
2241         else if (Matches2("COPY|\\copy", MatchAny) ||
2242                          Matches3("COPY", "BINARY", MatchAny))
2243                 COMPLETE_WITH_LIST2("FROM", "TO");
2244         /* If we have COPY [BINARY] <sth> FROM|TO, complete with filename */
2245         else if (Matches3("COPY|\\copy", MatchAny, "FROM|TO") ||
2246                          Matches4("COPY", "BINARY", MatchAny, "FROM|TO"))
2247         {
2248                 completion_charp = "";
2249                 matches = completion_matches(text, complete_from_files);
2250         }
2251
2252         /* Handle COPY [BINARY] <sth> FROM|TO filename */
2253         else if (Matches4("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
2254                          Matches5("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
2255                 COMPLETE_WITH_LIST6("BINARY", "OIDS", "DELIMITER", "NULL", "CSV",
2256                                                         "ENCODING");
2257
2258         /* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
2259         else if (Matches5("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") ||
2260                          Matches6("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV"))
2261                 COMPLETE_WITH_LIST5("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE",
2262                                                         "FORCE NOT NULL");
2263
2264         /* CREATE ACCESS METHOD */
2265         /* Complete "CREATE ACCESS METHOD <name>" */
2266         else if (Matches4("CREATE", "ACCESS", "METHOD", MatchAny))
2267                 COMPLETE_WITH_CONST("TYPE");
2268         /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2269         else if (Matches5("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2270                 COMPLETE_WITH_CONST("INDEX");
2271         /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2272         else if (Matches6("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2273                 COMPLETE_WITH_CONST("HANDLER");
2274
2275         /* CREATE DATABASE */
2276         else if (Matches3("CREATE", "DATABASE", MatchAny))
2277                 COMPLETE_WITH_LIST9("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2278                                                         "IS_TEMPLATE",
2279                                                         "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2280                                                         "LC_COLLATE", "LC_CTYPE");
2281
2282         else if (Matches4("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2283                 COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2284
2285         /* CREATE EXTENSION */
2286         /* Complete with available extensions rather than installed ones. */
2287         else if (Matches2("CREATE", "EXTENSION"))
2288                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2289         /* CREATE EXTENSION <name> */
2290         else if (Matches3("CREATE", "EXTENSION", MatchAny))
2291                 COMPLETE_WITH_LIST3("WITH SCHEMA", "CASCADE", "VERSION");
2292         /* CREATE EXTENSION <name> VERSION */
2293         else if (Matches4("CREATE", "EXTENSION", MatchAny, "VERSION"))
2294         {
2295                 completion_info_charp = prev2_wd;
2296                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2297         }
2298
2299         /* CREATE FOREIGN */
2300         else if (Matches2("CREATE", "FOREIGN"))
2301                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2302
2303         /* CREATE FOREIGN DATA WRAPPER */
2304         else if (Matches5("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2305                 COMPLETE_WITH_LIST3("HANDLER", "VALIDATOR", "OPTIONS");
2306
2307         /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2308         /* First off we complete CREATE UNIQUE with "INDEX" */
2309         else if (TailMatches2("CREATE", "UNIQUE"))
2310                 COMPLETE_WITH_CONST("INDEX");
2311
2312         /*
2313          * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
2314          * existing indexes
2315          */
2316         else if (TailMatches2("CREATE|UNIQUE", "INDEX"))
2317                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2318                                                                    " UNION SELECT 'ON'"
2319                                                                    " UNION SELECT 'CONCURRENTLY'");
2320
2321         /*
2322          * Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of relations
2323          * that can indexes can be created on
2324          */
2325         else if (TailMatches3("INDEX|CONCURRENTLY", MatchAny, "ON") ||
2326                          TailMatches2("INDEX|CONCURRENTLY", "ON"))
2327                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tpm, NULL);
2328
2329         /*
2330          * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
2331          * indexes
2332          */
2333         else if (TailMatches3("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
2334                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2335                                                                    " UNION SELECT 'ON'");
2336         /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
2337         else if (TailMatches3("CREATE|UNIQUE", "INDEX", MatchAny) ||
2338                          TailMatches4("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
2339                 COMPLETE_WITH_CONST("ON");
2340
2341         /*
2342          * Complete INDEX <name> ON <table> with a list of table columns (which
2343          * should really be in parens)
2344          */
2345         else if (TailMatches4("INDEX", MatchAny, "ON", MatchAny) ||
2346                          TailMatches3("INDEX|CONCURRENTLY", "ON", MatchAny))
2347                 COMPLETE_WITH_LIST2("(", "USING");
2348         else if (TailMatches5("INDEX", MatchAny, "ON", MatchAny, "(") ||
2349                          TailMatches4("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
2350                 COMPLETE_WITH_ATTR(prev2_wd, "");
2351         /* same if you put in USING */
2352         else if (TailMatches5("ON", MatchAny, "USING", MatchAny, "("))
2353                 COMPLETE_WITH_ATTR(prev4_wd, "");
2354         /* Complete USING with an index method */
2355         else if (TailMatches6("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
2356                          TailMatches5("INDEX", MatchAny, "ON", MatchAny, "USING") ||
2357                          TailMatches4("INDEX", "ON", MatchAny, "USING"))
2358                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2359         else if (TailMatches4("ON", MatchAny, "USING", MatchAny) &&
2360                          !TailMatches6("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
2361                          !TailMatches4("FOR", MatchAny, MatchAny, MatchAny))
2362                 COMPLETE_WITH_CONST("(");
2363
2364         /* CREATE POLICY */
2365         /* Complete "CREATE POLICY <name> ON" */
2366         else if (Matches3("CREATE", "POLICY", MatchAny))
2367                 COMPLETE_WITH_CONST("ON");
2368         /* Complete "CREATE POLICY <name> ON <table>" */
2369         else if (Matches4("CREATE", "POLICY", MatchAny, "ON"))
2370                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2371         /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
2372         else if (Matches5("CREATE", "POLICY", MatchAny, "ON", MatchAny))
2373                 COMPLETE_WITH_LIST5("AS", "FOR", "TO", "USING (", "WITH CHECK (");
2374         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
2375         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
2376                 COMPLETE_WITH_LIST2("PERMISSIVE", "RESTRICTIVE");
2377
2378         /*
2379          * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2380          * FOR|TO|USING|WITH CHECK
2381          */
2382         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
2383                 COMPLETE_WITH_LIST4("FOR", "TO", "USING", "WITH CHECK");
2384         /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2385         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
2386                 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2387         /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
2388         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
2389                 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2390         /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
2391         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
2392                 COMPLETE_WITH_LIST2("TO", "USING (");
2393         /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
2394         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
2395                 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2396         /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
2397         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
2398                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2399         /* Complete "CREATE POLICY <name> ON <table> USING (" */
2400         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
2401                 COMPLETE_WITH_CONST("(");
2402
2403         /*
2404          * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2405          * ALL|SELECT|INSERT|UPDATE|DELETE
2406          */
2407         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
2408                 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2409
2410         /*
2411          * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2412          * INSERT TO|WITH CHECK"
2413          */
2414         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
2415                 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2416
2417         /*
2418          * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2419          * SELECT|DELETE TO|USING"
2420          */
2421         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
2422                 COMPLETE_WITH_LIST2("TO", "USING (");
2423
2424         /*
2425          * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2426          * ALL|UPDATE TO|USING|WITH CHECK
2427          */
2428         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
2429                 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2430
2431         /*
2432          * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO
2433          * <role>"
2434          */
2435         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
2436                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2437
2438         /*
2439          * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2440          * USING ("
2441          */
2442         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
2443                 COMPLETE_WITH_CONST("(");
2444
2445
2446 /* CREATE PUBLICATION */
2447         else if (Matches3("CREATE", "PUBLICATION", MatchAny))
2448                 COMPLETE_WITH_LIST3("FOR TABLE", "FOR ALL TABLES", "WITH (");
2449         else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR"))
2450                 COMPLETE_WITH_LIST2("TABLE", "ALL TABLES");
2451         /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>" */
2452         else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR TABLE"))
2453                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2454         /* Complete "CREATE PUBLICATION <name> [...] WITH" */
2455         else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "("))
2456                 COMPLETE_WITH_CONST("publish");
2457
2458 /* CREATE RULE */
2459         /* Complete "CREATE RULE <sth>" with "AS ON" */
2460         else if (Matches3("CREATE", "RULE", MatchAny))
2461                 COMPLETE_WITH_CONST("AS ON");
2462         /* Complete "CREATE RULE <sth> AS" with "ON" */
2463         else if (Matches4("CREATE", "RULE", MatchAny, "AS"))
2464                 COMPLETE_WITH_CONST("ON");
2465         /* Complete "CREATE RULE <sth> AS ON" with SELECT|UPDATE|INSERT|DELETE */
2466         else if (Matches5("CREATE", "RULE", MatchAny, "AS", "ON"))
2467                 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE");
2468         /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
2469         else if (TailMatches3("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
2470                 COMPLETE_WITH_CONST("TO");
2471         /* Complete "AS ON <sth> TO" with a table name */
2472         else if (TailMatches4("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
2473                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2474
2475 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2476         else if (TailMatches3("CREATE", "SEQUENCE", MatchAny) ||
2477                          TailMatches4("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
2478                 COMPLETE_WITH_LIST8("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE",
2479                                                         "CYCLE", "OWNED BY", "START WITH");
2480         else if (TailMatches4("CREATE", "SEQUENCE", MatchAny, "NO") ||
2481                          TailMatches5("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
2482                 COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE");
2483
2484 /* CREATE SERVER <name> */
2485         else if (Matches3("CREATE", "SERVER", MatchAny))
2486                 COMPLETE_WITH_LIST3("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
2487
2488 /* CREATE STATISTICS <name> */
2489         else if (Matches3("CREATE", "STATISTICS", MatchAny))
2490                 COMPLETE_WITH_LIST2("(", "ON");
2491         else if (Matches4("CREATE", "STATISTICS", MatchAny, "("))
2492                 COMPLETE_WITH_LIST2("ndistinct", "dependencies");
2493         else if (HeadMatches3("CREATE", "STATISTICS", MatchAny) &&
2494                          previous_words[0][0] == '(' &&
2495                          previous_words[0][strlen(previous_words[0]) - 1] == ')')
2496                 COMPLETE_WITH_CONST("ON");
2497         else if (HeadMatches3("CREATE", "STATISTICS", MatchAny) &&
2498                          TailMatches1("FROM"))
2499                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2500
2501 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2502         /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
2503         else if (TailMatches2("CREATE", "TEMP|TEMPORARY"))
2504                 COMPLETE_WITH_LIST3("SEQUENCE", "TABLE", "VIEW");
2505         /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
2506         else if (TailMatches2("CREATE", "UNLOGGED"))
2507                 COMPLETE_WITH_LIST2("TABLE", "MATERIALIZED VIEW");
2508         /* Complete PARTITION BY with RANGE ( or LIST ( or ... */
2509         else if (TailMatches2("PARTITION", "BY"))
2510                 COMPLETE_WITH_LIST2("RANGE (", "LIST (");
2511         /* If we have xxx PARTITION OF, provide a list of partitioned tables */
2512         else if (TailMatches2("PARTITION", "OF"))
2513                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, "");
2514         /* Limited completion support for partition bound specification */
2515         else if (TailMatches3("PARTITION", "OF", MatchAny))
2516                 COMPLETE_WITH_LIST2("FOR VALUES", "DEFAULT");
2517
2518 /* CREATE TABLESPACE */
2519         else if (Matches3("CREATE", "TABLESPACE", MatchAny))
2520                 COMPLETE_WITH_LIST2("OWNER", "LOCATION");
2521         /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
2522         else if (Matches5("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
2523                 COMPLETE_WITH_CONST("LOCATION");
2524
2525 /* CREATE TEXT SEARCH */
2526         else if (Matches3("CREATE", "TEXT", "SEARCH"))
2527                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2528         else if (Matches5("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2529                 COMPLETE_WITH_CONST("(");
2530
2531 /* CREATE SUBSCRIPTION */
2532         else if (Matches3("CREATE", "SUBSCRIPTION", MatchAny))
2533                 COMPLETE_WITH_CONST("CONNECTION");
2534         else if (Matches5("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny))
2535                 COMPLETE_WITH_CONST("PUBLICATION");
2536         else if (Matches6("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",
2537                                           MatchAny, "PUBLICATION"))
2538         {
2539                 /* complete with nothing here as this refers to remote publications */
2540         }
2541         else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("PUBLICATION", MatchAny))
2542                 COMPLETE_WITH_CONST("WITH (");
2543         /* Complete "CREATE SUBSCRIPTION <name> ...  WITH ( <opt>" */
2544         else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("WITH", "("))
2545                 COMPLETE_WITH_LIST6("copy_data", "connect", "create_slot", "enabled",
2546                                                         "slot_name", "synchronous_commit");
2547
2548 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
2549         /* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
2550         else if (TailMatches3("CREATE", "TRIGGER", MatchAny))
2551                 COMPLETE_WITH_LIST3("BEFORE", "AFTER", "INSTEAD OF");
2552         /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
2553         else if (TailMatches4("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
2554                 COMPLETE_WITH_LIST4("INSERT", "DELETE", "UPDATE", "TRUNCATE");
2555         /* complete CREATE TRIGGER <name> INSTEAD OF with an event */
2556         else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
2557                 COMPLETE_WITH_LIST3("INSERT", "DELETE", "UPDATE");
2558         /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
2559         else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
2560                          TailMatches6("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
2561                 COMPLETE_WITH_LIST2("ON", "OR");
2562
2563         /*
2564          * complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of
2565          * tables
2566          */
2567         else if (TailMatches6("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
2568                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2569         /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */
2570         else if (TailMatches7("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
2571                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
2572         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("ON", MatchAny))
2573                 COMPLETE_WITH_LIST7("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2574                                                         "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2575         else if (HeadMatches2("CREATE", "TRIGGER") &&
2576                          (TailMatches1("DEFERRABLE") || TailMatches2("INITIALLY", "IMMEDIATE|DEFERRED")))
2577                 COMPLETE_WITH_LIST4("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2578         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("REFERENCING"))
2579                 COMPLETE_WITH_LIST2("OLD TABLE", "NEW TABLE");
2580         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("OLD|NEW", "TABLE"))
2581                 COMPLETE_WITH_CONST("AS");
2582         else if (HeadMatches2("CREATE", "TRIGGER") &&
2583                          (TailMatches5("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
2584                           TailMatches4("REFERENCING", "OLD", "TABLE", MatchAny)))
2585                 COMPLETE_WITH_LIST4("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2586         else if (HeadMatches2("CREATE", "TRIGGER") &&
2587                          (TailMatches5("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
2588                           TailMatches4("REFERENCING", "NEW", "TABLE", MatchAny)))
2589                 COMPLETE_WITH_LIST4("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2590         else if (HeadMatches2("CREATE", "TRIGGER") &&
2591                          (TailMatches9("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2592                           TailMatches8("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2593                           TailMatches8("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
2594                           TailMatches7("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
2595                 COMPLETE_WITH_LIST3("FOR", "WHEN (", "EXECUTE PROCEDURE");
2596         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("FOR"))
2597                 COMPLETE_WITH_LIST3("EACH", "ROW", "STATEMENT");
2598         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("FOR", "EACH"))
2599                 COMPLETE_WITH_LIST2("ROW", "STATEMENT");
2600         else if (HeadMatches2("CREATE", "TRIGGER") &&
2601                          (TailMatches3("FOR", "EACH", "ROW|STATEMENT") ||
2602                           TailMatches2("FOR", "ROW|STATEMENT")))
2603                 COMPLETE_WITH_LIST2("WHEN (", "EXECUTE PROCEDURE");
2604         /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE */
2605         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("EXECUTE"))
2606                 COMPLETE_WITH_CONST("PROCEDURE");
2607         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("EXECUTE", "PROCEDURE"))
2608                 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2609
2610 /* CREATE ROLE,USER,GROUP <name> */
2611         else if (Matches3("CREATE", "ROLE|GROUP|USER", MatchAny) &&
2612                          !TailMatches2("USER", "MAPPING"))
2613         {
2614                 static const char *const list_CREATEROLE[] =
2615                 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2616                         "ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2617                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2618                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2619                         "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2620                 "VALID UNTIL", "WITH", NULL};
2621
2622                 COMPLETE_WITH_LIST(list_CREATEROLE);
2623         }
2624
2625 /* CREATE ROLE,USER,GROUP <name> WITH */
2626         else if (Matches4("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
2627         {
2628                 /* Similar to the above, but don't complete "WITH" again. */
2629                 static const char *const list_CREATEROLE_WITH[] =
2630                 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2631                         "ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2632                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2633                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2634                         "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2635                 "VALID UNTIL", NULL};
2636
2637                 COMPLETE_WITH_LIST(list_CREATEROLE_WITH);
2638         }
2639
2640         /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
2641         else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
2642                 COMPLETE_WITH_LIST2("GROUP", "ROLE");
2643
2644 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
2645         /* Complete CREATE VIEW <name> with AS */
2646         else if (TailMatches3("CREATE", "VIEW", MatchAny))
2647                 COMPLETE_WITH_CONST("AS");
2648         /* Complete "CREATE VIEW <sth> AS with "SELECT" */
2649         else if (TailMatches4("CREATE", "VIEW", MatchAny, "AS"))
2650                 COMPLETE_WITH_CONST("SELECT");
2651
2652 /* CREATE MATERIALIZED VIEW */
2653         else if (Matches2("CREATE", "MATERIALIZED"))
2654                 COMPLETE_WITH_CONST("VIEW");
2655         /* Complete CREATE MATERIALIZED VIEW <name> with AS */
2656         else if (Matches4("CREATE", "MATERIALIZED", "VIEW", MatchAny))
2657                 COMPLETE_WITH_CONST("AS");
2658         /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
2659         else if (Matches5("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
2660                 COMPLETE_WITH_CONST("SELECT");
2661
2662 /* CREATE EVENT TRIGGER */
2663         else if (Matches2("CREATE", "EVENT"))
2664                 COMPLETE_WITH_CONST("TRIGGER");
2665         /* Complete CREATE EVENT TRIGGER <name> with ON */
2666         else if (Matches4("CREATE", "EVENT", "TRIGGER", MatchAny))
2667                 COMPLETE_WITH_CONST("ON");
2668         /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
2669         else if (Matches5("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
2670                 COMPLETE_WITH_LIST3("ddl_command_start", "ddl_command_end", "sql_drop");
2671
2672 /* DEALLOCATE */
2673         else if (Matches1("DEALLOCATE"))
2674                 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2675
2676 /* DECLARE */
2677         else if (Matches2("DECLARE", MatchAny))
2678                 COMPLETE_WITH_LIST5("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL",
2679                                                         "CURSOR");
2680         else if (HeadMatches1("DECLARE") && TailMatches1("CURSOR"))
2681                 COMPLETE_WITH_LIST3("WITH HOLD", "WITHOUT HOLD", "FOR");
2682
2683 /* DELETE --- can be inside EXPLAIN, RULE, etc */
2684         /* ... despite which, only complete DELETE with FROM at start of line */
2685         else if (Matches1("DELETE"))
2686                 COMPLETE_WITH_CONST("FROM");
2687         /* Complete DELETE FROM with a list of tables */
2688         else if (TailMatches2("DELETE", "FROM"))
2689                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2690         /* Complete DELETE FROM <table> */
2691         else if (TailMatches3("DELETE", "FROM", MatchAny))
2692                 COMPLETE_WITH_LIST2("USING", "WHERE");
2693         /* XXX: implement tab completion for DELETE ... USING */
2694
2695 /* DISCARD */
2696         else if (Matches1("DISCARD"))
2697                 COMPLETE_WITH_LIST4("ALL", "PLANS", "SEQUENCES", "TEMP");
2698
2699 /* DO */
2700         else if (Matches1("DO"))
2701                 COMPLETE_WITH_CONST("LANGUAGE");
2702
2703 /* DROP */
2704         /* Complete DROP object with CASCADE / RESTRICT */
2705         else if (Matches3("DROP",
2706                                           "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW",
2707                                           MatchAny) ||
2708                          Matches4("DROP", "ACCESS", "METHOD", MatchAny) ||
2709                          (Matches4("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) &&
2710                           ends_with(prev_wd, ')')) ||
2711                          Matches4("DROP", "EVENT", "TRIGGER", MatchAny) ||
2712                          Matches5("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
2713                          Matches4("DROP", "FOREIGN", "TABLE", MatchAny) ||
2714                          Matches5("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
2715                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2716
2717         /* help completing some of the variants */
2718         else if (Matches3("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
2719                 COMPLETE_WITH_CONST("(");
2720         else if (Matches4("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "("))
2721                 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
2722         else if (Matches2("DROP", "FOREIGN"))
2723                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2724
2725         /* DROP INDEX */
2726         else if (Matches2("DROP", "INDEX"))
2727                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2728                                                                    " UNION SELECT 'CONCURRENTLY'");
2729         else if (Matches3("DROP", "INDEX", "CONCURRENTLY"))
2730                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2731         else if (Matches3("DROP", "INDEX", MatchAny))
2732                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2733         else if (Matches4("DROP", "INDEX", "CONCURRENTLY", MatchAny))
2734                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2735
2736         /* DROP MATERIALIZED VIEW */
2737         else if (Matches2("DROP", "MATERIALIZED"))
2738                 COMPLETE_WITH_CONST("VIEW");
2739         else if (Matches3("DROP", "MATERIALIZED", "VIEW"))
2740                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2741
2742         /* DROP OWNED BY */
2743         else if (Matches2("DROP", "OWNED"))
2744                 COMPLETE_WITH_CONST("BY");
2745         else if (Matches3("DROP", "OWNED", "BY"))
2746                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2747
2748         /* DROP TEXT SEARCH */
2749         else if (Matches3("DROP", "TEXT", "SEARCH"))
2750                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2751
2752         /* DROP TRIGGER */
2753         else if (Matches3("DROP", "TRIGGER", MatchAny))
2754                 COMPLETE_WITH_CONST("ON");
2755         else if (Matches4("DROP", "TRIGGER", MatchAny, "ON"))
2756         {
2757                 completion_info_charp = prev2_wd;
2758                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2759         }
2760         else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
2761                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2762
2763         /* DROP ACCESS METHOD */
2764         else if (Matches2("DROP", "ACCESS"))
2765                 COMPLETE_WITH_CONST("METHOD");
2766         else if (Matches3("DROP", "ACCESS", "METHOD"))
2767                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2768
2769         /* DROP EVENT TRIGGER */
2770         else if (Matches2("DROP", "EVENT"))
2771                 COMPLETE_WITH_CONST("TRIGGER");
2772         else if (Matches3("DROP", "EVENT", "TRIGGER"))
2773                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2774
2775         /* DROP POLICY <name>  */
2776         else if (Matches2("DROP", "POLICY"))
2777                 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2778         /* DROP POLICY <name> ON */
2779         else if (Matches3("DROP", "POLICY", MatchAny))
2780                 COMPLETE_WITH_CONST("ON");
2781         /* DROP POLICY <name> ON <table> */
2782         else if (Matches4("DROP", "POLICY", MatchAny, "ON"))
2783         {
2784                 completion_info_charp = prev2_wd;
2785                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
2786         }
2787
2788         /* DROP RULE */
2789         else if (Matches3("DROP", "RULE", MatchAny))
2790                 COMPLETE_WITH_CONST("ON");
2791         else if (Matches4("DROP", "RULE", MatchAny, "ON"))
2792         {
2793                 completion_info_charp = prev2_wd;
2794                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2795         }
2796         else if (Matches5("DROP", "RULE", MatchAny, "ON", MatchAny))
2797                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2798
2799 /* EXECUTE */
2800         else if (Matches1("EXECUTE"))
2801                 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2802
2803 /* EXPLAIN */
2804
2805         /*
2806          * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands
2807          */
2808         else if (Matches1("EXPLAIN"))
2809                 COMPLETE_WITH_LIST7("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2810                                                         "ANALYZE", "VERBOSE");
2811         else if (Matches2("EXPLAIN", "ANALYZE"))
2812                 COMPLETE_WITH_LIST6("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2813                                                         "VERBOSE");
2814         else if (Matches2("EXPLAIN", "VERBOSE") ||
2815                          Matches3("EXPLAIN", "ANALYZE", "VERBOSE"))
2816                 COMPLETE_WITH_LIST5("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE");
2817
2818 /* FETCH && MOVE */
2819         /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
2820         else if (Matches1("FETCH|MOVE"))
2821                 COMPLETE_WITH_LIST4("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE");
2822         /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
2823         else if (Matches2("FETCH|MOVE", MatchAny))
2824                 COMPLETE_WITH_LIST3("ALL", "NEXT", "PRIOR");
2825
2826         /*
2827          * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
2828          * but we may as well tab-complete both: perhaps some users prefer one
2829          * variant or the other.
2830          */
2831         else if (Matches3("FETCH|MOVE", MatchAny, MatchAny))
2832                 COMPLETE_WITH_LIST2("FROM", "IN");
2833
2834 /* FOREIGN DATA WRAPPER */
2835         /* applies in ALTER/DROP FDW and in CREATE SERVER */
2836         else if (TailMatches3("FOREIGN", "DATA", "WRAPPER") &&
2837                          !TailMatches4("CREATE", MatchAny, MatchAny, MatchAny))
2838                 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
2839         /* applies in CREATE SERVER */
2840         else if (TailMatches4("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
2841                          HeadMatches2("CREATE", "SERVER"))
2842                 COMPLETE_WITH_CONST("OPTIONS");
2843
2844 /* FOREIGN TABLE */
2845         else if (TailMatches2("FOREIGN", "TABLE") &&
2846                          !TailMatches3("CREATE", MatchAny, MatchAny))
2847                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
2848
2849 /* FOREIGN SERVER */
2850         else if (TailMatches2("FOREIGN", "SERVER"))
2851                 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
2852
2853 /*
2854  * GRANT and REVOKE are allowed inside CREATE SCHEMA and
2855  * ALTER DEFAULT PRIVILEGES, so use TailMatches
2856  */
2857         /* Complete GRANT/REVOKE with a list of roles and privileges */
2858         else if (TailMatches1("GRANT|REVOKE"))
2859         {
2860                 /*
2861                  * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable
2862                  * privileges (can't grant roles)
2863                  */
2864                 if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES"))
2865                         COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE",
2866                                                                  "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2867                                                                  "EXECUTE", "USAGE", "ALL");
2868                 else
2869                         COMPLETE_WITH_QUERY(Query_for_list_of_roles
2870                                                                 " UNION SELECT 'SELECT'"
2871                                                                 " UNION SELECT 'INSERT'"
2872                                                                 " UNION SELECT 'UPDATE'"
2873                                                                 " UNION SELECT 'DELETE'"
2874                                                                 " UNION SELECT 'TRUNCATE'"
2875                                                                 " UNION SELECT 'REFERENCES'"
2876                                                                 " UNION SELECT 'TRIGGER'"
2877                                                                 " UNION SELECT 'CREATE'"
2878                                                                 " UNION SELECT 'CONNECT'"
2879                                                                 " UNION SELECT 'TEMPORARY'"
2880                                                                 " UNION SELECT 'EXECUTE'"
2881                                                                 " UNION SELECT 'USAGE'"
2882                                                                 " UNION SELECT 'ALL'");
2883         }
2884
2885         /*
2886          * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
2887          * TO/FROM
2888          */
2889         else if (TailMatches2("GRANT|REVOKE", MatchAny))
2890         {
2891                 if (TailMatches1("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
2892                         COMPLETE_WITH_CONST("ON");
2893                 else if (TailMatches2("GRANT", MatchAny))
2894                         COMPLETE_WITH_CONST("TO");
2895                 else
2896                         COMPLETE_WITH_CONST("FROM");
2897         }
2898
2899         /*
2900          * Complete GRANT/REVOKE <sth> ON with a list of tables, views, and
2901          * sequences.
2902          *
2903          * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query
2904          * result via UNION; seems to work intuitively.
2905          *
2906          * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
2907          * here will only work if the privilege list contains exactly one
2908          * privilege.
2909          */
2910         else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON"))
2911         {
2912                 /*
2913                  * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of
2914                  * objects supported.
2915                  */
2916                 if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES"))
2917                         COMPLETE_WITH_LIST7("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS");
2918                 else
2919                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf,
2920                                                                            " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
2921                                                                            " UNION SELECT 'ALL PROCEDURES IN SCHEMA'"
2922                                                                            " UNION SELECT 'ALL ROUTINES IN SCHEMA'"
2923                                                                            " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
2924                                                                            " UNION SELECT 'ALL TABLES IN SCHEMA'"
2925                                                                            " UNION SELECT 'DATABASE'"
2926                                                                            " UNION SELECT 'DOMAIN'"
2927                                                                            " UNION SELECT 'FOREIGN DATA WRAPPER'"
2928                                                                            " UNION SELECT 'FOREIGN SERVER'"
2929                                                                            " UNION SELECT 'FUNCTION'"
2930                                                                            " UNION SELECT 'LANGUAGE'"
2931                                                                            " UNION SELECT 'LARGE OBJECT'"
2932                                                                            " UNION SELECT 'PROCEDURE'"
2933                                                                            " UNION SELECT 'ROUTINE'"
2934                                                                            " UNION SELECT 'SCHEMA'"
2935                                                                            " UNION SELECT 'SEQUENCE'"
2936                                                                            " UNION SELECT 'TABLE'"
2937                                                                            " UNION SELECT 'TABLESPACE'"
2938                                                                            " UNION SELECT 'TYPE'");
2939         }
2940         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "ALL"))
2941                 COMPLETE_WITH_LIST5("FUNCTIONS IN SCHEMA",
2942                                                         "PROCEDURES IN SCHEMA",
2943                                                         "ROUTINES IN SCHEMA",
2944                                                         "SEQUENCES IN SCHEMA",
2945                                                         "TABLES IN SCHEMA");
2946         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"))
2947                 COMPLETE_WITH_LIST2("DATA WRAPPER", "SERVER");
2948
2949         /*
2950          * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
2951          * appropriate objects.
2952          *
2953          * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
2954          */
2955         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", MatchAny))
2956         {
2957                 if (TailMatches1("DATABASE"))
2958                         COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2959                 else if (TailMatches1("DOMAIN"))
2960                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
2961                 else if (TailMatches1("FUNCTION"))
2962                         COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2963                 else if (TailMatches1("LANGUAGE"))
2964                         COMPLETE_WITH_QUERY(Query_for_list_of_languages);
2965                 else if (TailMatches1("PROCEDURE"))
2966                         COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
2967                 else if (TailMatches1("ROUTINE"))
2968                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
2969                 else if (TailMatches1("SCHEMA"))
2970                         COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2971                 else if (TailMatches1("SEQUENCE"))
2972                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
2973                 else if (TailMatches1("TABLE"))
2974                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
2975                 else if (TailMatches1("TABLESPACE"))
2976                         COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
2977                 else if (TailMatches1("TYPE"))
2978                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
2979                 else if (TailMatches4("GRANT", MatchAny, MatchAny, MatchAny))
2980                         COMPLETE_WITH_CONST("TO");
2981                 else
2982                         COMPLETE_WITH_CONST("FROM");
2983         }
2984
2985         /*
2986          * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
2987          * CURRENT_USER, or SESSION_USER.
2988          */
2989         else if ((HeadMatches1("GRANT") && TailMatches1("TO")) ||
2990                          (HeadMatches1("REVOKE") && TailMatches1("FROM")))
2991                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2992         /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
2993         else if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM"))
2994                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2995         /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
2996         else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny))
2997                 COMPLETE_WITH_CONST("TO");
2998         else if (HeadMatches1("REVOKE") && TailMatches3("ON", MatchAny, MatchAny))
2999                 COMPLETE_WITH_CONST("FROM");
3000
3001         /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
3002         else if (TailMatches8("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
3003         {
3004                 if (TailMatches8("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3005                         COMPLETE_WITH_CONST("TO");
3006                 else
3007                         COMPLETE_WITH_CONST("FROM");
3008         }
3009
3010         /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
3011         else if (TailMatches7("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
3012         {
3013                 if (TailMatches7("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3014                         COMPLETE_WITH_CONST("TO");
3015                 else
3016                         COMPLETE_WITH_CONST("FROM");
3017         }
3018
3019         /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
3020         else if (TailMatches6("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
3021         {
3022                 if (TailMatches6("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3023                         COMPLETE_WITH_CONST("TO");
3024                 else
3025                         COMPLETE_WITH_CONST("FROM");
3026         }
3027
3028 /* GROUP BY */
3029         else if (TailMatches3("FROM", MatchAny, "GROUP"))
3030                 COMPLETE_WITH_CONST("BY");
3031
3032 /* IMPORT FOREIGN SCHEMA */
3033         else if (Matches1("IMPORT"))
3034                 COMPLETE_WITH_CONST("FOREIGN SCHEMA");
3035         else if (Matches2("IMPORT", "FOREIGN"))
3036                 COMPLETE_WITH_CONST("SCHEMA");
3037
3038 /* INSERT --- can be inside EXPLAIN, RULE, etc */
3039         /* Complete INSERT with "INTO" */
3040         else if (TailMatches1("INSERT"))
3041                 COMPLETE_WITH_CONST("INTO");
3042         /* Complete INSERT INTO with table names */
3043         else if (TailMatches2("INSERT", "INTO"))
3044                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3045         /* Complete "INSERT INTO <table> (" with attribute names */
3046         else if (TailMatches4("INSERT", "INTO", MatchAny, "("))
3047                 COMPLETE_WITH_ATTR(prev2_wd, "");
3048
3049         /*
3050          * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
3051          * "TABLE" or "DEFAULT VALUES" or "OVERRIDING"
3052          */
3053         else if (TailMatches3("INSERT", "INTO", MatchAny))
3054                 COMPLETE_WITH_LIST6("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING");
3055
3056         /*
3057          * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
3058          * "TABLE" or "OVERRIDING"
3059          */
3060         else if (TailMatches4("INSERT", "INTO", MatchAny, MatchAny) &&
3061                          ends_with(prev_wd, ')'))
3062                 COMPLETE_WITH_LIST4("SELECT", "TABLE", "VALUES", "OVERRIDING");
3063
3064         /* Complete OVERRIDING */
3065         else if (TailMatches1("OVERRIDING"))
3066                 COMPLETE_WITH_LIST2("SYSTEM VALUE", "USER VALUE");
3067
3068         /* Complete after OVERRIDING clause */
3069         else if (TailMatches3("OVERRIDING", MatchAny, "VALUE"))
3070                 COMPLETE_WITH_LIST3("SELECT", "TABLE", "VALUES");
3071
3072         /* Insert an open parenthesis after "VALUES" */
3073         else if (TailMatches1("VALUES") && !TailMatches2("DEFAULT", "VALUES"))
3074                 COMPLETE_WITH_CONST("(");
3075
3076 /* LOCK */
3077         /* Complete LOCK [TABLE] with a list of tables */
3078         else if (Matches1("LOCK"))
3079                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
3080                                                                    " UNION SELECT 'TABLE'");
3081         else if (Matches2("LOCK", "TABLE"))
3082                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
3083
3084         /* For the following, handle the case of a single table only for now */
3085
3086         /* Complete LOCK [TABLE] <table> with "IN" */
3087         else if (Matches2("LOCK", MatchAnyExcept("TABLE")) ||
3088                          Matches3("LOCK", "TABLE", MatchAny))
3089                 COMPLETE_WITH_CONST("IN");
3090
3091         /* Complete LOCK [TABLE] <table> IN with a lock mode */
3092         else if (Matches3("LOCK", MatchAny, "IN") ||
3093                          Matches4("LOCK", "TABLE", MatchAny, "IN"))
3094                 COMPLETE_WITH_LIST8("ACCESS SHARE MODE",
3095                                                         "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
3096                                                         "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
3097                                                         "SHARE ROW EXCLUSIVE MODE",
3098                                                         "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
3099
3100         /* Complete LOCK [TABLE] <table> IN ACCESS|ROW with rest of lock mode */
3101         else if (Matches4("LOCK", MatchAny, "IN", "ACCESS|ROW") ||
3102                          Matches5("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW"))
3103                 COMPLETE_WITH_LIST2("EXCLUSIVE MODE", "SHARE MODE");
3104
3105         /* Complete LOCK [TABLE] <table> IN SHARE with rest of lock mode */
3106         else if (Matches4("LOCK", MatchAny, "IN", "SHARE") ||
3107                          Matches5("LOCK", "TABLE", MatchAny, "IN", "SHARE"))
3108                 COMPLETE_WITH_LIST3("MODE", "ROW EXCLUSIVE MODE",
3109                                                         "UPDATE EXCLUSIVE MODE");
3110
3111 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
3112         else if (TailMatches1("NOTIFY"))
3113                 COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(channel) FROM pg_catalog.pg_listening_channels() AS channel WHERE substring(pg_catalog.quote_ident(channel),1,%d)='%s'");
3114
3115 /* OPTIONS */
3116         else if (TailMatches1("OPTIONS"))
3117                 COMPLETE_WITH_CONST("(");
3118
3119 /* OWNER TO  - complete with available roles */
3120         else if (TailMatches2("OWNER", "TO"))
3121                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3122
3123 /* ORDER BY */
3124         else if (TailMatches3("FROM", MatchAny, "ORDER"))
3125                 COMPLETE_WITH_CONST("BY");
3126         else if (TailMatches4("FROM", MatchAny, "ORDER", "BY"))
3127                 COMPLETE_WITH_ATTR(prev3_wd, "");
3128
3129 /* PREPARE xx AS */
3130         else if (Matches3("PREPARE", MatchAny, "AS"))
3131                 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE FROM");
3132
3133 /*
3134  * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
3135  * managers, not for manual use in interactive sessions.
3136  */
3137
3138 /* REASSIGN OWNED BY xxx TO yyy */
3139         else if (Matches1("REASSIGN"))
3140                 COMPLETE_WITH_CONST("OWNED BY");
3141         else if (Matches2("REASSIGN", "OWNED"))
3142                 COMPLETE_WITH_CONST("BY");
3143         else if (Matches3("REASSIGN", "OWNED", "BY"))
3144                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3145         else if (Matches4("REASSIGN", "OWNED", "BY", MatchAny))
3146                 COMPLETE_WITH_CONST("TO");
3147         else if (Matches5("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
3148                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3149
3150 /* REFRESH MATERIALIZED VIEW */
3151         else if (Matches1("REFRESH"))
3152                 COMPLETE_WITH_CONST("MATERIALIZED VIEW");
3153         else if (Matches2("REFRESH", "MATERIALIZED"))
3154                 COMPLETE_WITH_CONST("VIEW");
3155         else if (Matches3("REFRESH", "MATERIALIZED", "VIEW"))
3156                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
3157                                                                    " UNION SELECT 'CONCURRENTLY'");
3158         else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
3159                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3160         else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
3161                 COMPLETE_WITH_CONST("WITH");
3162         else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
3163                 COMPLETE_WITH_CONST("WITH");
3164         else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
3165                 COMPLETE_WITH_LIST2("NO DATA", "DATA");
3166         else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
3167                 COMPLETE_WITH_LIST2("NO DATA", "DATA");
3168         else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
3169                 COMPLETE_WITH_CONST("DATA");
3170         else if (Matches7("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
3171                 COMPLETE_WITH_CONST("DATA");
3172
3173 /* REINDEX */
3174         else if (Matches1("REINDEX"))
3175                 COMPLETE_WITH_LIST5("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
3176         else if (Matches2("REINDEX", "TABLE"))
3177                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
3178         else if (Matches2("REINDEX", "INDEX"))
3179                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3180         else if (Matches2("REINDEX", "SCHEMA"))
3181                 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3182         else if (Matches2("REINDEX", "SYSTEM|DATABASE"))
3183                 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3184
3185 /* SECURITY LABEL */
3186         else if (Matches1("SECURITY"))
3187                 COMPLETE_WITH_CONST("LABEL");
3188         else if (Matches2("SECURITY", "LABEL"))
3189                 COMPLETE_WITH_LIST2("ON", "FOR");
3190         else if (Matches4("SECURITY", "LABEL", "FOR", MatchAny))
3191                 COMPLETE_WITH_CONST("ON");
3192         else if (Matches3("SECURITY", "LABEL", "ON") ||
3193                          Matches5("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
3194         {
3195                 static const char *const list_SECURITY_LABEL[] =
3196                 {"TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
3197                         "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", "LARGE OBJECT",
3198                         "MATERIALIZED VIEW", "LANGUAGE", "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA",
3199                 "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW", NULL};
3200
3201                 COMPLETE_WITH_LIST(list_SECURITY_LABEL);
3202         }
3203         else if (Matches5("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
3204                 COMPLETE_WITH_CONST("IS");
3205
3206 /* SELECT */
3207         /* naah . . . */
3208
3209 /* SET, RESET, SHOW */
3210         /* Complete with a variable name */
3211         else if (TailMatches1("SET|RESET") && !TailMatches3("UPDATE", MatchAny, "SET"))
3212                 COMPLETE_WITH_QUERY(Query_for_list_of_set_vars);
3213         else if (Matches1("SHOW"))
3214                 COMPLETE_WITH_QUERY(Query_for_list_of_show_vars);
3215         /* Complete "SET TRANSACTION" */
3216         else if (Matches2("SET", "TRANSACTION"))
3217                 COMPLETE_WITH_LIST5("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3218         else if (Matches2("BEGIN|START", "TRANSACTION") ||
3219                          Matches2("BEGIN", "WORK") ||
3220                          Matches1("BEGIN") ||
3221                          Matches5("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
3222                 COMPLETE_WITH_LIST4("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3223         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
3224                          Matches2("BEGIN", "NOT") ||
3225                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
3226                 COMPLETE_WITH_CONST("DEFERRABLE");
3227         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
3228                          Matches2("BEGIN", "ISOLATION") ||
3229                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
3230                 COMPLETE_WITH_CONST("LEVEL");
3231         else if (Matches4("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
3232                          Matches3("BEGIN", "ISOLATION", "LEVEL") ||
3233                          Matches7("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
3234                 COMPLETE_WITH_LIST3("READ", "REPEATABLE READ", "SERIALIZABLE");
3235         else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
3236                          Matches4("BEGIN", "ISOLATION", "LEVEL", "READ") ||
3237                          Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
3238                 COMPLETE_WITH_LIST2("UNCOMMITTED", "COMMITTED");
3239         else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
3240                          Matches4("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
3241                          Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
3242                 COMPLETE_WITH_CONST("READ");
3243         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
3244                          Matches2("BEGIN", "READ") ||
3245                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
3246                 COMPLETE_WITH_LIST2("ONLY", "WRITE");
3247         /* SET CONSTRAINTS */
3248         else if (Matches2("SET", "CONSTRAINTS"))
3249                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'");
3250         /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
3251         else if (Matches3("SET", "CONSTRAINTS", MatchAny))
3252                 COMPLETE_WITH_LIST2("DEFERRED", "IMMEDIATE");
3253         /* Complete SET ROLE */
3254         else if (Matches2("SET", "ROLE"))
3255                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3256         /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
3257         else if (Matches2("SET", "SESSION"))
3258                 COMPLETE_WITH_LIST2("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
3259         /* Complete SET SESSION AUTHORIZATION with username */
3260         else if (Matches3("SET", "SESSION", "AUTHORIZATION"))
3261                 COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'");
3262         /* Complete RESET SESSION with AUTHORIZATION */
3263         else if (Matches2("RESET", "SESSION"))
3264                 COMPLETE_WITH_CONST("AUTHORIZATION");
3265         /* Complete SET <var> with "TO" */
3266         else if (Matches2("SET", MatchAny))
3267                 COMPLETE_WITH_CONST("TO");
3268
3269         /*
3270          * Complete ALTER DATABASE|FUNCTION||PROCEDURE|ROLE|ROUTINE|USER ... SET
3271          * <name>
3272          */
3273         else if (HeadMatches2("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") &&
3274                          TailMatches2("SET", MatchAny))
3275                 COMPLETE_WITH_LIST2("FROM CURRENT", "TO");
3276         /* Suggest possible variable values */
3277         else if (TailMatches3("SET", MatchAny, "TO|="))
3278         {
3279                 /* special cased code for individual GUCs */
3280                 if (TailMatches2("DateStyle", "TO|="))
3281                 {
3282                         static const char *const my_list[] =
3283                         {"ISO", "SQL", "Postgres", "German",
3284                                 "YMD", "DMY", "MDY",
3285                                 "US", "European", "NonEuropean",
3286                         "DEFAULT", NULL};
3287
3288                         COMPLETE_WITH_LIST(my_list);
3289                 }
3290                 else if (TailMatches2("search_path", "TO|="))
3291                         COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3292                                                                 " AND nspname not like 'pg\\_toast%%' "
3293                                                                 " AND nspname not like 'pg\\_temp%%' "
3294                                                                 " UNION SELECT 'DEFAULT' ");
3295                 else
3296                 {
3297                         /* generic, type based, GUC support */
3298                         char       *guctype = get_guctype(prev2_wd);
3299
3300                         if (guctype && strcmp(guctype, "enum") == 0)
3301                         {
3302                                 char            querybuf[1024];
3303
3304                                 snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd);
3305                                 COMPLETE_WITH_QUERY(querybuf);
3306                         }
3307                         else if (guctype && strcmp(guctype, "bool") == 0)
3308                                 COMPLETE_WITH_LIST9("on", "off", "true", "false", "yes", "no",
3309                                                                         "1", "0", "DEFAULT");
3310                         else
3311                                 COMPLETE_WITH_CONST("DEFAULT");
3312
3313                         if (guctype)
3314                                 free(guctype);
3315                 }
3316         }
3317
3318 /* START TRANSACTION */
3319         else if (Matches1("START"))
3320                 COMPLETE_WITH_CONST("TRANSACTION");
3321
3322 /* TABLE, but not TABLE embedded in other commands */
3323         else if (Matches1("TABLE"))
3324                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3325
3326 /* TABLESAMPLE */
3327         else if (TailMatches1("TABLESAMPLE"))
3328                 COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
3329         else if (TailMatches2("TABLESAMPLE", MatchAny))
3330                 COMPLETE_WITH_CONST("(");
3331
3332 /* TRUNCATE */
3333         else if (Matches1("TRUNCATE"))
3334                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3335
3336 /* UNLISTEN */
3337         else if (Matches1("UNLISTEN"))
3338                 COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(channel) FROM pg_catalog.pg_listening_channels() AS channel WHERE substring(pg_catalog.quote_ident(channel),1,%d)='%s' UNION SELECT '*'");
3339
3340 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
3341         /* If prev. word is UPDATE suggest a list of tables */
3342         else if (TailMatches1("UPDATE"))
3343                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3344         /* Complete UPDATE <table> with "SET" */
3345         else if (TailMatches2("UPDATE", MatchAny))
3346                 COMPLETE_WITH_CONST("SET");
3347         /* Complete UPDATE <table> SET with list of attributes */
3348         else if (TailMatches3("UPDATE", MatchAny, "SET"))
3349                 COMPLETE_WITH_ATTR(prev2_wd, "");
3350         /* UPDATE <table> SET <attr> = */
3351         else if (TailMatches4("UPDATE", MatchAny, "SET", MatchAny))
3352                 COMPLETE_WITH_CONST("=");
3353
3354 /* USER MAPPING */
3355         else if (Matches3("ALTER|CREATE|DROP", "USER", "MAPPING"))
3356                 COMPLETE_WITH_CONST("FOR");
3357         else if (Matches4("CREATE", "USER", "MAPPING", "FOR"))
3358                 COMPLETE_WITH_QUERY(Query_for_list_of_roles
3359                                                         " UNION SELECT 'CURRENT_USER'"
3360                                                         " UNION SELECT 'PUBLIC'"
3361                                                         " UNION SELECT 'USER'");
3362         else if (Matches4("ALTER|DROP", "USER", "MAPPING", "FOR"))
3363                 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3364         else if (Matches5("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
3365                 COMPLETE_WITH_CONST("SERVER");
3366         else if (Matches7("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
3367                 COMPLETE_WITH_CONST("OPTIONS");
3368
3369 /*
3370  * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ]
3371  * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]
3372  */
3373         else if (Matches1("VACUUM"))
3374                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3375                                                                    " UNION SELECT 'FULL'"
3376                                                                    " UNION SELECT 'FREEZE'"
3377                                                                    " UNION SELECT 'ANALYZE'"
3378                                                                    " UNION SELECT 'VERBOSE'");
3379         else if (Matches2("VACUUM", "FULL|FREEZE"))
3380                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3381                                                                    " UNION SELECT 'ANALYZE'"
3382                                                                    " UNION SELECT 'VERBOSE'");
3383         else if (Matches3("VACUUM", "FULL|FREEZE", "ANALYZE"))
3384                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3385                                                                    " UNION SELECT 'VERBOSE'");
3386         else if (Matches3("VACUUM", "FULL|FREEZE", "VERBOSE"))
3387                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3388                                                                    " UNION SELECT 'ANALYZE'");
3389         else if (Matches2("VACUUM", "VERBOSE"))
3390                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3391                                                                    " UNION SELECT 'ANALYZE'");
3392         else if (Matches2("VACUUM", "ANALYZE"))
3393                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3394                                                                    " UNION SELECT 'VERBOSE'");
3395         else if (HeadMatches1("VACUUM"))
3396                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
3397
3398 /* WITH [RECURSIVE] */
3399
3400         /*
3401          * Only match when WITH is the first word, as WITH may appear in many
3402          * other contexts.
3403          */
3404         else if (Matches1("WITH"))
3405                 COMPLETE_WITH_CONST("RECURSIVE");
3406
3407 /* ANALYZE */
3408         /* Complete with list of tables */
3409         else if (Matches1("ANALYZE"))
3410                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tmf, NULL);
3411
3412 /* WHERE */
3413         /* Simple case of the word before the where being the table name */
3414         else if (TailMatches2(MatchAny, "WHERE"))
3415                 COMPLETE_WITH_ATTR(prev2_wd, "");
3416
3417 /* ... FROM ... */
3418 /* TODO: also include SRF ? */
3419         else if (TailMatches1("FROM") && !Matches3("COPY|\\copy", MatchAny, "FROM"))
3420                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3421
3422 /* ... JOIN ... */
3423         else if (TailMatches1("JOIN"))
3424                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3425
3426 /* Backslash commands */
3427 /* TODO:  \dc \dd \dl */
3428         else if (TailMatchesCS1("\\?"))
3429                 COMPLETE_WITH_LIST_CS3("commands", "options", "variables");
3430         else if (TailMatchesCS1("\\connect|\\c"))
3431         {
3432                 if (!recognized_connection_string(text))
3433                         COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3434         }
3435         else if (TailMatchesCS2("\\connect|\\c", MatchAny))
3436         {
3437                 if (!recognized_connection_string(prev_wd))
3438                         COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3439         }
3440         else if (TailMatchesCS1("\\da*"))
3441                 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
3442         else if (TailMatchesCS1("\\dA*"))
3443                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3444         else if (TailMatchesCS1("\\db*"))
3445                 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3446         else if (TailMatchesCS1("\\dD*"))
3447                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3448         else if (TailMatchesCS1("\\des*"))
3449                 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3450         else if (TailMatchesCS1("\\deu*"))
3451                 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3452         else if (TailMatchesCS1("\\dew*"))
3453                 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3454         else if (TailMatchesCS1("\\df*"))
3455                 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3456
3457         else if (TailMatchesCS1("\\dFd*"))
3458                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
3459         else if (TailMatchesCS1("\\dFp*"))
3460                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
3461         else if (TailMatchesCS1("\\dFt*"))
3462                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
3463         /* must be at end of \dF alternatives: */
3464         else if (TailMatchesCS1("\\dF*"))
3465                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
3466
3467         else if (TailMatchesCS1("\\di*"))
3468                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3469         else if (TailMatchesCS1("\\dL*"))
3470                 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3471         else if (TailMatchesCS1("\\dn*"))
3472                 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3473         else if (TailMatchesCS1("\\dp") || TailMatchesCS1("\\z"))
3474                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3475         else if (TailMatchesCS1("\\ds*"))
3476                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3477         else if (TailMatchesCS1("\\dt*"))
3478                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3479         else if (TailMatchesCS1("\\dT*"))
3480                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3481         else if (TailMatchesCS1("\\du*") || TailMatchesCS1("\\dg*"))
3482                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3483         else if (TailMatchesCS1("\\dv*"))
3484                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3485         else if (TailMatchesCS1("\\dx*"))
3486                 COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
3487         else if (TailMatchesCS1("\\dm*"))
3488                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3489         else if (TailMatchesCS1("\\dE*"))
3490                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
3491         else if (TailMatchesCS1("\\dy*"))
3492                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3493
3494         /* must be at end of \d alternatives: */
3495         else if (TailMatchesCS1("\\d*"))
3496                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3497
3498         else if (TailMatchesCS1("\\ef"))
3499                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3500         else if (TailMatchesCS1("\\ev"))
3501                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3502
3503         else if (TailMatchesCS1("\\encoding"))
3504                 COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
3505         else if (TailMatchesCS1("\\h|\\help"))
3506                 COMPLETE_WITH_LIST(sql_commands);
3507         else if (TailMatchesCS2("\\h|\\help", MatchAny))
3508         {
3509                 if (TailMatches1("DROP"))
3510                         matches = completion_matches(text, drop_command_generator);
3511                 else if (TailMatches1("ALTER"))
3512                         matches = completion_matches(text, alter_command_generator);
3513
3514                 /*
3515                  * CREATE is recognized by tail match elsewhere, so doesn't need to be
3516                  * repeated here
3517                  */
3518         }
3519         else if (TailMatchesCS3("\\h|\\help", MatchAny, MatchAny))
3520         {
3521                 if (TailMatches2("CREATE|DROP", "ACCESS"))
3522                         COMPLETE_WITH_CONST("METHOD");
3523                 else if (TailMatches2("ALTER", "DEFAULT"))
3524                         COMPLETE_WITH_CONST("PRIVILEGES");
3525                 else if (TailMatches2("CREATE|ALTER|DROP", "EVENT"))
3526                         COMPLETE_WITH_CONST("TRIGGER");
3527                 else if (TailMatches2("CREATE|ALTER|DROP", "FOREIGN"))
3528                         COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
3529                 else if (TailMatches2("ALTER", "LARGE"))
3530                         COMPLETE_WITH_CONST("OBJECT");
3531                 else if (TailMatches2("CREATE|ALTER|DROP", "MATERIALIZED"))
3532                         COMPLETE_WITH_CONST("VIEW");
3533                 else if (TailMatches2("CREATE|ALTER|DROP", "TEXT"))
3534                         COMPLETE_WITH_CONST("SEARCH");
3535                 else if (TailMatches2("CREATE|ALTER|DROP", "USER"))
3536                         COMPLETE_WITH_CONST("MAPPING FOR");
3537         }
3538         else if (TailMatchesCS4("\\h|\\help", MatchAny, MatchAny, MatchAny))
3539         {
3540                 if (TailMatches3("CREATE|ALTER|DROP", "FOREIGN", "DATA"))
3541                         COMPLETE_WITH_CONST("WRAPPER");
3542                 else if (TailMatches3("CREATE|ALTER|DROP", "TEXT", "SEARCH"))
3543                         COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
3544                 else if (TailMatches3("CREATE|ALTER|DROP", "USER", "MAPPING"))
3545                         COMPLETE_WITH_CONST("FOR");
3546         }
3547         else if (TailMatchesCS1("\\l*") && !TailMatchesCS1("\\lo*"))
3548                 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3549         else if (TailMatchesCS1("\\password"))
3550                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3551         else if (TailMatchesCS1("\\pset"))
3552         {
3553                 static const char *const my_list[] =
3554                 {"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
3555                         "footer", "format", "linestyle", "null", "numericlocale",
3556                         "pager", "pager_min_lines", "recordsep", "recordsep_zero",
3557                         "tableattr", "title", "tuples_only", "unicode_border_linestyle",
3558                 "unicode_column_linestyle", "unicode_header_linestyle", NULL};
3559
3560                 COMPLETE_WITH_LIST_CS(my_list);
3561         }
3562         else if (TailMatchesCS2("\\pset", MatchAny))
3563         {
3564                 if (TailMatchesCS1("format"))
3565                 {
3566                         static const char *const my_list[] =
3567                         {"unaligned", "aligned", "wrapped", "html", "asciidoc",
3568                         "latex", "latex-longtable", "troff-ms", NULL};
3569
3570                         COMPLETE_WITH_LIST_CS(my_list);
3571                 }
3572                 else if (TailMatchesCS1("linestyle"))
3573                         COMPLETE_WITH_LIST_CS3("ascii", "old-ascii", "unicode");
3574                 else if (TailMatchesCS1("pager"))
3575                         COMPLETE_WITH_LIST_CS3("on", "off", "always");
3576                 else if (TailMatchesCS1("unicode_border_linestyle|"
3577                                                                 "unicode_column_linestyle|"
3578                                                                 "unicode_header_linestyle"))
3579                         COMPLETE_WITH_LIST_CS2("single", "double");
3580         }
3581         else if (TailMatchesCS1("\\unset"))
3582                 matches = complete_from_variables(text, "", "", true);
3583         else if (TailMatchesCS1("\\set"))
3584                 matches = complete_from_variables(text, "", "", false);
3585         else if (TailMatchesCS2("\\set", MatchAny))
3586         {
3587                 if (TailMatchesCS1("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
3588                                                    "SINGLELINE|SINGLESTEP"))
3589                         COMPLETE_WITH_LIST_CS2("on", "off");
3590                 else if (TailMatchesCS1("COMP_KEYWORD_CASE"))
3591                         COMPLETE_WITH_LIST_CS4("lower", "upper",
3592                                                                    "preserve-lower", "preserve-upper");
3593                 else if (TailMatchesCS1("ECHO"))
3594                         COMPLETE_WITH_LIST_CS4("errors", "queries", "all", "none");
3595                 else if (TailMatchesCS1("ECHO_HIDDEN"))
3596                         COMPLETE_WITH_LIST_CS3("noexec", "off", "on");
3597                 else if (TailMatchesCS1("HISTCONTROL"))
3598                         COMPLETE_WITH_LIST_CS4("ignorespace", "ignoredups",
3599                                                                    "ignoreboth", "none");
3600                 else if (TailMatchesCS1("ON_ERROR_ROLLBACK"))
3601                         COMPLETE_WITH_LIST_CS3("on", "off", "interactive");
3602                 else if (TailMatchesCS1("SHOW_CONTEXT"))
3603                         COMPLETE_WITH_LIST_CS3("never", "errors", "always");
3604                 else if (TailMatchesCS1("VERBOSITY"))
3605                         COMPLETE_WITH_LIST_CS3("default", "verbose", "terse");
3606         }
3607         else if (TailMatchesCS1("\\sf*"))
3608                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3609         else if (TailMatchesCS1("\\sv*"))
3610                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3611         else if (TailMatchesCS1("\\cd|\\e|\\edit|\\g|\\i|\\include|"
3612                                                         "\\ir|\\include_relative|\\o|\\out|"
3613                                                         "\\s|\\w|\\write|\\lo_import"))
3614         {
3615                 completion_charp = "\\";
3616                 matches = completion_matches(text, complete_from_files);
3617         }
3618
3619         /*
3620          * Finally, we look through the list of "things", such as TABLE, INDEX and
3621          * check if that was the previous word. If so, execute the query to get a
3622          * list of them.
3623          */
3624         else
3625         {
3626                 int                     i;
3627
3628                 for (i = 0; words_after_create[i].name; i++)
3629                 {
3630                         if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
3631                         {
3632                                 if (words_after_create[i].query)
3633                                         COMPLETE_WITH_QUERY(words_after_create[i].query);
3634                                 else if (words_after_create[i].vquery)
3635                                         COMPLETE_WITH_VERSIONED_QUERY(words_after_create[i].vquery);
3636                                 else if (words_after_create[i].squery)
3637                                         COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(words_after_create[i].squery,
3638                                                                                                                  NULL);
3639                                 break;
3640                         }
3641                 }
3642         }
3643
3644         /*
3645          * If we still don't have anything to match we have to fabricate some sort
3646          * of default list. If we were to just return NULL, readline automatically
3647          * attempts filename completion, and that's usually no good.
3648          */
3649         if (matches == NULL)
3650         {
3651                 COMPLETE_WITH_CONST("");
3652 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
3653                 rl_completion_append_character = '\0';
3654 #endif
3655         }
3656
3657         /* free storage */
3658         free(previous_words);
3659         free(words_buffer);
3660
3661         /* Return our Grand List O' Matches */
3662         return matches;
3663 }
3664
3665
3666 /*
3667  * GENERATOR FUNCTIONS
3668  *
3669  * These functions do all the actual work of completing the input. They get
3670  * passed the text so far and the count how many times they have been called
3671  * so far with the same text.
3672  * If you read the above carefully, you'll see that these don't get called
3673  * directly but through the readline interface.
3674  * The return value is expected to be the full completion of the text, going
3675  * through a list each time, or NULL if there are no more matches. The string
3676  * will be free()'d by readline, so you must run it through strdup() or
3677  * something of that sort.
3678  */
3679
3680 /*
3681  * Common routine for create_command_generator and drop_command_generator.
3682  * Entries that have 'excluded' flags are not returned.
3683  */
3684 static char *
3685 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
3686 {
3687         static int      list_index,
3688                                 string_length;
3689         const char *name;
3690
3691         /* If this is the first time for this completion, init some values */
3692         if (state == 0)
3693         {
3694                 list_index = 0;
3695                 string_length = strlen(text);
3696         }
3697
3698         /* find something that matches */
3699         while ((name = words_after_create[list_index++].name))
3700         {
3701                 if ((pg_strncasecmp(name, text, string_length) == 0) &&
3702                         !(words_after_create[list_index - 1].flags & excluded))
3703                         return pg_strdup_keyword_case(name, text);
3704         }
3705         /* if nothing matches, return NULL */
3706         return NULL;
3707 }
3708
3709 /*
3710  * This one gives you one from a list of things you can put after CREATE
3711  * as defined above.
3712  */
3713 static char *
3714 create_command_generator(const char *text, int state)
3715 {
3716         return create_or_drop_command_generator(text, state, THING_NO_CREATE);
3717 }
3718
3719 /*
3720  * This function gives you a list of things you can put after a DROP command.
3721  */
3722 static char *
3723 drop_command_generator(const char *text, int state)
3724 {
3725         return create_or_drop_command_generator(text, state, THING_NO_DROP);
3726 }
3727
3728 /*
3729  * This function gives you a list of things you can put after an ALTER command.
3730  */
3731 static char *
3732 alter_command_generator(const char *text, int state)
3733 {
3734         return create_or_drop_command_generator(text, state, THING_NO_ALTER);
3735 }
3736
3737 /*
3738  * These functions generate lists using server queries.
3739  * They are all wrappers for _complete_from_query.
3740  */
3741
3742 static char *
3743 complete_from_query(const char *text, int state)
3744 {
3745         /* query is assumed to work for any server version */
3746         return _complete_from_query(completion_charp, NULL, text, state);
3747 }
3748
3749 static char *
3750 complete_from_versioned_query(const char *text, int state)
3751 {
3752         const VersionedQuery *vquery = completion_vquery;
3753
3754         /* Find appropriate array element */
3755         while (pset.sversion < vquery->min_server_version)
3756                 vquery++;
3757         /* Fail completion if server is too old */
3758         if (vquery->query == NULL)
3759                 return NULL;
3760
3761         return _complete_from_query(vquery->query, NULL, text, state);
3762 }
3763
3764 static char *
3765 complete_from_schema_query(const char *text, int state)
3766 {
3767         /* query is assumed to work for any server version */
3768         return _complete_from_query(completion_charp, completion_squery,
3769                                                                 text, state);
3770 }
3771
3772 static char *
3773 complete_from_versioned_schema_query(const char *text, int state)
3774 {
3775         const SchemaQuery *squery = completion_squery;
3776         const VersionedQuery *vquery = completion_vquery;
3777
3778         /* Find appropriate array element */
3779         while (pset.sversion < squery->min_server_version)
3780                 squery++;
3781         /* Fail completion if server is too old */
3782         if (squery->catname == NULL)
3783                 return NULL;
3784
3785         /* Likewise for the add-on text, if any */
3786         if (vquery)
3787         {
3788                 while (pset.sversion < vquery->min_server_version)
3789                         vquery++;
3790                 if (vquery->query == NULL)
3791                         return NULL;
3792         }
3793
3794         return _complete_from_query(vquery ? vquery->query : NULL,
3795                                                                 squery, text, state);
3796 }
3797
3798
3799 /*
3800  * This creates a list of matching things, according to a query described by
3801  * the initial arguments.  The caller has already done any work needed to
3802  * select the appropriate query for the server's version.
3803  *
3804  * The query can be one of two kinds:
3805  *
3806  * 1. A simple query which must contain a %d and a %s, which will be replaced
3807  * by the string length of the text and the text itself. The query may also
3808  * have up to four more %s in it; the first two such will be replaced by the
3809  * value of completion_info_charp, the next two by the value of
3810  * completion_info_charp2.
3811  *
3812  * 2. A schema query used for completion of both schema and relation names.
3813  * These are more complex and must contain in the following order:
3814  * %d %s %d %s %d %s %s %d %s
3815  * where %d is the string length of the text and %s the text itself.
3816  *
3817  * If both simple_query and schema_query are non-NULL, then we construct
3818  * a schema query and append the (uninterpreted) string simple_query to it.
3819  *
3820  * It is assumed that strings should be escaped to become SQL literals
3821  * (that is, what is in the query is actually ... '%s' ...)
3822  *
3823  * See top of file for examples of both kinds of query.
3824  *
3825  * "text" and "state" are supplied by readline.
3826  */
3827 static char *
3828 _complete_from_query(const char *simple_query,
3829                                          const SchemaQuery *schema_query,
3830                                          const char *text, int state)
3831 {
3832         static int      list_index,
3833                                 byte_length;
3834         static PGresult *result = NULL;
3835
3836         /*
3837          * If this is the first time for this completion, we fetch a list of our
3838          * "things" from the backend.
3839          */
3840         if (state == 0)
3841         {
3842                 PQExpBufferData query_buffer;
3843                 char       *e_text;
3844                 char       *e_info_charp;
3845                 char       *e_info_charp2;
3846                 const char *pstr = text;
3847                 int                     char_length = 0;
3848
3849                 list_index = 0;
3850                 byte_length = strlen(text);
3851
3852                 /*
3853                  * Count length as number of characters (not bytes), for passing to
3854                  * substring
3855                  */
3856                 while (*pstr)
3857                 {
3858                         char_length++;
3859                         pstr += PQmblen(pstr, pset.encoding);
3860                 }
3861
3862                 /* Free any prior result */
3863                 PQclear(result);
3864                 result = NULL;
3865
3866                 /* Set up suitably-escaped copies of textual inputs */
3867                 e_text = escape_string(text);
3868
3869                 if (completion_info_charp)
3870                         e_info_charp = escape_string(completion_info_charp);
3871                 else
3872                         e_info_charp = NULL;
3873
3874                 if (completion_info_charp2)
3875                         e_info_charp2 = escape_string(completion_info_charp2);
3876                 else
3877                         e_info_charp2 = NULL;
3878
3879                 initPQExpBuffer(&query_buffer);
3880
3881                 if (schema_query)
3882                 {
3883                         /* schema_query gives us the pieces to assemble */
3884                         const char *qualresult = schema_query->qualresult;
3885
3886                         if (qualresult == NULL)
3887                                 qualresult = schema_query->result;
3888
3889                         /* Get unqualified names matching the input-so-far */
3890                         appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
3891                                                           schema_query->result,
3892                                                           schema_query->catname);
3893                         if (schema_query->selcondition)
3894                                 appendPQExpBuffer(&query_buffer, "%s AND ",
3895                                                                   schema_query->selcondition);
3896                         appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
3897                                                           schema_query->result,
3898                                                           char_length, e_text);
3899                         appendPQExpBuffer(&query_buffer, " AND %s",
3900                                                           schema_query->viscondition);
3901
3902                         /*
3903                          * When fetching relation names, suppress system catalogs unless
3904                          * the input-so-far begins with "pg_".  This is a compromise
3905                          * between not offering system catalogs for completion at all, and
3906                          * having them swamp the result when the input is just "p".
3907                          */
3908                         if (strcmp(schema_query->catname,
3909                                            "pg_catalog.pg_class c") == 0 &&
3910                                 strncmp(text, "pg_", 3) !=0)
3911                         {
3912                                 appendPQExpBufferStr(&query_buffer,
3913                                                                          " AND c.relnamespace <> (SELECT oid FROM"
3914                                                                          " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
3915                         }
3916
3917                         /*
3918                          * Add in matching schema names, but only if there is more than
3919                          * one potential match among schema names.
3920                          */
3921                         appendPQExpBuffer(&query_buffer, "\nUNION\n"
3922                                                           "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
3923                                                           "FROM pg_catalog.pg_namespace n "
3924                                                           "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
3925                                                           char_length, e_text);
3926                         appendPQExpBuffer(&query_buffer,
3927                                                           " AND (SELECT pg_catalog.count(*)"
3928                                                           " FROM pg_catalog.pg_namespace"
3929                                                           " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3930                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
3931                                                           char_length, e_text);
3932
3933                         /*
3934                          * Add in matching qualified names, but only if there is exactly
3935                          * one schema matching the input-so-far.
3936                          */
3937                         appendPQExpBuffer(&query_buffer, "\nUNION\n"
3938                                                           "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
3939                                                           "FROM %s, pg_catalog.pg_namespace n "
3940                                                           "WHERE %s = n.oid AND ",
3941                                                           qualresult,
3942                                                           schema_query->catname,
3943                                                           schema_query->namespace);
3944                         if (schema_query->selcondition)
3945                                 appendPQExpBuffer(&query_buffer, "%s AND ",
3946                                                                   schema_query->selcondition);
3947                         appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
3948                                                           qualresult,
3949                                                           char_length, e_text);
3950
3951                         /*
3952                          * This condition exploits the single-matching-schema rule to
3953                          * speed up the query
3954                          */
3955                         appendPQExpBuffer(&query_buffer,
3956                                                           " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
3957                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
3958                                                           char_length, e_text);
3959                         appendPQExpBuffer(&query_buffer,
3960                                                           " AND (SELECT pg_catalog.count(*)"
3961                                                           " FROM pg_catalog.pg_namespace"
3962                                                           " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3963                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
3964                                                           char_length, e_text);
3965
3966                         /* If an addon query was provided, use it */
3967                         if (simple_query)
3968                                 appendPQExpBuffer(&query_buffer, "\n%s", simple_query);
3969                 }
3970                 else
3971                 {
3972                         Assert(simple_query);
3973                         /* simple_query is an sprintf-style format string */
3974                         appendPQExpBuffer(&query_buffer, simple_query,
3975                                                           char_length, e_text,
3976                                                           e_info_charp, e_info_charp,
3977                                                           e_info_charp2, e_info_charp2);
3978                 }
3979
3980                 /* Limit the number of records in the result */
3981                 appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
3982                                                   completion_max_records);
3983
3984                 result = exec_query(query_buffer.data);
3985
3986                 termPQExpBuffer(&query_buffer);
3987                 free(e_text);
3988                 if (e_info_charp)
3989                         free(e_info_charp);
3990                 if (e_info_charp2)
3991                         free(e_info_charp2);
3992         }
3993
3994         /* Find something that matches */
3995         if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
3996         {
3997                 const char *item;
3998
3999                 while (list_index < PQntuples(result) &&
4000                            (item = PQgetvalue(result, list_index++, 0)))
4001                         if (pg_strncasecmp(text, item, byte_length) == 0)
4002                                 return pg_strdup(item);
4003         }
4004
4005         /* If nothing matches, free the db structure and return null */
4006         PQclear(result);
4007         result = NULL;
4008         return NULL;
4009 }
4010
4011
4012 /*
4013  * This function returns in order one of a fixed, NULL pointer terminated list
4014  * of strings (if matching). This can be used if there are only a fixed number
4015  * SQL words that can appear at certain spot.
4016  */
4017 static char *
4018 complete_from_list(const char *text, int state)
4019 {
4020         static int      string_length,
4021                                 list_index,
4022                                 matches;
4023         static bool casesensitive;
4024         const char *item;
4025
4026         /* need to have a list */
4027         Assert(completion_charpp != NULL);
4028
4029         /* Initialization */
4030         if (state == 0)
4031         {
4032                 list_index = 0;
4033                 string_length = strlen(text);
4034                 casesensitive = completion_case_sensitive;
4035                 matches = 0;
4036         }
4037
4038         while ((item = completion_charpp[list_index++]))
4039         {
4040                 /* First pass is case sensitive */
4041                 if (casesensitive && strncmp(text, item, string_length) == 0)
4042                 {
4043                         matches++;
4044                         return pg_strdup(item);
4045                 }
4046
4047                 /* Second pass is case insensitive, don't bother counting matches */
4048                 if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
4049                 {
4050                         if (completion_case_sensitive)
4051                                 return pg_strdup(item);
4052                         else
4053
4054                                 /*
4055                                  * If case insensitive matching was requested initially,
4056                                  * adjust the case according to setting.
4057                                  */
4058                                 return pg_strdup_keyword_case(item, text);
4059                 }
4060         }
4061
4062         /*
4063          * No matches found. If we're not case insensitive already, lets switch to
4064          * being case insensitive and try again
4065          */
4066         if (casesensitive && matches == 0)
4067         {
4068                 casesensitive = false;
4069                 list_index = 0;
4070                 state++;
4071                 return complete_from_list(text, state);
4072         }
4073
4074         /* If no more matches, return null. */
4075         return NULL;
4076 }
4077
4078
4079 /*
4080  * This function returns one fixed string the first time even if it doesn't
4081  * match what's there, and nothing the second time. This should be used if
4082  * there is only one possibility that can appear at a certain spot, so
4083  * misspellings will be overwritten.  The string to be passed must be in
4084  * completion_charp.
4085  */
4086 static char *
4087 complete_from_const(const char *text, int state)
4088 {
4089         Assert(completion_charp != NULL);
4090         if (state == 0)
4091         {
4092                 if (completion_case_sensitive)
4093                         return pg_strdup(completion_charp);
4094                 else
4095
4096                         /*
4097                          * If case insensitive matching was requested initially, adjust
4098                          * the case according to setting.
4099                          */
4100                         return pg_strdup_keyword_case(completion_charp, text);
4101         }
4102         else
4103                 return NULL;
4104 }
4105
4106
4107 /*
4108  * This function appends the variable name with prefix and suffix to
4109  * the variable names array.
4110  */
4111 static void
4112 append_variable_names(char ***varnames, int *nvars,
4113                                           int *maxvars, const char *varname,
4114                                           const char *prefix, const char *suffix)
4115 {
4116         if (*nvars >= *maxvars)
4117         {
4118                 *maxvars *= 2;
4119                 *varnames = (char **) pg_realloc(*varnames,
4120                                                                                  ((*maxvars) + 1) * sizeof(char *));
4121         }
4122
4123         (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
4124 }
4125
4126
4127 /*
4128  * This function supports completion with the name of a psql variable.
4129  * The variable names can be prefixed and suffixed with additional text
4130  * to support quoting usages. If need_value is true, only variables
4131  * that are currently set are included; otherwise, special variables
4132  * (those that have hooks) are included even if currently unset.
4133  */
4134 static char **
4135 complete_from_variables(const char *text, const char *prefix, const char *suffix,
4136                                                 bool need_value)
4137 {
4138         char      **matches;
4139         char      **varnames;
4140         int                     nvars = 0;
4141         int                     maxvars = 100;
4142         int                     i;
4143         struct _variable *ptr;
4144
4145         varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
4146
4147         for (ptr = pset.vars->next; ptr; ptr = ptr->next)
4148         {
4149                 if (need_value && !(ptr->value))
4150                         continue;
4151                 append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
4152                                                           prefix, suffix);
4153         }
4154
4155         varnames[nvars] = NULL;
4156         COMPLETE_WITH_LIST_CS((const char *const *) varnames);
4157
4158         for (i = 0; i < nvars; i++)
4159                 free(varnames[i]);
4160         free(varnames);
4161
4162         return matches;
4163 }
4164
4165
4166 /*
4167  * This function wraps rl_filename_completion_function() to strip quotes from
4168  * the input before searching for matches and to quote any matches for which
4169  * the consuming command will require it.
4170  */
4171 static char *
4172 complete_from_files(const char *text, int state)
4173 {
4174         static const char *unquoted_text;
4175         char       *unquoted_match;
4176         char       *ret = NULL;
4177
4178         if (state == 0)
4179         {
4180                 /* Initialization: stash the unquoted input. */
4181                 unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
4182                                                                 false, true, pset.encoding);
4183                 /* expect a NULL return for the empty string only */
4184                 if (!unquoted_text)
4185                 {
4186                         Assert(*text == '\0');
4187                         unquoted_text = text;
4188                 }
4189         }
4190
4191         unquoted_match = filename_completion_function(unquoted_text, state);
4192         if (unquoted_match)
4193         {
4194                 /*
4195                  * Caller sets completion_charp to a zero- or one-character string
4196                  * containing the escape character.  This is necessary since \copy has
4197                  * no escape character, but every other backslash command recognizes
4198                  * "\" as an escape character.  Since we have only two callers, don't
4199                  * bother providing a macro to simplify this.
4200                  */
4201                 ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
4202                                                           '\'', *completion_charp, pset.encoding);
4203                 if (ret)
4204                         free(unquoted_match);
4205                 else
4206                         ret = unquoted_match;
4207         }
4208
4209         return ret;
4210 }
4211
4212
4213 /* HELPER FUNCTIONS */
4214
4215
4216 /*
4217  * Make a pg_strdup copy of s and convert the case according to
4218  * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
4219  */
4220 static char *
4221 pg_strdup_keyword_case(const char *s, const char *ref)
4222 {
4223         char       *ret,
4224                            *p;
4225         unsigned char first = ref[0];
4226
4227         ret = pg_strdup(s);
4228
4229         if (pset.comp_case == PSQL_COMP_CASE_LOWER ||
4230                 ((pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER ||
4231                   pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
4232                 (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
4233         {
4234                 for (p = ret; *p; p++)
4235                         *p = pg_tolower((unsigned char) *p);
4236         }
4237         else
4238         {
4239                 for (p = ret; *p; p++)
4240                         *p = pg_toupper((unsigned char) *p);
4241         }
4242
4243         return ret;
4244 }
4245
4246
4247 /*
4248  * escape_string - Escape argument for use as string literal.
4249  *
4250  * The returned value has to be freed.
4251  */
4252 static char *
4253 escape_string(const char *text)
4254 {
4255         size_t          text_length;
4256         char       *result;
4257
4258         text_length = strlen(text);
4259
4260         result = pg_malloc(text_length * 2 + 1);
4261         PQescapeStringConn(pset.db, result, text, text_length, NULL);
4262
4263         return result;
4264 }
4265
4266
4267 /*
4268  * Execute a query and report any errors. This should be the preferred way of
4269  * talking to the database in this file.
4270  */
4271 static PGresult *
4272 exec_query(const char *query)
4273 {
4274         PGresult   *result;
4275
4276         if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
4277                 return NULL;
4278
4279         result = PQexec(pset.db, query);
4280
4281         if (PQresultStatus(result) != PGRES_TUPLES_OK)
4282         {
4283 #ifdef NOT_USED
4284                 psql_error("tab completion query failed: %s\nQuery was:\n%s\n",
4285                                    PQerrorMessage(pset.db), query);
4286 #endif
4287                 PQclear(result);
4288                 result = NULL;
4289         }
4290
4291         return result;
4292 }
4293
4294
4295 /*
4296  * Parse all the word(s) before point.
4297  *
4298  * Returns a malloc'd array of character pointers that point into the malloc'd
4299  * data array returned to *buffer; caller must free() both of these when done.
4300  * *nwords receives the number of words found, ie, the valid length of the
4301  * return array.
4302  *
4303  * Words are returned right to left, that is, previous_words[0] gets the last
4304  * word before point, previous_words[1] the next-to-last, etc.
4305  */
4306 static char **
4307 get_previous_words(int point, char **buffer, int *nwords)
4308 {
4309         char      **previous_words;
4310         char       *buf;
4311         char       *outptr;
4312         int                     words_found = 0;
4313         int                     i;
4314
4315         /*
4316          * If we have anything in tab_completion_query_buf, paste it together with
4317          * rl_line_buffer to construct the full query.  Otherwise we can just use
4318          * rl_line_buffer as the input string.
4319          */
4320         if (tab_completion_query_buf && tab_completion_query_buf->len > 0)
4321         {
4322                 i = tab_completion_query_buf->len;
4323                 buf = pg_malloc(point + i + 2);
4324                 memcpy(buf, tab_completion_query_buf->data, i);
4325                 buf[i++] = '\n';
4326                 memcpy(buf + i, rl_line_buffer, point);
4327                 i += point;
4328                 buf[i] = '\0';
4329                 /* Readjust point to reference appropriate offset in buf */
4330                 point = i;
4331         }
4332         else
4333                 buf = rl_line_buffer;
4334
4335         /*
4336          * Allocate an array of string pointers and a buffer to hold the strings
4337          * themselves.  The worst case is that the line contains only
4338          * non-whitespace WORD_BREAKS characters, making each one a separate word.
4339          * This is usually much more space than we need, but it's cheaper than
4340          * doing a separate malloc() for each word.
4341          */
4342         previous_words = (char **) pg_malloc(point * sizeof(char *));
4343         *buffer = outptr = (char *) pg_malloc(point * 2);
4344
4345         /*
4346          * First we look for a non-word char before the current point.  (This is
4347          * probably useless, if readline is on the same page as we are about what
4348          * is a word, but if so it's cheap.)
4349          */
4350         for (i = point - 1; i >= 0; i--)
4351         {
4352                 if (strchr(WORD_BREAKS, buf[i]))
4353                         break;
4354         }
4355         point = i;
4356
4357         /*
4358          * Now parse words, working backwards, until we hit start of line.  The
4359          * backwards scan has some interesting but intentional properties
4360          * concerning parenthesis handling.
4361          */
4362         while (point >= 0)
4363         {
4364                 int                     start,
4365                                         end;
4366                 bool            inquotes = false;
4367                 int                     parentheses = 0;
4368
4369                 /* now find the first non-space which then constitutes the end */
4370                 end = -1;
4371                 for (i = point; i >= 0; i--)
4372                 {
4373                         if (!isspace((unsigned char) buf[i]))
4374                         {
4375                                 end = i;
4376                                 break;
4377                         }
4378                 }
4379                 /* if no end found, we're done */
4380                 if (end < 0)
4381                         break;
4382
4383                 /*
4384                  * Otherwise we now look for the start.  The start is either the last
4385                  * character before any word-break character going backwards from the
4386                  * end, or it's simply character 0.  We also handle open quotes and
4387                  * parentheses.
4388                  */
4389                 for (start = end; start > 0; start--)
4390                 {
4391                         if (buf[start] == '"')
4392                                 inquotes = !inquotes;
4393                         if (!inquotes)
4394                         {
4395                                 if (buf[start] == ')')
4396                                         parentheses++;
4397                                 else if (buf[start] == '(')
4398                                 {
4399                                         if (--parentheses <= 0)
4400                                                 break;
4401                                 }
4402                                 else if (parentheses == 0 &&
4403                                                  strchr(WORD_BREAKS, buf[start - 1]))
4404                                         break;
4405                         }
4406                 }
4407
4408                 /* Return the word located at start to end inclusive */
4409                 previous_words[words_found++] = outptr;
4410                 i = end - start + 1;
4411                 memcpy(outptr, &buf[start], i);
4412                 outptr += i;
4413                 *outptr++ = '\0';
4414
4415                 /* Continue searching */
4416                 point = start - 1;
4417         }
4418
4419         /* Release parsing input workspace, if we made one above */
4420         if (buf != rl_line_buffer)
4421                 free(buf);
4422
4423         *nwords = words_found;
4424         return previous_words;
4425 }
4426
4427 /*
4428  * Look up the type for the GUC variable with the passed name.
4429  *
4430  * Returns NULL if the variable is unknown. Otherwise the returned string,
4431  * containing the type, has to be freed.
4432  */
4433 static char *
4434 get_guctype(const char *varname)
4435 {
4436         PQExpBufferData query_buffer;
4437         char       *e_varname;
4438         PGresult   *result;
4439         char       *guctype = NULL;
4440
4441         e_varname = escape_string(varname);
4442
4443         initPQExpBuffer(&query_buffer);
4444         appendPQExpBuffer(&query_buffer,
4445                                           "SELECT vartype FROM pg_catalog.pg_settings "
4446                                           "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4447                                           e_varname);
4448
4449         result = exec_query(query_buffer.data);
4450         termPQExpBuffer(&query_buffer);
4451         free(e_varname);
4452
4453         if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
4454                 guctype = pg_strdup(PQgetvalue(result, 0, 0));
4455
4456         PQclear(result);
4457
4458         return guctype;
4459 }
4460
4461 #ifdef NOT_USED
4462
4463 /*
4464  * Surround a string with single quotes. This works for both SQL and
4465  * psql internal. Currently disabled because it is reported not to
4466  * cooperate with certain versions of readline.
4467  */
4468 static char *
4469 quote_file_name(char *text, int match_type, char *quote_pointer)
4470 {
4471         char       *s;
4472         size_t          length;
4473
4474         (void) quote_pointer;           /* not used */
4475
4476         length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
4477         s = pg_malloc(length);
4478         s[0] = '\'';
4479         strcpy(s + 1, text);
4480         if (match_type == SINGLE_MATCH)
4481                 s[length - 2] = '\'';
4482         s[length - 1] = '\0';
4483         return s;
4484 }
4485
4486 static char *
4487 dequote_file_name(char *text, char quote_char)
4488 {
4489         char       *s;
4490         size_t          length;
4491
4492         if (!quote_char)
4493                 return pg_strdup(text);
4494
4495         length = strlen(text);
4496         s = pg_malloc(length - 2 + 1);
4497         strlcpy(s, text +1, length - 2 + 1);
4498
4499         return s;
4500 }
4501 #endif                                                  /* NOT_USED */
4502
4503 #endif                                                  /* USE_READLINE */