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