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