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