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