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