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