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