]> granicus.if.org Git - postgresql/blob - src/bin/psql/tab-complete.c
Clean up psql's behavior for a few more control variables.
[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') ss "\
679 " WHERE substring(name,1,%d)='%s'"\
680 " UNION ALL SELECT 'all' ss"
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         /* ALTER SYSTEM SET|RESET <name> */
1665         else if (Matches3("ALTER", "SYSTEM", "SET|RESET"))
1666                 COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars);
1667         /* ALTER VIEW <name> */
1668         else if (Matches3("ALTER", "VIEW", MatchAny))
1669                 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1670                                                         "SET SCHEMA");
1671         /* ALTER MATERIALIZED VIEW <name> */
1672         else if (Matches4("ALTER", "MATERIALIZED", "VIEW", MatchAny))
1673                 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1674                                                         "SET SCHEMA");
1675
1676         /* ALTER POLICY <name> */
1677         else if (Matches2("ALTER", "POLICY"))
1678                 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
1679         /* ALTER POLICY <name> ON */
1680         else if (Matches3("ALTER", "POLICY", MatchAny))
1681                 COMPLETE_WITH_CONST("ON");
1682         /* ALTER POLICY <name> ON <table> */
1683         else if (Matches4("ALTER", "POLICY", MatchAny, "ON"))
1684         {
1685                 completion_info_charp = prev2_wd;
1686                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
1687         }
1688         /* ALTER POLICY <name> ON <table> - show options */
1689         else if (Matches5("ALTER", "POLICY", MatchAny, "ON", MatchAny))
1690                 COMPLETE_WITH_LIST4("RENAME TO", "TO", "USING (", "WITH CHECK (");
1691         /* ALTER POLICY <name> ON <table> TO <role> */
1692         else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
1693                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
1694         /* ALTER POLICY <name> ON <table> USING ( */
1695         else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
1696                 COMPLETE_WITH_CONST("(");
1697         /* ALTER POLICY <name> ON <table> WITH CHECK ( */
1698         else if (Matches7("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
1699                 COMPLETE_WITH_CONST("(");
1700
1701         /* ALTER RULE <name>, add ON */
1702         else if (Matches3("ALTER", "RULE", MatchAny))
1703                 COMPLETE_WITH_CONST("ON");
1704
1705         /* If we have ALTER RULE <name> ON, then add the correct tablename */
1706         else if (Matches4("ALTER", "RULE", MatchAny, "ON"))
1707         {
1708                 completion_info_charp = prev2_wd;
1709                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1710         }
1711
1712         /* ALTER RULE <name> ON <name> */
1713         else if (Matches5("ALTER", "RULE", MatchAny, "ON", MatchAny))
1714                 COMPLETE_WITH_CONST("RENAME TO");
1715
1716         /* ALTER TRIGGER <name>, add ON */
1717         else if (Matches3("ALTER", "TRIGGER", MatchAny))
1718                 COMPLETE_WITH_CONST("ON");
1719
1720         else if (Matches4("ALTER", "TRIGGER", MatchAny, MatchAny))
1721         {
1722                 completion_info_charp = prev2_wd;
1723                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
1724         }
1725
1726         /*
1727          * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
1728          */
1729         else if (Matches4("ALTER", "TRIGGER", MatchAny, "ON"))
1730                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
1731
1732         /* ALTER TRIGGER <name> ON <name> */
1733         else if (Matches5("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
1734                 COMPLETE_WITH_CONST("RENAME TO");
1735
1736         /*
1737          * If we detect ALTER TABLE <name>, suggest sub commands
1738          */
1739         else if (Matches3("ALTER", "TABLE", MatchAny))
1740         {
1741                 static const char *const list_ALTER2[] =
1742                 {"ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", "ENABLE", "INHERIT",
1743                         "NO INHERIT", "RENAME", "RESET", "OWNER TO", "SET",
1744                 "VALIDATE CONSTRAINT", "REPLICA IDENTITY", NULL};
1745
1746                 COMPLETE_WITH_LIST(list_ALTER2);
1747         }
1748         /* ALTER TABLE xxx ENABLE */
1749         else if (Matches4("ALTER", "TABLE", MatchAny, "ENABLE"))
1750                 COMPLETE_WITH_LIST5("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
1751                                                         "TRIGGER");
1752         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
1753                 COMPLETE_WITH_LIST2("RULE", "TRIGGER");
1754         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
1755         {
1756                 completion_info_charp = prev3_wd;
1757                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1758         }
1759         else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
1760         {
1761                 completion_info_charp = prev4_wd;
1762                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1763         }
1764         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
1765         {
1766                 completion_info_charp = prev3_wd;
1767                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1768         }
1769         else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
1770         {
1771                 completion_info_charp = prev4_wd;
1772                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1773         }
1774         /* ALTER TABLE xxx INHERIT */
1775         else if (Matches4("ALTER", "TABLE", MatchAny, "INHERIT"))
1776                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1777         /* ALTER TABLE xxx NO INHERIT */
1778         else if (Matches5("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
1779                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1780         /* ALTER TABLE xxx DISABLE */
1781         else if (Matches4("ALTER", "TABLE", MatchAny, "DISABLE"))
1782                 COMPLETE_WITH_LIST3("ROW LEVEL SECURITY", "RULE", "TRIGGER");
1783         else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
1784         {
1785                 completion_info_charp = prev3_wd;
1786                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1787         }
1788         else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
1789         {
1790                 completion_info_charp = prev3_wd;
1791                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1792         }
1793
1794         /* ALTER TABLE xxx ALTER */
1795         else if (Matches4("ALTER", "TABLE", MatchAny, "ALTER"))
1796                 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'");
1797
1798         /* ALTER TABLE xxx RENAME */
1799         else if (Matches4("ALTER", "TABLE", MatchAny, "RENAME"))
1800                 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'");
1801         else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
1802                 COMPLETE_WITH_ATTR(prev3_wd, "");
1803
1804         /* ALTER TABLE xxx RENAME yyy */
1805         else if (Matches5("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
1806                 COMPLETE_WITH_CONST("TO");
1807
1808         /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
1809         else if (Matches6("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
1810                 COMPLETE_WITH_CONST("TO");
1811
1812         /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
1813         else if (Matches4("ALTER", "TABLE", MatchAny, "DROP"))
1814                 COMPLETE_WITH_LIST2("COLUMN", "CONSTRAINT");
1815         /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
1816         else if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
1817                 COMPLETE_WITH_ATTR(prev3_wd, "");
1818
1819         /*
1820          * If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
1821          * provide list of constraints
1822          */
1823         else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
1824         {
1825                 completion_info_charp = prev3_wd;
1826                 COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
1827         }
1828         /* ALTER TABLE ALTER [COLUMN] <foo> */
1829         else if (Matches6("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
1830                          Matches5("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
1831                 COMPLETE_WITH_LIST4("TYPE", "SET", "RESET", "DROP");
1832         /* ALTER TABLE ALTER [COLUMN] <foo> SET */
1833         else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
1834                          Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
1835                 COMPLETE_WITH_LIST5("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE");
1836         /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
1837         else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
1838                  Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
1839                 COMPLETE_WITH_LIST2("n_distinct", "n_distinct_inherited");
1840         /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
1841         else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
1842         Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
1843                 COMPLETE_WITH_LIST4("PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
1844         /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
1845         else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
1846                          Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
1847                 COMPLETE_WITH_LIST2("DEFAULT", "NOT NULL");
1848         else if (Matches4("ALTER", "TABLE", MatchAny, "CLUSTER"))
1849                 COMPLETE_WITH_CONST("ON");
1850         else if (Matches5("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
1851         {
1852                 completion_info_charp = prev3_wd;
1853                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1854         }
1855         /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
1856         else if (Matches4("ALTER", "TABLE", MatchAny, "SET"))
1857                 COMPLETE_WITH_LIST7("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED",
1858                                                         "WITH", "WITHOUT");
1859
1860         /*
1861          * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
1862          * tablespaces
1863          */
1864         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
1865                 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1866         /* If we have ALTER TABLE <sth> SET WITH provide OIDS */
1867         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITH"))
1868                 COMPLETE_WITH_CONST("OIDS");
1869         /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
1870         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
1871                 COMPLETE_WITH_LIST2("CLUSTER", "OIDS");
1872         /* ALTER TABLE <foo> RESET */
1873         else if (Matches4("ALTER", "TABLE", MatchAny, "RESET"))
1874                 COMPLETE_WITH_CONST("(");
1875         /* ALTER TABLE <foo> SET|RESET ( */
1876         else if (Matches5("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
1877         {
1878                 static const char *const list_TABLEOPTIONS[] =
1879                 {
1880                         "autovacuum_analyze_scale_factor",
1881                         "autovacuum_analyze_threshold",
1882                         "autovacuum_enabled",
1883                         "autovacuum_freeze_max_age",
1884                         "autovacuum_freeze_min_age",
1885                         "autovacuum_freeze_table_age",
1886                         "autovacuum_multixact_freeze_max_age",
1887                         "autovacuum_multixact_freeze_min_age",
1888                         "autovacuum_multixact_freeze_table_age",
1889                         "autovacuum_vacuum_cost_delay",
1890                         "autovacuum_vacuum_cost_limit",
1891                         "autovacuum_vacuum_scale_factor",
1892                         "autovacuum_vacuum_threshold",
1893                         "fillfactor",
1894                         "parallel_workers",
1895                         "log_autovacuum_min_duration",
1896                         "toast.autovacuum_enabled",
1897                         "toast.autovacuum_freeze_max_age",
1898                         "toast.autovacuum_freeze_min_age",
1899                         "toast.autovacuum_freeze_table_age",
1900                         "toast.autovacuum_multixact_freeze_max_age",
1901                         "toast.autovacuum_multixact_freeze_min_age",
1902                         "toast.autovacuum_multixact_freeze_table_age",
1903                         "toast.autovacuum_vacuum_cost_delay",
1904                         "toast.autovacuum_vacuum_cost_limit",
1905                         "toast.autovacuum_vacuum_scale_factor",
1906                         "toast.autovacuum_vacuum_threshold",
1907                         "toast.log_autovacuum_min_duration",
1908                         "user_catalog_table",
1909                         NULL
1910                 };
1911
1912                 COMPLETE_WITH_LIST(list_TABLEOPTIONS);
1913         }
1914         else if (Matches7("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
1915         {
1916                 completion_info_charp = prev5_wd;
1917                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1918         }
1919         else if (Matches6("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
1920                 COMPLETE_WITH_CONST("INDEX");
1921         else if (Matches5("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
1922                 COMPLETE_WITH_LIST4("FULL", "NOTHING", "DEFAULT", "USING");
1923         else if (Matches4("ALTER", "TABLE", MatchAny, "REPLICA"))
1924                 COMPLETE_WITH_CONST("IDENTITY");
1925
1926         /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
1927         else if (Matches3("ALTER", "TABLESPACE", MatchAny))
1928                 COMPLETE_WITH_LIST4("RENAME TO", "OWNER TO", "SET", "RESET");
1929         /* ALTER TABLESPACE <foo> SET|RESET */
1930         else if (Matches4("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
1931                 COMPLETE_WITH_CONST("(");
1932         /* ALTER TABLESPACE <foo> SET|RESET ( */
1933         else if (Matches5("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
1934                 COMPLETE_WITH_LIST3("seq_page_cost", "random_page_cost",
1935                                                         "effective_io_concurrency");
1936
1937         /* ALTER TEXT SEARCH */
1938         else if (Matches3("ALTER", "TEXT", "SEARCH"))
1939                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
1940         else if (Matches5("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
1941                 COMPLETE_WITH_LIST2("RENAME TO", "SET SCHEMA");
1942         else if (Matches5("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
1943                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1944         else if (Matches5("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
1945                 COMPLETE_WITH_LIST6("ADD MAPPING FOR", "ALTER MAPPING",
1946                                                         "DROP MAPPING FOR",
1947                                                         "OWNER TO", "RENAME TO", "SET SCHEMA");
1948
1949         /* complete ALTER TYPE <foo> with actions */
1950         else if (Matches3("ALTER", "TYPE", MatchAny))
1951                 COMPLETE_WITH_LIST7("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
1952                                                         "DROP ATTRIBUTE",
1953                                                         "OWNER TO", "RENAME", "SET SCHEMA");
1954         /* complete ALTER TYPE <foo> ADD with actions */
1955         else if (Matches4("ALTER", "TYPE", MatchAny, "ADD"))
1956                 COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE");
1957         /* ALTER TYPE <foo> RENAME      */
1958         else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME"))
1959                 COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE");
1960         /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
1961         else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
1962                 COMPLETE_WITH_CONST("TO");
1963         /*
1964          * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
1965          * of attributes
1966          */
1967         else if (Matches5("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
1968                 COMPLETE_WITH_ATTR(prev3_wd, "");
1969         /* ALTER TYPE ALTER ATTRIBUTE <foo> */
1970         else if (Matches6("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
1971                 COMPLETE_WITH_CONST("TYPE");
1972         /* complete ALTER GROUP <foo> */
1973         else if (Matches3("ALTER", "GROUP", MatchAny))
1974                 COMPLETE_WITH_LIST3("ADD USER", "DROP USER", "RENAME TO");
1975         /* complete ALTER GROUP <foo> ADD|DROP with USER */
1976         else if (Matches4("ALTER", "GROUP", MatchAny, "ADD|DROP"))
1977                 COMPLETE_WITH_CONST("USER");
1978         /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
1979         else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
1980                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1981
1982         /*
1983          * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
1984          */
1985         else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
1986                 COMPLETE_WITH_ENUM_VALUE(prev3_wd);
1987
1988 /* BEGIN */
1989         else if (Matches1("BEGIN"))
1990                 COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
1991 /* END, ABORT */
1992         else if (Matches1("END|ABORT"))
1993                 COMPLETE_WITH_LIST2("WORK", "TRANSACTION");
1994 /* COMMIT */
1995         else if (Matches1("COMMIT"))
1996                 COMPLETE_WITH_LIST3("WORK", "TRANSACTION", "PREPARED");
1997 /* RELEASE SAVEPOINT */
1998         else if (Matches1("RELEASE"))
1999                 COMPLETE_WITH_CONST("SAVEPOINT");
2000 /* ROLLBACK */
2001         else if (Matches1("ROLLBACK"))
2002                 COMPLETE_WITH_LIST4("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
2003 /* CLUSTER */
2004         else if (Matches1("CLUSTER"))
2005                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, "UNION SELECT 'VERBOSE'");
2006         else if (Matches2("CLUSTER", "VERBOSE"))
2007                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2008         /* If we have CLUSTER <sth>, then add "USING" */
2009         else if (Matches2("CLUSTER", MatchAnyExcept("VERBOSE|ON")))
2010                 COMPLETE_WITH_CONST("USING");
2011         /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
2012         else if (Matches3("CLUSTER", "VERBOSE", MatchAny))
2013                 COMPLETE_WITH_CONST("USING");
2014         /* If we have CLUSTER <sth> USING, then add the index as well */
2015         else if (Matches3("CLUSTER", MatchAny, "USING") ||
2016                          Matches4("CLUSTER", "VERBOSE", MatchAny, "USING"))
2017         {
2018                 completion_info_charp = prev2_wd;
2019                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
2020         }
2021
2022 /* COMMENT */
2023         else if (Matches1("COMMENT"))
2024                 COMPLETE_WITH_CONST("ON");
2025         else if (Matches2("COMMENT", "ON"))
2026         {
2027                 static const char *const list_COMMENT[] =
2028                 {"ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", "DATABASE",
2029                         "EVENT TRIGGER", "EXTENSION",
2030                         "FOREIGN DATA WRAPPER", "FOREIGN TABLE",
2031                         "SERVER", "INDEX", "LANGUAGE", "POLICY", "RULE", "SCHEMA", "SEQUENCE",
2032                         "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
2033                         "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
2034                 "TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
2035
2036                 COMPLETE_WITH_LIST(list_COMMENT);
2037         }
2038         else if (Matches4("COMMENT", "ON", "ACCESS", "METHOD"))
2039                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2040         else if (Matches3("COMMENT", "ON", "FOREIGN"))
2041                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2042         else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH"))
2043                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2044         else if (Matches3("COMMENT", "ON", "CONSTRAINT"))
2045                 COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2046         else if (Matches4("COMMENT", "ON", "CONSTRAINT", MatchAny))
2047                 COMPLETE_WITH_CONST("ON");
2048         else if (Matches5("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2049         {
2050                 completion_info_charp = prev2_wd;
2051                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint);
2052         }
2053         else if (Matches4("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2054                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2055         else if (Matches4("COMMENT", "ON", "EVENT", "TRIGGER"))
2056                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2057         else if (Matches4("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2058                 Matches5("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2059                          Matches6("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2060                 COMPLETE_WITH_CONST("IS");
2061
2062 /* COPY */
2063
2064         /*
2065          * If we have COPY, offer list of tables or "(" (Also cover the analogous
2066          * backslash command).
2067          */
2068         else if (Matches1("COPY|\\copy"))
2069                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2070                                                                    " UNION ALL SELECT '('");
2071         /* If we have COPY BINARY, complete with list of tables */
2072         else if (Matches2("COPY", "BINARY"))
2073                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2074         /* If we have COPY (, complete it with legal commands */
2075         else if (Matches2("COPY|\\copy", "("))
2076                 COMPLETE_WITH_LIST7("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH");
2077         /* If we have COPY [BINARY] <sth>, complete it with "TO" or "FROM" */
2078         else if (Matches2("COPY|\\copy", MatchAny) ||
2079                          Matches3("COPY", "BINARY", MatchAny))
2080                 COMPLETE_WITH_LIST2("FROM", "TO");
2081         /* If we have COPY [BINARY] <sth> FROM|TO, complete with filename */
2082         else if (Matches3("COPY|\\copy", MatchAny, "FROM|TO") ||
2083                          Matches4("COPY", "BINARY", MatchAny, "FROM|TO"))
2084         {
2085                 completion_charp = "";
2086                 matches = completion_matches(text, complete_from_files);
2087         }
2088
2089         /* Handle COPY [BINARY] <sth> FROM|TO filename */
2090         else if (Matches4("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
2091                          Matches5("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
2092                 COMPLETE_WITH_LIST6("BINARY", "OIDS", "DELIMITER", "NULL", "CSV",
2093                                                         "ENCODING");
2094
2095         /* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
2096         else if (Matches5("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") ||
2097                          Matches6("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV"))
2098                 COMPLETE_WITH_LIST5("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE",
2099                                                         "FORCE NOT NULL");
2100
2101         /* CREATE ACCESS METHOD */
2102         /* Complete "CREATE ACCESS METHOD <name>" */
2103         else if (Matches4("CREATE", "ACCESS", "METHOD", MatchAny))
2104                 COMPLETE_WITH_CONST("TYPE");
2105         /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2106         else if (Matches5("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2107                 COMPLETE_WITH_CONST("INDEX");
2108         /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2109         else if (Matches6("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2110                 COMPLETE_WITH_CONST("HANDLER");
2111
2112         /* CREATE DATABASE */
2113         else if (Matches3("CREATE", "DATABASE", MatchAny))
2114                 COMPLETE_WITH_LIST9("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2115                                                         "IS_TEMPLATE",
2116                                                         "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2117                                                         "LC_COLLATE", "LC_CTYPE");
2118
2119         else if (Matches4("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2120                 COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2121
2122         /* CREATE EXTENSION */
2123         /* Complete with available extensions rather than installed ones. */
2124         else if (Matches2("CREATE", "EXTENSION"))
2125                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2126         /* CREATE EXTENSION <name> */
2127         else if (Matches3("CREATE", "EXTENSION", MatchAny))
2128                 COMPLETE_WITH_LIST3("WITH SCHEMA", "CASCADE", "VERSION");
2129         /* CREATE EXTENSION <name> VERSION */
2130         else if (Matches4("CREATE", "EXTENSION", MatchAny, "VERSION"))
2131         {
2132                 completion_info_charp = prev2_wd;
2133                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2134         }
2135
2136         /* CREATE FOREIGN */
2137         else if (Matches2("CREATE", "FOREIGN"))
2138                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2139
2140         /* CREATE FOREIGN DATA WRAPPER */
2141         else if (Matches5("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2142                 COMPLETE_WITH_LIST3("HANDLER", "VALIDATOR", "OPTIONS");
2143
2144         /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2145         /* First off we complete CREATE UNIQUE with "INDEX" */
2146         else if (TailMatches2("CREATE", "UNIQUE"))
2147                 COMPLETE_WITH_CONST("INDEX");
2148
2149         /*
2150          * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
2151          * existing indexes
2152          */
2153         else if (TailMatches2("CREATE|UNIQUE", "INDEX"))
2154                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2155                                                                    " UNION SELECT 'ON'"
2156                                                                    " UNION SELECT 'CONCURRENTLY'");
2157         /* Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of tables  */
2158         else if (TailMatches3("INDEX|CONCURRENTLY", MatchAny, "ON") ||
2159                          TailMatches2("INDEX|CONCURRENTLY", "ON"))
2160                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2161
2162         /*
2163          * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
2164          * indexes
2165          */
2166         else if (TailMatches3("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
2167                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2168                                                                    " UNION SELECT 'ON'");
2169         /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
2170         else if (TailMatches3("CREATE|UNIQUE", "INDEX", MatchAny) ||
2171                          TailMatches4("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
2172                 COMPLETE_WITH_CONST("ON");
2173
2174         /*
2175          * Complete INDEX <name> ON <table> with a list of table columns (which
2176          * should really be in parens)
2177          */
2178         else if (TailMatches4("INDEX", MatchAny, "ON", MatchAny) ||
2179                          TailMatches3("INDEX|CONCURRENTLY", "ON", MatchAny))
2180                 COMPLETE_WITH_LIST2("(", "USING");
2181         else if (TailMatches5("INDEX", MatchAny, "ON", MatchAny, "(") ||
2182                          TailMatches4("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
2183                 COMPLETE_WITH_ATTR(prev2_wd, "");
2184         /* same if you put in USING */
2185         else if (TailMatches5("ON", MatchAny, "USING", MatchAny, "("))
2186                 COMPLETE_WITH_ATTR(prev4_wd, "");
2187         /* Complete USING with an index method */
2188         else if (TailMatches6("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
2189                          TailMatches5("INDEX", MatchAny, "ON", MatchAny, "USING") ||
2190                          TailMatches4("INDEX", "ON", MatchAny, "USING"))
2191                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2192         else if (TailMatches4("ON", MatchAny, "USING", MatchAny) &&
2193                          !TailMatches6("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
2194                          !TailMatches4("FOR", MatchAny, MatchAny, MatchAny))
2195                 COMPLETE_WITH_CONST("(");
2196
2197         /* CREATE POLICY */
2198         /* Complete "CREATE POLICY <name> ON" */
2199         else if (Matches3("CREATE", "POLICY", MatchAny))
2200                 COMPLETE_WITH_CONST("ON");
2201         /* Complete "CREATE POLICY <name> ON <table>" */
2202         else if (Matches4("CREATE", "POLICY", MatchAny, "ON"))
2203                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2204         /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
2205         else if (Matches5("CREATE", "POLICY", MatchAny, "ON", MatchAny))
2206                 COMPLETE_WITH_LIST5("AS", "FOR", "TO", "USING (", "WITH CHECK (");
2207         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
2208         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
2209                 COMPLETE_WITH_LIST2("PERMISSIVE", "RESTRICTIVE");
2210         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR|TO|USING|WITH CHECK */
2211         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
2212                 COMPLETE_WITH_LIST4("FOR", "TO", "USING", "WITH CHECK");
2213         /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2214         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
2215                 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2216         /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
2217         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
2218                 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2219         /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
2220         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
2221                 COMPLETE_WITH_LIST2("TO", "USING (");
2222         /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
2223         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
2224                 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2225         /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
2226         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
2227                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2228         /* Complete "CREATE POLICY <name> ON <table> USING (" */
2229         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
2230                 COMPLETE_WITH_CONST("(");
2231         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2232         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
2233                 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2234         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR INSERT TO|WITH CHECK" */
2235         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
2236                 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2237         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR SELECT|DELETE TO|USING" */
2238         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
2239                 COMPLETE_WITH_LIST2("TO", "USING (");
2240         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR ALL|UPDATE TO|USING|WITH CHECK */
2241         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
2242                 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2243         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO <role>" */
2244         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
2245                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2246         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE USING (" */
2247         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
2248                 COMPLETE_WITH_CONST("(");
2249
2250
2251 /* CREATE PUBLICATION */
2252         else if (Matches3("CREATE", "PUBLICATION", MatchAny))
2253                 COMPLETE_WITH_LIST3("FOR TABLE", "FOR ALL TABLES", "WITH (");
2254         else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR"))
2255                 COMPLETE_WITH_LIST2("TABLE", "ALL TABLES");
2256         /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>" */
2257         else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR TABLE"))
2258                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2259         /* Complete "CREATE PUBLICATION <name> [...] WITH" */
2260         else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "("))
2261                 COMPLETE_WITH_LIST2("PUBLISH", "NOPUBLISH");
2262         else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches3("WITH", "(", MatchAny))
2263                 COMPLETE_WITH_LIST3("INSERT", "UPDATE", "DELETE");
2264
2265 /* CREATE RULE */
2266         /* Complete "CREATE RULE <sth>" with "AS ON" */
2267         else if (Matches3("CREATE", "RULE", MatchAny))
2268                 COMPLETE_WITH_CONST("AS ON");
2269         /* Complete "CREATE RULE <sth> AS" with "ON" */
2270         else if (Matches4("CREATE", "RULE", MatchAny, "AS"))
2271                 COMPLETE_WITH_CONST("ON");
2272         /* Complete "CREATE RULE <sth> AS ON" with SELECT|UPDATE|INSERT|DELETE */
2273         else if (Matches5("CREATE", "RULE", MatchAny, "AS", "ON"))
2274                 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE");
2275         /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
2276         else if (TailMatches3("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
2277                 COMPLETE_WITH_CONST("TO");
2278         /* Complete "AS ON <sth> TO" with a table name */
2279         else if (TailMatches4("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
2280                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2281
2282 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2283         else if (TailMatches3("CREATE", "SEQUENCE", MatchAny) ||
2284                          TailMatches4("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
2285                 COMPLETE_WITH_LIST8("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE",
2286                                                         "CYCLE", "OWNED BY", "START WITH");
2287         else if (TailMatches4("CREATE", "SEQUENCE", MatchAny, "NO") ||
2288                 TailMatches5("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
2289                 COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE");
2290
2291 /* CREATE SERVER <name> */
2292         else if (Matches3("CREATE", "SERVER", MatchAny))
2293                 COMPLETE_WITH_LIST3("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
2294
2295 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2296         /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
2297         else if (TailMatches2("CREATE", "TEMP|TEMPORARY"))
2298                 COMPLETE_WITH_LIST3("SEQUENCE", "TABLE", "VIEW");
2299         /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
2300         else if (TailMatches2("CREATE", "UNLOGGED"))
2301                 COMPLETE_WITH_LIST2("TABLE", "MATERIALIZED VIEW");
2302
2303 /* CREATE TABLESPACE */
2304         else if (Matches3("CREATE", "TABLESPACE", MatchAny))
2305                 COMPLETE_WITH_LIST2("OWNER", "LOCATION");
2306         /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
2307         else if (Matches5("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
2308                 COMPLETE_WITH_CONST("LOCATION");
2309
2310 /* CREATE TEXT SEARCH */
2311         else if (Matches3("CREATE", "TEXT", "SEARCH"))
2312                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2313         else if (Matches5("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2314                 COMPLETE_WITH_CONST("(");
2315
2316 /* CREATE SUBSCRIPTION */
2317         else if (Matches3("CREATE", "SUBSCRIPTION", MatchAny))
2318                 COMPLETE_WITH_CONST("CONNECTION");
2319         else if (Matches5("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",MatchAny))
2320                 COMPLETE_WITH_CONST("PUBLICATION");
2321         /* Complete "CREATE SUBSCRIPTION <name> ...  WITH ( <opt>" */
2322         else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("WITH", "("))
2323                 COMPLETE_WITH_LIST5("ENABLED", "DISABLED", "CREATE SLOT",
2324                                                         "NOCREATE SLOT", "SLOT NAME");
2325
2326 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
2327         /* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
2328         else if (TailMatches3("CREATE", "TRIGGER", MatchAny))
2329                 COMPLETE_WITH_LIST3("BEFORE", "AFTER", "INSTEAD OF");
2330         /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
2331         else if (TailMatches4("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
2332                 COMPLETE_WITH_LIST4("INSERT", "DELETE", "UPDATE", "TRUNCATE");
2333         /* complete CREATE TRIGGER <name> INSTEAD OF with an event */
2334         else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
2335                 COMPLETE_WITH_LIST3("INSERT", "DELETE", "UPDATE");
2336         /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
2337         else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
2338           TailMatches6("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
2339                 COMPLETE_WITH_LIST2("ON", "OR");
2340
2341         /*
2342          * complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of
2343          * tables
2344          */
2345         else if (TailMatches6("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
2346                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2347         /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */
2348         else if (TailMatches7("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
2349                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
2350         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("ON", MatchAny))
2351                 COMPLETE_WITH_LIST7("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2352                                                         "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2353         else if (HeadMatches2("CREATE", "TRIGGER") &&
2354                          (TailMatches1("DEFERRABLE") || TailMatches2("INITIALLY", "IMMEDIATE|DEFERRED")))
2355                 COMPLETE_WITH_LIST4("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2356         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("REFERENCING"))
2357                 COMPLETE_WITH_LIST2("OLD TABLE", "NEW TABLE");
2358         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("OLD|NEW", "TABLE"))
2359                 COMPLETE_WITH_CONST("AS");
2360         else if (HeadMatches2("CREATE", "TRIGGER") &&
2361                          (TailMatches5("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
2362                           TailMatches4("REFERENCING", "OLD", "TABLE", MatchAny)))
2363                 COMPLETE_WITH_LIST4("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2364         else if (HeadMatches2("CREATE", "TRIGGER") &&
2365                          (TailMatches5("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
2366                           TailMatches4("REFERENCING", "NEW", "TABLE", MatchAny)))
2367                 COMPLETE_WITH_LIST4("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2368         else if (HeadMatches2("CREATE", "TRIGGER") &&
2369                          (TailMatches9("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2370                           TailMatches8("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2371                           TailMatches8("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
2372                           TailMatches7("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
2373                 COMPLETE_WITH_LIST3("FOR", "WHEN (", "EXECUTE PROCEDURE");
2374         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("FOR"))
2375                 COMPLETE_WITH_LIST3("EACH", "ROW", "STATEMENT");
2376         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("FOR", "EACH"))
2377                 COMPLETE_WITH_LIST2("ROW", "STATEMENT");
2378         else if (HeadMatches2("CREATE", "TRIGGER") &&
2379                          (TailMatches3("FOR", "EACH", "ROW|STATEMENT") ||
2380                           TailMatches2("FOR", "ROW|STATEMENT")))
2381                 COMPLETE_WITH_LIST2("WHEN (", "EXECUTE PROCEDURE");
2382         /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE */
2383         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("EXECUTE"))
2384                 COMPLETE_WITH_CONST("PROCEDURE");
2385         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("EXECUTE", "PROCEDURE"))
2386                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2387
2388 /* CREATE ROLE,USER,GROUP <name> */
2389         else if (Matches3("CREATE", "ROLE|GROUP|USER", MatchAny) &&
2390                          !TailMatches2("USER", "MAPPING"))
2391         {
2392                 static const char *const list_CREATEROLE[] =
2393                 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2394                         "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2395                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2396                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2397                         "REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
2398                 "VALID UNTIL", "WITH", NULL};
2399
2400                 COMPLETE_WITH_LIST(list_CREATEROLE);
2401         }
2402
2403 /* CREATE ROLE,USER,GROUP <name> WITH */
2404         else if (Matches4("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
2405         {
2406                 /* Similar to the above, but don't complete "WITH" again. */
2407                 static const char *const list_CREATEROLE_WITH[] =
2408                 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2409                         "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2410                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2411                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2412                         "REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
2413                 "VALID UNTIL", NULL};
2414
2415                 COMPLETE_WITH_LIST(list_CREATEROLE_WITH);
2416         }
2417
2418         /*
2419          * complete CREATE ROLE,USER,GROUP <name> ENCRYPTED,UNENCRYPTED with
2420          * PASSWORD
2421          */
2422         else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "ENCRYPTED|UNENCRYPTED"))
2423                 COMPLETE_WITH_CONST("PASSWORD");
2424         /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
2425         else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
2426                 COMPLETE_WITH_LIST2("GROUP", "ROLE");
2427
2428 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
2429         /* Complete CREATE VIEW <name> with AS */
2430         else if (TailMatches3("CREATE", "VIEW", MatchAny))
2431                 COMPLETE_WITH_CONST("AS");
2432         /* Complete "CREATE VIEW <sth> AS with "SELECT" */
2433         else if (TailMatches4("CREATE", "VIEW", MatchAny, "AS"))
2434                 COMPLETE_WITH_CONST("SELECT");
2435
2436 /* CREATE MATERIALIZED VIEW */
2437         else if (Matches2("CREATE", "MATERIALIZED"))
2438                 COMPLETE_WITH_CONST("VIEW");
2439         /* Complete CREATE MATERIALIZED VIEW <name> with AS */
2440         else if (Matches4("CREATE", "MATERIALIZED", "VIEW", MatchAny))
2441                 COMPLETE_WITH_CONST("AS");
2442         /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
2443         else if (Matches5("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
2444                 COMPLETE_WITH_CONST("SELECT");
2445
2446 /* CREATE EVENT TRIGGER */
2447         else if (Matches2("CREATE", "EVENT"))
2448                 COMPLETE_WITH_CONST("TRIGGER");
2449         /* Complete CREATE EVENT TRIGGER <name> with ON */
2450         else if (Matches4("CREATE", "EVENT", "TRIGGER", MatchAny))
2451                 COMPLETE_WITH_CONST("ON");
2452         /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
2453         else if (Matches5("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
2454                 COMPLETE_WITH_LIST3("ddl_command_start", "ddl_command_end", "sql_drop");
2455
2456 /* DECLARE */
2457         else if (Matches2("DECLARE", MatchAny))
2458                 COMPLETE_WITH_LIST5("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL",
2459                                                         "CURSOR");
2460         else if (HeadMatches1("DECLARE") && TailMatches1("CURSOR"))
2461                 COMPLETE_WITH_LIST3("WITH HOLD", "WITHOUT HOLD", "FOR");
2462
2463 /* DELETE --- can be inside EXPLAIN, RULE, etc */
2464         /* ... despite which, only complete DELETE with FROM at start of line */
2465         else if (Matches1("DELETE"))
2466                 COMPLETE_WITH_CONST("FROM");
2467         /* Complete DELETE FROM with a list of tables */
2468         else if (TailMatches2("DELETE", "FROM"))
2469                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2470         /* Complete DELETE FROM <table> */
2471         else if (TailMatches3("DELETE", "FROM", MatchAny))
2472                 COMPLETE_WITH_LIST2("USING", "WHERE");
2473         /* XXX: implement tab completion for DELETE ... USING */
2474
2475 /* DISCARD */
2476         else if (Matches1("DISCARD"))
2477                 COMPLETE_WITH_LIST4("ALL", "PLANS", "SEQUENCES", "TEMP");
2478
2479 /* DO */
2480         else if (Matches1("DO"))
2481                 COMPLETE_WITH_CONST("LANGUAGE");
2482
2483 /* DROP */
2484         /* Complete DROP object with CASCADE / RESTRICT */
2485         else if (Matches3("DROP",
2486                                           "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|TABLE|TYPE|VIEW",
2487                                           MatchAny) ||
2488                          Matches4("DROP", "ACCESS", "METHOD", MatchAny) ||
2489                          (Matches4("DROP", "AGGREGATE|FUNCTION", MatchAny, MatchAny) &&
2490                           ends_with(prev_wd, ')')) ||
2491                          Matches4("DROP", "EVENT", "TRIGGER", MatchAny) ||
2492                          Matches5("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
2493                          Matches4("DROP", "FOREIGN", "TABLE", MatchAny) ||
2494                          Matches5("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
2495                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2496
2497         /* help completing some of the variants */
2498         else if (Matches3("DROP", "AGGREGATE|FUNCTION", MatchAny))
2499                 COMPLETE_WITH_CONST("(");
2500         else if (Matches4("DROP", "AGGREGATE|FUNCTION", MatchAny, "("))
2501                 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
2502         else if (Matches2("DROP", "FOREIGN"))
2503                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2504
2505         /* DROP INDEX */
2506         else if (Matches2("DROP", "INDEX"))
2507                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2508                                                                    " UNION SELECT 'CONCURRENTLY'");
2509         else if (Matches3("DROP", "INDEX", "CONCURRENTLY"))
2510                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2511         else if (Matches3("DROP", "INDEX", MatchAny))
2512                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2513         else if (Matches4("DROP", "INDEX", "CONCURRENTLY", MatchAny))
2514                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2515
2516         /* DROP MATERIALIZED VIEW */
2517         else if (Matches2("DROP", "MATERIALIZED"))
2518                 COMPLETE_WITH_CONST("VIEW");
2519         else if (Matches3("DROP", "MATERIALIZED", "VIEW"))
2520                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2521
2522         /* DROP OWNED BY */
2523         else if (Matches2("DROP", "OWNED"))
2524                 COMPLETE_WITH_CONST("BY");
2525         else if (Matches3("DROP", "OWNED", "BY"))
2526                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2527
2528         else if (Matches3("DROP", "TEXT", "SEARCH"))
2529                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2530
2531         /* DROP TRIGGER */
2532         else if (Matches3("DROP", "TRIGGER", MatchAny))
2533                 COMPLETE_WITH_CONST("ON");
2534         else if (Matches4("DROP", "TRIGGER", MatchAny, "ON"))
2535         {
2536                 completion_info_charp = prev2_wd;
2537                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2538         }
2539         else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
2540                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2541
2542         /* DROP ACCESS METHOD */
2543         else if (Matches2("DROP", "ACCESS"))
2544                 COMPLETE_WITH_CONST("METHOD");
2545         else if (Matches3("DROP", "ACCESS", "METHOD"))
2546                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2547
2548         /* DROP EVENT TRIGGER */
2549         else if (Matches2("DROP", "EVENT"))
2550                 COMPLETE_WITH_CONST("TRIGGER");
2551         else if (Matches3("DROP", "EVENT", "TRIGGER"))
2552                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2553
2554         /* DROP POLICY <name>  */
2555         else if (Matches2("DROP", "POLICY"))
2556                 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2557         /* DROP POLICY <name> ON */
2558         else if (Matches3("DROP", "POLICY", MatchAny))
2559                 COMPLETE_WITH_CONST("ON");
2560         /* DROP POLICY <name> ON <table> */
2561         else if (Matches4("DROP", "POLICY", MatchAny, "ON"))
2562         {
2563                 completion_info_charp = prev2_wd;
2564                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
2565         }
2566
2567         /* DROP RULE */
2568         else if (Matches3("DROP", "RULE", MatchAny))
2569                 COMPLETE_WITH_CONST("ON");
2570         else if (Matches4("DROP", "RULE", MatchAny, "ON"))
2571         {
2572                 completion_info_charp = prev2_wd;
2573                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2574         }
2575         else if (Matches5("DROP", "RULE", MatchAny, "ON", MatchAny))
2576                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2577
2578 /* EXECUTE */
2579         else if (Matches1("EXECUTE"))
2580                 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2581
2582 /* EXPLAIN */
2583
2584         /*
2585          * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands
2586          */
2587         else if (Matches1("EXPLAIN"))
2588                 COMPLETE_WITH_LIST7("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2589                                                         "ANALYZE", "VERBOSE");
2590         else if (Matches2("EXPLAIN", "ANALYZE"))
2591                 COMPLETE_WITH_LIST6("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2592                                                         "VERBOSE");
2593         else if (Matches2("EXPLAIN", "VERBOSE") ||
2594                          Matches3("EXPLAIN", "ANALYZE", "VERBOSE"))
2595                 COMPLETE_WITH_LIST5("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE");
2596
2597 /* FETCH && MOVE */
2598         /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
2599         else if (Matches1("FETCH|MOVE"))
2600                 COMPLETE_WITH_LIST4("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE");
2601         /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
2602         else if (Matches2("FETCH|MOVE", MatchAny))
2603                 COMPLETE_WITH_LIST3("ALL", "NEXT", "PRIOR");
2604
2605         /*
2606          * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
2607          * but we may as well tab-complete both: perhaps some users prefer one
2608          * variant or the other.
2609          */
2610         else if (Matches3("FETCH|MOVE", MatchAny, MatchAny))
2611                 COMPLETE_WITH_LIST2("FROM", "IN");
2612
2613 /* FOREIGN DATA WRAPPER */
2614         /* applies in ALTER/DROP FDW and in CREATE SERVER */
2615         else if (TailMatches3("FOREIGN", "DATA", "WRAPPER") &&
2616                          !TailMatches4("CREATE", MatchAny, MatchAny, MatchAny))
2617                 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
2618         /* applies in CREATE SERVER */
2619         else if (TailMatches4("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
2620                          HeadMatches2("CREATE", "SERVER"))
2621                 COMPLETE_WITH_CONST("OPTIONS");
2622
2623 /* FOREIGN TABLE */
2624         else if (TailMatches2("FOREIGN", "TABLE") &&
2625                          !TailMatches3("CREATE", MatchAny, MatchAny))
2626                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
2627
2628 /* FOREIGN SERVER */
2629         else if (TailMatches2("FOREIGN", "SERVER"))
2630                 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
2631
2632 /*
2633  * GRANT and REVOKE are allowed inside CREATE SCHEMA and
2634  * ALTER DEFAULT PRIVILEGES, so use TailMatches
2635  */
2636         /* Complete GRANT/REVOKE with a list of roles and privileges */
2637         else if (TailMatches1("GRANT|REVOKE"))
2638                 /*
2639                  * With ALTER DEFAULT PRIVILEGES, restrict completion
2640                  * to grantable privileges (can't grant roles)
2641                  */
2642                 if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2643                         COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE",
2644                                 "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2645                                                 "EXECUTE", "USAGE", "ALL");
2646                 else
2647                         COMPLETE_WITH_QUERY(Query_for_list_of_roles
2648                                                         " UNION SELECT 'SELECT'"
2649                                                         " UNION SELECT 'INSERT'"
2650                                                         " UNION SELECT 'UPDATE'"
2651                                                         " UNION SELECT 'DELETE'"
2652                                                         " UNION SELECT 'TRUNCATE'"
2653                                                         " UNION SELECT 'REFERENCES'"
2654                                                         " UNION SELECT 'TRIGGER'"
2655                                                         " UNION SELECT 'CREATE'"
2656                                                         " UNION SELECT 'CONNECT'"
2657                                                         " UNION SELECT 'TEMPORARY'"
2658                                                         " UNION SELECT 'EXECUTE'"
2659                                                         " UNION SELECT 'USAGE'"
2660                                                         " UNION SELECT 'ALL'");
2661
2662         /*
2663          * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
2664          * TO/FROM
2665          */
2666         else if (TailMatches2("GRANT|REVOKE", MatchAny))
2667         {
2668                 if (TailMatches1("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
2669                         COMPLETE_WITH_CONST("ON");
2670                 else if (TailMatches2("GRANT", MatchAny))
2671                         COMPLETE_WITH_CONST("TO");
2672                 else
2673                         COMPLETE_WITH_CONST("FROM");
2674         }
2675
2676         /*
2677          * Complete GRANT/REVOKE <sth> ON with a list of tables, views, and
2678          * sequences.
2679          *
2680          * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query
2681          * result via UNION; seems to work intuitively.
2682          *
2683          * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
2684          * here will only work if the privilege list contains exactly one
2685          * privilege.
2686          */
2687         else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON"))
2688                 /*
2689                  * With ALTER DEFAULT PRIVILEGES, restrict completion
2690                  * to the kinds of objects supported.
2691                  */
2692                 if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2693                         COMPLETE_WITH_LIST4("TABLES", "SEQUENCES", "FUNCTIONS", "TYPES");
2694                 else
2695                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf,
2696                                                                    " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
2697                                                                    " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
2698                                                                    " UNION SELECT 'ALL TABLES IN SCHEMA'"
2699                                                                    " UNION SELECT 'DATABASE'"
2700                                                                    " UNION SELECT 'DOMAIN'"
2701                                                                    " UNION SELECT 'FOREIGN DATA WRAPPER'"
2702                                                                    " UNION SELECT 'FOREIGN SERVER'"
2703                                                                    " UNION SELECT 'FUNCTION'"
2704                                                                    " UNION SELECT 'LANGUAGE'"
2705                                                                    " UNION SELECT 'LARGE OBJECT'"
2706                                                                    " UNION SELECT 'SCHEMA'"
2707                                                                    " UNION SELECT 'SEQUENCE'"
2708                                                                    " UNION SELECT 'TABLE'"
2709                                                                    " UNION SELECT 'TABLESPACE'"
2710                                                                    " UNION SELECT 'TYPE'");
2711
2712         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "ALL"))
2713                 COMPLETE_WITH_LIST3("FUNCTIONS IN SCHEMA", "SEQUENCES IN SCHEMA",
2714                                                         "TABLES IN SCHEMA");
2715
2716         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"))
2717                 COMPLETE_WITH_LIST2("DATA WRAPPER", "SERVER");
2718
2719         /*
2720          * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
2721          * appropriate objects.
2722          *
2723          * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
2724          */
2725         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", MatchAny))
2726         {
2727                 if (TailMatches1("DATABASE"))
2728                         COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2729                 else if (TailMatches1("DOMAIN"))
2730                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
2731                 else if (TailMatches1("FUNCTION"))
2732                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2733                 else if (TailMatches1("LANGUAGE"))
2734                         COMPLETE_WITH_QUERY(Query_for_list_of_languages);
2735                 else if (TailMatches1("SCHEMA"))
2736                         COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2737                 else if (TailMatches1("SEQUENCE"))
2738                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
2739                 else if (TailMatches1("TABLE"))
2740                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
2741                 else if (TailMatches1("TABLESPACE"))
2742                         COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
2743                 else if (TailMatches1("TYPE"))
2744                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
2745                 else if (TailMatches4("GRANT", MatchAny, MatchAny, MatchAny))
2746                         COMPLETE_WITH_CONST("TO");
2747                 else
2748                         COMPLETE_WITH_CONST("FROM");
2749         }
2750
2751         /*
2752          * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
2753          * CURRENT_USER, or SESSION_USER.
2754          */
2755         else if ((HeadMatches1("GRANT") && TailMatches1("TO")) ||
2756                          (HeadMatches1("REVOKE") && TailMatches1("FROM")))
2757                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2758         /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
2759         else if (HeadMatches3("ALTER","DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM"))
2760                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2761         /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
2762         else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny))
2763                 COMPLETE_WITH_CONST("TO");
2764         else if (HeadMatches1("REVOKE") && TailMatches3("ON", MatchAny, MatchAny))
2765                 COMPLETE_WITH_CONST("FROM");
2766
2767         /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
2768         else if (TailMatches8("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
2769         {
2770                 if (TailMatches8("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2771                         COMPLETE_WITH_CONST("TO");
2772                 else
2773                         COMPLETE_WITH_CONST("FROM");
2774         }
2775
2776         /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
2777         else if (TailMatches7("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2778         {
2779                 if (TailMatches7("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2780                         COMPLETE_WITH_CONST("TO");
2781                 else
2782                         COMPLETE_WITH_CONST("FROM");
2783         }
2784
2785         /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
2786         else if (TailMatches6("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
2787         {
2788                 if (TailMatches6("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2789                         COMPLETE_WITH_CONST("TO");
2790                 else
2791                         COMPLETE_WITH_CONST("FROM");
2792         }
2793
2794 /* GROUP BY */
2795         else if (TailMatches3("FROM", MatchAny, "GROUP"))
2796                 COMPLETE_WITH_CONST("BY");
2797
2798 /* IMPORT FOREIGN SCHEMA */
2799         else if (Matches1("IMPORT"))
2800                 COMPLETE_WITH_CONST("FOREIGN SCHEMA");
2801         else if (Matches2("IMPORT", "FOREIGN"))
2802                 COMPLETE_WITH_CONST("SCHEMA");
2803
2804 /* INSERT --- can be inside EXPLAIN, RULE, etc */
2805         /* Complete INSERT with "INTO" */
2806         else if (TailMatches1("INSERT"))
2807                 COMPLETE_WITH_CONST("INTO");
2808         /* Complete INSERT INTO with table names */
2809         else if (TailMatches2("INSERT", "INTO"))
2810                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2811         /* Complete "INSERT INTO <table> (" with attribute names */
2812         else if (TailMatches4("INSERT", "INTO", MatchAny, "("))
2813                 COMPLETE_WITH_ATTR(prev2_wd, "");
2814
2815         /*
2816          * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
2817          * "TABLE" or "DEFAULT VALUES"
2818          */
2819         else if (TailMatches3("INSERT", "INTO", MatchAny))
2820                 COMPLETE_WITH_LIST5("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES");
2821
2822         /*
2823          * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
2824          * "TABLE"
2825          */
2826         else if (TailMatches4("INSERT", "INTO", MatchAny, MatchAny) &&
2827                          ends_with(prev_wd, ')'))
2828                 COMPLETE_WITH_LIST3("SELECT", "TABLE", "VALUES");
2829
2830         /* Insert an open parenthesis after "VALUES" */
2831         else if (TailMatches1("VALUES") && !TailMatches2("DEFAULT", "VALUES"))
2832                 COMPLETE_WITH_CONST("(");
2833
2834 /* LOCK */
2835         /* Complete LOCK [TABLE] with a list of tables */
2836         else if (Matches1("LOCK"))
2837                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2838                                                                    " UNION SELECT 'TABLE'");
2839         else if (Matches2("LOCK", "TABLE"))
2840                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
2841
2842         /* For the following, handle the case of a single table only for now */
2843
2844         /* Complete LOCK [TABLE] <table> with "IN" */
2845         else if (Matches2("LOCK", MatchAnyExcept("TABLE")) ||
2846                          Matches3("LOCK", "TABLE", MatchAny))
2847                 COMPLETE_WITH_CONST("IN");
2848
2849         /* Complete LOCK [TABLE] <table> IN with a lock mode */
2850         else if (Matches3("LOCK", MatchAny, "IN") ||
2851                          Matches4("LOCK", "TABLE", MatchAny, "IN"))
2852                 COMPLETE_WITH_LIST8("ACCESS SHARE MODE",
2853                                                         "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
2854                                                         "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
2855                                                         "SHARE ROW EXCLUSIVE MODE",
2856                                                         "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
2857
2858         /* Complete LOCK [TABLE] <table> IN ACCESS|ROW with rest of lock mode */
2859         else if (Matches4("LOCK", MatchAny, "IN", "ACCESS|ROW") ||
2860                          Matches5("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW"))
2861                 COMPLETE_WITH_LIST2("EXCLUSIVE MODE", "SHARE MODE");
2862
2863         /* Complete LOCK [TABLE] <table> IN SHARE with rest of lock mode */
2864         else if (Matches4("LOCK", MatchAny, "IN", "SHARE") ||
2865                          Matches5("LOCK", "TABLE", MatchAny, "IN", "SHARE"))
2866                 COMPLETE_WITH_LIST3("MODE", "ROW EXCLUSIVE MODE",
2867                                                         "UPDATE EXCLUSIVE MODE");
2868
2869 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
2870         else if (TailMatches1("NOTIFY"))
2871                 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'");
2872
2873 /* OPTIONS */
2874         else if (TailMatches1("OPTIONS"))
2875                 COMPLETE_WITH_CONST("(");
2876
2877 /* OWNER TO  - complete with available roles */
2878         else if (TailMatches2("OWNER", "TO"))
2879                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2880
2881 /* ORDER BY */
2882         else if (TailMatches3("FROM", MatchAny, "ORDER"))
2883                 COMPLETE_WITH_CONST("BY");
2884         else if (TailMatches4("FROM", MatchAny, "ORDER", "BY"))
2885                 COMPLETE_WITH_ATTR(prev3_wd, "");
2886
2887 /* PREPARE xx AS */
2888         else if (Matches3("PREPARE", MatchAny, "AS"))
2889                 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE FROM");
2890
2891 /*
2892  * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
2893  * managers, not for manual use in interactive sessions.
2894  */
2895
2896 /* REASSIGN OWNED BY xxx TO yyy */
2897         else if (Matches1("REASSIGN"))
2898                 COMPLETE_WITH_CONST("OWNED BY");
2899         else if (Matches2("REASSIGN", "OWNED"))
2900                 COMPLETE_WITH_CONST("BY");
2901         else if (Matches3("REASSIGN", "OWNED", "BY"))
2902                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2903         else if (Matches4("REASSIGN", "OWNED", "BY", MatchAny))
2904                 COMPLETE_WITH_CONST("TO");
2905         else if (Matches5("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
2906                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2907
2908 /* REFRESH MATERIALIZED VIEW */
2909         else if (Matches1("REFRESH"))
2910                 COMPLETE_WITH_CONST("MATERIALIZED VIEW");
2911         else if (Matches2("REFRESH", "MATERIALIZED"))
2912                 COMPLETE_WITH_CONST("VIEW");
2913         else if (Matches3("REFRESH", "MATERIALIZED", "VIEW"))
2914                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
2915                                                                    " UNION SELECT 'CONCURRENTLY'");
2916         else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
2917                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2918         else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
2919                 COMPLETE_WITH_CONST("WITH");
2920         else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
2921                 COMPLETE_WITH_CONST("WITH");
2922         else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
2923                 COMPLETE_WITH_LIST2("NO DATA", "DATA");
2924         else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
2925                 COMPLETE_WITH_LIST2("NO DATA", "DATA");
2926         else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
2927                 COMPLETE_WITH_CONST("DATA");
2928         else if (Matches7("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
2929                 COMPLETE_WITH_CONST("DATA");
2930
2931 /* REINDEX */
2932         else if (Matches1("REINDEX"))
2933                 COMPLETE_WITH_LIST5("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
2934         else if (Matches2("REINDEX", "TABLE"))
2935                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2936         else if (Matches2("REINDEX", "INDEX"))
2937                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2938         else if (Matches2("REINDEX", "SCHEMA"))
2939                 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2940         else if (Matches2("REINDEX", "SYSTEM|DATABASE"))
2941                 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2942
2943 /* SECURITY LABEL */
2944         else if (Matches1("SECURITY"))
2945                 COMPLETE_WITH_CONST("LABEL");
2946         else if (Matches2("SECURITY", "LABEL"))
2947                 COMPLETE_WITH_LIST2("ON", "FOR");
2948         else if (Matches4("SECURITY", "LABEL", "FOR", MatchAny))
2949                 COMPLETE_WITH_CONST("ON");
2950         else if (Matches3("SECURITY", "LABEL", "ON") ||
2951                          Matches5("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
2952         {
2953                 static const char *const list_SECURITY_LABEL[] =
2954                 {"TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
2955                         "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", "LARGE OBJECT",
2956                         "MATERIALIZED VIEW", "LANGUAGE", "ROLE", "SCHEMA",
2957                 "SEQUENCE", "TABLESPACE", "TYPE", "VIEW", NULL};
2958
2959                 COMPLETE_WITH_LIST(list_SECURITY_LABEL);
2960         }
2961         else if (Matches5("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
2962                 COMPLETE_WITH_CONST("IS");
2963
2964 /* SELECT */
2965         /* naah . . . */
2966
2967 /* SET, RESET, SHOW */
2968         /* Complete with a variable name */
2969         else if (TailMatches1("SET|RESET") && !TailMatches3("UPDATE", MatchAny, "SET"))
2970                 COMPLETE_WITH_QUERY(Query_for_list_of_set_vars);
2971         else if (Matches1("SHOW"))
2972                 COMPLETE_WITH_QUERY(Query_for_list_of_show_vars);
2973         /* Complete "SET TRANSACTION" */
2974         else if (Matches2("SET", "TRANSACTION"))
2975                 COMPLETE_WITH_LIST5("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2976         else if (Matches2("BEGIN|START", "TRANSACTION") ||
2977                          Matches2("BEGIN", "WORK") ||
2978                          Matches1("BEGIN") ||
2979                   Matches5("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
2980                 COMPLETE_WITH_LIST4("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2981         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
2982                          Matches2("BEGIN", "NOT") ||
2983                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
2984                 COMPLETE_WITH_CONST("DEFERRABLE");
2985         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
2986                          Matches2("BEGIN", "ISOLATION") ||
2987                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
2988                 COMPLETE_WITH_CONST("LEVEL");
2989         else if (Matches4("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
2990                          Matches3("BEGIN", "ISOLATION", "LEVEL") ||
2991                          Matches7("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
2992                 COMPLETE_WITH_LIST3("READ", "REPEATABLE READ", "SERIALIZABLE");
2993         else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
2994                          Matches4("BEGIN", "ISOLATION", "LEVEL", "READ") ||
2995                          Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
2996                 COMPLETE_WITH_LIST2("UNCOMMITTED", "COMMITTED");
2997         else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
2998                          Matches4("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
2999                          Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
3000                 COMPLETE_WITH_CONST("READ");
3001         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
3002                          Matches2("BEGIN", "READ") ||
3003                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
3004                 COMPLETE_WITH_LIST2("ONLY", "WRITE");
3005         /* SET CONSTRAINTS */
3006         else if (Matches2("SET", "CONSTRAINTS"))
3007                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'");
3008         /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
3009         else if (Matches3("SET", "CONSTRAINTS", MatchAny))
3010                 COMPLETE_WITH_LIST2("DEFERRED", "IMMEDIATE");
3011         /* Complete SET ROLE */
3012         else if (Matches2("SET", "ROLE"))
3013                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3014         /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
3015         else if (Matches2("SET", "SESSION"))
3016                 COMPLETE_WITH_LIST2("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
3017         /* Complete SET SESSION AUTHORIZATION with username */
3018         else if (Matches3("SET", "SESSION", "AUTHORIZATION"))
3019                 COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'");
3020         /* Complete RESET SESSION with AUTHORIZATION */
3021         else if (Matches2("RESET", "SESSION"))
3022                 COMPLETE_WITH_CONST("AUTHORIZATION");
3023         /* Complete SET <var> with "TO" */
3024         else if (Matches2("SET", MatchAny))
3025                 COMPLETE_WITH_CONST("TO");
3026         /* Complete ALTER DATABASE|FUNCTION|ROLE|USER ... SET <name> */
3027         else if (HeadMatches2("ALTER", "DATABASE|FUNCTION|ROLE|USER") &&
3028                          TailMatches2("SET", MatchAny))
3029                 COMPLETE_WITH_LIST2("FROM CURRENT", "TO");
3030         /* Suggest possible variable values */
3031         else if (TailMatches3("SET", MatchAny, "TO|="))
3032         {
3033                 /* special cased code for individual GUCs */
3034                 if (TailMatches2("DateStyle", "TO|="))
3035                 {
3036                         static const char *const my_list[] =
3037                         {"ISO", "SQL", "Postgres", "German",
3038                                 "YMD", "DMY", "MDY",
3039                                 "US", "European", "NonEuropean",
3040                         "DEFAULT", NULL};
3041
3042                         COMPLETE_WITH_LIST(my_list);
3043                 }
3044                 else if (TailMatches2("search_path", "TO|="))
3045                         COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3046                                                                 " AND nspname not like 'pg\\_toast%%' "
3047                                                                 " AND nspname not like 'pg\\_temp%%' "
3048                                                                 " UNION SELECT 'DEFAULT' ");
3049                 else
3050                 {
3051                         /* generic, type based, GUC support */
3052                         char       *guctype = get_guctype(prev2_wd);
3053
3054                         if (guctype && strcmp(guctype, "enum") == 0)
3055                         {
3056                                 char            querybuf[1024];
3057
3058                                 snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd);
3059                                 COMPLETE_WITH_QUERY(querybuf);
3060                         }
3061                         else if (guctype && strcmp(guctype, "bool") == 0)
3062                                 COMPLETE_WITH_LIST9("on", "off", "true", "false", "yes", "no",
3063                                                                         "1", "0", "DEFAULT");
3064                         else
3065                                 COMPLETE_WITH_CONST("DEFAULT");
3066
3067                         if (guctype)
3068                                 free(guctype);
3069                 }
3070         }
3071
3072 /* START TRANSACTION */
3073         else if (Matches1("START"))
3074                 COMPLETE_WITH_CONST("TRANSACTION");
3075
3076 /* TABLE, but not TABLE embedded in other commands */
3077         else if (Matches1("TABLE"))
3078                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3079
3080 /* TABLESAMPLE */
3081         else if (TailMatches1("TABLESAMPLE"))
3082                 COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
3083         else if (TailMatches2("TABLESAMPLE", MatchAny))
3084                 COMPLETE_WITH_CONST("(");
3085
3086 /* TRUNCATE */
3087         else if (Matches1("TRUNCATE"))
3088                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3089
3090 /* UNLISTEN */
3091         else if (Matches1("UNLISTEN"))
3092                 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 '*'");
3093
3094 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
3095         /* If prev. word is UPDATE suggest a list of tables */
3096         else if (TailMatches1("UPDATE"))
3097                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3098         /* Complete UPDATE <table> with "SET" */
3099         else if (TailMatches2("UPDATE", MatchAny))
3100                 COMPLETE_WITH_CONST("SET");
3101         /* Complete UPDATE <table> SET with list of attributes */
3102         else if (TailMatches3("UPDATE", MatchAny, "SET"))
3103                 COMPLETE_WITH_ATTR(prev2_wd, "");
3104         /* UPDATE <table> SET <attr> = */
3105         else if (TailMatches4("UPDATE", MatchAny, "SET", MatchAny))
3106                 COMPLETE_WITH_CONST("=");
3107
3108 /* USER MAPPING */
3109         else if (Matches3("ALTER|CREATE|DROP", "USER", "MAPPING"))
3110                 COMPLETE_WITH_CONST("FOR");
3111         else if (Matches4("CREATE", "USER", "MAPPING", "FOR"))
3112                 COMPLETE_WITH_QUERY(Query_for_list_of_roles
3113                                                         " UNION SELECT 'CURRENT_USER'"
3114                                                         " UNION SELECT 'PUBLIC'"
3115                                                         " UNION SELECT 'USER'");
3116         else if (Matches4("ALTER|DROP", "USER", "MAPPING", "FOR"))
3117                 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3118         else if (Matches5("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
3119                 COMPLETE_WITH_CONST("SERVER");
3120         else if (Matches7("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
3121                 COMPLETE_WITH_CONST("OPTIONS");
3122
3123 /*
3124  * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ]
3125  * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]
3126  */
3127         else if (Matches1("VACUUM"))
3128                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3129                                                                    " UNION SELECT 'FULL'"
3130                                                                    " UNION SELECT 'FREEZE'"
3131                                                                    " UNION SELECT 'ANALYZE'"
3132                                                                    " UNION SELECT 'VERBOSE'");
3133         else if (Matches2("VACUUM", "FULL|FREEZE"))
3134                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3135                                                                    " UNION SELECT 'ANALYZE'"
3136                                                                    " UNION SELECT 'VERBOSE'");
3137         else if (Matches3("VACUUM", "FULL|FREEZE", "ANALYZE"))
3138                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3139                                                                    " UNION SELECT 'VERBOSE'");
3140         else if (Matches3("VACUUM", "FULL|FREEZE", "VERBOSE"))
3141                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3142                                                                    " UNION SELECT 'ANALYZE'");
3143         else if (Matches2("VACUUM", "VERBOSE"))
3144                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3145                                                                    " UNION SELECT 'ANALYZE'");
3146         else if (Matches2("VACUUM", "ANALYZE"))
3147                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3148                                                                    " UNION SELECT 'VERBOSE'");
3149         else if (HeadMatches1("VACUUM"))
3150                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
3151
3152 /* WITH [RECURSIVE] */
3153
3154         /*
3155          * Only match when WITH is the first word, as WITH may appear in many
3156          * other contexts.
3157          */
3158         else if (Matches1("WITH"))
3159                 COMPLETE_WITH_CONST("RECURSIVE");
3160
3161 /* ANALYZE */
3162         /* Complete with list of tables */
3163         else if (Matches1("ANALYZE"))
3164                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tmf, NULL);
3165
3166 /* WHERE */
3167         /* Simple case of the word before the where being the table name */
3168         else if (TailMatches2(MatchAny, "WHERE"))
3169                 COMPLETE_WITH_ATTR(prev2_wd, "");
3170
3171 /* ... FROM ... */
3172 /* TODO: also include SRF ? */
3173         else if (TailMatches1("FROM") && !Matches3("COPY|\\copy", MatchAny, "FROM"))
3174                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3175
3176 /* ... JOIN ... */
3177         else if (TailMatches1("JOIN"))
3178                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3179
3180 /* Backslash commands */
3181 /* TODO:  \dc \dd \dl */
3182         else if (TailMatchesCS1("\\?"))
3183                 COMPLETE_WITH_LIST_CS3("commands", "options", "variables");
3184         else if (TailMatchesCS1("\\connect|\\c"))
3185         {
3186                 if (!recognized_connection_string(text))
3187                         COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3188         }
3189         else if (TailMatchesCS2("\\connect|\\c", MatchAny))
3190         {
3191                 if (!recognized_connection_string(prev_wd))
3192                         COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3193         }
3194         else if (TailMatchesCS1("\\da*"))
3195                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
3196         else if (TailMatchesCS1("\\dA*"))
3197                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3198         else if (TailMatchesCS1("\\db*"))
3199                 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3200         else if (TailMatchesCS1("\\dD*"))
3201                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3202         else if (TailMatchesCS1("\\des*"))
3203                 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3204         else if (TailMatchesCS1("\\deu*"))
3205                 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3206         else if (TailMatchesCS1("\\dew*"))
3207                 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3208         else if (TailMatchesCS1("\\df*"))
3209                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3210
3211         else if (TailMatchesCS1("\\dFd*"))
3212                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
3213         else if (TailMatchesCS1("\\dFp*"))
3214                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
3215         else if (TailMatchesCS1("\\dFt*"))
3216                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
3217         /* must be at end of \dF alternatives: */
3218         else if (TailMatchesCS1("\\dF*"))
3219                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
3220
3221         else if (TailMatchesCS1("\\di*"))
3222                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3223         else if (TailMatchesCS1("\\dL*"))
3224                 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3225         else if (TailMatchesCS1("\\dn*"))
3226                 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3227         else if (TailMatchesCS1("\\dp") || TailMatchesCS1("\\z"))
3228                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3229         else if (TailMatchesCS1("\\ds*"))
3230                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3231         else if (TailMatchesCS1("\\dt*"))
3232                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3233         else if (TailMatchesCS1("\\dT*"))
3234                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3235         else if (TailMatchesCS1("\\du*") || TailMatchesCS1("\\dg*"))
3236                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3237         else if (TailMatchesCS1("\\dv*"))
3238                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3239         else if (TailMatchesCS1("\\dx*"))
3240                 COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
3241         else if (TailMatchesCS1("\\dm*"))
3242                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3243         else if (TailMatchesCS1("\\dE*"))
3244                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
3245         else if (TailMatchesCS1("\\dy*"))
3246                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3247
3248         /* must be at end of \d alternatives: */
3249         else if (TailMatchesCS1("\\d*"))
3250                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3251
3252         else if (TailMatchesCS1("\\ef"))
3253                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3254         else if (TailMatchesCS1("\\ev"))
3255                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3256
3257         else if (TailMatchesCS1("\\encoding"))
3258                 COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
3259         else if (TailMatchesCS1("\\h") || TailMatchesCS1("\\help"))
3260                 COMPLETE_WITH_LIST(sql_commands);
3261         else if (TailMatchesCS1("\\l*") && !TailMatchesCS1("\\lo*"))
3262                 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3263         else if (TailMatchesCS1("\\password"))
3264                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3265         else if (TailMatchesCS1("\\pset"))
3266         {
3267                 static const char *const my_list[] =
3268                 {"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
3269                         "footer", "format", "linestyle", "null", "numericlocale",
3270                         "pager", "pager_min_lines", "recordsep", "recordsep_zero",
3271                         "tableattr", "title", "tuples_only", "unicode_border_linestyle",
3272                 "unicode_column_linestyle", "unicode_header_linestyle", NULL};
3273
3274                 COMPLETE_WITH_LIST_CS(my_list);
3275         }
3276         else if (TailMatchesCS2("\\pset", MatchAny))
3277         {
3278                 if (TailMatchesCS1("format"))
3279                 {
3280                         static const char *const my_list[] =
3281                         {"unaligned", "aligned", "wrapped", "html", "asciidoc",
3282                         "latex", "latex-longtable", "troff-ms", NULL};
3283
3284                         COMPLETE_WITH_LIST_CS(my_list);
3285                 }
3286                 else if (TailMatchesCS1("linestyle"))
3287                         COMPLETE_WITH_LIST_CS3("ascii", "old-ascii", "unicode");
3288                 else if (TailMatchesCS1("unicode_border_linestyle|"
3289                                                                 "unicode_column_linestyle|"
3290                                                                 "unicode_header_linestyle"))
3291                         COMPLETE_WITH_LIST_CS2("single", "double");
3292         }
3293         else if (TailMatchesCS1("\\unset"))
3294         {
3295                 matches = complete_from_variables(text, "", "", true);
3296         }
3297         else if (TailMatchesCS1("\\set"))
3298         {
3299                 matches = complete_from_variables(text, "", "", false);
3300         }
3301         else if (TailMatchesCS2("\\set", MatchAny))
3302         {
3303                 if (TailMatchesCS1("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
3304                                                    "SINGLELINE|SINGLESTEP"))
3305                         COMPLETE_WITH_LIST_CS2("on", "off");
3306                 else if (TailMatchesCS1("COMP_KEYWORD_CASE"))
3307                         COMPLETE_WITH_LIST_CS4("lower", "upper",
3308                                                                    "preserve-lower", "preserve-upper");
3309                 else if (TailMatchesCS1("ECHO"))
3310                         COMPLETE_WITH_LIST_CS4("errors", "queries", "all", "none");
3311                 else if (TailMatchesCS1("ECHO_HIDDEN"))
3312                         COMPLETE_WITH_LIST_CS3("noexec", "off", "on");
3313                 else if (TailMatchesCS1("HISTCONTROL"))
3314                         COMPLETE_WITH_LIST_CS4("ignorespace", "ignoredups",
3315                                                                    "ignoreboth", "none");
3316                 else if (TailMatchesCS1("ON_ERROR_ROLLBACK"))
3317                         COMPLETE_WITH_LIST_CS3("on", "off", "interactive");
3318                 else if (TailMatchesCS1("SHOW_CONTEXT"))
3319                         COMPLETE_WITH_LIST_CS3("never", "errors", "always");
3320                 else if (TailMatchesCS1("VERBOSITY"))
3321                         COMPLETE_WITH_LIST_CS3("default", "verbose", "terse");
3322         }
3323         else if (TailMatchesCS1("\\sf*"))
3324                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3325         else if (TailMatchesCS1("\\sv*"))
3326                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3327         else if (TailMatchesCS1("\\cd|\\e|\\edit|\\g|\\i|\\include|"
3328                                                         "\\ir|\\include_relative|\\o|\\out|"
3329                                                         "\\s|\\w|\\write|\\lo_import"))
3330         {
3331                 completion_charp = "\\";
3332                 matches = completion_matches(text, complete_from_files);
3333         }
3334
3335         /*
3336          * Finally, we look through the list of "things", such as TABLE, INDEX and
3337          * check if that was the previous word. If so, execute the query to get a
3338          * list of them.
3339          */
3340         else
3341         {
3342                 int                     i;
3343
3344                 for (i = 0; words_after_create[i].name; i++)
3345                 {
3346                         if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
3347                         {
3348                                 if (words_after_create[i].query)
3349                                         COMPLETE_WITH_QUERY(words_after_create[i].query);
3350                                 else if (words_after_create[i].squery)
3351                                         COMPLETE_WITH_SCHEMA_QUERY(*words_after_create[i].squery,
3352                                                                                            NULL);
3353                                 break;
3354                         }
3355                 }
3356         }
3357
3358         /*
3359          * If we still don't have anything to match we have to fabricate some sort
3360          * of default list. If we were to just return NULL, readline automatically
3361          * attempts filename completion, and that's usually no good.
3362          */
3363         if (matches == NULL)
3364         {
3365                 COMPLETE_WITH_CONST("");
3366 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
3367                 rl_completion_append_character = '\0';
3368 #endif
3369         }
3370
3371         /* free storage */
3372         free(previous_words);
3373         free(words_buffer);
3374
3375         /* Return our Grand List O' Matches */
3376         return matches;
3377 }
3378
3379
3380 /*
3381  * GENERATOR FUNCTIONS
3382  *
3383  * These functions do all the actual work of completing the input. They get
3384  * passed the text so far and the count how many times they have been called
3385  * so far with the same text.
3386  * If you read the above carefully, you'll see that these don't get called
3387  * directly but through the readline interface.
3388  * The return value is expected to be the full completion of the text, going
3389  * through a list each time, or NULL if there are no more matches. The string
3390  * will be free()'d by readline, so you must run it through strdup() or
3391  * something of that sort.
3392  */
3393
3394 /*
3395  * Common routine for create_command_generator and drop_command_generator.
3396  * Entries that have 'excluded' flags are not returned.
3397  */
3398 static char *
3399 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
3400 {
3401         static int      list_index,
3402                                 string_length;
3403         const char *name;
3404
3405         /* If this is the first time for this completion, init some values */
3406         if (state == 0)
3407         {
3408                 list_index = 0;
3409                 string_length = strlen(text);
3410         }
3411
3412         /* find something that matches */
3413         while ((name = words_after_create[list_index++].name))
3414         {
3415                 if ((pg_strncasecmp(name, text, string_length) == 0) &&
3416                         !(words_after_create[list_index - 1].flags & excluded))
3417                         return pg_strdup_keyword_case(name, text);
3418         }
3419         /* if nothing matches, return NULL */
3420         return NULL;
3421 }
3422
3423 /*
3424  * This one gives you one from a list of things you can put after CREATE
3425  * as defined above.
3426  */
3427 static char *
3428 create_command_generator(const char *text, int state)
3429 {
3430         return create_or_drop_command_generator(text, state, THING_NO_CREATE);
3431 }
3432
3433 /*
3434  * This function gives you a list of things you can put after a DROP command.
3435  */
3436 static char *
3437 drop_command_generator(const char *text, int state)
3438 {
3439         return create_or_drop_command_generator(text, state, THING_NO_DROP);
3440 }
3441
3442 /* The following two functions are wrappers for _complete_from_query */
3443
3444 static char *
3445 complete_from_query(const char *text, int state)
3446 {
3447         return _complete_from_query(0, text, state);
3448 }
3449
3450 static char *
3451 complete_from_schema_query(const char *text, int state)
3452 {
3453         return _complete_from_query(1, text, state);
3454 }
3455
3456
3457 /*
3458  * This creates a list of matching things, according to a query pointed to
3459  * by completion_charp.
3460  * The query can be one of two kinds:
3461  *
3462  * 1. A simple query which must contain a %d and a %s, which will be replaced
3463  * by the string length of the text and the text itself. The query may also
3464  * have up to four more %s in it; the first two such will be replaced by the
3465  * value of completion_info_charp, the next two by the value of
3466  * completion_info_charp2.
3467  *
3468  * 2. A schema query used for completion of both schema and relation names.
3469  * These are more complex and must contain in the following order:
3470  * %d %s %d %s %d %s %s %d %s
3471  * where %d is the string length of the text and %s the text itself.
3472  *
3473  * It is assumed that strings should be escaped to become SQL literals
3474  * (that is, what is in the query is actually ... '%s' ...)
3475  *
3476  * See top of file for examples of both kinds of query.
3477  */
3478 static char *
3479 _complete_from_query(int is_schema_query, const char *text, int state)
3480 {
3481         static int      list_index,
3482                                 byte_length;
3483         static PGresult *result = NULL;
3484
3485         /*
3486          * If this is the first time for this completion, we fetch a list of our
3487          * "things" from the backend.
3488          */
3489         if (state == 0)
3490         {
3491                 PQExpBufferData query_buffer;
3492                 char       *e_text;
3493                 char       *e_info_charp;
3494                 char       *e_info_charp2;
3495                 const char *pstr = text;
3496                 int                     char_length = 0;
3497
3498                 list_index = 0;
3499                 byte_length = strlen(text);
3500
3501                 /*
3502                  * Count length as number of characters (not bytes), for passing to
3503                  * substring
3504                  */
3505                 while (*pstr)
3506                 {
3507                         char_length++;
3508                         pstr += PQmblen(pstr, pset.encoding);
3509                 }
3510
3511                 /* Free any prior result */
3512                 PQclear(result);
3513                 result = NULL;
3514
3515                 /* Set up suitably-escaped copies of textual inputs */
3516                 e_text = escape_string(text);
3517
3518                 if (completion_info_charp)
3519                         e_info_charp = escape_string(completion_info_charp);
3520                 else
3521                         e_info_charp = NULL;
3522
3523                 if (completion_info_charp2)
3524                         e_info_charp2 = escape_string(completion_info_charp2);
3525                 else
3526                         e_info_charp2 = NULL;
3527
3528                 initPQExpBuffer(&query_buffer);
3529
3530                 if (is_schema_query)
3531                 {
3532                         /* completion_squery gives us the pieces to assemble */
3533                         const char *qualresult = completion_squery->qualresult;
3534
3535                         if (qualresult == NULL)
3536                                 qualresult = completion_squery->result;
3537
3538                         /* Get unqualified names matching the input-so-far */
3539                         appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
3540                                                           completion_squery->result,
3541                                                           completion_squery->catname);
3542                         if (completion_squery->selcondition)
3543                                 appendPQExpBuffer(&query_buffer, "%s AND ",
3544                                                                   completion_squery->selcondition);
3545                         appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
3546                                                           completion_squery->result,
3547                                                           char_length, e_text);
3548                         appendPQExpBuffer(&query_buffer, " AND %s",
3549                                                           completion_squery->viscondition);
3550
3551                         /*
3552                          * When fetching relation names, suppress system catalogs unless
3553                          * the input-so-far begins with "pg_".  This is a compromise
3554                          * between not offering system catalogs for completion at all, and
3555                          * having them swamp the result when the input is just "p".
3556                          */
3557                         if (strcmp(completion_squery->catname,
3558                                            "pg_catalog.pg_class c") == 0 &&
3559                                 strncmp(text, "pg_", 3) !=0)
3560                         {
3561                                 appendPQExpBufferStr(&query_buffer,
3562                                                                          " AND c.relnamespace <> (SELECT oid FROM"
3563                                    " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
3564                         }
3565
3566                         /*
3567                          * Add in matching schema names, but only if there is more than
3568                          * one potential match among schema names.
3569                          */
3570                         appendPQExpBuffer(&query_buffer, "\nUNION\n"
3571                                                    "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
3572                                                           "FROM pg_catalog.pg_namespace n "
3573                                                           "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
3574                                                           char_length, e_text);
3575                         appendPQExpBuffer(&query_buffer,
3576                                                           " AND (SELECT pg_catalog.count(*)"
3577                                                           " FROM pg_catalog.pg_namespace"
3578                         " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3579                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
3580                                                           char_length, e_text);
3581
3582                         /*
3583                          * Add in matching qualified names, but only if there is exactly
3584                          * one schema matching the input-so-far.
3585                          */
3586                         appendPQExpBuffer(&query_buffer, "\nUNION\n"
3587                                          "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
3588                                                           "FROM %s, pg_catalog.pg_namespace n "
3589                                                           "WHERE %s = n.oid AND ",
3590                                                           qualresult,
3591                                                           completion_squery->catname,
3592                                                           completion_squery->namespace);
3593                         if (completion_squery->selcondition)
3594                                 appendPQExpBuffer(&query_buffer, "%s AND ",
3595                                                                   completion_squery->selcondition);
3596                         appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
3597                                                           qualresult,
3598                                                           char_length, e_text);
3599
3600                         /*
3601                          * This condition exploits the single-matching-schema rule to
3602                          * speed up the query
3603                          */
3604                         appendPQExpBuffer(&query_buffer,
3605                         " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
3606                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
3607                                                           char_length, e_text);
3608                         appendPQExpBuffer(&query_buffer,
3609                                                           " AND (SELECT pg_catalog.count(*)"
3610                                                           " FROM pg_catalog.pg_namespace"
3611                         " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3612                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
3613                                                           char_length, e_text);
3614
3615                         /* If an addon query was provided, use it */
3616                         if (completion_charp)
3617                                 appendPQExpBuffer(&query_buffer, "\n%s", completion_charp);
3618                 }
3619                 else
3620                 {
3621                         /* completion_charp is an sprintf-style format string */
3622                         appendPQExpBuffer(&query_buffer, completion_charp,
3623                                                           char_length, e_text,
3624                                                           e_info_charp, e_info_charp,
3625                                                           e_info_charp2, e_info_charp2);
3626                 }
3627
3628                 /* Limit the number of records in the result */
3629                 appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
3630                                                   completion_max_records);
3631
3632                 result = exec_query(query_buffer.data);
3633
3634                 termPQExpBuffer(&query_buffer);
3635                 free(e_text);
3636                 if (e_info_charp)
3637                         free(e_info_charp);
3638                 if (e_info_charp2)
3639                         free(e_info_charp2);
3640         }
3641
3642         /* Find something that matches */
3643         if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
3644         {
3645                 const char *item;
3646
3647                 while (list_index < PQntuples(result) &&
3648                            (item = PQgetvalue(result, list_index++, 0)))
3649                         if (pg_strncasecmp(text, item, byte_length) == 0)
3650                                 return pg_strdup(item);
3651         }
3652
3653         /* If nothing matches, free the db structure and return null */
3654         PQclear(result);
3655         result = NULL;
3656         return NULL;
3657 }
3658
3659
3660 /*
3661  * This function returns in order one of a fixed, NULL pointer terminated list
3662  * of strings (if matching). This can be used if there are only a fixed number
3663  * SQL words that can appear at certain spot.
3664  */
3665 static char *
3666 complete_from_list(const char *text, int state)
3667 {
3668         static int      string_length,
3669                                 list_index,
3670                                 matches;
3671         static bool casesensitive;
3672         const char *item;
3673
3674         /* need to have a list */
3675         Assert(completion_charpp != NULL);
3676
3677         /* Initialization */
3678         if (state == 0)
3679         {
3680                 list_index = 0;
3681                 string_length = strlen(text);
3682                 casesensitive = completion_case_sensitive;
3683                 matches = 0;
3684         }
3685
3686         while ((item = completion_charpp[list_index++]))
3687         {
3688                 /* First pass is case sensitive */
3689                 if (casesensitive && strncmp(text, item, string_length) == 0)
3690                 {
3691                         matches++;
3692                         return pg_strdup(item);
3693                 }
3694
3695                 /* Second pass is case insensitive, don't bother counting matches */
3696                 if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
3697                 {
3698                         if (completion_case_sensitive)
3699                                 return pg_strdup(item);
3700                         else
3701
3702                                 /*
3703                                  * If case insensitive matching was requested initially,
3704                                  * adjust the case according to setting.
3705                                  */
3706                                 return pg_strdup_keyword_case(item, text);
3707                 }
3708         }
3709
3710         /*
3711          * No matches found. If we're not case insensitive already, lets switch to
3712          * being case insensitive and try again
3713          */
3714         if (casesensitive && matches == 0)
3715         {
3716                 casesensitive = false;
3717                 list_index = 0;
3718                 state++;
3719                 return complete_from_list(text, state);
3720         }
3721
3722         /* If no more matches, return null. */
3723         return NULL;
3724 }
3725
3726
3727 /*
3728  * This function returns one fixed string the first time even if it doesn't
3729  * match what's there, and nothing the second time. This should be used if
3730  * there is only one possibility that can appear at a certain spot, so
3731  * misspellings will be overwritten.  The string to be passed must be in
3732  * completion_charp.
3733  */
3734 static char *
3735 complete_from_const(const char *text, int state)
3736 {
3737         Assert(completion_charp != NULL);
3738         if (state == 0)
3739         {
3740                 if (completion_case_sensitive)
3741                         return pg_strdup(completion_charp);
3742                 else
3743
3744                         /*
3745                          * If case insensitive matching was requested initially, adjust
3746                          * the case according to setting.
3747                          */
3748                         return pg_strdup_keyword_case(completion_charp, text);
3749         }
3750         else
3751                 return NULL;
3752 }
3753
3754
3755 /*
3756  * This function appends the variable name with prefix and suffix to
3757  * the variable names array.
3758  */
3759 static void
3760 append_variable_names(char ***varnames, int *nvars,
3761                                           int *maxvars, const char *varname,
3762                                           const char *prefix, const char *suffix)
3763 {
3764         if (*nvars >= *maxvars)
3765         {
3766                 *maxvars *= 2;
3767                 *varnames = (char **) pg_realloc(*varnames,
3768                                                                                  ((*maxvars) + 1) * sizeof(char *));
3769         }
3770
3771         (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
3772 }
3773
3774
3775 /*
3776  * This function supports completion with the name of a psql variable.
3777  * The variable names can be prefixed and suffixed with additional text
3778  * to support quoting usages. If need_value is true, only variables
3779  * that are currently set are included; otherwise, special variables
3780  * (those that have hooks) are included even if currently unset.
3781  */
3782 static char **
3783 complete_from_variables(const char *text, const char *prefix, const char *suffix,
3784                                                 bool need_value)
3785 {
3786         char      **matches;
3787         char      **varnames;
3788         int                     nvars = 0;
3789         int                     maxvars = 100;
3790         int                     i;
3791         struct _variable *ptr;
3792
3793         varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
3794
3795         for (ptr = pset.vars->next; ptr; ptr = ptr->next)
3796         {
3797                 if (need_value && !(ptr->value))
3798                         continue;
3799                 append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
3800                                                           prefix, suffix);
3801         }
3802
3803         varnames[nvars] = NULL;
3804         COMPLETE_WITH_LIST_CS((const char *const *) varnames);
3805
3806         for (i = 0; i < nvars; i++)
3807                 free(varnames[i]);
3808         free(varnames);
3809
3810         return matches;
3811 }
3812
3813
3814 /*
3815  * This function wraps rl_filename_completion_function() to strip quotes from
3816  * the input before searching for matches and to quote any matches for which
3817  * the consuming command will require it.
3818  */
3819 static char *
3820 complete_from_files(const char *text, int state)
3821 {
3822         static const char *unquoted_text;
3823         char       *unquoted_match;
3824         char       *ret = NULL;
3825
3826         if (state == 0)
3827         {
3828                 /* Initialization: stash the unquoted input. */
3829                 unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
3830                                                                 false, true, pset.encoding);
3831                 /* expect a NULL return for the empty string only */
3832                 if (!unquoted_text)
3833                 {
3834                         Assert(*text == '\0');
3835                         unquoted_text = text;
3836                 }
3837         }
3838
3839         unquoted_match = filename_completion_function(unquoted_text, state);
3840         if (unquoted_match)
3841         {
3842                 /*
3843                  * Caller sets completion_charp to a zero- or one-character string
3844                  * containing the escape character.  This is necessary since \copy has
3845                  * no escape character, but every other backslash command recognizes
3846                  * "\" as an escape character.  Since we have only two callers, don't
3847                  * bother providing a macro to simplify this.
3848                  */
3849                 ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
3850                                                           '\'', *completion_charp, pset.encoding);
3851                 if (ret)
3852                         free(unquoted_match);
3853                 else
3854                         ret = unquoted_match;
3855         }
3856
3857         return ret;
3858 }
3859
3860
3861 /* HELPER FUNCTIONS */
3862
3863
3864 /*
3865  * Make a pg_strdup copy of s and convert the case according to
3866  * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
3867  */
3868 static char *
3869 pg_strdup_keyword_case(const char *s, const char *ref)
3870 {
3871         char       *ret,
3872                            *p;
3873         unsigned char first = ref[0];
3874
3875         ret = pg_strdup(s);
3876
3877         if (pset.comp_case == PSQL_COMP_CASE_LOWER ||
3878                 ((pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER ||
3879            pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
3880                 (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
3881         {
3882                 for (p = ret; *p; p++)
3883                         *p = pg_tolower((unsigned char) *p);
3884         }
3885         else
3886         {
3887                 for (p = ret; *p; p++)
3888                         *p = pg_toupper((unsigned char) *p);
3889         }
3890
3891         return ret;
3892 }
3893
3894
3895 /*
3896  * escape_string - Escape argument for use as string literal.
3897  *
3898  * The returned value has to be freed.
3899  */
3900 static char *
3901 escape_string(const char *text)
3902 {
3903         size_t          text_length;
3904         char       *result;
3905
3906         text_length = strlen(text);
3907
3908         result = pg_malloc(text_length * 2 + 1);
3909         PQescapeStringConn(pset.db, result, text, text_length, NULL);
3910
3911         return result;
3912 }
3913
3914
3915 /*
3916  * Execute a query and report any errors. This should be the preferred way of
3917  * talking to the database in this file.
3918  */
3919 static PGresult *
3920 exec_query(const char *query)
3921 {
3922         PGresult   *result;
3923
3924         if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
3925                 return NULL;
3926
3927         result = PQexec(pset.db, query);
3928
3929         if (PQresultStatus(result) != PGRES_TUPLES_OK)
3930         {
3931 #ifdef NOT_USED
3932                 psql_error("tab completion query failed: %s\nQuery was:\n%s\n",
3933                                    PQerrorMessage(pset.db), query);
3934 #endif
3935                 PQclear(result);
3936                 result = NULL;
3937         }
3938
3939         return result;
3940 }
3941
3942
3943 /*
3944  * Parse all the word(s) before point.
3945  *
3946  * Returns a malloc'd array of character pointers that point into the malloc'd
3947  * data array returned to *buffer; caller must free() both of these when done.
3948  * *nwords receives the number of words found, ie, the valid length of the
3949  * return array.
3950  *
3951  * Words are returned right to left, that is, previous_words[0] gets the last
3952  * word before point, previous_words[1] the next-to-last, etc.
3953  */
3954 static char **
3955 get_previous_words(int point, char **buffer, int *nwords)
3956 {
3957         char      **previous_words;
3958         char       *buf;
3959         char       *outptr;
3960         int                     words_found = 0;
3961         int                     i;
3962
3963         /*
3964          * If we have anything in tab_completion_query_buf, paste it together with
3965          * rl_line_buffer to construct the full query.  Otherwise we can just use
3966          * rl_line_buffer as the input string.
3967          */
3968         if (tab_completion_query_buf && tab_completion_query_buf->len > 0)
3969         {
3970                 i = tab_completion_query_buf->len;
3971                 buf = pg_malloc(point + i + 2);
3972                 memcpy(buf, tab_completion_query_buf->data, i);
3973                 buf[i++] = '\n';
3974                 memcpy(buf + i, rl_line_buffer, point);
3975                 i += point;
3976                 buf[i] = '\0';
3977                 /* Readjust point to reference appropriate offset in buf */
3978                 point = i;
3979         }
3980         else
3981                 buf = rl_line_buffer;
3982
3983         /*
3984          * Allocate an array of string pointers and a buffer to hold the strings
3985          * themselves.  The worst case is that the line contains only
3986          * non-whitespace WORD_BREAKS characters, making each one a separate word.
3987          * This is usually much more space than we need, but it's cheaper than
3988          * doing a separate malloc() for each word.
3989          */
3990         previous_words = (char **) pg_malloc(point * sizeof(char *));
3991         *buffer = outptr = (char *) pg_malloc(point * 2);
3992
3993         /*
3994          * First we look for a non-word char before the current point.  (This is
3995          * probably useless, if readline is on the same page as we are about what
3996          * is a word, but if so it's cheap.)
3997          */
3998         for (i = point - 1; i >= 0; i--)
3999         {
4000                 if (strchr(WORD_BREAKS, buf[i]))
4001                         break;
4002         }
4003         point = i;
4004
4005         /*
4006          * Now parse words, working backwards, until we hit start of line.  The
4007          * backwards scan has some interesting but intentional properties
4008          * concerning parenthesis handling.
4009          */
4010         while (point >= 0)
4011         {
4012                 int                     start,
4013                                         end;
4014                 bool            inquotes = false;
4015                 int                     parentheses = 0;
4016
4017                 /* now find the first non-space which then constitutes the end */
4018                 end = -1;
4019                 for (i = point; i >= 0; i--)
4020                 {
4021                         if (!isspace((unsigned char) buf[i]))
4022                         {
4023                                 end = i;
4024                                 break;
4025                         }
4026                 }
4027                 /* if no end found, we're done */
4028                 if (end < 0)
4029                         break;
4030
4031                 /*
4032                  * Otherwise we now look for the start.  The start is either the last
4033                  * character before any word-break character going backwards from the
4034                  * end, or it's simply character 0.  We also handle open quotes and
4035                  * parentheses.
4036                  */
4037                 for (start = end; start > 0; start--)
4038                 {
4039                         if (buf[start] == '"')
4040                                 inquotes = !inquotes;
4041                         if (!inquotes)
4042                         {
4043                                 if (buf[start] == ')')
4044                                         parentheses++;
4045                                 else if (buf[start] == '(')
4046                                 {
4047                                         if (--parentheses <= 0)
4048                                                 break;
4049                                 }
4050                                 else if (parentheses == 0 &&
4051                                                  strchr(WORD_BREAKS, buf[start - 1]))
4052                                         break;
4053                         }
4054                 }
4055
4056                 /* Return the word located at start to end inclusive */
4057                 previous_words[words_found++] = outptr;
4058                 i = end - start + 1;
4059                 memcpy(outptr, &buf[start], i);
4060                 outptr += i;
4061                 *outptr++ = '\0';
4062
4063                 /* Continue searching */
4064                 point = start - 1;
4065         }
4066
4067         /* Release parsing input workspace, if we made one above */
4068         if (buf != rl_line_buffer)
4069                 free(buf);
4070
4071         *nwords = words_found;
4072         return previous_words;
4073 }
4074
4075 /*
4076  * Look up the type for the GUC variable with the passed name.
4077  *
4078  * Returns NULL if the variable is unknown. Otherwise the returned string,
4079  * containing the type, has to be freed.
4080  */
4081 static char *
4082 get_guctype(const char *varname)
4083 {
4084         PQExpBufferData query_buffer;
4085         char       *e_varname;
4086         PGresult   *result;
4087         char       *guctype = NULL;
4088
4089         e_varname = escape_string(varname);
4090
4091         initPQExpBuffer(&query_buffer);
4092         appendPQExpBuffer(&query_buffer,
4093                                           "SELECT vartype FROM pg_catalog.pg_settings "
4094                                           "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4095                                           e_varname);
4096
4097         result = exec_query(query_buffer.data);
4098         termPQExpBuffer(&query_buffer);
4099         free(e_varname);
4100
4101         if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
4102                 guctype = pg_strdup(PQgetvalue(result, 0, 0));
4103
4104         PQclear(result);
4105
4106         return guctype;
4107 }
4108
4109 #ifdef NOT_USED
4110
4111 /*
4112  * Surround a string with single quotes. This works for both SQL and
4113  * psql internal. Currently disabled because it is reported not to
4114  * cooperate with certain versions of readline.
4115  */
4116 static char *
4117 quote_file_name(char *text, int match_type, char *quote_pointer)
4118 {
4119         char       *s;
4120         size_t          length;
4121
4122         (void) quote_pointer;           /* not used */
4123
4124         length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
4125         s = pg_malloc(length);
4126         s[0] = '\'';
4127         strcpy(s + 1, text);
4128         if (match_type == SINGLE_MATCH)
4129                 s[length - 2] = '\'';
4130         s[length - 1] = '\0';
4131         return s;
4132 }
4133
4134 static char *
4135 dequote_file_name(char *text, char quote_char)
4136 {
4137         char       *s;
4138         size_t          length;
4139
4140         if (!quote_char)
4141                 return pg_strdup(text);
4142
4143         length = strlen(text);
4144         s = pg_malloc(length - 2 + 1);
4145         strlcpy(s, text +1, length - 2 + 1);
4146
4147         return s;
4148 }
4149 #endif   /* NOT_USED */
4150
4151 #endif   /* USE_READLINE */