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