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