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