]> granicus.if.org Git - postgresql/blob - src/bin/psql/tab-complete.c
Fix tab completion in psql for ALTER DEFAULT PRIVILEGES
[postgresql] / src / bin / psql / tab-complete.c
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2016, 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         {"ROLE", Query_for_list_of_roles},
964         {"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
965         {"SCHEMA", Query_for_list_of_schemas},
966         {"SEQUENCE", NULL, &Query_for_list_of_sequences},
967         {"SERVER", Query_for_list_of_servers},
968         {"TABLE", NULL, &Query_for_list_of_tables},
969         {"TABLESPACE", Query_for_list_of_tablespaces},
970         {"TEMP", NULL, NULL, THING_NO_DROP},            /* for CREATE TEMP TABLE ... */
971         {"TEMPLATE", Query_for_list_of_ts_templates, NULL, THING_NO_SHOW},
972         {"TEXT SEARCH", NULL, NULL},
973         {"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"},
974         {"TYPE", NULL, &Query_for_list_of_datatypes},
975         {"UNIQUE", NULL, NULL, THING_NO_DROP},          /* for CREATE UNIQUE INDEX ... */
976         {"UNLOGGED", NULL, NULL, THING_NO_DROP},        /* for CREATE UNLOGGED TABLE
977                                                                                                  * ... */
978         {"USER", Query_for_list_of_roles},
979         {"USER MAPPING FOR", NULL, NULL},
980         {"VIEW", NULL, &Query_for_list_of_views},
981         {NULL}                                          /* end of list */
982 };
983
984
985 /* Forward declaration of functions */
986 static char **psql_completion(const char *text, int start, int end);
987 static char *create_command_generator(const char *text, int state);
988 static char *drop_command_generator(const char *text, int state);
989 static char *complete_from_query(const char *text, int state);
990 static char *complete_from_schema_query(const char *text, int state);
991 static char *_complete_from_query(int is_schema_query,
992                                          const char *text, int state);
993 static char *complete_from_list(const char *text, int state);
994 static char *complete_from_const(const char *text, int state);
995 static void append_variable_names(char ***varnames, int *nvars,
996                                           int *maxvars, const char *varname,
997                                           const char *prefix, const char *suffix);
998 static char **complete_from_variables(const char *text,
999                                         const char *prefix, const char *suffix, bool need_value);
1000 static char *complete_from_files(const char *text, int state);
1001
1002 static char *pg_strdup_keyword_case(const char *s, const char *ref);
1003 static char *escape_string(const char *text);
1004 static PGresult *exec_query(const char *query);
1005
1006 static char **get_previous_words(int point, char **buffer, int *nwords);
1007
1008 static char *get_guctype(const char *varname);
1009
1010 #ifdef NOT_USED
1011 static char *quote_file_name(char *text, int match_type, char *quote_pointer);
1012 static char *dequote_file_name(char *text, char quote_char);
1013 #endif
1014
1015
1016 /*
1017  * Initialize the readline library for our purposes.
1018  */
1019 void
1020 initialize_readline(void)
1021 {
1022         rl_readline_name = (char *) pset.progname;
1023         rl_attempted_completion_function = psql_completion;
1024
1025         rl_basic_word_break_characters = WORD_BREAKS;
1026
1027         completion_max_records = 1000;
1028
1029         /*
1030          * There is a variable rl_completion_query_items for this but apparently
1031          * it's not defined everywhere.
1032          */
1033 }
1034
1035 /*
1036  * Check if 'word' matches any of the '|'-separated strings in 'pattern',
1037  * using case-insensitive or case-sensitive comparisons.
1038  *
1039  * If pattern is NULL, it's a wild card that matches any word.
1040  * If pattern begins with '!', the result is negated, ie we check that 'word'
1041  * does *not* match any alternative appearing in the rest of 'pattern'.
1042  * Any alternative can end with '*' which is a wild card, i.e., it means
1043  * match any word that matches the characters so far.  (We do not currently
1044  * support '*' elsewhere than the end of an alternative.)
1045  *
1046  * For readability, callers should use the macros MatchAny and MatchAnyExcept
1047  * to invoke those two special cases for 'pattern'.  (But '|' and '*' must
1048  * just be written directly in patterns.)
1049  */
1050 #define MatchAny  NULL
1051 #define MatchAnyExcept(pattern)  ("!" pattern)
1052
1053 static bool
1054 word_matches_internal(const char *pattern,
1055                                           const char *word,
1056                                           bool case_sensitive)
1057 {
1058         size_t          wordlen,
1059                                 patternlen;
1060
1061         /* NULL pattern matches anything. */
1062         if (pattern == NULL)
1063                 return true;
1064
1065         /* Handle negated patterns from the MatchAnyExcept macro. */
1066         if (*pattern == '!')
1067                 return !word_matches_internal(pattern + 1, word, case_sensitive);
1068
1069         /* Else consider each alternative in the pattern. */
1070         wordlen = strlen(word);
1071         for (;;)
1072         {
1073                 const char *c;
1074
1075                 /* Find end of current alternative. */
1076                 c = pattern;
1077                 while (*c != '\0' && *c != '|')
1078                         c++;
1079                 /* Was there a wild card?  (Assumes first alternative is not empty) */
1080                 if (c[-1] == '*')
1081                 {
1082                         /* Yes, wildcard match? */
1083                         patternlen = c - pattern - 1;
1084                         if (wordlen >= patternlen &&
1085                                 (case_sensitive ?
1086                                  strncmp(word, pattern, patternlen) == 0 :
1087                                  pg_strncasecmp(word, pattern, patternlen) == 0))
1088                                 return true;
1089                 }
1090                 else
1091                 {
1092                         /* No, plain match? */
1093                         patternlen = c - pattern;
1094                         if (wordlen == patternlen &&
1095                                 (case_sensitive ?
1096                                  strncmp(word, pattern, wordlen) == 0 :
1097                                  pg_strncasecmp(word, pattern, wordlen) == 0))
1098                                 return true;
1099                 }
1100                 /* Out of alternatives? */
1101                 if (*c == '\0')
1102                         break;
1103                 /* Nope, try next alternative. */
1104                 pattern = c + 1;
1105         }
1106
1107         return false;
1108 }
1109
1110 /*
1111  * There are enough matching calls below that it seems worth having these two
1112  * interface routines rather than including a third parameter in every call.
1113  *
1114  * word_matches --- match case-insensitively.
1115  */
1116 static bool
1117 word_matches(const char *pattern, const char *word)
1118 {
1119         return word_matches_internal(pattern, word, false);
1120 }
1121
1122 /*
1123  * word_matches_cs --- match case-sensitively.
1124  */
1125 static bool
1126 word_matches_cs(const char *pattern, const char *word)
1127 {
1128         return word_matches_internal(pattern, word, true);
1129 }
1130
1131 /*
1132  * Check if the final character of 's' is 'c'.
1133  */
1134 static bool
1135 ends_with(const char *s, char c)
1136 {
1137         size_t          length = strlen(s);
1138
1139         return (length > 0 && s[length - 1] == c);
1140 }
1141
1142 /*
1143  * The completion function.
1144  *
1145  * According to readline spec this gets passed the text entered so far and its
1146  * start and end positions in the readline buffer. The return value is some
1147  * partially obscure list format that can be generated by readline's
1148  * completion_matches() function, so we don't have to worry about it.
1149  */
1150 static char **
1151 psql_completion(const char *text, int start, int end)
1152 {
1153         /* This is the variable we'll return. */
1154         char      **matches = NULL;
1155
1156         /* Workspace for parsed words. */
1157         char       *words_buffer;
1158
1159         /* This array will contain pointers to parsed words. */
1160         char      **previous_words;
1161
1162         /* The number of words found on the input line. */
1163         int                     previous_words_count;
1164
1165         /*
1166          * For compactness, we use these macros to reference previous_words[].
1167          * Caution: do not access a previous_words[] entry without having checked
1168          * previous_words_count to be sure it's valid.  In most cases below, that
1169          * check is implicit in a TailMatches() or similar macro, but in some
1170          * places we have to check it explicitly.
1171          */
1172 #define prev_wd   (previous_words[0])
1173 #define prev2_wd  (previous_words[1])
1174 #define prev3_wd  (previous_words[2])
1175 #define prev4_wd  (previous_words[3])
1176 #define prev5_wd  (previous_words[4])
1177 #define prev6_wd  (previous_words[5])
1178 #define prev7_wd  (previous_words[6])
1179 #define prev8_wd  (previous_words[7])
1180 #define prev9_wd  (previous_words[8])
1181
1182         /* Macros for matching the last N words before point, case-insensitively. */
1183 #define TailMatches1(p1) \
1184         (previous_words_count >= 1 && \
1185          word_matches(p1, prev_wd))
1186
1187 #define TailMatches2(p2, p1) \
1188         (previous_words_count >= 2 && \
1189          word_matches(p1, prev_wd) && \
1190          word_matches(p2, prev2_wd))
1191
1192 #define TailMatches3(p3, p2, p1) \
1193         (previous_words_count >= 3 && \
1194          word_matches(p1, prev_wd) && \
1195          word_matches(p2, prev2_wd) && \
1196          word_matches(p3, prev3_wd))
1197
1198 #define TailMatches4(p4, p3, p2, p1) \
1199         (previous_words_count >= 4 && \
1200          word_matches(p1, prev_wd) && \
1201          word_matches(p2, prev2_wd) && \
1202          word_matches(p3, prev3_wd) && \
1203          word_matches(p4, prev4_wd))
1204
1205 #define TailMatches5(p5, p4, p3, p2, p1) \
1206         (previous_words_count >= 5 && \
1207          word_matches(p1, prev_wd) && \
1208          word_matches(p2, prev2_wd) && \
1209          word_matches(p3, prev3_wd) && \
1210          word_matches(p4, prev4_wd) && \
1211          word_matches(p5, prev5_wd))
1212
1213 #define TailMatches6(p6, p5, p4, p3, p2, p1) \
1214         (previous_words_count >= 6 && \
1215          word_matches(p1, prev_wd) && \
1216          word_matches(p2, prev2_wd) && \
1217          word_matches(p3, prev3_wd) && \
1218          word_matches(p4, prev4_wd) && \
1219          word_matches(p5, prev5_wd) && \
1220          word_matches(p6, prev6_wd))
1221
1222 #define TailMatches7(p7, p6, p5, p4, p3, p2, p1) \
1223         (previous_words_count >= 7 && \
1224          word_matches(p1, prev_wd) && \
1225          word_matches(p2, prev2_wd) && \
1226          word_matches(p3, prev3_wd) && \
1227          word_matches(p4, prev4_wd) && \
1228          word_matches(p5, prev5_wd) && \
1229          word_matches(p6, prev6_wd) && \
1230          word_matches(p7, prev7_wd))
1231
1232 #define TailMatches8(p8, p7, p6, p5, p4, p3, p2, p1) \
1233         (previous_words_count >= 8 && \
1234          word_matches(p1, prev_wd) && \
1235          word_matches(p2, prev2_wd) && \
1236          word_matches(p3, prev3_wd) && \
1237          word_matches(p4, prev4_wd) && \
1238          word_matches(p5, prev5_wd) && \
1239          word_matches(p6, prev6_wd) && \
1240          word_matches(p7, prev7_wd) && \
1241          word_matches(p8, prev8_wd))
1242
1243 #define TailMatches9(p9, p8, p7, p6, p5, p4, p3, p2, p1) \
1244         (previous_words_count >= 9 && \
1245          word_matches(p1, prev_wd) && \
1246          word_matches(p2, prev2_wd) && \
1247          word_matches(p3, prev3_wd) && \
1248          word_matches(p4, prev4_wd) && \
1249          word_matches(p5, prev5_wd) && \
1250          word_matches(p6, prev6_wd) && \
1251          word_matches(p7, prev7_wd) && \
1252          word_matches(p8, prev8_wd) && \
1253          word_matches(p9, prev9_wd))
1254
1255         /* Macros for matching the last N words before point, case-sensitively. */
1256 #define TailMatchesCS1(p1) \
1257         (previous_words_count >= 1 && \
1258          word_matches_cs(p1, prev_wd))
1259 #define TailMatchesCS2(p2, p1) \
1260         (previous_words_count >= 2 && \
1261          word_matches_cs(p1, prev_wd) && \
1262          word_matches_cs(p2, prev2_wd))
1263
1264         /*
1265          * Macros for matching N words beginning at the start of the line,
1266          * case-insensitively.
1267          */
1268 #define Matches1(p1) \
1269         (previous_words_count == 1 && \
1270          TailMatches1(p1))
1271 #define Matches2(p1, p2) \
1272         (previous_words_count == 2 && \
1273          TailMatches2(p1, p2))
1274 #define Matches3(p1, p2, p3) \
1275         (previous_words_count == 3 && \
1276          TailMatches3(p1, p2, p3))
1277 #define Matches4(p1, p2, p3, p4) \
1278         (previous_words_count == 4 && \
1279          TailMatches4(p1, p2, p3, p4))
1280 #define Matches5(p1, p2, p3, p4, p5) \
1281         (previous_words_count == 5 && \
1282          TailMatches5(p1, p2, p3, p4, p5))
1283 #define Matches6(p1, p2, p3, p4, p5, p6) \
1284         (previous_words_count == 6 && \
1285          TailMatches6(p1, p2, p3, p4, p5, p6))
1286 #define Matches7(p1, p2, p3, p4, p5, p6, p7) \
1287         (previous_words_count == 7 && \
1288          TailMatches7(p1, p2, p3, p4, p5, p6, p7))
1289 #define Matches8(p1, p2, p3, p4, p5, p6, p7, p8) \
1290         (previous_words_count == 8 && \
1291          TailMatches8(p1, p2, p3, p4, p5, p6, p7, p8))
1292 #define Matches9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \
1293         (previous_words_count == 9 && \
1294          TailMatches9(p1, p2, p3, p4, p5, p6, p7, p8, p9))
1295
1296         /*
1297          * Macros for matching N words at the start of the line, regardless of
1298          * what is after them, case-insensitively.
1299          */
1300 #define HeadMatches1(p1) \
1301         (previous_words_count >= 1 && \
1302          word_matches(p1, previous_words[previous_words_count - 1]))
1303
1304 #define HeadMatches2(p1, p2) \
1305         (previous_words_count >= 2 && \
1306          word_matches(p1, previous_words[previous_words_count - 1]) && \
1307          word_matches(p2, previous_words[previous_words_count - 2]))
1308
1309 #define HeadMatches3(p1, p2, p3) \
1310         (previous_words_count >= 3 && \
1311          word_matches(p1, previous_words[previous_words_count - 1]) && \
1312          word_matches(p2, previous_words[previous_words_count - 2]) && \
1313          word_matches(p3, previous_words[previous_words_count - 3]))
1314
1315         /* Known command-starting keywords. */
1316         static const char *const sql_commands[] = {
1317                 "ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER",
1318                 "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
1319                 "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
1320                 "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK",
1321                 "MOVE", "NOTIFY", "PREPARE",
1322                 "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
1323                 "RESET", "REVOKE", "ROLLBACK",
1324                 "SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
1325                 "TABLE", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", "VALUES", "WITH",
1326                 NULL
1327         };
1328
1329         /* psql's backslash commands. */
1330         static const char *const backslash_commands[] = {
1331                 "\\a", "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
1332                 "\\copyright", "\\crosstabview",
1333                 "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
1334                 "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
1335                 "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
1336                 "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\drds", "\\ds", "\\dS",
1337                 "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
1338                 "\\e", "\\echo", "\\ef", "\\encoding", "\\errverbose", "\\ev",
1339                 "\\f", "\\g", "\\gexec", "\\gset", "\\h", "\\help", "\\H", "\\i", "\\ir", "\\l",
1340                 "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
1341                 "\\o", "\\p", "\\password", "\\prompt", "\\pset", "\\q", "\\qecho", "\\r",
1342                 "\\s", "\\set", "\\setenv", "\\sf", "\\sv", "\\t", "\\T",
1343                 "\\timing", "\\unset", "\\x", "\\w", "\\watch", "\\z", "\\!", NULL
1344         };
1345
1346         (void) end;                                     /* "end" is not used */
1347
1348 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1349         rl_completion_append_character = ' ';
1350 #endif
1351
1352         /* Clear a few things. */
1353         completion_charp = NULL;
1354         completion_charpp = NULL;
1355         completion_info_charp = NULL;
1356         completion_info_charp2 = NULL;
1357
1358         /*
1359          * Scan the input line to extract the words before our current position.
1360          * According to those we'll make some smart decisions on what the user is
1361          * probably intending to type.
1362          */
1363         previous_words = get_previous_words(start,
1364                                                                                 &words_buffer,
1365                                                                                 &previous_words_count);
1366
1367         /* If current word is a backslash command, offer completions for that */
1368         if (text[0] == '\\')
1369                 COMPLETE_WITH_LIST_CS(backslash_commands);
1370
1371         /* If current word is a variable interpolation, handle that case */
1372         else if (text[0] == ':' && text[1] != ':')
1373         {
1374                 if (text[1] == '\'')
1375                         matches = complete_from_variables(text, ":'", "'", true);
1376                 else if (text[1] == '"')
1377                         matches = complete_from_variables(text, ":\"", "\"", true);
1378                 else
1379                         matches = complete_from_variables(text, ":", "", true);
1380         }
1381
1382         /* If no previous word, suggest one of the basic sql commands */
1383         else if (previous_words_count == 0)
1384                 COMPLETE_WITH_LIST(sql_commands);
1385
1386 /* CREATE */
1387         /* complete with something you can create */
1388         else if (TailMatches1("CREATE"))
1389                 matches = completion_matches(text, create_command_generator);
1390
1391 /* DROP, but not DROP embedded in other commands */
1392         /* complete with something you can drop */
1393         else if (Matches1("DROP"))
1394                 matches = completion_matches(text, drop_command_generator);
1395
1396 /* ALTER */
1397
1398         /* ALTER TABLE */
1399         else if (Matches2("ALTER", "TABLE"))
1400                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
1401                                                                    "UNION SELECT 'ALL IN TABLESPACE'");
1402
1403         /* ALTER something */
1404         else if (Matches1("ALTER"))
1405         {
1406                 static const char *const list_ALTER[] =
1407                 {"AGGREGATE", "COLLATION", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN",
1408                         "EVENT TRIGGER", "EXTENSION", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "FUNCTION",
1409                         "GROUP", "INDEX", "LANGUAGE", "LARGE OBJECT", "MATERIALIZED VIEW", "OPERATOR",
1410                         "POLICY", "ROLE", "RULE", "SCHEMA", "SERVER", "SEQUENCE", "SYSTEM", "TABLE",
1411                         "TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE",
1412                 "USER", "USER MAPPING FOR", "VIEW", NULL};
1413
1414                 COMPLETE_WITH_LIST(list_ALTER);
1415         }
1416         /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */
1417         else if (TailMatches4("ALL", "IN", "TABLESPACE", MatchAny))
1418                 COMPLETE_WITH_LIST2("SET TABLESPACE", "OWNED BY");
1419         /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */
1420         else if (TailMatches6("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"))
1421                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1422         /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */
1423         else if (TailMatches7("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny))
1424                 COMPLETE_WITH_CONST("SET TABLESPACE");
1425         /* ALTER AGGREGATE,FUNCTION <name> */
1426         else if (Matches3("ALTER", "AGGREGATE|FUNCTION", MatchAny))
1427                 COMPLETE_WITH_CONST("(");
1428         /* ALTER AGGREGATE,FUNCTION <name> (...) */
1429         else if (Matches4("ALTER", "AGGREGATE|FUNCTION", MatchAny, MatchAny))
1430         {
1431                 if (ends_with(prev_wd, ')'))
1432                         COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1433                 else
1434                         COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
1435         }
1436
1437         /* ALTER SCHEMA <name> */
1438         else if (Matches3("ALTER", "SCHEMA", MatchAny))
1439                 COMPLETE_WITH_LIST2("OWNER TO", "RENAME TO");
1440
1441         /* ALTER COLLATION <name> */
1442         else if (Matches3("ALTER", "COLLATION", MatchAny))
1443                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1444
1445         /* ALTER CONVERSION <name> */
1446         else if (Matches3("ALTER", "CONVERSION", MatchAny))
1447                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1448
1449         /* ALTER DATABASE <name> */
1450         else if (Matches3("ALTER", "DATABASE", MatchAny))
1451                 COMPLETE_WITH_LIST7("RESET", "SET", "OWNER TO", "RENAME TO",
1452                                                         "IS_TEMPLATE", "ALLOW_CONNECTIONS",
1453                                                         "CONNECTION LIMIT");
1454
1455         /* ALTER EVENT TRIGGER */
1456         else if (Matches3("ALTER", "EVENT", "TRIGGER"))
1457                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
1458
1459         /* ALTER EVENT TRIGGER <name> */
1460         else if (Matches4("ALTER", "EVENT", "TRIGGER", MatchAny))
1461                 COMPLETE_WITH_LIST4("DISABLE", "ENABLE", "OWNER TO", "RENAME TO");
1462
1463         /* ALTER EVENT TRIGGER <name> ENABLE */
1464         else if (Matches5("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"))
1465                 COMPLETE_WITH_LIST2("REPLICA", "ALWAYS");
1466
1467         /* ALTER EXTENSION <name> */
1468         else if (Matches3("ALTER", "EXTENSION", MatchAny))
1469                 COMPLETE_WITH_LIST4("ADD", "DROP", "UPDATE", "SET SCHEMA");
1470
1471         /* ALTER EXTENSION <name> UPDATE */
1472         else if (Matches4("ALTER", "EXTENSION", MatchAny, "UPDATE"))
1473         {
1474                 completion_info_charp = prev2_wd;
1475                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO);
1476         }
1477
1478         /* ALTER EXTENSION <name> UPDATE TO */
1479         else if (Matches5("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"))
1480         {
1481                 completion_info_charp = prev3_wd;
1482                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
1483         }
1484
1485         /* ALTER FOREIGN */
1486         else if (Matches2("ALTER", "FOREIGN"))
1487                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
1488
1489         /* ALTER FOREIGN DATA WRAPPER <name> */
1490         else if (Matches5("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
1491                 COMPLETE_WITH_LIST5("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO");
1492
1493         /* ALTER FOREIGN TABLE <name> */
1494         else if (Matches4("ALTER", "FOREIGN", "TABLE", MatchAny))
1495         {
1496                 static const char *const list_ALTER_FOREIGN_TABLE[] =
1497                 {"ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE", "INHERIT",
1498                         "NO INHERIT", "OPTIONS", "OWNER TO", "RENAME", "SET",
1499                 "VALIDATE CONSTRAINT", NULL};
1500
1501                 COMPLETE_WITH_LIST(list_ALTER_FOREIGN_TABLE);
1502         }
1503
1504         /* ALTER INDEX */
1505         else if (Matches2("ALTER", "INDEX"))
1506                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
1507                                                                    "UNION SELECT 'ALL IN TABLESPACE'");
1508         /* ALTER INDEX <name> */
1509         else if (Matches3("ALTER", "INDEX", MatchAny))
1510                 COMPLETE_WITH_LIST4("OWNER TO", "RENAME TO", "SET", "RESET");
1511         /* ALTER INDEX <name> SET */
1512         else if (Matches4("ALTER", "INDEX", MatchAny, "SET"))
1513                 COMPLETE_WITH_LIST2("(", "TABLESPACE");
1514         /* ALTER INDEX <name> RESET */
1515         else if (Matches4("ALTER", "INDEX", MatchAny, "RESET"))
1516                 COMPLETE_WITH_CONST("(");
1517         /* ALTER INDEX <foo> SET|RESET ( */
1518         else if (Matches5("ALTER", "INDEX", MatchAny, "RESET", "("))
1519                 COMPLETE_WITH_LIST3("fillfactor", "fastupdate",
1520                                                         "gin_pending_list_limit");
1521         else if (Matches5("ALTER", "INDEX", MatchAny, "SET", "("))
1522                 COMPLETE_WITH_LIST3("fillfactor =", "fastupdate =",
1523                                                         "gin_pending_list_limit =");
1524
1525         /* ALTER LANGUAGE <name> */
1526         else if (Matches3("ALTER", "LANGUAGE", MatchAny))
1527                 COMPLETE_WITH_LIST2("OWNER_TO", "RENAME TO");
1528
1529         /* ALTER LARGE OBJECT <oid> */
1530         else if (Matches4("ALTER", "LARGE", "OBJECT", MatchAny))
1531                 COMPLETE_WITH_CONST("OWNER TO");
1532
1533         /* ALTER MATERIALIZED VIEW */
1534         else if (Matches3("ALTER", "MATERIALIZED", "VIEW"))
1535                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
1536                                                                    "UNION SELECT 'ALL IN TABLESPACE'");
1537
1538         /* ALTER USER,ROLE <name> */
1539         else if (Matches3("ALTER", "USER|ROLE", MatchAny) &&
1540                          !TailMatches2("USER", "MAPPING"))
1541         {
1542                 static const char *const list_ALTERUSER[] =
1543                 {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1544                         "ENCRYPTED", "INHERIT", "LOGIN", "NOBYPASSRLS",
1545                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1546                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
1547                         "REPLICATION", "RESET", "SET", "SUPERUSER", "UNENCRYPTED",
1548                 "VALID UNTIL", "WITH", NULL};
1549
1550                 COMPLETE_WITH_LIST(list_ALTERUSER);
1551         }
1552
1553         /* ALTER USER,ROLE <name> WITH */
1554         else if (Matches4("ALTER", "USER|ROLE", MatchAny, "WITH"))
1555         {
1556                 /* Similar to the above, but don't complete "WITH" again. */
1557                 static const char *const list_ALTERUSER_WITH[] =
1558                 {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1559                         "ENCRYPTED", "INHERIT", "LOGIN", "NOBYPASSRLS",
1560                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1561                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
1562                         "REPLICATION", "RESET", "SET", "SUPERUSER", "UNENCRYPTED",
1563                 "VALID UNTIL", NULL};
1564
1565                 COMPLETE_WITH_LIST(list_ALTERUSER_WITH);
1566         }
1567
1568         /* complete ALTER USER,ROLE <name> ENCRYPTED,UNENCRYPTED with PASSWORD */
1569         else if (Matches4("ALTER", "USER|ROLE", MatchAny, "ENCRYPTED|UNENCRYPTED"))
1570                 COMPLETE_WITH_CONST("PASSWORD");
1571         /* ALTER DEFAULT PRIVILEGES */
1572         else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES"))
1573                 COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA");
1574         /* ALTER DEFAULT PRIVILEGES FOR */
1575         else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
1576                 COMPLETE_WITH_CONST("ROLE");
1577         /* ALTER DEFAULT PRIVILEGES IN */
1578         else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
1579                 COMPLETE_WITH_CONST("SCHEMA");
1580         /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
1581         else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1582                                 MatchAny))
1583                 COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA");
1584         /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
1585         else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1586                                 MatchAny))
1587                 COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE");
1588         /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
1589         else if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1590                                 MatchAny, "FOR"))
1591                 COMPLETE_WITH_CONST("ROLE");
1592         /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
1593         /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
1594         else if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1595                                         MatchAny, "IN", "SCHEMA", MatchAny) ||
1596                 Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1597                                         MatchAny, "FOR", "ROLE|USER", MatchAny))
1598                 COMPLETE_WITH_LIST2("GRANT", "REVOKE");
1599         /* ALTER DOMAIN <name> */
1600         else if (Matches3("ALTER", "DOMAIN", MatchAny))
1601                 COMPLETE_WITH_LIST6("ADD", "DROP", "OWNER TO", "RENAME", "SET",
1602                                                         "VALIDATE CONSTRAINT");
1603         /* ALTER DOMAIN <sth> DROP */
1604         else if (Matches4("ALTER", "DOMAIN", MatchAny, "DROP"))
1605                 COMPLETE_WITH_LIST3("CONSTRAINT", "DEFAULT", "NOT NULL");
1606         /* ALTER DOMAIN <sth> DROP|RENAME|VALIDATE CONSTRAINT */
1607         else if (Matches5("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
1608         {
1609                 completion_info_charp = prev3_wd;
1610                 COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
1611         }
1612         /* ALTER DOMAIN <sth> RENAME */
1613         else if (Matches4("ALTER", "DOMAIN", MatchAny, "RENAME"))
1614                 COMPLETE_WITH_LIST2("CONSTRAINT", "TO");
1615         /* ALTER DOMAIN <sth> RENAME CONSTRAINT <sth> */
1616         else if (Matches6("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny))
1617                 COMPLETE_WITH_CONST("TO");
1618
1619         /* ALTER DOMAIN <sth> SET */
1620         else if (Matches4("ALTER", "DOMAIN", MatchAny, "SET"))
1621                 COMPLETE_WITH_LIST3("DEFAULT", "NOT NULL", "SCHEMA");
1622         /* ALTER SEQUENCE <name> */
1623         else if (Matches3("ALTER", "SEQUENCE", MatchAny))
1624         {
1625                 static const char *const list_ALTERSEQUENCE[] =
1626                 {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE",
1627                 "SET SCHEMA", "OWNED BY", "OWNER TO", "RENAME TO", NULL};
1628
1629                 COMPLETE_WITH_LIST(list_ALTERSEQUENCE);
1630         }
1631         /* ALTER SEQUENCE <name> NO */
1632         else if (Matches4("ALTER", "SEQUENCE", MatchAny, "NO"))
1633                 COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE");
1634         /* ALTER SERVER <name> */
1635         else if (Matches3("ALTER", "SERVER", MatchAny))
1636                 COMPLETE_WITH_LIST4("VERSION", "OPTIONS", "OWNER TO", "RENAME TO");
1637         /* ALTER SERVER <name> VERSION <version> */
1638         else if (Matches5("ALTER", "SERVER", MatchAny, "VERSION", MatchAny))
1639                 COMPLETE_WITH_CONST("OPTIONS");
1640         /* ALTER SYSTEM SET, RESET, RESET ALL */
1641         else if (Matches2("ALTER", "SYSTEM"))
1642                 COMPLETE_WITH_LIST2("SET", "RESET");
1643         /* ALTER SYSTEM SET|RESET <name> */
1644         else if (Matches3("ALTER", "SYSTEM", "SET|RESET"))
1645                 COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars);
1646         /* ALTER VIEW <name> */
1647         else if (Matches3("ALTER", "VIEW", MatchAny))
1648                 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1649                                                         "SET SCHEMA");
1650         /* ALTER MATERIALIZED VIEW <name> */
1651         else if (Matches4("ALTER", "MATERIALIZED", "VIEW", MatchAny))
1652                 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1653                                                         "SET SCHEMA");
1654
1655         /* ALTER POLICY <name> */
1656         else if (Matches2("ALTER", "POLICY"))
1657                 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
1658         /* ALTER POLICY <name> ON */
1659         else if (Matches3("ALTER", "POLICY", MatchAny))
1660                 COMPLETE_WITH_CONST("ON");
1661         /* ALTER POLICY <name> ON <table> */
1662         else if (Matches4("ALTER", "POLICY", MatchAny, "ON"))
1663         {
1664                 completion_info_charp = prev2_wd;
1665                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
1666         }
1667         /* ALTER POLICY <name> ON <table> - show options */
1668         else if (Matches5("ALTER", "POLICY", MatchAny, "ON", MatchAny))
1669                 COMPLETE_WITH_LIST4("RENAME TO", "TO", "USING (", "WITH CHECK (");
1670         /* ALTER POLICY <name> ON <table> TO <role> */
1671         else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
1672                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
1673         /* ALTER POLICY <name> ON <table> USING ( */
1674         else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
1675                 COMPLETE_WITH_CONST("(");
1676         /* ALTER POLICY <name> ON <table> WITH CHECK ( */
1677         else if (Matches7("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
1678                 COMPLETE_WITH_CONST("(");
1679
1680         /* ALTER RULE <name>, add ON */
1681         else if (Matches3("ALTER", "RULE", MatchAny))
1682                 COMPLETE_WITH_CONST("ON");
1683
1684         /* If we have ALTER RULE <name> ON, then add the correct tablename */
1685         else if (Matches4("ALTER", "RULE", MatchAny, "ON"))
1686         {
1687                 completion_info_charp = prev2_wd;
1688                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1689         }
1690
1691         /* ALTER RULE <name> ON <name> */
1692         else if (Matches5("ALTER", "RULE", MatchAny, "ON", MatchAny))
1693                 COMPLETE_WITH_CONST("RENAME TO");
1694
1695         /* ALTER TRIGGER <name>, add ON */
1696         else if (Matches3("ALTER", "TRIGGER", MatchAny))
1697                 COMPLETE_WITH_CONST("ON");
1698
1699         else if (Matches4("ALTER", "TRIGGER", MatchAny, MatchAny))
1700         {
1701                 completion_info_charp = prev2_wd;
1702                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
1703         }
1704
1705         /*
1706          * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
1707          */
1708         else if (Matches4("ALTER", "TRIGGER", MatchAny, "ON"))
1709                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
1710
1711         /* ALTER TRIGGER <name> ON <name> */
1712         else if (Matches5("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
1713                 COMPLETE_WITH_CONST("RENAME TO");
1714
1715         /*
1716          * If we detect ALTER TABLE <name>, suggest sub commands
1717          */
1718         else if (Matches3("ALTER", "TABLE", MatchAny))
1719         {
1720                 static const char *const list_ALTER2[] =
1721                 {"ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", "ENABLE", "INHERIT",
1722                         "NO INHERIT", "RENAME", "RESET", "OWNER TO", "SET",
1723                 "VALIDATE CONSTRAINT", "REPLICA IDENTITY", NULL};
1724
1725                 COMPLETE_WITH_LIST(list_ALTER2);
1726         }
1727         /* ALTER TABLE xxx ENABLE */
1728         else if (Matches4("ALTER", "TABLE", MatchAny, "ENABLE"))
1729                 COMPLETE_WITH_LIST5("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
1730                                                         "TRIGGER");
1731         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
1732                 COMPLETE_WITH_LIST2("RULE", "TRIGGER");
1733         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
1734         {
1735                 completion_info_charp = prev3_wd;
1736                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1737         }
1738         else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
1739         {
1740                 completion_info_charp = prev4_wd;
1741                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1742         }
1743         else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
1744         {
1745                 completion_info_charp = prev3_wd;
1746                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1747         }
1748         else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
1749         {
1750                 completion_info_charp = prev4_wd;
1751                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1752         }
1753         /* ALTER TABLE xxx INHERIT */
1754         else if (Matches4("ALTER", "TABLE", MatchAny, "INHERIT"))
1755                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1756         /* ALTER TABLE xxx NO INHERIT */
1757         else if (Matches5("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
1758                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1759         /* ALTER TABLE xxx DISABLE */
1760         else if (Matches4("ALTER", "TABLE", MatchAny, "DISABLE"))
1761                 COMPLETE_WITH_LIST3("ROW LEVEL SECURITY", "RULE", "TRIGGER");
1762         else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
1763         {
1764                 completion_info_charp = prev3_wd;
1765                 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1766         }
1767         else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
1768         {
1769                 completion_info_charp = prev3_wd;
1770                 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1771         }
1772
1773         /* ALTER TABLE xxx ALTER */
1774         else if (Matches4("ALTER", "TABLE", MatchAny, "ALTER"))
1775                 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'");
1776
1777         /* ALTER TABLE xxx RENAME */
1778         else if (Matches4("ALTER", "TABLE", MatchAny, "RENAME"))
1779                 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'");
1780         else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
1781                 COMPLETE_WITH_ATTR(prev3_wd, "");
1782
1783         /* ALTER TABLE xxx RENAME yyy */
1784         else if (Matches5("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
1785                 COMPLETE_WITH_CONST("TO");
1786
1787         /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
1788         else if (Matches6("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
1789                 COMPLETE_WITH_CONST("TO");
1790
1791         /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
1792         else if (Matches4("ALTER", "TABLE", MatchAny, "DROP"))
1793                 COMPLETE_WITH_LIST2("COLUMN", "CONSTRAINT");
1794         /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
1795         else if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
1796                 COMPLETE_WITH_ATTR(prev3_wd, "");
1797
1798         /*
1799          * If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
1800          * provide list of constraints
1801          */
1802         else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
1803         {
1804                 completion_info_charp = prev3_wd;
1805                 COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
1806         }
1807         /* ALTER TABLE ALTER [COLUMN] <foo> */
1808         else if (Matches6("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
1809                          Matches5("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
1810                 COMPLETE_WITH_LIST4("TYPE", "SET", "RESET", "DROP");
1811         /* ALTER TABLE ALTER [COLUMN] <foo> SET */
1812         else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
1813                          Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
1814                 COMPLETE_WITH_LIST5("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE");
1815         /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
1816         else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
1817                  Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
1818                 COMPLETE_WITH_LIST2("n_distinct", "n_distinct_inherited");
1819         /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
1820         else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
1821         Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
1822                 COMPLETE_WITH_LIST4("PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
1823         /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
1824         else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
1825                          Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
1826                 COMPLETE_WITH_LIST2("DEFAULT", "NOT NULL");
1827         else if (Matches4("ALTER", "TABLE", MatchAny, "CLUSTER"))
1828                 COMPLETE_WITH_CONST("ON");
1829         else if (Matches5("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
1830         {
1831                 completion_info_charp = prev3_wd;
1832                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1833         }
1834         /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
1835         else if (Matches4("ALTER", "TABLE", MatchAny, "SET"))
1836                 COMPLETE_WITH_LIST7("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED",
1837                                                         "WITH", "WITHOUT");
1838
1839         /*
1840          * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
1841          * tablespaces
1842          */
1843         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
1844                 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1845         /* If we have ALTER TABLE <sth> SET WITH provide OIDS */
1846         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITH"))
1847                 COMPLETE_WITH_CONST("OIDS");
1848         /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
1849         else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
1850                 COMPLETE_WITH_LIST2("CLUSTER", "OIDS");
1851         /* ALTER TABLE <foo> RESET */
1852         else if (Matches4("ALTER", "TABLE", MatchAny, "RESET"))
1853                 COMPLETE_WITH_CONST("(");
1854         /* ALTER TABLE <foo> SET|RESET ( */
1855         else if (Matches5("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
1856         {
1857                 static const char *const list_TABLEOPTIONS[] =
1858                 {
1859                         "autovacuum_analyze_scale_factor",
1860                         "autovacuum_analyze_threshold",
1861                         "autovacuum_enabled",
1862                         "autovacuum_freeze_max_age",
1863                         "autovacuum_freeze_min_age",
1864                         "autovacuum_freeze_table_age",
1865                         "autovacuum_multixact_freeze_max_age",
1866                         "autovacuum_multixact_freeze_min_age",
1867                         "autovacuum_multixact_freeze_table_age",
1868                         "autovacuum_vacuum_cost_delay",
1869                         "autovacuum_vacuum_cost_limit",
1870                         "autovacuum_vacuum_scale_factor",
1871                         "autovacuum_vacuum_threshold",
1872                         "fillfactor",
1873                         "parallel_workers",
1874                         "log_autovacuum_min_duration",
1875                         "toast.autovacuum_enabled",
1876                         "toast.autovacuum_freeze_max_age",
1877                         "toast.autovacuum_freeze_min_age",
1878                         "toast.autovacuum_freeze_table_age",
1879                         "toast.autovacuum_multixact_freeze_max_age",
1880                         "toast.autovacuum_multixact_freeze_min_age",
1881                         "toast.autovacuum_multixact_freeze_table_age",
1882                         "toast.autovacuum_vacuum_cost_delay",
1883                         "toast.autovacuum_vacuum_cost_limit",
1884                         "toast.autovacuum_vacuum_scale_factor",
1885                         "toast.autovacuum_vacuum_threshold",
1886                         "toast.log_autovacuum_min_duration",
1887                         "user_catalog_table",
1888                         NULL
1889                 };
1890
1891                 COMPLETE_WITH_LIST(list_TABLEOPTIONS);
1892         }
1893         else if (Matches7("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
1894         {
1895                 completion_info_charp = prev5_wd;
1896                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1897         }
1898         else if (Matches6("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
1899                 COMPLETE_WITH_CONST("INDEX");
1900         else if (Matches5("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
1901                 COMPLETE_WITH_LIST4("FULL", "NOTHING", "DEFAULT", "USING");
1902         else if (Matches4("ALTER", "TABLE", MatchAny, "REPLICA"))
1903                 COMPLETE_WITH_CONST("IDENTITY");
1904
1905         /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
1906         else if (Matches3("ALTER", "TABLESPACE", MatchAny))
1907                 COMPLETE_WITH_LIST4("RENAME TO", "OWNER TO", "SET", "RESET");
1908         /* ALTER TABLESPACE <foo> SET|RESET */
1909         else if (Matches4("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
1910                 COMPLETE_WITH_CONST("(");
1911         /* ALTER TABLESPACE <foo> SET|RESET ( */
1912         else if (Matches5("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
1913                 COMPLETE_WITH_LIST3("seq_page_cost", "random_page_cost",
1914                                                         "effective_io_concurrency");
1915
1916         /* ALTER TEXT SEARCH */
1917         else if (Matches3("ALTER", "TEXT", "SEARCH"))
1918                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
1919         else if (Matches5("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
1920                 COMPLETE_WITH_LIST2("RENAME TO", "SET SCHEMA");
1921         else if (Matches5("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
1922                 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1923         else if (Matches5("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
1924                 COMPLETE_WITH_LIST6("ADD MAPPING FOR", "ALTER MAPPING",
1925                                                         "DROP MAPPING FOR",
1926                                                         "OWNER TO", "RENAME TO", "SET SCHEMA");
1927
1928         /* complete ALTER TYPE <foo> with actions */
1929         else if (Matches3("ALTER", "TYPE", MatchAny))
1930                 COMPLETE_WITH_LIST7("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
1931                                                         "DROP ATTRIBUTE",
1932                                                         "OWNER TO", "RENAME", "SET SCHEMA");
1933         /* complete ALTER TYPE <foo> ADD with actions */
1934         else if (Matches4("ALTER", "TYPE", MatchAny, "ADD"))
1935                 COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE");
1936         /* ALTER TYPE <foo> RENAME      */
1937         else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME"))
1938                 COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE");
1939         /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
1940         else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
1941                 COMPLETE_WITH_CONST("TO");
1942         /*
1943          * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
1944          * of attributes
1945          */
1946         else if (Matches5("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
1947                 COMPLETE_WITH_ATTR(prev3_wd, "");
1948         /* ALTER TYPE ALTER ATTRIBUTE <foo> */
1949         else if (Matches6("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
1950                 COMPLETE_WITH_CONST("TYPE");
1951         /* complete ALTER GROUP <foo> */
1952         else if (Matches3("ALTER", "GROUP", MatchAny))
1953                 COMPLETE_WITH_LIST3("ADD USER", "DROP USER", "RENAME TO");
1954         /* complete ALTER GROUP <foo> ADD|DROP with USER */
1955         else if (Matches4("ALTER", "GROUP", MatchAny, "ADD|DROP"))
1956                 COMPLETE_WITH_CONST("USER");
1957         /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
1958         else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
1959                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1960
1961         /*
1962          * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
1963          */
1964         else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
1965                 COMPLETE_WITH_ENUM_VALUE(prev3_wd);
1966
1967 /* BEGIN */
1968         else if (Matches1("BEGIN"))
1969                 COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
1970 /* END, ABORT */
1971         else if (Matches1("END|ABORT"))
1972                 COMPLETE_WITH_LIST2("WORK", "TRANSACTION");
1973 /* COMMIT */
1974         else if (Matches1("COMMIT"))
1975                 COMPLETE_WITH_LIST3("WORK", "TRANSACTION", "PREPARED");
1976 /* RELEASE SAVEPOINT */
1977         else if (Matches1("RELEASE"))
1978                 COMPLETE_WITH_CONST("SAVEPOINT");
1979 /* ROLLBACK */
1980         else if (Matches1("ROLLBACK"))
1981                 COMPLETE_WITH_LIST4("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
1982 /* CLUSTER */
1983         else if (Matches1("CLUSTER"))
1984                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, "UNION SELECT 'VERBOSE'");
1985         else if (Matches2("CLUSTER", "VERBOSE"))
1986                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
1987         /* If we have CLUSTER <sth>, then add "USING" */
1988         else if (Matches2("CLUSTER", MatchAnyExcept("VERBOSE|ON")))
1989                 COMPLETE_WITH_CONST("USING");
1990         /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
1991         else if (Matches3("CLUSTER", "VERBOSE", MatchAny))
1992                 COMPLETE_WITH_CONST("USING");
1993         /* If we have CLUSTER <sth> USING, then add the index as well */
1994         else if (Matches3("CLUSTER", MatchAny, "USING") ||
1995                          Matches4("CLUSTER", "VERBOSE", MatchAny, "USING"))
1996         {
1997                 completion_info_charp = prev2_wd;
1998                 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1999         }
2000
2001 /* COMMENT */
2002         else if (Matches1("COMMENT"))
2003                 COMPLETE_WITH_CONST("ON");
2004         else if (Matches2("COMMENT", "ON"))
2005         {
2006                 static const char *const list_COMMENT[] =
2007                 {"ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", "DATABASE",
2008                         "EVENT TRIGGER", "EXTENSION",
2009                         "FOREIGN DATA WRAPPER", "FOREIGN TABLE",
2010                         "SERVER", "INDEX", "LANGUAGE", "POLICY", "RULE", "SCHEMA", "SEQUENCE",
2011                         "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
2012                         "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
2013                 "TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
2014
2015                 COMPLETE_WITH_LIST(list_COMMENT);
2016         }
2017         else if (Matches4("COMMENT", "ON", "ACCESS", "METHOD"))
2018                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2019         else if (Matches3("COMMENT", "ON", "FOREIGN"))
2020                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2021         else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH"))
2022                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2023         else if (Matches3("COMMENT", "ON", "CONSTRAINT"))
2024                 COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2025         else if (Matches4("COMMENT", "ON", "CONSTRAINT", MatchAny))
2026                 COMPLETE_WITH_CONST("ON");
2027         else if (Matches5("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2028         {
2029                 completion_info_charp = prev2_wd;
2030                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint);
2031         }
2032         else if (Matches4("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2033                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2034         else if (Matches4("COMMENT", "ON", "EVENT", "TRIGGER"))
2035                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2036         else if (Matches4("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2037                 Matches5("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2038                          Matches6("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2039                 COMPLETE_WITH_CONST("IS");
2040
2041 /* COPY */
2042
2043         /*
2044          * If we have COPY, offer list of tables or "(" (Also cover the analogous
2045          * backslash command).
2046          */
2047         else if (Matches1("COPY|\\copy"))
2048                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2049                                                                    " UNION ALL SELECT '('");
2050         /* If we have COPY BINARY, complete with list of tables */
2051         else if (Matches2("COPY", "BINARY"))
2052                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2053         /* If we have COPY (, complete it with legal commands */
2054         else if (Matches2("COPY|\\copy", "("))
2055                 COMPLETE_WITH_LIST7("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH");
2056         /* If we have COPY [BINARY] <sth>, complete it with "TO" or "FROM" */
2057         else if (Matches2("COPY|\\copy", MatchAny) ||
2058                          Matches3("COPY", "BINARY", MatchAny))
2059                 COMPLETE_WITH_LIST2("FROM", "TO");
2060         /* If we have COPY [BINARY] <sth> FROM|TO, complete with filename */
2061         else if (Matches3("COPY|\\copy", MatchAny, "FROM|TO") ||
2062                          Matches4("COPY", "BINARY", MatchAny, "FROM|TO"))
2063         {
2064                 completion_charp = "";
2065                 matches = completion_matches(text, complete_from_files);
2066         }
2067
2068         /* Handle COPY [BINARY] <sth> FROM|TO filename */
2069         else if (Matches4("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
2070                          Matches5("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
2071                 COMPLETE_WITH_LIST6("BINARY", "OIDS", "DELIMITER", "NULL", "CSV",
2072                                                         "ENCODING");
2073
2074         /* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
2075         else if (Matches5("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") ||
2076                          Matches6("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV"))
2077                 COMPLETE_WITH_LIST5("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE",
2078                                                         "FORCE NOT NULL");
2079
2080         /* CREATE ACCESS METHOD */
2081         /* Complete "CREATE ACCESS METHOD <name>" */
2082         else if (Matches4("CREATE", "ACCESS", "METHOD", MatchAny))
2083                 COMPLETE_WITH_CONST("TYPE");
2084         /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2085         else if (Matches5("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2086                 COMPLETE_WITH_CONST("INDEX");
2087         /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2088         else if (Matches6("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2089                 COMPLETE_WITH_CONST("HANDLER");
2090
2091         /* CREATE DATABASE */
2092         else if (Matches3("CREATE", "DATABASE", MatchAny))
2093                 COMPLETE_WITH_LIST9("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2094                                                         "IS_TEMPLATE",
2095                                                         "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2096                                                         "LC_COLLATE", "LC_CTYPE");
2097
2098         else if (Matches4("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2099                 COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2100
2101         /* CREATE EXTENSION */
2102         /* Complete with available extensions rather than installed ones. */
2103         else if (Matches2("CREATE", "EXTENSION"))
2104                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2105         /* CREATE EXTENSION <name> */
2106         else if (Matches3("CREATE", "EXTENSION", MatchAny))
2107                 COMPLETE_WITH_LIST3("WITH SCHEMA", "CASCADE", "VERSION");
2108         /* CREATE EXTENSION <name> VERSION */
2109         else if (Matches4("CREATE", "EXTENSION", MatchAny, "VERSION"))
2110         {
2111                 completion_info_charp = prev2_wd;
2112                 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2113         }
2114
2115         /* CREATE FOREIGN */
2116         else if (Matches2("CREATE", "FOREIGN"))
2117                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2118
2119         /* CREATE FOREIGN DATA WRAPPER */
2120         else if (Matches5("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2121                 COMPLETE_WITH_LIST3("HANDLER", "VALIDATOR", "OPTIONS");
2122
2123         /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2124         /* First off we complete CREATE UNIQUE with "INDEX" */
2125         else if (TailMatches2("CREATE", "UNIQUE"))
2126                 COMPLETE_WITH_CONST("INDEX");
2127
2128         /*
2129          * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
2130          * existing indexes
2131          */
2132         else if (TailMatches2("CREATE|UNIQUE", "INDEX"))
2133                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2134                                                                    " UNION SELECT 'ON'"
2135                                                                    " UNION SELECT 'CONCURRENTLY'");
2136         /* Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of tables  */
2137         else if (TailMatches3("INDEX|CONCURRENTLY", MatchAny, "ON") ||
2138                          TailMatches2("INDEX|CONCURRENTLY", "ON"))
2139                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2140
2141         /*
2142          * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
2143          * indexes
2144          */
2145         else if (TailMatches3("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
2146                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2147                                                                    " UNION SELECT 'ON'");
2148         /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
2149         else if (TailMatches3("CREATE|UNIQUE", "INDEX", MatchAny) ||
2150                          TailMatches4("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
2151                 COMPLETE_WITH_CONST("ON");
2152
2153         /*
2154          * Complete INDEX <name> ON <table> with a list of table columns (which
2155          * should really be in parens)
2156          */
2157         else if (TailMatches4("INDEX", MatchAny, "ON", MatchAny) ||
2158                          TailMatches3("INDEX|CONCURRENTLY", "ON", MatchAny))
2159                 COMPLETE_WITH_LIST2("(", "USING");
2160         else if (TailMatches5("INDEX", MatchAny, "ON", MatchAny, "(") ||
2161                          TailMatches4("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
2162                 COMPLETE_WITH_ATTR(prev2_wd, "");
2163         /* same if you put in USING */
2164         else if (TailMatches5("ON", MatchAny, "USING", MatchAny, "("))
2165                 COMPLETE_WITH_ATTR(prev4_wd, "");
2166         /* Complete USING with an index method */
2167         else if (TailMatches6("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
2168                          TailMatches5("INDEX", MatchAny, "ON", MatchAny, "USING") ||
2169                          TailMatches4("INDEX", "ON", MatchAny, "USING"))
2170                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2171         else if (TailMatches4("ON", MatchAny, "USING", MatchAny) &&
2172                          !TailMatches6("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
2173                          !TailMatches4("FOR", MatchAny, MatchAny, MatchAny))
2174                 COMPLETE_WITH_CONST("(");
2175
2176         /* CREATE POLICY */
2177         /* Complete "CREATE POLICY <name> ON" */
2178         else if (Matches3("CREATE", "POLICY", MatchAny))
2179                 COMPLETE_WITH_CONST("ON");
2180         /* Complete "CREATE POLICY <name> ON <table>" */
2181         else if (Matches4("CREATE", "POLICY", MatchAny, "ON"))
2182                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2183         /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
2184         else if (Matches5("CREATE", "POLICY", MatchAny, "ON", MatchAny))
2185                 COMPLETE_WITH_LIST5("AS", "FOR", "TO", "USING (", "WITH CHECK (");
2186         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
2187         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
2188                 COMPLETE_WITH_LIST2("PERMISSIVE", "RESTRICTIVE");
2189         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR|TO|USING|WITH CHECK */
2190         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
2191                 COMPLETE_WITH_LIST4("FOR", "TO", "USING", "WITH CHECK");
2192         /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2193         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
2194                 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2195         /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
2196         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
2197                 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2198         /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
2199         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
2200                 COMPLETE_WITH_LIST2("TO", "USING (");
2201         /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
2202         else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
2203                 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2204         /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
2205         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
2206                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2207         /* Complete "CREATE POLICY <name> ON <table> USING (" */
2208         else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
2209                 COMPLETE_WITH_CONST("(");
2210         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2211         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
2212                 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2213         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR INSERT TO|WITH CHECK" */
2214         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
2215                 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2216         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR SELECT|DELETE TO|USING" */
2217         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
2218                 COMPLETE_WITH_LIST2("TO", "USING (");
2219         /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR ALL|UPDATE TO|USING|WITH CHECK */
2220         else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
2221                 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2222         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO <role>" */
2223         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
2224                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2225         /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE USING (" */
2226         else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
2227                 COMPLETE_WITH_CONST("(");
2228
2229
2230 /* CREATE RULE */
2231         /* Complete "CREATE RULE <sth>" with "AS ON" */
2232         else if (Matches3("CREATE", "RULE", MatchAny))
2233                 COMPLETE_WITH_CONST("AS ON");
2234         /* Complete "CREATE RULE <sth> AS" with "ON" */
2235         else if (Matches4("CREATE", "RULE", MatchAny, "AS"))
2236                 COMPLETE_WITH_CONST("ON");
2237         /* Complete "CREATE RULE <sth> AS ON" with SELECT|UPDATE|INSERT|DELETE */
2238         else if (Matches5("CREATE", "RULE", MatchAny, "AS", "ON"))
2239                 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE");
2240         /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
2241         else if (TailMatches3("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
2242                 COMPLETE_WITH_CONST("TO");
2243         /* Complete "AS ON <sth> TO" with a table name */
2244         else if (TailMatches4("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
2245                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2246
2247 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2248         else if (TailMatches3("CREATE", "SEQUENCE", MatchAny) ||
2249                          TailMatches4("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
2250                 COMPLETE_WITH_LIST8("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE",
2251                                                         "CYCLE", "OWNED BY", "START WITH");
2252         else if (TailMatches4("CREATE", "SEQUENCE", MatchAny, "NO") ||
2253                 TailMatches5("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
2254                 COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE");
2255
2256 /* CREATE SERVER <name> */
2257         else if (Matches3("CREATE", "SERVER", MatchAny))
2258                 COMPLETE_WITH_LIST3("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
2259
2260 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2261         /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
2262         else if (TailMatches2("CREATE", "TEMP|TEMPORARY"))
2263                 COMPLETE_WITH_LIST3("SEQUENCE", "TABLE", "VIEW");
2264         /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
2265         else if (TailMatches2("CREATE", "UNLOGGED"))
2266                 COMPLETE_WITH_LIST2("TABLE", "MATERIALIZED VIEW");
2267
2268 /* CREATE TABLESPACE */
2269         else if (Matches3("CREATE", "TABLESPACE", MatchAny))
2270                 COMPLETE_WITH_LIST2("OWNER", "LOCATION");
2271         /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
2272         else if (Matches5("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
2273                 COMPLETE_WITH_CONST("LOCATION");
2274
2275 /* CREATE TEXT SEARCH */
2276         else if (Matches3("CREATE", "TEXT", "SEARCH"))
2277                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2278         else if (Matches5("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2279                 COMPLETE_WITH_CONST("(");
2280
2281 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
2282         /* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
2283         else if (TailMatches3("CREATE", "TRIGGER", MatchAny))
2284                 COMPLETE_WITH_LIST3("BEFORE", "AFTER", "INSTEAD OF");
2285         /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
2286         else if (TailMatches4("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
2287                 COMPLETE_WITH_LIST4("INSERT", "DELETE", "UPDATE", "TRUNCATE");
2288         /* complete CREATE TRIGGER <name> INSTEAD OF with an event */
2289         else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
2290                 COMPLETE_WITH_LIST3("INSERT", "DELETE", "UPDATE");
2291         /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
2292         else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
2293           TailMatches6("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
2294                 COMPLETE_WITH_LIST2("ON", "OR");
2295
2296         /*
2297          * complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of
2298          * tables
2299          */
2300         else if (TailMatches6("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
2301                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2302         /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */
2303         else if (TailMatches7("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
2304                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
2305         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("ON", MatchAny))
2306                 COMPLETE_WITH_LIST7("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2307                                                         "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2308         else if (HeadMatches2("CREATE", "TRIGGER") &&
2309                          (TailMatches1("DEFERRABLE") || TailMatches2("INITIALLY", "IMMEDIATE|DEFERRED")))
2310                 COMPLETE_WITH_LIST4("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2311         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("REFERENCING"))
2312                 COMPLETE_WITH_LIST2("OLD TABLE", "NEW TABLE");
2313         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("OLD|NEW", "TABLE"))
2314                 COMPLETE_WITH_CONST("AS");
2315         else if (HeadMatches2("CREATE", "TRIGGER") &&
2316                          (TailMatches5("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
2317                           TailMatches4("REFERENCING", "OLD", "TABLE", MatchAny)))
2318                 COMPLETE_WITH_LIST4("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2319         else if (HeadMatches2("CREATE", "TRIGGER") &&
2320                          (TailMatches5("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
2321                           TailMatches4("REFERENCING", "NEW", "TABLE", MatchAny)))
2322                 COMPLETE_WITH_LIST4("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2323         else if (HeadMatches2("CREATE", "TRIGGER") &&
2324                          (TailMatches9("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2325                           TailMatches8("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2326                           TailMatches8("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
2327                           TailMatches7("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
2328                 COMPLETE_WITH_LIST3("FOR", "WHEN (", "EXECUTE PROCEDURE");
2329         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("FOR"))
2330                 COMPLETE_WITH_LIST3("EACH", "ROW", "STATEMENT");
2331         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("FOR", "EACH"))
2332                 COMPLETE_WITH_LIST2("ROW", "STATEMENT");
2333         else if (HeadMatches2("CREATE", "TRIGGER") &&
2334                          (TailMatches3("FOR", "EACH", "ROW|STATEMENT") ||
2335                           TailMatches2("FOR", "ROW|STATEMENT")))
2336                 COMPLETE_WITH_LIST2("WHEN (", "EXECUTE PROCEDURE");
2337         /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE */
2338         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("EXECUTE"))
2339                 COMPLETE_WITH_CONST("PROCEDURE");
2340         else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("EXECUTE", "PROCEDURE"))
2341                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2342
2343 /* CREATE ROLE,USER,GROUP <name> */
2344         else if (Matches3("CREATE", "ROLE|GROUP|USER", MatchAny) &&
2345                          !TailMatches2("USER", "MAPPING"))
2346         {
2347                 static const char *const list_CREATEROLE[] =
2348                 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2349                         "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2350                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2351                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2352                         "REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
2353                 "VALID UNTIL", "WITH", NULL};
2354
2355                 COMPLETE_WITH_LIST(list_CREATEROLE);
2356         }
2357
2358 /* CREATE ROLE,USER,GROUP <name> WITH */
2359         else if (Matches4("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
2360         {
2361                 /* Similar to the above, but don't complete "WITH" again. */
2362                 static const char *const list_CREATEROLE_WITH[] =
2363                 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2364                         "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2365                         "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2366                         "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2367                         "REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
2368                 "VALID UNTIL", NULL};
2369
2370                 COMPLETE_WITH_LIST(list_CREATEROLE_WITH);
2371         }
2372
2373         /*
2374          * complete CREATE ROLE,USER,GROUP <name> ENCRYPTED,UNENCRYPTED with
2375          * PASSWORD
2376          */
2377         else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "ENCRYPTED|UNENCRYPTED"))
2378                 COMPLETE_WITH_CONST("PASSWORD");
2379         /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
2380         else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
2381                 COMPLETE_WITH_LIST2("GROUP", "ROLE");
2382
2383 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
2384         /* Complete CREATE VIEW <name> with AS */
2385         else if (TailMatches3("CREATE", "VIEW", MatchAny))
2386                 COMPLETE_WITH_CONST("AS");
2387         /* Complete "CREATE VIEW <sth> AS with "SELECT" */
2388         else if (TailMatches4("CREATE", "VIEW", MatchAny, "AS"))
2389                 COMPLETE_WITH_CONST("SELECT");
2390
2391 /* CREATE MATERIALIZED VIEW */
2392         else if (Matches2("CREATE", "MATERIALIZED"))
2393                 COMPLETE_WITH_CONST("VIEW");
2394         /* Complete CREATE MATERIALIZED VIEW <name> with AS */
2395         else if (Matches4("CREATE", "MATERIALIZED", "VIEW", MatchAny))
2396                 COMPLETE_WITH_CONST("AS");
2397         /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
2398         else if (Matches5("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
2399                 COMPLETE_WITH_CONST("SELECT");
2400
2401 /* CREATE EVENT TRIGGER */
2402         else if (Matches2("CREATE", "EVENT"))
2403                 COMPLETE_WITH_CONST("TRIGGER");
2404         /* Complete CREATE EVENT TRIGGER <name> with ON */
2405         else if (Matches4("CREATE", "EVENT", "TRIGGER", MatchAny))
2406                 COMPLETE_WITH_CONST("ON");
2407         /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
2408         else if (Matches5("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
2409                 COMPLETE_WITH_LIST3("ddl_command_start", "ddl_command_end", "sql_drop");
2410
2411 /* DECLARE */
2412         else if (Matches2("DECLARE", MatchAny))
2413                 COMPLETE_WITH_LIST5("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL",
2414                                                         "CURSOR");
2415         else if (HeadMatches1("DECLARE") && TailMatches1("CURSOR"))
2416                 COMPLETE_WITH_LIST3("WITH HOLD", "WITHOUT HOLD", "FOR");
2417
2418 /* DELETE --- can be inside EXPLAIN, RULE, etc */
2419         /* ... despite which, only complete DELETE with FROM at start of line */
2420         else if (Matches1("DELETE"))
2421                 COMPLETE_WITH_CONST("FROM");
2422         /* Complete DELETE FROM with a list of tables */
2423         else if (TailMatches2("DELETE", "FROM"))
2424                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2425         /* Complete DELETE FROM <table> */
2426         else if (TailMatches3("DELETE", "FROM", MatchAny))
2427                 COMPLETE_WITH_LIST2("USING", "WHERE");
2428         /* XXX: implement tab completion for DELETE ... USING */
2429
2430 /* DISCARD */
2431         else if (Matches1("DISCARD"))
2432                 COMPLETE_WITH_LIST4("ALL", "PLANS", "SEQUENCES", "TEMP");
2433
2434 /* DO */
2435         else if (Matches1("DO"))
2436                 COMPLETE_WITH_CONST("LANGUAGE");
2437
2438 /* DROP */
2439         /* Complete DROP object with CASCADE / RESTRICT */
2440         else if (Matches3("DROP",
2441                                           "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|SCHEMA|SEQUENCE|SERVER|TABLE|TYPE|VIEW",
2442                                           MatchAny) ||
2443                          Matches4("DROP", "ACCESS", "METHOD", MatchAny) ||
2444                          (Matches4("DROP", "AGGREGATE|FUNCTION", MatchAny, MatchAny) &&
2445                           ends_with(prev_wd, ')')) ||
2446                          Matches4("DROP", "EVENT", "TRIGGER", MatchAny) ||
2447                          Matches5("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
2448                          Matches4("DROP", "FOREIGN", "TABLE", MatchAny) ||
2449                          Matches5("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
2450                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2451
2452         /* help completing some of the variants */
2453         else if (Matches3("DROP", "AGGREGATE|FUNCTION", MatchAny))
2454                 COMPLETE_WITH_CONST("(");
2455         else if (Matches4("DROP", "AGGREGATE|FUNCTION", MatchAny, "("))
2456                 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
2457         else if (Matches2("DROP", "FOREIGN"))
2458                 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2459
2460         /* DROP INDEX */
2461         else if (Matches2("DROP", "INDEX"))
2462                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2463                                                                    " UNION SELECT 'CONCURRENTLY'");
2464         else if (Matches3("DROP", "INDEX", "CONCURRENTLY"))
2465                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2466         else if (Matches3("DROP", "INDEX", MatchAny))
2467                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2468         else if (Matches4("DROP", "INDEX", "CONCURRENTLY", MatchAny))
2469                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2470
2471         /* DROP MATERIALIZED VIEW */
2472         else if (Matches2("DROP", "MATERIALIZED"))
2473                 COMPLETE_WITH_CONST("VIEW");
2474         else if (Matches3("DROP", "MATERIALIZED", "VIEW"))
2475                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2476
2477         /* DROP OWNED BY */
2478         else if (Matches2("DROP", "OWNED"))
2479                 COMPLETE_WITH_CONST("BY");
2480         else if (Matches3("DROP", "OWNED", "BY"))
2481                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2482
2483         else if (Matches3("DROP", "TEXT", "SEARCH"))
2484                 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2485
2486         /* DROP TRIGGER */
2487         else if (Matches3("DROP", "TRIGGER", MatchAny))
2488                 COMPLETE_WITH_CONST("ON");
2489         else if (Matches4("DROP", "TRIGGER", MatchAny, "ON"))
2490         {
2491                 completion_info_charp = prev2_wd;
2492                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2493         }
2494         else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
2495                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2496
2497         /* DROP ACCESS METHOD */
2498         else if (Matches2("DROP", "ACCESS"))
2499                 COMPLETE_WITH_CONST("METHOD");
2500         else if (Matches3("DROP", "ACCESS", "METHOD"))
2501                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2502
2503         /* DROP EVENT TRIGGER */
2504         else if (Matches2("DROP", "EVENT"))
2505                 COMPLETE_WITH_CONST("TRIGGER");
2506         else if (Matches3("DROP", "EVENT", "TRIGGER"))
2507                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2508
2509         /* DROP POLICY <name>  */
2510         else if (Matches2("DROP", "POLICY"))
2511                 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2512         /* DROP POLICY <name> ON */
2513         else if (Matches3("DROP", "POLICY", MatchAny))
2514                 COMPLETE_WITH_CONST("ON");
2515         /* DROP POLICY <name> ON <table> */
2516         else if (Matches4("DROP", "POLICY", MatchAny, "ON"))
2517         {
2518                 completion_info_charp = prev2_wd;
2519                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
2520         }
2521
2522         /* DROP RULE */
2523         else if (Matches3("DROP", "RULE", MatchAny))
2524                 COMPLETE_WITH_CONST("ON");
2525         else if (Matches4("DROP", "RULE", MatchAny, "ON"))
2526         {
2527                 completion_info_charp = prev2_wd;
2528                 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2529         }
2530         else if (Matches5("DROP", "RULE", MatchAny, "ON", MatchAny))
2531                 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2532
2533 /* EXECUTE */
2534         else if (Matches1("EXECUTE"))
2535                 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2536
2537 /* EXPLAIN */
2538
2539         /*
2540          * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands
2541          */
2542         else if (Matches1("EXPLAIN"))
2543                 COMPLETE_WITH_LIST7("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2544                                                         "ANALYZE", "VERBOSE");
2545         else if (Matches2("EXPLAIN", "ANALYZE"))
2546                 COMPLETE_WITH_LIST6("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2547                                                         "VERBOSE");
2548         else if (Matches2("EXPLAIN", "VERBOSE") ||
2549                          Matches3("EXPLAIN", "ANALYZE", "VERBOSE"))
2550                 COMPLETE_WITH_LIST5("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE");
2551
2552 /* FETCH && MOVE */
2553         /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
2554         else if (Matches1("FETCH|MOVE"))
2555                 COMPLETE_WITH_LIST4("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE");
2556         /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
2557         else if (Matches2("FETCH|MOVE", MatchAny))
2558                 COMPLETE_WITH_LIST3("ALL", "NEXT", "PRIOR");
2559
2560         /*
2561          * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
2562          * but we may as well tab-complete both: perhaps some users prefer one
2563          * variant or the other.
2564          */
2565         else if (Matches3("FETCH|MOVE", MatchAny, MatchAny))
2566                 COMPLETE_WITH_LIST2("FROM", "IN");
2567
2568 /* FOREIGN DATA WRAPPER */
2569         /* applies in ALTER/DROP FDW and in CREATE SERVER */
2570         else if (TailMatches3("FOREIGN", "DATA", "WRAPPER") &&
2571                          !TailMatches4("CREATE", MatchAny, MatchAny, MatchAny))
2572                 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
2573         /* applies in CREATE SERVER */
2574         else if (TailMatches4("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
2575                          HeadMatches2("CREATE", "SERVER"))
2576                 COMPLETE_WITH_CONST("OPTIONS");
2577
2578 /* FOREIGN TABLE */
2579         else if (TailMatches2("FOREIGN", "TABLE") &&
2580                          !TailMatches3("CREATE", MatchAny, MatchAny))
2581                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
2582
2583 /* FOREIGN SERVER */
2584         else if (TailMatches2("FOREIGN", "SERVER"))
2585                 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
2586
2587 /*
2588  * GRANT and REVOKE are allowed inside CREATE SCHEMA and
2589  * ALTER DEFAULT PRIVILEGES, so use TailMatches
2590  */
2591         /* Complete GRANT/REVOKE with a list of roles and privileges */
2592         else if (TailMatches1("GRANT|REVOKE"))
2593                 /*
2594                  * With ALTER DEFAULT PRIVILEGES, restrict completion
2595                  * to grantable privileges (can't grant roles)
2596                  */
2597                 if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2598                         COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE",
2599                                 "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2600                                                 "EXECUTE", "USAGE", "ALL");
2601                 else
2602                         COMPLETE_WITH_QUERY(Query_for_list_of_roles
2603                                                         " UNION SELECT 'SELECT'"
2604                                                         " UNION SELECT 'INSERT'"
2605                                                         " UNION SELECT 'UPDATE'"
2606                                                         " UNION SELECT 'DELETE'"
2607                                                         " UNION SELECT 'TRUNCATE'"
2608                                                         " UNION SELECT 'REFERENCES'"
2609                                                         " UNION SELECT 'TRIGGER'"
2610                                                         " UNION SELECT 'CREATE'"
2611                                                         " UNION SELECT 'CONNECT'"
2612                                                         " UNION SELECT 'TEMPORARY'"
2613                                                         " UNION SELECT 'EXECUTE'"
2614                                                         " UNION SELECT 'USAGE'"
2615                                                         " UNION SELECT 'ALL'");
2616
2617         /*
2618          * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
2619          * TO/FROM
2620          */
2621         else if (TailMatches2("GRANT|REVOKE", MatchAny))
2622         {
2623                 if (TailMatches1("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
2624                         COMPLETE_WITH_CONST("ON");
2625                 else if (TailMatches2("GRANT", MatchAny))
2626                         COMPLETE_WITH_CONST("TO");
2627                 else
2628                         COMPLETE_WITH_CONST("FROM");
2629         }
2630
2631         /*
2632          * Complete GRANT/REVOKE <sth> ON with a list of tables, views, and
2633          * sequences.
2634          *
2635          * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query
2636          * result via UNION; seems to work intuitively.
2637          *
2638          * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
2639          * here will only work if the privilege list contains exactly one
2640          * privilege.
2641          */
2642         else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON"))
2643                 /*
2644                  * With ALTER DEFAULT PRIVILEGES, restrict completion
2645                  * to the kinds of objects supported.
2646                  */
2647                 if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2648                         COMPLETE_WITH_LIST4("TABLES", "SEQUENCES", "FUNCTIONS", "TYPES");
2649                 else
2650                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf,
2651                                                                    " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
2652                                                                    " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
2653                                                                    " UNION SELECT 'ALL TABLES IN SCHEMA'"
2654                                                                    " UNION SELECT 'DATABASE'"
2655                                                                    " UNION SELECT 'DOMAIN'"
2656                                                                    " UNION SELECT 'FOREIGN DATA WRAPPER'"
2657                                                                    " UNION SELECT 'FOREIGN SERVER'"
2658                                                                    " UNION SELECT 'FUNCTION'"
2659                                                                    " UNION SELECT 'LANGUAGE'"
2660                                                                    " UNION SELECT 'LARGE OBJECT'"
2661                                                                    " UNION SELECT 'SCHEMA'"
2662                                                                    " UNION SELECT 'SEQUENCE'"
2663                                                                    " UNION SELECT 'TABLE'"
2664                                                                    " UNION SELECT 'TABLESPACE'"
2665                                                                    " UNION SELECT 'TYPE'");
2666
2667         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "ALL"))
2668                 COMPLETE_WITH_LIST3("FUNCTIONS IN SCHEMA", "SEQUENCES IN SCHEMA",
2669                                                         "TABLES IN SCHEMA");
2670
2671         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"))
2672                 COMPLETE_WITH_LIST2("DATA WRAPPER", "SERVER");
2673
2674         /*
2675          * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
2676          * appropriate objects.
2677          *
2678          * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
2679          */
2680         else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", MatchAny))
2681         {
2682                 if (TailMatches1("DATABASE"))
2683                         COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2684                 else if (TailMatches1("DOMAIN"))
2685                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
2686                 else if (TailMatches1("FUNCTION"))
2687                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2688                 else if (TailMatches1("LANGUAGE"))
2689                         COMPLETE_WITH_QUERY(Query_for_list_of_languages);
2690                 else if (TailMatches1("SCHEMA"))
2691                         COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2692                 else if (TailMatches1("SEQUENCE"))
2693                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
2694                 else if (TailMatches1("TABLE"))
2695                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
2696                 else if (TailMatches1("TABLESPACE"))
2697                         COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
2698                 else if (TailMatches1("TYPE"))
2699                         COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
2700                 else if (TailMatches4("GRANT", MatchAny, MatchAny, MatchAny))
2701                         COMPLETE_WITH_CONST("TO");
2702                 else
2703                         COMPLETE_WITH_CONST("FROM");
2704         }
2705
2706         /*
2707          * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
2708          * CURRENT_USER, or SESSION_USER.
2709          */
2710         else if ((HeadMatches1("GRANT") && TailMatches1("TO")) ||
2711                          (HeadMatches1("REVOKE") && TailMatches1("FROM")))
2712                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2713         /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
2714         else if (HeadMatches3("ALTER","DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM"))
2715                 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2716         /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
2717         else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny))
2718                 COMPLETE_WITH_CONST("TO");
2719         else if (HeadMatches1("REVOKE") && TailMatches3("ON", MatchAny, MatchAny))
2720                 COMPLETE_WITH_CONST("FROM");
2721
2722         /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
2723         else if (TailMatches8("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
2724         {
2725                 if (TailMatches8("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2726                         COMPLETE_WITH_CONST("TO");
2727                 else
2728                         COMPLETE_WITH_CONST("FROM");
2729         }
2730
2731         /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
2732         else if (TailMatches7("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2733         {
2734                 if (TailMatches7("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2735                         COMPLETE_WITH_CONST("TO");
2736                 else
2737                         COMPLETE_WITH_CONST("FROM");
2738         }
2739
2740         /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
2741         else if (TailMatches6("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
2742         {
2743                 if (TailMatches6("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2744                         COMPLETE_WITH_CONST("TO");
2745                 else
2746                         COMPLETE_WITH_CONST("FROM");
2747         }
2748
2749 /* GROUP BY */
2750         else if (TailMatches3("FROM", MatchAny, "GROUP"))
2751                 COMPLETE_WITH_CONST("BY");
2752
2753 /* IMPORT FOREIGN SCHEMA */
2754         else if (Matches1("IMPORT"))
2755                 COMPLETE_WITH_CONST("FOREIGN SCHEMA");
2756         else if (Matches2("IMPORT", "FOREIGN"))
2757                 COMPLETE_WITH_CONST("SCHEMA");
2758
2759 /* INSERT --- can be inside EXPLAIN, RULE, etc */
2760         /* Complete INSERT with "INTO" */
2761         else if (TailMatches1("INSERT"))
2762                 COMPLETE_WITH_CONST("INTO");
2763         /* Complete INSERT INTO with table names */
2764         else if (TailMatches2("INSERT", "INTO"))
2765                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2766         /* Complete "INSERT INTO <table> (" with attribute names */
2767         else if (TailMatches4("INSERT", "INTO", MatchAny, "("))
2768                 COMPLETE_WITH_ATTR(prev2_wd, "");
2769
2770         /*
2771          * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
2772          * "TABLE" or "DEFAULT VALUES"
2773          */
2774         else if (TailMatches3("INSERT", "INTO", MatchAny))
2775                 COMPLETE_WITH_LIST5("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES");
2776
2777         /*
2778          * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
2779          * "TABLE"
2780          */
2781         else if (TailMatches4("INSERT", "INTO", MatchAny, MatchAny) &&
2782                          ends_with(prev_wd, ')'))
2783                 COMPLETE_WITH_LIST3("SELECT", "TABLE", "VALUES");
2784
2785         /* Insert an open parenthesis after "VALUES" */
2786         else if (TailMatches1("VALUES") && !TailMatches2("DEFAULT", "VALUES"))
2787                 COMPLETE_WITH_CONST("(");
2788
2789 /* LOCK */
2790         /* Complete LOCK [TABLE] with a list of tables */
2791         else if (Matches1("LOCK"))
2792                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2793                                                                    " UNION SELECT 'TABLE'");
2794         else if (Matches2("LOCK", "TABLE"))
2795                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
2796
2797         /* For the following, handle the case of a single table only for now */
2798
2799         /* Complete LOCK [TABLE] <table> with "IN" */
2800         else if (Matches2("LOCK", MatchAnyExcept("TABLE")) ||
2801                          Matches3("LOCK", "TABLE", MatchAny))
2802                 COMPLETE_WITH_CONST("IN");
2803
2804         /* Complete LOCK [TABLE] <table> IN with a lock mode */
2805         else if (Matches3("LOCK", MatchAny, "IN") ||
2806                          Matches4("LOCK", "TABLE", MatchAny, "IN"))
2807                 COMPLETE_WITH_LIST8("ACCESS SHARE MODE",
2808                                                         "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
2809                                                         "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
2810                                                         "SHARE ROW EXCLUSIVE MODE",
2811                                                         "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
2812
2813         /* Complete LOCK [TABLE] <table> IN ACCESS|ROW with rest of lock mode */
2814         else if (Matches4("LOCK", MatchAny, "IN", "ACCESS|ROW") ||
2815                          Matches5("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW"))
2816                 COMPLETE_WITH_LIST2("EXCLUSIVE MODE", "SHARE MODE");
2817
2818         /* Complete LOCK [TABLE] <table> IN SHARE with rest of lock mode */
2819         else if (Matches4("LOCK", MatchAny, "IN", "SHARE") ||
2820                          Matches5("LOCK", "TABLE", MatchAny, "IN", "SHARE"))
2821                 COMPLETE_WITH_LIST3("MODE", "ROW EXCLUSIVE MODE",
2822                                                         "UPDATE EXCLUSIVE MODE");
2823
2824 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
2825         else if (TailMatches1("NOTIFY"))
2826                 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'");
2827
2828 /* OPTIONS */
2829         else if (TailMatches1("OPTIONS"))
2830                 COMPLETE_WITH_CONST("(");
2831
2832 /* OWNER TO  - complete with available roles */
2833         else if (TailMatches2("OWNER", "TO"))
2834                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2835
2836 /* ORDER BY */
2837         else if (TailMatches3("FROM", MatchAny, "ORDER"))
2838                 COMPLETE_WITH_CONST("BY");
2839         else if (TailMatches4("FROM", MatchAny, "ORDER", "BY"))
2840                 COMPLETE_WITH_ATTR(prev3_wd, "");
2841
2842 /* PREPARE xx AS */
2843         else if (Matches3("PREPARE", MatchAny, "AS"))
2844                 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE FROM");
2845
2846 /*
2847  * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
2848  * managers, not for manual use in interactive sessions.
2849  */
2850
2851 /* REASSIGN OWNED BY xxx TO yyy */
2852         else if (Matches1("REASSIGN"))
2853                 COMPLETE_WITH_CONST("OWNED BY");
2854         else if (Matches2("REASSIGN", "OWNED"))
2855                 COMPLETE_WITH_CONST("BY");
2856         else if (Matches3("REASSIGN", "OWNED", "BY"))
2857                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2858         else if (Matches4("REASSIGN", "OWNED", "BY", MatchAny))
2859                 COMPLETE_WITH_CONST("TO");
2860         else if (Matches5("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
2861                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2862
2863 /* REFRESH MATERIALIZED VIEW */
2864         else if (Matches1("REFRESH"))
2865                 COMPLETE_WITH_CONST("MATERIALIZED VIEW");
2866         else if (Matches2("REFRESH", "MATERIALIZED"))
2867                 COMPLETE_WITH_CONST("VIEW");
2868         else if (Matches3("REFRESH", "MATERIALIZED", "VIEW"))
2869                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
2870                                                                    " UNION SELECT 'CONCURRENTLY'");
2871         else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
2872                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2873         else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
2874                 COMPLETE_WITH_CONST("WITH");
2875         else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
2876                 COMPLETE_WITH_CONST("WITH");
2877         else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
2878                 COMPLETE_WITH_LIST2("NO DATA", "DATA");
2879         else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
2880                 COMPLETE_WITH_LIST2("NO DATA", "DATA");
2881         else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
2882                 COMPLETE_WITH_CONST("DATA");
2883         else if (Matches7("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
2884                 COMPLETE_WITH_CONST("DATA");
2885
2886 /* REINDEX */
2887         else if (Matches1("REINDEX"))
2888                 COMPLETE_WITH_LIST5("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
2889         else if (Matches2("REINDEX", "TABLE"))
2890                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2891         else if (Matches2("REINDEX", "INDEX"))
2892                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2893         else if (Matches2("REINDEX", "SCHEMA"))
2894                 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2895         else if (Matches2("REINDEX", "SYSTEM|DATABASE"))
2896                 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2897
2898 /* SECURITY LABEL */
2899         else if (Matches1("SECURITY"))
2900                 COMPLETE_WITH_CONST("LABEL");
2901         else if (Matches2("SECURITY", "LABEL"))
2902                 COMPLETE_WITH_LIST2("ON", "FOR");
2903         else if (Matches4("SECURITY", "LABEL", "FOR", MatchAny))
2904                 COMPLETE_WITH_CONST("ON");
2905         else if (Matches3("SECURITY", "LABEL", "ON") ||
2906                          Matches5("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
2907         {
2908                 static const char *const list_SECURITY_LABEL[] =
2909                 {"TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
2910                         "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", "LARGE OBJECT",
2911                         "MATERIALIZED VIEW", "LANGUAGE", "ROLE", "SCHEMA",
2912                 "SEQUENCE", "TABLESPACE", "TYPE", "VIEW", NULL};
2913
2914                 COMPLETE_WITH_LIST(list_SECURITY_LABEL);
2915         }
2916         else if (Matches5("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
2917                 COMPLETE_WITH_CONST("IS");
2918
2919 /* SELECT */
2920         /* naah . . . */
2921
2922 /* SET, RESET, SHOW */
2923         /* Complete with a variable name */
2924         else if (TailMatches1("SET|RESET") && !TailMatches3("UPDATE", MatchAny, "SET"))
2925                 COMPLETE_WITH_QUERY(Query_for_list_of_set_vars);
2926         else if (Matches1("SHOW"))
2927                 COMPLETE_WITH_QUERY(Query_for_list_of_show_vars);
2928         /* Complete "SET TRANSACTION" */
2929         else if (Matches2("SET", "TRANSACTION"))
2930                 COMPLETE_WITH_LIST5("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2931         else if (Matches2("BEGIN|START", "TRANSACTION") ||
2932                          Matches2("BEGIN", "WORK") ||
2933                          Matches1("BEGIN") ||
2934                   Matches5("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
2935                 COMPLETE_WITH_LIST4("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2936         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
2937                          Matches2("BEGIN", "NOT") ||
2938                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
2939                 COMPLETE_WITH_CONST("DEFERRABLE");
2940         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
2941                          Matches2("BEGIN", "ISOLATION") ||
2942                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
2943                 COMPLETE_WITH_CONST("LEVEL");
2944         else if (Matches4("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
2945                          Matches3("BEGIN", "ISOLATION", "LEVEL") ||
2946                          Matches7("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
2947                 COMPLETE_WITH_LIST3("READ", "REPEATABLE READ", "SERIALIZABLE");
2948         else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
2949                          Matches4("BEGIN", "ISOLATION", "LEVEL", "READ") ||
2950                          Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
2951                 COMPLETE_WITH_LIST2("UNCOMMITTED", "COMMITTED");
2952         else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
2953                          Matches4("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
2954                          Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
2955                 COMPLETE_WITH_CONST("READ");
2956         else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
2957                          Matches2("BEGIN", "READ") ||
2958                          Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
2959                 COMPLETE_WITH_LIST2("ONLY", "WRITE");
2960         /* SET CONSTRAINTS */
2961         else if (Matches2("SET", "CONSTRAINTS"))
2962                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'");
2963         /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
2964         else if (Matches3("SET", "CONSTRAINTS", MatchAny))
2965                 COMPLETE_WITH_LIST2("DEFERRED", "IMMEDIATE");
2966         /* Complete SET ROLE */
2967         else if (Matches2("SET", "ROLE"))
2968                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2969         /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
2970         else if (Matches2("SET", "SESSION"))
2971                 COMPLETE_WITH_LIST2("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
2972         /* Complete SET SESSION AUTHORIZATION with username */
2973         else if (Matches3("SET", "SESSION", "AUTHORIZATION"))
2974                 COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'");
2975         /* Complete RESET SESSION with AUTHORIZATION */
2976         else if (Matches2("RESET", "SESSION"))
2977                 COMPLETE_WITH_CONST("AUTHORIZATION");
2978         /* Complete SET <var> with "TO" */
2979         else if (Matches2("SET", MatchAny))
2980                 COMPLETE_WITH_CONST("TO");
2981         /* Complete ALTER DATABASE|FUNCTION|ROLE|USER ... SET <name> */
2982         else if (HeadMatches2("ALTER", "DATABASE|FUNCTION|ROLE|USER") &&
2983                          TailMatches2("SET", MatchAny))
2984                 COMPLETE_WITH_LIST2("FROM CURRENT", "TO");
2985         /* Suggest possible variable values */
2986         else if (TailMatches3("SET", MatchAny, "TO|="))
2987         {
2988                 /* special cased code for individual GUCs */
2989                 if (TailMatches2("DateStyle", "TO|="))
2990                 {
2991                         static const char *const my_list[] =
2992                         {"ISO", "SQL", "Postgres", "German",
2993                                 "YMD", "DMY", "MDY",
2994                                 "US", "European", "NonEuropean",
2995                         "DEFAULT", NULL};
2996
2997                         COMPLETE_WITH_LIST(my_list);
2998                 }
2999                 else if (TailMatches2("search_path", "TO|="))
3000                         COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3001                                                                 " AND nspname not like 'pg\\_toast%%' "
3002                                                                 " AND nspname not like 'pg\\_temp%%' "
3003                                                                 " UNION SELECT 'DEFAULT' ");
3004                 else
3005                 {
3006                         /* generic, type based, GUC support */
3007                         char       *guctype = get_guctype(prev2_wd);
3008
3009                         if (guctype && strcmp(guctype, "enum") == 0)
3010                         {
3011                                 char            querybuf[1024];
3012
3013                                 snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd);
3014                                 COMPLETE_WITH_QUERY(querybuf);
3015                         }
3016                         else if (guctype && strcmp(guctype, "bool") == 0)
3017                                 COMPLETE_WITH_LIST9("on", "off", "true", "false", "yes", "no",
3018                                                                         "1", "0", "DEFAULT");
3019                         else
3020                                 COMPLETE_WITH_CONST("DEFAULT");
3021
3022                         if (guctype)
3023                                 free(guctype);
3024                 }
3025         }
3026
3027 /* START TRANSACTION */
3028         else if (Matches1("START"))
3029                 COMPLETE_WITH_CONST("TRANSACTION");
3030
3031 /* TABLE, but not TABLE embedded in other commands */
3032         else if (Matches1("TABLE"))
3033                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3034
3035 /* TABLESAMPLE */
3036         else if (TailMatches1("TABLESAMPLE"))
3037                 COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
3038         else if (TailMatches2("TABLESAMPLE", MatchAny))
3039                 COMPLETE_WITH_CONST("(");
3040
3041 /* TRUNCATE */
3042         else if (Matches1("TRUNCATE"))
3043                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3044
3045 /* UNLISTEN */
3046         else if (Matches1("UNLISTEN"))
3047                 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 '*'");
3048
3049 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
3050         /* If prev. word is UPDATE suggest a list of tables */
3051         else if (TailMatches1("UPDATE"))
3052                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3053         /* Complete UPDATE <table> with "SET" */
3054         else if (TailMatches2("UPDATE", MatchAny))
3055                 COMPLETE_WITH_CONST("SET");
3056         /* Complete UPDATE <table> SET with list of attributes */
3057         else if (TailMatches3("UPDATE", MatchAny, "SET"))
3058                 COMPLETE_WITH_ATTR(prev2_wd, "");
3059         /* UPDATE <table> SET <attr> = */
3060         else if (TailMatches4("UPDATE", MatchAny, "SET", MatchAny))
3061                 COMPLETE_WITH_CONST("=");
3062
3063 /* USER MAPPING */
3064         else if (Matches3("ALTER|CREATE|DROP", "USER", "MAPPING"))
3065                 COMPLETE_WITH_CONST("FOR");
3066         else if (Matches4("CREATE", "USER", "MAPPING", "FOR"))
3067                 COMPLETE_WITH_QUERY(Query_for_list_of_roles
3068                                                         " UNION SELECT 'CURRENT_USER'"
3069                                                         " UNION SELECT 'PUBLIC'"
3070                                                         " UNION SELECT 'USER'");
3071         else if (Matches4("ALTER|DROP", "USER", "MAPPING", "FOR"))
3072                 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3073         else if (Matches5("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
3074                 COMPLETE_WITH_CONST("SERVER");
3075         else if (Matches7("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
3076                 COMPLETE_WITH_CONST("OPTIONS");
3077
3078 /*
3079  * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ]
3080  * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]
3081  */
3082         else if (Matches1("VACUUM"))
3083                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3084                                                                    " UNION SELECT 'FULL'"
3085                                                                    " UNION SELECT 'FREEZE'"
3086                                                                    " UNION SELECT 'ANALYZE'"
3087                                                                    " UNION SELECT 'VERBOSE'");
3088         else if (Matches2("VACUUM", "FULL|FREEZE"))
3089                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3090                                                                    " UNION SELECT 'ANALYZE'"
3091                                                                    " UNION SELECT 'VERBOSE'");
3092         else if (Matches3("VACUUM", "FULL|FREEZE", "ANALYZE"))
3093                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3094                                                                    " UNION SELECT 'VERBOSE'");
3095         else if (Matches3("VACUUM", "FULL|FREEZE", "VERBOSE"))
3096                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3097                                                                    " UNION SELECT 'ANALYZE'");
3098         else if (Matches2("VACUUM", "VERBOSE"))
3099                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3100                                                                    " UNION SELECT 'ANALYZE'");
3101         else if (Matches2("VACUUM", "ANALYZE"))
3102                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3103                                                                    " UNION SELECT 'VERBOSE'");
3104         else if (HeadMatches1("VACUUM"))
3105                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
3106
3107 /* WITH [RECURSIVE] */
3108
3109         /*
3110          * Only match when WITH is the first word, as WITH may appear in many
3111          * other contexts.
3112          */
3113         else if (Matches1("WITH"))
3114                 COMPLETE_WITH_CONST("RECURSIVE");
3115
3116 /* ANALYZE */
3117         /* Complete with list of tables */
3118         else if (Matches1("ANALYZE"))
3119                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tmf, NULL);
3120
3121 /* WHERE */
3122         /* Simple case of the word before the where being the table name */
3123         else if (TailMatches2(MatchAny, "WHERE"))
3124                 COMPLETE_WITH_ATTR(prev2_wd, "");
3125
3126 /* ... FROM ... */
3127 /* TODO: also include SRF ? */
3128         else if (TailMatches1("FROM") && !Matches3("COPY|\\copy", MatchAny, "FROM"))
3129                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3130
3131 /* ... JOIN ... */
3132         else if (TailMatches1("JOIN"))
3133                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3134
3135 /* Backslash commands */
3136 /* TODO:  \dc \dd \dl */
3137         else if (TailMatchesCS1("\\?"))
3138                 COMPLETE_WITH_LIST_CS3("commands", "options", "variables");
3139         else if (TailMatchesCS1("\\connect|\\c"))
3140         {
3141                 if (!recognized_connection_string(text))
3142                         COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3143         }
3144         else if (TailMatchesCS2("\\connect|\\c", MatchAny))
3145         {
3146                 if (!recognized_connection_string(prev_wd))
3147                         COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3148         }
3149         else if (TailMatchesCS1("\\da*"))
3150                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
3151         else if (TailMatchesCS1("\\dA*"))
3152                 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3153         else if (TailMatchesCS1("\\db*"))
3154                 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3155         else if (TailMatchesCS1("\\dD*"))
3156                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3157         else if (TailMatchesCS1("\\des*"))
3158                 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3159         else if (TailMatchesCS1("\\deu*"))
3160                 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3161         else if (TailMatchesCS1("\\dew*"))
3162                 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3163         else if (TailMatchesCS1("\\df*"))
3164                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3165
3166         else if (TailMatchesCS1("\\dFd*"))
3167                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
3168         else if (TailMatchesCS1("\\dFp*"))
3169                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
3170         else if (TailMatchesCS1("\\dFt*"))
3171                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
3172         /* must be at end of \dF alternatives: */
3173         else if (TailMatchesCS1("\\dF*"))
3174                 COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
3175
3176         else if (TailMatchesCS1("\\di*"))
3177                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3178         else if (TailMatchesCS1("\\dL*"))
3179                 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3180         else if (TailMatchesCS1("\\dn*"))
3181                 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3182         else if (TailMatchesCS1("\\dp") || TailMatchesCS1("\\z"))
3183                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3184         else if (TailMatchesCS1("\\ds*"))
3185                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3186         else if (TailMatchesCS1("\\dt*"))
3187                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3188         else if (TailMatchesCS1("\\dT*"))
3189                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3190         else if (TailMatchesCS1("\\du*") || TailMatchesCS1("\\dg*"))
3191                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3192         else if (TailMatchesCS1("\\dv*"))
3193                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3194         else if (TailMatchesCS1("\\dx*"))
3195                 COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
3196         else if (TailMatchesCS1("\\dm*"))
3197                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3198         else if (TailMatchesCS1("\\dE*"))
3199                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
3200         else if (TailMatchesCS1("\\dy*"))
3201                 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3202
3203         /* must be at end of \d alternatives: */
3204         else if (TailMatchesCS1("\\d*"))
3205                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3206
3207         else if (TailMatchesCS1("\\ef"))
3208                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3209         else if (TailMatchesCS1("\\ev"))
3210                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3211
3212         else if (TailMatchesCS1("\\encoding"))
3213                 COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
3214         else if (TailMatchesCS1("\\h") || TailMatchesCS1("\\help"))
3215                 COMPLETE_WITH_LIST(sql_commands);
3216         else if (TailMatchesCS1("\\l*") && !TailMatchesCS1("\\lo*"))
3217                 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3218         else if (TailMatchesCS1("\\password"))
3219                 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3220         else if (TailMatchesCS1("\\pset"))
3221         {
3222                 static const char *const my_list[] =
3223                 {"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
3224                         "footer", "format", "linestyle", "null", "numericlocale",
3225                         "pager", "pager_min_lines", "recordsep", "recordsep_zero",
3226                         "tableattr", "title", "tuples_only", "unicode_border_linestyle",
3227                 "unicode_column_linestyle", "unicode_header_linestyle", NULL};
3228
3229                 COMPLETE_WITH_LIST_CS(my_list);
3230         }
3231         else if (TailMatchesCS2("\\pset", MatchAny))
3232         {
3233                 if (TailMatchesCS1("format"))
3234                 {
3235                         static const char *const my_list[] =
3236                         {"unaligned", "aligned", "wrapped", "html", "asciidoc",
3237                         "latex", "latex-longtable", "troff-ms", NULL};
3238
3239                         COMPLETE_WITH_LIST_CS(my_list);
3240                 }
3241                 else if (TailMatchesCS1("linestyle"))
3242                         COMPLETE_WITH_LIST_CS3("ascii", "old-ascii", "unicode");
3243                 else if (TailMatchesCS1("unicode_border_linestyle|"
3244                                                                 "unicode_column_linestyle|"
3245                                                                 "unicode_header_linestyle"))
3246                         COMPLETE_WITH_LIST_CS2("single", "double");
3247         }
3248         else if (TailMatchesCS1("\\unset"))
3249         {
3250                 matches = complete_from_variables(text, "", "", true);
3251         }
3252         else if (TailMatchesCS1("\\set"))
3253         {
3254                 matches = complete_from_variables(text, "", "", false);
3255         }
3256         else if (TailMatchesCS2("\\set", MatchAny))
3257         {
3258                 if (TailMatchesCS1("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
3259                                                    "SINGLELINE|SINGLESTEP"))
3260                         COMPLETE_WITH_LIST_CS2("on", "off");
3261                 else if (TailMatchesCS1("COMP_KEYWORD_CASE"))
3262                         COMPLETE_WITH_LIST_CS4("lower", "upper",
3263                                                                    "preserve-lower", "preserve-upper");
3264                 else if (TailMatchesCS1("ECHO"))
3265                         COMPLETE_WITH_LIST_CS4("errors", "queries", "all", "none");
3266                 else if (TailMatchesCS1("ECHO_HIDDEN"))
3267                         COMPLETE_WITH_LIST_CS3("noexec", "off", "on");
3268                 else if (TailMatchesCS1("HISTCONTROL"))
3269                         COMPLETE_WITH_LIST_CS4("ignorespace", "ignoredups",
3270                                                                    "ignoreboth", "none");
3271                 else if (TailMatchesCS1("ON_ERROR_ROLLBACK"))
3272                         COMPLETE_WITH_LIST_CS3("on", "off", "interactive");
3273                 else if (TailMatchesCS1("SHOW_CONTEXT"))
3274                         COMPLETE_WITH_LIST_CS3("never", "errors", "always");
3275                 else if (TailMatchesCS1("VERBOSITY"))
3276                         COMPLETE_WITH_LIST_CS3("default", "verbose", "terse");
3277         }
3278         else if (TailMatchesCS1("\\sf*"))
3279                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3280         else if (TailMatchesCS1("\\sv*"))
3281                 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3282         else if (TailMatchesCS1("\\cd|\\e|\\edit|\\g|\\i|\\include|"
3283                                                         "\\ir|\\include_relative|\\o|\\out|"
3284                                                         "\\s|\\w|\\write|\\lo_import"))
3285         {
3286                 completion_charp = "\\";
3287                 matches = completion_matches(text, complete_from_files);
3288         }
3289
3290         /*
3291          * Finally, we look through the list of "things", such as TABLE, INDEX and
3292          * check if that was the previous word. If so, execute the query to get a
3293          * list of them.
3294          */
3295         else
3296         {
3297                 int                     i;
3298
3299                 for (i = 0; words_after_create[i].name; i++)
3300                 {
3301                         if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
3302                         {
3303                                 if (words_after_create[i].query)
3304                                         COMPLETE_WITH_QUERY(words_after_create[i].query);
3305                                 else if (words_after_create[i].squery)
3306                                         COMPLETE_WITH_SCHEMA_QUERY(*words_after_create[i].squery,
3307                                                                                            NULL);
3308                                 break;
3309                         }
3310                 }
3311         }
3312
3313         /*
3314          * If we still don't have anything to match we have to fabricate some sort
3315          * of default list. If we were to just return NULL, readline automatically
3316          * attempts filename completion, and that's usually no good.
3317          */
3318         if (matches == NULL)
3319         {
3320                 COMPLETE_WITH_CONST("");
3321 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
3322                 rl_completion_append_character = '\0';
3323 #endif
3324         }
3325
3326         /* free storage */
3327         free(previous_words);
3328         free(words_buffer);
3329
3330         /* Return our Grand List O' Matches */
3331         return matches;
3332 }
3333
3334
3335 /*
3336  * GENERATOR FUNCTIONS
3337  *
3338  * These functions do all the actual work of completing the input. They get
3339  * passed the text so far and the count how many times they have been called
3340  * so far with the same text.
3341  * If you read the above carefully, you'll see that these don't get called
3342  * directly but through the readline interface.
3343  * The return value is expected to be the full completion of the text, going
3344  * through a list each time, or NULL if there are no more matches. The string
3345  * will be free()'d by readline, so you must run it through strdup() or
3346  * something of that sort.
3347  */
3348
3349 /*
3350  * Common routine for create_command_generator and drop_command_generator.
3351  * Entries that have 'excluded' flags are not returned.
3352  */
3353 static char *
3354 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
3355 {
3356         static int      list_index,
3357                                 string_length;
3358         const char *name;
3359
3360         /* If this is the first time for this completion, init some values */
3361         if (state == 0)
3362         {
3363                 list_index = 0;
3364                 string_length = strlen(text);
3365         }
3366
3367         /* find something that matches */
3368         while ((name = words_after_create[list_index++].name))
3369         {
3370                 if ((pg_strncasecmp(name, text, string_length) == 0) &&
3371                         !(words_after_create[list_index - 1].flags & excluded))
3372                         return pg_strdup_keyword_case(name, text);
3373         }
3374         /* if nothing matches, return NULL */
3375         return NULL;
3376 }
3377
3378 /*
3379  * This one gives you one from a list of things you can put after CREATE
3380  * as defined above.
3381  */
3382 static char *
3383 create_command_generator(const char *text, int state)
3384 {
3385         return create_or_drop_command_generator(text, state, THING_NO_CREATE);
3386 }
3387
3388 /*
3389  * This function gives you a list of things you can put after a DROP command.
3390  */
3391 static char *
3392 drop_command_generator(const char *text, int state)
3393 {
3394         return create_or_drop_command_generator(text, state, THING_NO_DROP);
3395 }
3396
3397 /* The following two functions are wrappers for _complete_from_query */
3398
3399 static char *
3400 complete_from_query(const char *text, int state)
3401 {
3402         return _complete_from_query(0, text, state);
3403 }
3404
3405 static char *
3406 complete_from_schema_query(const char *text, int state)
3407 {
3408         return _complete_from_query(1, text, state);
3409 }
3410
3411
3412 /*
3413  * This creates a list of matching things, according to a query pointed to
3414  * by completion_charp.
3415  * The query can be one of two kinds:
3416  *
3417  * 1. A simple query which must contain a %d and a %s, which will be replaced
3418  * by the string length of the text and the text itself. The query may also
3419  * have up to four more %s in it; the first two such will be replaced by the
3420  * value of completion_info_charp, the next two by the value of
3421  * completion_info_charp2.
3422  *
3423  * 2. A schema query used for completion of both schema and relation names.
3424  * These are more complex and must contain in the following order:
3425  * %d %s %d %s %d %s %s %d %s
3426  * where %d is the string length of the text and %s the text itself.
3427  *
3428  * It is assumed that strings should be escaped to become SQL literals
3429  * (that is, what is in the query is actually ... '%s' ...)
3430  *
3431  * See top of file for examples of both kinds of query.
3432  */
3433 static char *
3434 _complete_from_query(int is_schema_query, const char *text, int state)
3435 {
3436         static int      list_index,
3437                                 byte_length;
3438         static PGresult *result = NULL;
3439
3440         /*
3441          * If this is the first time for this completion, we fetch a list of our
3442          * "things" from the backend.
3443          */
3444         if (state == 0)
3445         {
3446                 PQExpBufferData query_buffer;
3447                 char       *e_text;
3448                 char       *e_info_charp;
3449                 char       *e_info_charp2;
3450                 const char *pstr = text;
3451                 int                     char_length = 0;
3452
3453                 list_index = 0;
3454                 byte_length = strlen(text);
3455
3456                 /*
3457                  * Count length as number of characters (not bytes), for passing to
3458                  * substring
3459                  */
3460                 while (*pstr)
3461                 {
3462                         char_length++;
3463                         pstr += PQmblen(pstr, pset.encoding);
3464                 }
3465
3466                 /* Free any prior result */
3467                 PQclear(result);
3468                 result = NULL;
3469
3470                 /* Set up suitably-escaped copies of textual inputs */
3471                 e_text = escape_string(text);
3472
3473                 if (completion_info_charp)
3474                         e_info_charp = escape_string(completion_info_charp);
3475                 else
3476                         e_info_charp = NULL;
3477
3478                 if (completion_info_charp2)
3479                         e_info_charp2 = escape_string(completion_info_charp2);
3480                 else
3481                         e_info_charp2 = NULL;
3482
3483                 initPQExpBuffer(&query_buffer);
3484
3485                 if (is_schema_query)
3486                 {
3487                         /* completion_squery gives us the pieces to assemble */
3488                         const char *qualresult = completion_squery->qualresult;
3489
3490                         if (qualresult == NULL)
3491                                 qualresult = completion_squery->result;
3492
3493                         /* Get unqualified names matching the input-so-far */
3494                         appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
3495                                                           completion_squery->result,
3496                                                           completion_squery->catname);
3497                         if (completion_squery->selcondition)
3498                                 appendPQExpBuffer(&query_buffer, "%s AND ",
3499                                                                   completion_squery->selcondition);
3500                         appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
3501                                                           completion_squery->result,
3502                                                           char_length, e_text);
3503                         appendPQExpBuffer(&query_buffer, " AND %s",
3504                                                           completion_squery->viscondition);
3505
3506                         /*
3507                          * When fetching relation names, suppress system catalogs unless
3508                          * the input-so-far begins with "pg_".  This is a compromise
3509                          * between not offering system catalogs for completion at all, and
3510                          * having them swamp the result when the input is just "p".
3511                          */
3512                         if (strcmp(completion_squery->catname,
3513                                            "pg_catalog.pg_class c") == 0 &&
3514                                 strncmp(text, "pg_", 3) !=0)
3515                         {
3516                                 appendPQExpBufferStr(&query_buffer,
3517                                                                          " AND c.relnamespace <> (SELECT oid FROM"
3518                                    " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
3519                         }
3520
3521                         /*
3522                          * Add in matching schema names, but only if there is more than
3523                          * one potential match among schema names.
3524                          */
3525                         appendPQExpBuffer(&query_buffer, "\nUNION\n"
3526                                                    "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
3527                                                           "FROM pg_catalog.pg_namespace n "
3528                                                           "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
3529                                                           char_length, e_text);
3530                         appendPQExpBuffer(&query_buffer,
3531                                                           " AND (SELECT pg_catalog.count(*)"
3532                                                           " FROM pg_catalog.pg_namespace"
3533                         " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3534                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
3535                                                           char_length, e_text);
3536
3537                         /*
3538                          * Add in matching qualified names, but only if there is exactly
3539                          * one schema matching the input-so-far.
3540                          */
3541                         appendPQExpBuffer(&query_buffer, "\nUNION\n"
3542                                          "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
3543                                                           "FROM %s, pg_catalog.pg_namespace n "
3544                                                           "WHERE %s = n.oid AND ",
3545                                                           qualresult,
3546                                                           completion_squery->catname,
3547                                                           completion_squery->namespace);
3548                         if (completion_squery->selcondition)
3549                                 appendPQExpBuffer(&query_buffer, "%s AND ",
3550                                                                   completion_squery->selcondition);
3551                         appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
3552                                                           qualresult,
3553                                                           char_length, e_text);
3554
3555                         /*
3556                          * This condition exploits the single-matching-schema rule to
3557                          * speed up the query
3558                          */
3559                         appendPQExpBuffer(&query_buffer,
3560                         " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
3561                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
3562                                                           char_length, e_text);
3563                         appendPQExpBuffer(&query_buffer,
3564                                                           " AND (SELECT pg_catalog.count(*)"
3565                                                           " FROM pg_catalog.pg_namespace"
3566                         " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3567                                                           " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
3568                                                           char_length, e_text);
3569
3570                         /* If an addon query was provided, use it */
3571                         if (completion_charp)
3572                                 appendPQExpBuffer(&query_buffer, "\n%s", completion_charp);
3573                 }
3574                 else
3575                 {
3576                         /* completion_charp is an sprintf-style format string */
3577                         appendPQExpBuffer(&query_buffer, completion_charp,
3578                                                           char_length, e_text,
3579                                                           e_info_charp, e_info_charp,
3580                                                           e_info_charp2, e_info_charp2);
3581                 }
3582
3583                 /* Limit the number of records in the result */
3584                 appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
3585                                                   completion_max_records);
3586
3587                 result = exec_query(query_buffer.data);
3588
3589                 termPQExpBuffer(&query_buffer);
3590                 free(e_text);
3591                 if (e_info_charp)
3592                         free(e_info_charp);
3593                 if (e_info_charp2)
3594                         free(e_info_charp2);
3595         }
3596
3597         /* Find something that matches */
3598         if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
3599         {
3600                 const char *item;
3601
3602                 while (list_index < PQntuples(result) &&
3603                            (item = PQgetvalue(result, list_index++, 0)))
3604                         if (pg_strncasecmp(text, item, byte_length) == 0)
3605                                 return pg_strdup(item);
3606         }
3607
3608         /* If nothing matches, free the db structure and return null */
3609         PQclear(result);
3610         result = NULL;
3611         return NULL;
3612 }
3613
3614
3615 /*
3616  * This function returns in order one of a fixed, NULL pointer terminated list
3617  * of strings (if matching). This can be used if there are only a fixed number
3618  * SQL words that can appear at certain spot.
3619  */
3620 static char *
3621 complete_from_list(const char *text, int state)
3622 {
3623         static int      string_length,
3624                                 list_index,
3625                                 matches;
3626         static bool casesensitive;
3627         const char *item;
3628
3629         /* need to have a list */
3630         Assert(completion_charpp != NULL);
3631
3632         /* Initialization */
3633         if (state == 0)
3634         {
3635                 list_index = 0;
3636                 string_length = strlen(text);
3637                 casesensitive = completion_case_sensitive;
3638                 matches = 0;
3639         }
3640
3641         while ((item = completion_charpp[list_index++]))
3642         {
3643                 /* First pass is case sensitive */
3644                 if (casesensitive && strncmp(text, item, string_length) == 0)
3645                 {
3646                         matches++;
3647                         return pg_strdup(item);
3648                 }
3649
3650                 /* Second pass is case insensitive, don't bother counting matches */
3651                 if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
3652                 {
3653                         if (completion_case_sensitive)
3654                                 return pg_strdup(item);
3655                         else
3656
3657                                 /*
3658                                  * If case insensitive matching was requested initially,
3659                                  * adjust the case according to setting.
3660                                  */
3661                                 return pg_strdup_keyword_case(item, text);
3662                 }
3663         }
3664
3665         /*
3666          * No matches found. If we're not case insensitive already, lets switch to
3667          * being case insensitive and try again
3668          */
3669         if (casesensitive && matches == 0)
3670         {
3671                 casesensitive = false;
3672                 list_index = 0;
3673                 state++;
3674                 return complete_from_list(text, state);
3675         }
3676
3677         /* If no more matches, return null. */
3678         return NULL;
3679 }
3680
3681
3682 /*
3683  * This function returns one fixed string the first time even if it doesn't
3684  * match what's there, and nothing the second time. This should be used if
3685  * there is only one possibility that can appear at a certain spot, so
3686  * misspellings will be overwritten.  The string to be passed must be in
3687  * completion_charp.
3688  */
3689 static char *
3690 complete_from_const(const char *text, int state)
3691 {
3692         Assert(completion_charp != NULL);
3693         if (state == 0)
3694         {
3695                 if (completion_case_sensitive)
3696                         return pg_strdup(completion_charp);
3697                 else
3698
3699                         /*
3700                          * If case insensitive matching was requested initially, adjust
3701                          * the case according to setting.
3702                          */
3703                         return pg_strdup_keyword_case(completion_charp, text);
3704         }
3705         else
3706                 return NULL;
3707 }
3708
3709
3710 /*
3711  * This function appends the variable name with prefix and suffix to
3712  * the variable names array.
3713  */
3714 static void
3715 append_variable_names(char ***varnames, int *nvars,
3716                                           int *maxvars, const char *varname,
3717                                           const char *prefix, const char *suffix)
3718 {
3719         if (*nvars >= *maxvars)
3720         {
3721                 *maxvars *= 2;
3722                 *varnames = (char **) pg_realloc(*varnames,
3723                                                                                  ((*maxvars) + 1) * sizeof(char *));
3724         }
3725
3726         (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
3727 }
3728
3729
3730 /*
3731  * This function supports completion with the name of a psql variable.
3732  * The variable names can be prefixed and suffixed with additional text
3733  * to support quoting usages. If need_value is true, only the variables
3734  * that have the set values are picked up.
3735  */
3736 static char **
3737 complete_from_variables(const char *text, const char *prefix, const char *suffix,
3738                                                 bool need_value)
3739 {
3740         char      **matches;
3741         char      **varnames;
3742         int                     nvars = 0;
3743         int                     maxvars = 100;
3744         int                     i;
3745         struct _variable *ptr;
3746
3747         static const char *const known_varnames[] = {
3748                 "AUTOCOMMIT", "COMP_KEYWORD_CASE", "DBNAME", "ECHO", "ECHO_HIDDEN",
3749                 "ENCODING", "FETCH_COUNT", "HISTCONTROL", "HISTFILE", "HISTSIZE",
3750                 "HOST", "IGNOREEOF", "LASTOID", "ON_ERROR_ROLLBACK", "ON_ERROR_STOP",
3751                 "PORT", "PROMPT1", "PROMPT2", "PROMPT3", "QUIET",
3752                 "SHOW_CONTEXT", "SINGLELINE", "SINGLESTEP",
3753                 "USER", "VERBOSITY", NULL
3754         };
3755
3756         varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
3757
3758         if (!need_value)
3759         {
3760                 for (i = 0; known_varnames[i] && nvars < maxvars; i++)
3761                         append_variable_names(&varnames, &nvars, &maxvars,
3762                                                                   known_varnames[i], prefix, suffix);
3763         }
3764
3765         for (ptr = pset.vars->next; ptr; ptr = ptr->next)
3766         {
3767                 if (need_value && !(ptr->value))
3768                         continue;
3769                 for (i = 0; known_varnames[i]; i++)             /* remove duplicate entry */
3770                 {
3771                         if (strcmp(ptr->name, known_varnames[i]) == 0)
3772                                 continue;
3773                 }
3774                 append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
3775                                                           prefix, suffix);
3776         }
3777
3778         varnames[nvars] = NULL;
3779         COMPLETE_WITH_LIST_CS((const char *const *) varnames);
3780
3781         for (i = 0; i < nvars; i++)
3782                 free(varnames[i]);
3783         free(varnames);
3784
3785         return matches;
3786 }
3787
3788
3789 /*
3790  * This function wraps rl_filename_completion_function() to strip quotes from
3791  * the input before searching for matches and to quote any matches for which
3792  * the consuming command will require it.
3793  */
3794 static char *
3795 complete_from_files(const char *text, int state)
3796 {
3797         static const char *unquoted_text;
3798         char       *unquoted_match;
3799         char       *ret = NULL;
3800
3801         if (state == 0)
3802         {
3803                 /* Initialization: stash the unquoted input. */
3804                 unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
3805                                                                 false, true, pset.encoding);
3806                 /* expect a NULL return for the empty string only */
3807                 if (!unquoted_text)
3808                 {
3809                         Assert(*text == '\0');
3810                         unquoted_text = text;
3811                 }
3812         }
3813
3814         unquoted_match = filename_completion_function(unquoted_text, state);
3815         if (unquoted_match)
3816         {
3817                 /*
3818                  * Caller sets completion_charp to a zero- or one-character string
3819                  * containing the escape character.  This is necessary since \copy has
3820                  * no escape character, but every other backslash command recognizes
3821                  * "\" as an escape character.  Since we have only two callers, don't
3822                  * bother providing a macro to simplify this.
3823                  */
3824                 ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
3825                                                           '\'', *completion_charp, pset.encoding);
3826                 if (ret)
3827                         free(unquoted_match);
3828                 else
3829                         ret = unquoted_match;
3830         }
3831
3832         return ret;
3833 }
3834
3835
3836 /* HELPER FUNCTIONS */
3837
3838
3839 /*
3840  * Make a pg_strdup copy of s and convert the case according to
3841  * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
3842  */
3843 static char *
3844 pg_strdup_keyword_case(const char *s, const char *ref)
3845 {
3846         char       *ret,
3847                            *p;
3848         unsigned char first = ref[0];
3849
3850         ret = pg_strdup(s);
3851
3852         if (pset.comp_case == PSQL_COMP_CASE_LOWER ||
3853                 ((pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER ||
3854            pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
3855                 (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
3856         {
3857                 for (p = ret; *p; p++)
3858                         *p = pg_tolower((unsigned char) *p);
3859         }
3860         else
3861         {
3862                 for (p = ret; *p; p++)
3863                         *p = pg_toupper((unsigned char) *p);
3864         }
3865
3866         return ret;
3867 }
3868
3869
3870 /*
3871  * escape_string - Escape argument for use as string literal.
3872  *
3873  * The returned value has to be freed.
3874  */
3875 static char *
3876 escape_string(const char *text)
3877 {
3878         size_t          text_length;
3879         char       *result;
3880
3881         text_length = strlen(text);
3882
3883         result = pg_malloc(text_length * 2 + 1);
3884         PQescapeStringConn(pset.db, result, text, text_length, NULL);
3885
3886         return result;
3887 }
3888
3889
3890 /*
3891  * Execute a query and report any errors. This should be the preferred way of
3892  * talking to the database in this file.
3893  */
3894 static PGresult *
3895 exec_query(const char *query)
3896 {
3897         PGresult   *result;
3898
3899         if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
3900                 return NULL;
3901
3902         result = PQexec(pset.db, query);
3903
3904         if (PQresultStatus(result) != PGRES_TUPLES_OK)
3905         {
3906 #ifdef NOT_USED
3907                 psql_error("tab completion query failed: %s\nQuery was:\n%s\n",
3908                                    PQerrorMessage(pset.db), query);
3909 #endif
3910                 PQclear(result);
3911                 result = NULL;
3912         }
3913
3914         return result;
3915 }
3916
3917
3918 /*
3919  * Parse all the word(s) before point.
3920  *
3921  * Returns a malloc'd array of character pointers that point into the malloc'd
3922  * data array returned to *buffer; caller must free() both of these when done.
3923  * *nwords receives the number of words found, ie, the valid length of the
3924  * return array.
3925  *
3926  * Words are returned right to left, that is, previous_words[0] gets the last
3927  * word before point, previous_words[1] the next-to-last, etc.
3928  */
3929 static char **
3930 get_previous_words(int point, char **buffer, int *nwords)
3931 {
3932         char      **previous_words;
3933         char       *buf;
3934         char       *outptr;
3935         int                     words_found = 0;
3936         int                     i;
3937
3938         /*
3939          * If we have anything in tab_completion_query_buf, paste it together with
3940          * rl_line_buffer to construct the full query.  Otherwise we can just use
3941          * rl_line_buffer as the input string.
3942          */
3943         if (tab_completion_query_buf && tab_completion_query_buf->len > 0)
3944         {
3945                 i = tab_completion_query_buf->len;
3946                 buf = pg_malloc(point + i + 2);
3947                 memcpy(buf, tab_completion_query_buf->data, i);
3948                 buf[i++] = '\n';
3949                 memcpy(buf + i, rl_line_buffer, point);
3950                 i += point;
3951                 buf[i] = '\0';
3952                 /* Readjust point to reference appropriate offset in buf */
3953                 point = i;
3954         }
3955         else
3956                 buf = rl_line_buffer;
3957
3958         /*
3959          * Allocate an array of string pointers and a buffer to hold the strings
3960          * themselves.  The worst case is that the line contains only
3961          * non-whitespace WORD_BREAKS characters, making each one a separate word.
3962          * This is usually much more space than we need, but it's cheaper than
3963          * doing a separate malloc() for each word.
3964          */
3965         previous_words = (char **) pg_malloc(point * sizeof(char *));
3966         *buffer = outptr = (char *) pg_malloc(point * 2);
3967
3968         /*
3969          * First we look for a non-word char before the current point.  (This is
3970          * probably useless, if readline is on the same page as we are about what
3971          * is a word, but if so it's cheap.)
3972          */
3973         for (i = point - 1; i >= 0; i--)
3974         {
3975                 if (strchr(WORD_BREAKS, buf[i]))
3976                         break;
3977         }
3978         point = i;
3979
3980         /*
3981          * Now parse words, working backwards, until we hit start of line.  The
3982          * backwards scan has some interesting but intentional properties
3983          * concerning parenthesis handling.
3984          */
3985         while (point >= 0)
3986         {
3987                 int                     start,
3988                                         end;
3989                 bool            inquotes = false;
3990                 int                     parentheses = 0;
3991
3992                 /* now find the first non-space which then constitutes the end */
3993                 end = -1;
3994                 for (i = point; i >= 0; i--)
3995                 {
3996                         if (!isspace((unsigned char) buf[i]))
3997                         {
3998                                 end = i;
3999                                 break;
4000                         }
4001                 }
4002                 /* if no end found, we're done */
4003                 if (end < 0)
4004                         break;
4005
4006                 /*
4007                  * Otherwise we now look for the start.  The start is either the last
4008                  * character before any word-break character going backwards from the
4009                  * end, or it's simply character 0.  We also handle open quotes and
4010                  * parentheses.
4011                  */
4012                 for (start = end; start > 0; start--)
4013                 {
4014                         if (buf[start] == '"')
4015                                 inquotes = !inquotes;
4016                         if (!inquotes)
4017                         {
4018                                 if (buf[start] == ')')
4019                                         parentheses++;
4020                                 else if (buf[start] == '(')
4021                                 {
4022                                         if (--parentheses <= 0)
4023                                                 break;
4024                                 }
4025                                 else if (parentheses == 0 &&
4026                                                  strchr(WORD_BREAKS, buf[start - 1]))
4027                                         break;
4028                         }
4029                 }
4030
4031                 /* Return the word located at start to end inclusive */
4032                 previous_words[words_found++] = outptr;
4033                 i = end - start + 1;
4034                 memcpy(outptr, &buf[start], i);
4035                 outptr += i;
4036                 *outptr++ = '\0';
4037
4038                 /* Continue searching */
4039                 point = start - 1;
4040         }
4041
4042         /* Release parsing input workspace, if we made one above */
4043         if (buf != rl_line_buffer)
4044                 free(buf);
4045
4046         *nwords = words_found;
4047         return previous_words;
4048 }
4049
4050 /*
4051  * Look up the type for the GUC variable with the passed name.
4052  *
4053  * Returns NULL if the variable is unknown. Otherwise the returned string,
4054  * containing the type, has to be freed.
4055  */
4056 static char *
4057 get_guctype(const char *varname)
4058 {
4059         PQExpBufferData query_buffer;
4060         char       *e_varname;
4061         PGresult   *result;
4062         char       *guctype = NULL;
4063
4064         e_varname = escape_string(varname);
4065
4066         initPQExpBuffer(&query_buffer);
4067         appendPQExpBuffer(&query_buffer,
4068                                           "SELECT vartype FROM pg_catalog.pg_settings "
4069                                           "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4070                                           e_varname);
4071
4072         result = exec_query(query_buffer.data);
4073         termPQExpBuffer(&query_buffer);
4074         free(e_varname);
4075
4076         if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
4077                 guctype = pg_strdup(PQgetvalue(result, 0, 0));
4078
4079         PQclear(result);
4080
4081         return guctype;
4082 }
4083
4084 #ifdef NOT_USED
4085
4086 /*
4087  * Surround a string with single quotes. This works for both SQL and
4088  * psql internal. Currently disabled because it is reported not to
4089  * cooperate with certain versions of readline.
4090  */
4091 static char *
4092 quote_file_name(char *text, int match_type, char *quote_pointer)
4093 {
4094         char       *s;
4095         size_t          length;
4096
4097         (void) quote_pointer;           /* not used */
4098
4099         length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
4100         s = pg_malloc(length);
4101         s[0] = '\'';
4102         strcpy(s + 1, text);
4103         if (match_type == SINGLE_MATCH)
4104                 s[length - 2] = '\'';
4105         s[length - 1] = '\0';
4106         return s;
4107 }
4108
4109 static char *
4110 dequote_file_name(char *text, char quote_char)
4111 {
4112         char       *s;
4113         size_t          length;
4114
4115         if (!quote_char)
4116                 return pg_strdup(text);
4117
4118         length = strlen(text);
4119         s = pg_malloc(length - 2 + 1);
4120         strlcpy(s, text +1, length - 2 + 1);
4121
4122         return s;
4123 }
4124 #endif   /* NOT_USED */
4125
4126 #endif   /* USE_READLINE */