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