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 ROLE", "IN SCHEMA");
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  "OF", "NOT OF");
2357  /* ALTER TABLE xxx ADD */
2358  else if (Matches("ALTER", "TABLE", MatchAny, "ADD"))
2359  {
2360  /* make sure to keep this list and the !Matches() below in sync */
2361  COMPLETE_WITH("COLUMN", "CONSTRAINT", "CHECK", "UNIQUE", "PRIMARY KEY",
2362  "EXCLUDE", "FOREIGN KEY");
2363  }
2364  /* ALTER TABLE xxx ADD [COLUMN] yyy */
2365  else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "COLUMN", MatchAny) ||
2366  (Matches("ALTER", "TABLE", MatchAny, "ADD", MatchAny) &&
2367  !Matches("ALTER", "TABLE", MatchAny, "ADD", "COLUMN|CONSTRAINT|CHECK|UNIQUE|PRIMARY|EXCLUDE|FOREIGN")))
2368  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
2369  /* ALTER TABLE xxx ADD CONSTRAINT yyy */
2370  else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny))
2371  COMPLETE_WITH("CHECK", "UNIQUE", "PRIMARY KEY", "EXCLUDE", "FOREIGN KEY");
2372  /* ALTER TABLE xxx ADD [CONSTRAINT yyy] (PRIMARY KEY|UNIQUE) */
2373  else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "PRIMARY", "KEY") ||
2374  Matches("ALTER", "TABLE", MatchAny, "ADD", "UNIQUE") ||
2375  Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "PRIMARY", "KEY") ||
2376  Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "UNIQUE"))
2377  COMPLETE_WITH("(", "USING INDEX");
2378  /* ALTER TABLE xxx ADD PRIMARY KEY USING INDEX */
2379  else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "PRIMARY", "KEY", "USING", "INDEX"))
2380  {
2381  set_completion_reference(prev6_wd);
2382  COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
2383  }
2384  /* ALTER TABLE xxx ADD UNIQUE USING INDEX */
2385  else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "UNIQUE", "USING", "INDEX"))
2386  {
2387  set_completion_reference(prev5_wd);
2388  COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
2389  }
2390  /* ALTER TABLE xxx ADD CONSTRAINT yyy PRIMARY KEY USING INDEX */
2391  else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny,
2392  "PRIMARY", "KEY", "USING", "INDEX"))
2393  {
2394  set_completion_reference(prev8_wd);
2395  COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
2396  }
2397  /* ALTER TABLE xxx ADD CONSTRAINT yyy UNIQUE USING INDEX */
2398  else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny,
2399  "UNIQUE", "USING", "INDEX"))
2400  {
2401  set_completion_reference(prev7_wd);
2402  COMPLETE_WITH_SCHEMA_QUERY(Query_for_unique_index_of_table);
2403  }
2404  /* ALTER TABLE xxx ENABLE */
2405  else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE"))
2406  COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
2407  "TRIGGER");
2408  else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
2409  COMPLETE_WITH("RULE", "TRIGGER");
2410  else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
2411  {
2412  set_completion_reference(prev3_wd);
2413  COMPLETE_WITH_SCHEMA_QUERY(Query_for_rule_of_table);
2414  }
2415  else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
2416  {
2417  set_completion_reference(prev4_wd);
2418  COMPLETE_WITH_SCHEMA_QUERY(Query_for_rule_of_table);
2419  }
2420  else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
2421  {
2422  set_completion_reference(prev3_wd);
2423  COMPLETE_WITH_SCHEMA_QUERY(Query_for_trigger_of_table);
2424  }
2425  else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
2426  {
2427  set_completion_reference(prev4_wd);
2428  COMPLETE_WITH_SCHEMA_QUERY(Query_for_trigger_of_table);
2429  }
2430  /* ALTER TABLE xxx INHERIT */
2431  else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT"))
2432  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
2433  /* ALTER TABLE xxx NO */
2434  else if (Matches("ALTER", "TABLE", MatchAny, "NO"))
2435  COMPLETE_WITH("FORCE ROW LEVEL SECURITY", "INHERIT");
2436  /* ALTER TABLE xxx NO INHERIT */
2437  else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
2438  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
2439  /* ALTER TABLE xxx DISABLE */
2440  else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE"))
2441  COMPLETE_WITH("ROW LEVEL SECURITY", "RULE", "TRIGGER");
2442  else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
2443  {
2444  set_completion_reference(prev3_wd);
2445  COMPLETE_WITH_SCHEMA_QUERY(Query_for_rule_of_table);
2446  }
2447  else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
2448  {
2449  set_completion_reference(prev3_wd);
2450  COMPLETE_WITH_SCHEMA_QUERY(Query_for_trigger_of_table);
2451  }
2452 
2453  /* ALTER TABLE xxx ALTER */
2454  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER"))
2455  COMPLETE_WITH_ATTR_PLUS(prev2_wd, "COLUMN", "CONSTRAINT");
2456 
2457  /* ALTER TABLE xxx RENAME */
2458  else if (Matches("ALTER", "TABLE", MatchAny, "RENAME"))
2459  COMPLETE_WITH_ATTR_PLUS(prev2_wd, "COLUMN", "CONSTRAINT", "TO");
2460  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
2461  COMPLETE_WITH_ATTR(prev3_wd);
2462 
2463  /* ALTER TABLE xxx RENAME yyy */
2464  else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
2465  COMPLETE_WITH("TO");
2466 
2467  /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
2468  else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
2469  COMPLETE_WITH("TO");
2470 
2471  /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
2472  else if (Matches("ALTER", "TABLE", MatchAny, "DROP"))
2473  COMPLETE_WITH("COLUMN", "CONSTRAINT");
2474  /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
2475  else if (Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
2476  COMPLETE_WITH_ATTR(prev3_wd);
2477  /* ALTER TABLE <sth> ALTER|DROP|RENAME CONSTRAINT <constraint> */
2478  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME", "CONSTRAINT"))
2479  {
2480  set_completion_reference(prev3_wd);
2481  COMPLETE_WITH_SCHEMA_QUERY(Query_for_constraint_of_table);
2482  }
2483  /* ALTER TABLE <sth> VALIDATE CONSTRAINT <non-validated constraint> */
2484  else if (Matches("ALTER", "TABLE", MatchAny, "VALIDATE", "CONSTRAINT"))
2485  {
2486  set_completion_reference(prev3_wd);
2487  COMPLETE_WITH_SCHEMA_QUERY(Query_for_constraint_of_table_not_validated);
2488  }
2489  /* ALTER TABLE ALTER [COLUMN] <foo> */
2490  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
2491  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
2492  COMPLETE_WITH("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP");
2493  /* ALTER TABLE ALTER [COLUMN] <foo> ADD */
2494  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD") ||
2495  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD"))
2496  COMPLETE_WITH("GENERATED");
2497  /* ALTER TABLE ALTER [COLUMN] <foo> ADD GENERATED */
2498  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED") ||
2499  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED"))
2500  COMPLETE_WITH("ALWAYS", "BY DEFAULT");
2501  /* ALTER TABLE ALTER [COLUMN] <foo> ADD GENERATED */
2502  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED", "ALWAYS") ||
2503  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED", "ALWAYS") ||
2504  Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "ADD", "GENERATED", "BY", "DEFAULT") ||
2505  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "ADD", "GENERATED", "BY", "DEFAULT"))
2506  COMPLETE_WITH("AS IDENTITY");
2507  /* ALTER TABLE ALTER [COLUMN] <foo> SET */
2508  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
2509  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
2510  COMPLETE_WITH("(", "COMPRESSION", "DATA TYPE", "DEFAULT", "EXPRESSION", "GENERATED", "NOT NULL",
2511  "STATISTICS", "STORAGE",
2512  /* a subset of ALTER SEQUENCE options */
2513  "INCREMENT", "MINVALUE", "MAXVALUE", "START", "NO", "CACHE", "CYCLE");
2514  /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
2515  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
2516  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
2517  COMPLETE_WITH("n_distinct", "n_distinct_inherited");
2518  /* ALTER TABLE ALTER [COLUMN] <foo> SET COMPRESSION */
2519  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "COMPRESSION") ||
2520  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "COMPRESSION"))
2521  COMPLETE_WITH("DEFAULT", "PGLZ", "LZ4");
2522  /* ALTER TABLE ALTER [COLUMN] <foo> SET EXPRESSION */
2523  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "EXPRESSION") ||
2524  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "EXPRESSION"))
2525  COMPLETE_WITH("AS");
2526  /* ALTER TABLE ALTER [COLUMN] <foo> SET EXPRESSION AS */
2527  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "EXPRESSION", "AS") ||
2528  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "EXPRESSION", "AS"))
2529  COMPLETE_WITH("(");
2530  /* ALTER TABLE ALTER [COLUMN] <foo> SET GENERATED */
2531  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "GENERATED") ||
2532  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "GENERATED"))
2533  COMPLETE_WITH("ALWAYS", "BY DEFAULT");
2534  /* ALTER TABLE ALTER [COLUMN] <foo> SET NO */
2535  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "NO") ||
2536  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "NO"))
2537  COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
2538  /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
2539  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
2540  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
2541  COMPLETE_WITH("DEFAULT", "PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
2542  /* ALTER TABLE ALTER [COLUMN] <foo> SET STATISTICS */
2543  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS") ||
2544  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STATISTICS"))
2545  {
2546  /* Enforce no completion here, as an integer has to be specified */
2547  }
2548  /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
2549  else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
2550  Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
2551  COMPLETE_WITH("DEFAULT", "EXPRESSION", "IDENTITY", "NOT NULL");
2552  else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER"))
2553  COMPLETE_WITH("ON");
2554  else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
2555  {
2556  set_completion_reference(prev3_wd);
2557  COMPLETE_WITH_SCHEMA_QUERY(Query_for_index_of_table);
2558  }
2559  /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
2560  else if (Matches("ALTER", "TABLE", MatchAny, "SET"))
2561  COMPLETE_WITH("(", "ACCESS METHOD", "LOGGED", "SCHEMA",
2562  "TABLESPACE", "UNLOGGED", "WITH", "WITHOUT");
2563 
2564  /*
2565  * If we have ALTER TABLE <sth> SET ACCESS METHOD provide a list of table
2566  * AMs.
2567  */
2568  else if (Matches("ALTER", "TABLE", MatchAny, "SET", "ACCESS", "METHOD"))
2569  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_table_access_methods,
2570  "DEFAULT");
2571 
2572  /*
2573  * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
2574  * tablespaces
2575  */
2576  else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
2577  COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
2578  /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
2579  else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
2580  COMPLETE_WITH("CLUSTER", "OIDS");
2581  /* ALTER TABLE <foo> RESET */
2582  else if (Matches("ALTER", "TABLE", MatchAny, "RESET"))
2583  COMPLETE_WITH("(");
2584  /* ALTER TABLE <foo> SET|RESET ( */
2585  else if (Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
2586  COMPLETE_WITH_LIST(table_storage_parameters);
2587  else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
2588  {
2589  set_completion_reference(prev5_wd);
2590  COMPLETE_WITH_SCHEMA_QUERY(Query_for_index_of_table);
2591  }
2592  else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
2593  COMPLETE_WITH("INDEX");
2594  else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
2595  COMPLETE_WITH("FULL", "NOTHING", "DEFAULT", "USING");
2596  else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA"))
2597  COMPLETE_WITH("IDENTITY");
2598 
2599  /*
2600  * If we have ALTER TABLE <foo> ATTACH PARTITION, provide a list of
2601  * tables.
2602  */
2603  else if (Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION"))
2604  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
2605  /* Limited completion support for partition bound specification */
2606  else if (TailMatches("ATTACH", "PARTITION", MatchAny))
2607  COMPLETE_WITH("FOR VALUES", "DEFAULT");
2608  else if (TailMatches("FOR", "VALUES"))
2609  COMPLETE_WITH("FROM (", "IN (", "WITH (");
2610 
2611  /*
2612  * If we have ALTER TABLE <foo> DETACH PARTITION, provide a list of
2613  * partitions of <foo>.
2614  */
2615  else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION"))
2616  {
2617  set_completion_reference(prev3_wd);
2618  COMPLETE_WITH_SCHEMA_QUERY(Query_for_partition_of_table);
2619  }
2620  else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION", MatchAny))
2621  COMPLETE_WITH("CONCURRENTLY", "FINALIZE");
2622 
2623  /* ALTER TABLE <name> OF */
2624  else if (Matches("ALTER", "TABLE", MatchAny, "OF"))
2625  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes);
2626 
2627  /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
2628  else if (Matches("ALTER", "TABLESPACE", MatchAny))
2629  COMPLETE_WITH("RENAME TO", "OWNER TO", "SET", "RESET");
2630  /* ALTER TABLESPACE <foo> SET|RESET */
2631  else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
2632  COMPLETE_WITH("(");
2633  /* ALTER TABLESPACE <foo> SET|RESET ( */
2634  else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
2635  COMPLETE_WITH("seq_page_cost", "random_page_cost",
2636  "effective_io_concurrency", "maintenance_io_concurrency");
2637 
2638  /* ALTER TEXT SEARCH */
2639  else if (Matches("ALTER", "TEXT", "SEARCH"))
2640  COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2641  else if (Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
2642  COMPLETE_WITH("RENAME TO", "SET SCHEMA");
2643  else if (Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
2644  COMPLETE_WITH("(", "OWNER TO", "RENAME TO", "SET SCHEMA");
2645  else if (Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2646  COMPLETE_WITH("ADD MAPPING FOR", "ALTER MAPPING",
2647  "DROP MAPPING FOR",
2648  "OWNER TO", "RENAME TO", "SET SCHEMA");
2649 
2650  /* complete ALTER TYPE <foo> with actions */
2651  else if (Matches("ALTER", "TYPE", MatchAny))
2652  COMPLETE_WITH("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
2653  "DROP ATTRIBUTE",
2654  "OWNER TO", "RENAME", "SET SCHEMA", "SET (");
2655  /* complete ALTER TYPE <foo> ADD with actions */
2656  else if (Matches("ALTER", "TYPE", MatchAny, "ADD"))
2657  COMPLETE_WITH("ATTRIBUTE", "VALUE");
2658  /* ALTER TYPE <foo> RENAME */
2659  else if (Matches("ALTER", "TYPE", MatchAny, "RENAME"))
2660  COMPLETE_WITH("ATTRIBUTE", "TO", "VALUE");
2661  /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
2662  else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
2663  COMPLETE_WITH("TO");
2664 
2665  /*
2666  * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
2667  * of attributes
2668  */
2669  else if (Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
2670  COMPLETE_WITH_ATTR(prev3_wd);
2671  /* ALTER TYPE ALTER ATTRIBUTE <foo> */
2672  else if (Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
2673  COMPLETE_WITH("TYPE");
2674  /* complete ALTER TYPE <sth> RENAME VALUE with list of enum values */
2675  else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
2676  COMPLETE_WITH_ENUM_VALUE(prev3_wd);
2677  /* ALTER TYPE <foo> SET */
2678  else if (Matches("ALTER", "TYPE", MatchAny, "SET"))
2679  COMPLETE_WITH("(", "SCHEMA");
2680  /* complete ALTER TYPE <foo> SET ( with settable properties */
2681  else if (Matches("ALTER", "TYPE", MatchAny, "SET", "("))
2682  COMPLETE_WITH("ANALYZE", "RECEIVE", "SEND", "STORAGE", "SUBSCRIPT",
2683  "TYPMOD_IN", "TYPMOD_OUT");
2684 
2685  /* complete ALTER GROUP <foo> */
2686  else if (Matches("ALTER", "GROUP", MatchAny))
2687  COMPLETE_WITH("ADD USER", "DROP USER", "RENAME TO");
2688  /* complete ALTER GROUP <foo> ADD|DROP with USER */
2689  else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP"))
2690  COMPLETE_WITH("USER");
2691  /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
2692  else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
2693  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2694 
2695 /*
2696  * ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
2697  * ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]
2698  */
2699  else if (Matches("ANALYZE"))
2700  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_analyzables,
2701  "VERBOSE");
2702  else if (HeadMatches("ANALYZE", "(*") &&
2703  !HeadMatches("ANALYZE", "(*)"))
2704  {
2705  /*
2706  * This fires if we're in an unfinished parenthesized option list.
2707  * get_previous_words treats a completed parenthesized option list as
2708  * one word, so the above test is correct.
2709  */
2710  if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
2711  COMPLETE_WITH("VERBOSE", "SKIP_LOCKED", "BUFFER_USAGE_LIMIT");
2712  else if (TailMatches("VERBOSE|SKIP_LOCKED"))
2713  COMPLETE_WITH("ON", "OFF");
2714  }
2715  else if (HeadMatches("ANALYZE") && TailMatches("("))
2716  /* "ANALYZE (" should be caught above, so assume we want columns */
2717  COMPLETE_WITH_ATTR(prev2_wd);
2718  else if (HeadMatches("ANALYZE"))
2719  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables);
2720 
2721 /* BEGIN */
2722  else if (Matches("BEGIN"))
2723  COMPLETE_WITH("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2724 /* END, ABORT */
2725  else if (Matches("END|ABORT"))
2726  COMPLETE_WITH("AND", "WORK", "TRANSACTION");
2727 /* COMMIT */
2728  else if (Matches("COMMIT"))
2729  COMPLETE_WITH("AND", "WORK", "TRANSACTION", "PREPARED");
2730 /* RELEASE SAVEPOINT */
2731  else if (Matches("RELEASE"))
2732  COMPLETE_WITH("SAVEPOINT");
2733 /* ROLLBACK */
2734  else if (Matches("ROLLBACK"))
2735  COMPLETE_WITH("AND", "WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
2736  else if (Matches("ABORT|END|COMMIT|ROLLBACK", "AND"))
2737  COMPLETE_WITH("CHAIN");
2738 /* CALL */
2739  else if (Matches("CALL"))
2740  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures);
2741  else if (Matches("CALL", MatchAny))
2742  COMPLETE_WITH("(");
2743 /* CLOSE */
2744  else if (Matches("CLOSE"))
2745  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
2746  "ALL");
2747 /* CLUSTER */
2748  else if (Matches("CLUSTER"))
2749  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_clusterables,
2750  "VERBOSE");
2751  else if (Matches("CLUSTER", "VERBOSE") ||
2752  Matches("CLUSTER", "(*)"))
2753  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables);
2754  /* If we have CLUSTER <sth>, then add "USING" */
2755  else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON|(|(*)")))
2756  COMPLETE_WITH("USING");
2757  /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
2758  else if (Matches("CLUSTER", "VERBOSE|(*)", MatchAny))
2759  COMPLETE_WITH("USING");
2760  /* If we have CLUSTER <sth> USING, then add the index as well */
2761  else if (Matches("CLUSTER", MatchAny, "USING") ||
2762  Matches("CLUSTER", "VERBOSE|(*)", MatchAny, "USING"))
2763  {
2764  set_completion_reference(prev2_wd);
2765  COMPLETE_WITH_SCHEMA_QUERY(Query_for_index_of_table);
2766  }
2767  else if (HeadMatches("CLUSTER", "(*") &&
2768  !HeadMatches("CLUSTER", "(*)"))
2769  {
2770  /*
2771  * This fires if we're in an unfinished parenthesized option list.
2772  * get_previous_words treats a completed parenthesized option list as
2773  * one word, so the above test is correct.
2774  */
2775  if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
2776  COMPLETE_WITH("VERBOSE");
2777  }
2778 
2779 /* COMMENT */
2780  else if (Matches("COMMENT"))
2781  COMPLETE_WITH("ON");
2782  else if (Matches("COMMENT", "ON"))
2783  COMPLETE_WITH("ACCESS METHOD", "AGGREGATE", "CAST", "COLLATION",
2784  "COLUMN", "CONSTRAINT", "CONVERSION", "DATABASE",
2785  "DOMAIN", "EXTENSION", "EVENT TRIGGER",
2786  "FOREIGN DATA WRAPPER", "FOREIGN TABLE",
2787  "FUNCTION", "INDEX", "LANGUAGE", "LARGE OBJECT",
2788  "MATERIALIZED VIEW", "OPERATOR", "POLICY",
2789  "PROCEDURE", "PROCEDURAL LANGUAGE", "PUBLICATION", "ROLE",
2790  "ROUTINE", "RULE", "SCHEMA", "SEQUENCE", "SERVER",
2791  "STATISTICS", "SUBSCRIPTION", "TABLE",
2792  "TABLESPACE", "TEXT SEARCH", "TRANSFORM FOR",
2793  "TRIGGER", "TYPE", "VIEW");
2794  else if (Matches("COMMENT", "ON", "ACCESS", "METHOD"))
2795  COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2796  else if (Matches("COMMENT", "ON", "CONSTRAINT"))
2797  COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2798  else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny))
2799  COMPLETE_WITH("ON");
2800  else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2801  {
2802  set_completion_reference(prev2_wd);
2803  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables_for_constraint,
2804  "DOMAIN");
2805  }
2806  else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON", "DOMAIN"))
2807  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains);
2808  else if (Matches("COMMENT", "ON", "EVENT", "TRIGGER"))
2809  COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2810  else if (Matches("COMMENT", "ON", "FOREIGN"))
2811  COMPLETE_WITH("DATA WRAPPER", "TABLE");
2812  else if (Matches("COMMENT", "ON", "FOREIGN", "TABLE"))
2813  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables);
2814  else if (Matches("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2815  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
2816  else if (Matches("COMMENT", "ON", "POLICY"))
2817  COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2818  else if (Matches("COMMENT", "ON", "POLICY", MatchAny))
2819  COMPLETE_WITH("ON");
2820  else if (Matches("COMMENT", "ON", "POLICY", MatchAny, "ON"))
2821  {
2822  set_completion_reference(prev2_wd);
2823  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_policy);
2824  }
2825  else if (Matches("COMMENT", "ON", "PROCEDURAL", "LANGUAGE"))
2826  COMPLETE_WITH_QUERY(Query_for_list_of_languages);
2827  else if (Matches("COMMENT", "ON", "RULE", MatchAny))
2828  COMPLETE_WITH("ON");
2829  else if (Matches("COMMENT", "ON", "RULE", MatchAny, "ON"))
2830  {
2831  set_completion_reference(prev2_wd);
2832  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_rule);
2833  }
2834  else if (Matches("COMMENT", "ON", "TEXT", "SEARCH"))
2835  COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2836  else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "CONFIGURATION"))
2837  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_configurations);
2838  else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "DICTIONARY"))
2839  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_dictionaries);
2840  else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "PARSER"))
2841  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_parsers);
2842  else if (Matches("COMMENT", "ON", "TEXT", "SEARCH", "TEMPLATE"))
2843  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_templates);
2844  else if (Matches("COMMENT", "ON", "TRANSFORM", "FOR"))
2845  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
2846  else if (Matches("COMMENT", "ON", "TRANSFORM", "FOR", MatchAny))
2847  COMPLETE_WITH("LANGUAGE");
2848  else if (Matches("COMMENT", "ON", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"))
2849  {
2850  set_completion_reference(prev2_wd);
2851  COMPLETE_WITH_QUERY(Query_for_list_of_languages);
2852  }
2853  else if (Matches("COMMENT", "ON", "TRIGGER", MatchAny))
2854  COMPLETE_WITH("ON");
2855  else if (Matches("COMMENT", "ON", "TRIGGER", MatchAny, "ON"))
2856  {
2857  set_completion_reference(prev2_wd);
2858  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_trigger);
2859  }
2860  else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2861  Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2862  Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2863  Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2864  COMPLETE_WITH("IS");
2865 
2866 /* COPY */
2867 
2868  /*
2869  * If we have COPY, offer list of tables or "(" (Also cover the analogous
2870  * backslash command).
2871  */
2872  else if (Matches("COPY|\\copy"))
2873  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables, "(");
2874  /* Complete COPY ( with legal query commands */
2875  else if (Matches("COPY|\\copy", "("))
2876  COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT INTO", "UPDATE", "DELETE FROM", "WITH");
2877  /* Complete COPY <sth> */
2878  else if (Matches("COPY|\\copy", MatchAny))
2879  COMPLETE_WITH("FROM", "TO");
2880  /* Complete COPY <sth> FROM|TO with filename */
2881  else if (Matches("COPY", MatchAny, "FROM|TO"))
2882  {
2883  completion_charp = "";
2884  completion_force_quote = true; /* COPY requires quoted filename */
2885  matches = rl_completion_matches(text, complete_from_files);
2886  }
2887  else if (Matches("\\copy", MatchAny, "FROM|TO"))
2888  {
2889  completion_charp = "";
2890  completion_force_quote = false;
2891  matches = rl_completion_matches(text, complete_from_files);
2892  }
2893 
2894  /* Complete COPY <sth> TO <sth> */
2895  else if (Matches("COPY|\\copy", MatchAny, "TO", MatchAny))
2896  COMPLETE_WITH("WITH (");
2897 
2898  /* Complete COPY <sth> FROM <sth> */
2899  else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAny))
2900  COMPLETE_WITH("WITH (", "WHERE");
2901 
2902  /* Complete COPY <sth> FROM|TO filename WITH ( */
2903  else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
2904  COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
2905  "HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
2906  "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING", "DEFAULT",
2907  "ON_ERROR");
2908 
2909  /* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
2910  else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
2911  COMPLETE_WITH("binary", "csv", "text");
2912 
2913  /* Complete COPY <sth> FROM filename WITH (ON_ERROR */
2914  else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "ON_ERROR"))
2915  COMPLETE_WITH("stop", "ignore");
2916 
2917  /* Complete COPY <sth> FROM <sth> WITH (<options>) */
2918  else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAny, "WITH", MatchAny))
2919  COMPLETE_WITH("WHERE");
2920 
2921  /* CREATE ACCESS METHOD */
2922  /* Complete "CREATE ACCESS METHOD <name>" */
2923  else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny))
2924  COMPLETE_WITH("TYPE");
2925  /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2926  else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2927  COMPLETE_WITH("INDEX", "TABLE");
2928  /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2929  else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2930  COMPLETE_WITH("HANDLER");
2931 
2932  /* CREATE COLLATION */
2933  else if (Matches("CREATE", "COLLATION", MatchAny))
2934  COMPLETE_WITH("(", "FROM");
2935  else if (Matches("CREATE", "COLLATION", MatchAny, "FROM"))
2936  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_collations);
2937  else if (HeadMatches("CREATE", "COLLATION", MatchAny, "(*"))
2938  {
2939  if (TailMatches("(|*,"))
2940  COMPLETE_WITH("LOCALE =", "LC_COLLATE =", "LC_CTYPE =",
2941  "PROVIDER =", "DETERMINISTIC =");
2942  else if (TailMatches("PROVIDER", "="))
2943  COMPLETE_WITH("libc", "icu");
2944  else if (TailMatches("DETERMINISTIC", "="))
2945  COMPLETE_WITH("true", "false");
2946  }
2947 
2948  /* CREATE DATABASE */
2949  else if (Matches("CREATE", "DATABASE", MatchAny))
2950  COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2951  "IS_TEMPLATE", "STRATEGY",
2952  "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2953  "LC_COLLATE", "LC_CTYPE", "LOCALE", "OID",
2954  "LOCALE_PROVIDER", "ICU_LOCALE");
2955 
2956  else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2957  COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2958  else if (Matches("CREATE", "DATABASE", MatchAny, "STRATEGY"))
2959  COMPLETE_WITH("WAL_LOG", "FILE_COPY");
2960 
2961  /* CREATE DOMAIN */
2962  else if (Matches("CREATE", "DOMAIN", MatchAny))
2963  COMPLETE_WITH("AS");
2964  else if (Matches("CREATE", "DOMAIN", MatchAny, "AS"))
2965  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
2966  else if (Matches("CREATE", "DOMAIN", MatchAny, "AS", MatchAny))
2967  COMPLETE_WITH("COLLATE", "DEFAULT", "CONSTRAINT",
2968  "NOT NULL", "NULL", "CHECK (");
2969  else if (Matches("CREATE", "DOMAIN", MatchAny, "COLLATE"))
2970  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_collations);
2971 
2972  /* CREATE EXTENSION */
2973  /* Complete with available extensions rather than installed ones. */
2974  else if (Matches("CREATE", "EXTENSION"))
2975  COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2976  /* CREATE EXTENSION <name> */
2977  else if (Matches("CREATE", "EXTENSION", MatchAny))
2978  COMPLETE_WITH("WITH SCHEMA", "CASCADE", "VERSION");
2979  /* CREATE EXTENSION <name> VERSION */
2980  else if (Matches("CREATE", "EXTENSION", MatchAny, "VERSION"))
2981  {
2982  set_completion_reference(prev2_wd);
2983  COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2984  }
2985 
2986  /* CREATE FOREIGN */
2987  else if (Matches("CREATE", "FOREIGN"))
2988  COMPLETE_WITH("DATA WRAPPER", "TABLE");
2989 
2990  /* CREATE FOREIGN DATA WRAPPER */
2991  else if (Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2992  COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS");
2993 
2994  /* CREATE FOREIGN TABLE */
2995  else if (Matches("CREATE", "FOREIGN", "TABLE", MatchAny))
2996  COMPLETE_WITH("(", "PARTITION OF");
2997 
2998  /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2999  /* First off we complete CREATE UNIQUE with "INDEX" */
3000  else if (TailMatches("CREATE", "UNIQUE"))
3001  COMPLETE_WITH("INDEX");
3002 
3003  /*
3004  * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
3005  * existing indexes
3006  */
3007  else if (TailMatches("CREATE|UNIQUE", "INDEX"))
3008  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
3009  "ON", "CONCURRENTLY");
3010 
3011  /*
3012  * Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of relations
3013  * that indexes can be created on
3014  */
3015  else if (TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON") ||
3016  TailMatches("INDEX|CONCURRENTLY", "ON"))
3017  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables);
3018 
3019  /*
3020  * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
3021  * indexes
3022  */
3023  else if (TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
3024  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
3025  "ON");
3026  /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
3027  else if (TailMatches("CREATE|UNIQUE", "INDEX", MatchAny) ||
3028  TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
3029  COMPLETE_WITH("ON");
3030 
3031  /*
3032  * Complete INDEX <name> ON <table> with a list of table columns (which
3033  * should really be in parens)
3034  */
3035  else if (TailMatches("INDEX", MatchAny, "ON", MatchAny) ||
3036  TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny))
3037  COMPLETE_WITH("(", "USING");
3038  else if (TailMatches("INDEX", MatchAny, "ON", MatchAny, "(") ||
3039  TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
3040  COMPLETE_WITH_ATTR(prev2_wd);
3041  /* same if you put in USING */
3042  else if (TailMatches("ON", MatchAny, "USING", MatchAny, "("))
3043  COMPLETE_WITH_ATTR(prev4_wd);
3044  /* Complete USING with an index method */
3045  else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
3046  TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") ||
3047  TailMatches("INDEX", "ON", MatchAny, "USING"))
3048  COMPLETE_WITH_QUERY(Query_for_list_of_index_access_methods);
3049  else if (TailMatches("ON", MatchAny, "USING", MatchAny) &&
3050  !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
3051  !TailMatches("FOR", MatchAny, MatchAny, MatchAny))
3052  COMPLETE_WITH("(");
3053 
3054  /* CREATE OR REPLACE */
3055  else if (Matches("CREATE", "OR"))
3056  COMPLETE_WITH("REPLACE");
3057 
3058  /* CREATE POLICY */
3059  /* Complete "CREATE POLICY <name> ON" */
3060  else if (Matches("CREATE", "POLICY", MatchAny))
3061  COMPLETE_WITH("ON");
3062  /* Complete "CREATE POLICY <name> ON <table>" */
3063  else if (Matches("CREATE", "POLICY", MatchAny, "ON"))
3064  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
3065  /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
3066  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny))
3067  COMPLETE_WITH("AS", "FOR", "TO", "USING (", "WITH CHECK (");
3068  /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
3069  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
3070  COMPLETE_WITH("PERMISSIVE", "RESTRICTIVE");
3071 
3072  /*
3073  * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
3074  * FOR|TO|USING|WITH CHECK
3075  */
3076  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
3077  COMPLETE_WITH("FOR", "TO", "USING", "WITH CHECK");
3078  /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
3079  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
3080  COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
3081  /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
3082  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
3083  COMPLETE_WITH("TO", "WITH CHECK (");
3084  /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
3085  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
3086  COMPLETE_WITH("TO", "USING (");
3087  /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
3088  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
3089  COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
3090  /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
3091  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
3092  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
3093  Keywords_for_list_of_grant_roles);
3094  /* Complete "CREATE POLICY <name> ON <table> USING (" */
3095  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
3096  COMPLETE_WITH("(");
3097 
3098  /*
3099  * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
3100  * ALL|SELECT|INSERT|UPDATE|DELETE
3101  */
3102  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
3103  COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
3104 
3105  /*
3106  * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
3107  * INSERT TO|WITH CHECK"
3108  */
3109  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
3110  COMPLETE_WITH("TO", "WITH CHECK (");
3111 
3112  /*
3113  * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
3114  * SELECT|DELETE TO|USING"
3115  */
3116  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
3117  COMPLETE_WITH("TO", "USING (");
3118 
3119  /*
3120  * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
3121  * ALL|UPDATE TO|USING|WITH CHECK
3122  */
3123  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
3124  COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
3125 
3126  /*
3127  * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO
3128  * <role>"
3129  */
3130  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
3131  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
3132  Keywords_for_list_of_grant_roles);
3133 
3134  /*
3135  * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
3136  * USING ("
3137  */
3138  else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
3139  COMPLETE_WITH("(");
3140 
3141 
3142 /* CREATE PUBLICATION */
3143  else if (Matches("CREATE", "PUBLICATION", MatchAny))
3144  COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "FOR TABLES IN SCHEMA", "WITH (");
3145  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR"))
3146  COMPLETE_WITH("TABLE", "ALL TABLES", "TABLES IN SCHEMA");
3147  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL"))
3148  COMPLETE_WITH("TABLES");
3149  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "ALL", "TABLES"))
3150  COMPLETE_WITH("WITH (");
3151  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES"))
3152  COMPLETE_WITH("IN SCHEMA");
3153  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE", MatchAny) && !ends_with(prev_wd, ','))
3154  COMPLETE_WITH("WHERE (", "WITH (");
3155  /* Complete "CREATE PUBLICATION <name> FOR TABLE" with "<table>, ..." */
3156  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"))
3157  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
3158 
3159  /*
3160  * "CREATE PUBLICATION <name> FOR TABLE <name> WHERE (" - complete with
3161  * table attributes
3162  */
3163  else if (HeadMatches("CREATE", "PUBLICATION", MatchAny) && TailMatches("WHERE"))
3164  COMPLETE_WITH("(");
3165  else if (HeadMatches("CREATE", "PUBLICATION", MatchAny) && TailMatches("WHERE", "("))
3166  COMPLETE_WITH_ATTR(prev3_wd);
3167  else if (HeadMatches("CREATE", "PUBLICATION", MatchAny) && TailMatches("WHERE", "(*)"))
3168  COMPLETE_WITH(" WITH (");
3169 
3170  /*
3171  * Complete "CREATE PUBLICATION <name> FOR TABLES IN SCHEMA <schema>, ..."
3172  */
3173  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA"))
3174  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas
3175  " AND nspname NOT LIKE E'pg\\\\_%%'",
3176  "CURRENT_SCHEMA");
3177  else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLES", "IN", "SCHEMA", MatchAny) && (!ends_with(prev_wd, ',')))
3178  COMPLETE_WITH("WITH (");
3179  /* Complete "CREATE PUBLICATION <name> [...] WITH" */
3180  else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "("))
3181  COMPLETE_WITH("publish", "publish_via_partition_root");
3182 
3183 /* CREATE RULE */
3184  /* Complete "CREATE [ OR REPLACE ] RULE <sth>" with "AS ON" */
3185  else if (Matches("CREATE", "RULE", MatchAny) ||
3186  Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny))
3187  COMPLETE_WITH("AS ON");
3188  /* Complete "CREATE [ OR REPLACE ] RULE <sth> AS" with "ON" */
3189  else if (Matches("CREATE", "RULE", MatchAny, "AS") ||
3190  Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS"))
3191  COMPLETE_WITH("ON");
3192 
3193  /*
3194  * Complete "CREATE [ OR REPLACE ] RULE <sth> AS ON" with
3195  * SELECT|UPDATE|INSERT|DELETE
3196  */
3197  else if (Matches("CREATE", "RULE", MatchAny, "AS", "ON") ||
3198  Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS", "ON"))
3199  COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE");
3200  /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
3201  else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
3202  COMPLETE_WITH("TO");
3203  /* Complete "AS ON <sth> TO" with a table name */
3204  else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
3205  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
3206 
3207 /* CREATE SCHEMA [ <name> ] [ AUTHORIZATION ] */
3208  else if (Matches("CREATE", "SCHEMA"))
3209  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas,
3210  "AUTHORIZATION");
3211  else if (Matches("CREATE", "SCHEMA", "AUTHORIZATION") ||
3212  Matches("CREATE", "SCHEMA", MatchAny, "AUTHORIZATION"))
3213  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
3214  Keywords_for_list_of_owner_roles);
3215  else if (Matches("CREATE", "SCHEMA", "AUTHORIZATION", MatchAny) ||
3216  Matches("CREATE", "SCHEMA", MatchAny, "AUTHORIZATION", MatchAny))
3217  COMPLETE_WITH("CREATE", "GRANT");
3218  else if (Matches("CREATE", "SCHEMA", MatchAny))
3219  COMPLETE_WITH("AUTHORIZATION", "CREATE", "GRANT");
3220 
3221 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
3222  else if (TailMatches("CREATE", "SEQUENCE", MatchAny) ||
3223  TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
3224  COMPLETE_WITH("AS", "INCREMENT BY", "MINVALUE", "MAXVALUE", "NO",
3225  "CACHE", "CYCLE", "OWNED BY", "START WITH");
3226  else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "AS") ||
3227  TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "AS"))
3228  COMPLETE_WITH_CS("smallint", "integer", "bigint");
3229  else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "NO") ||
3230  TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
3231  COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
3232 
3233 /* CREATE SERVER <name> */
3234  else if (Matches("CREATE", "SERVER", MatchAny))
3235  COMPLETE_WITH("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
3236 
3237 /* CREATE STATISTICS <name> */
3238  else if (Matches("CREATE", "STATISTICS", MatchAny))
3239  COMPLETE_WITH("(", "ON");
3240  else if (Matches("CREATE", "STATISTICS", MatchAny, "("))
3241  COMPLETE_WITH("ndistinct", "dependencies", "mcv");
3242  else if (Matches("CREATE", "STATISTICS", MatchAny, "(*)"))
3243  COMPLETE_WITH("ON");
3244  else if (HeadMatches("CREATE", "STATISTICS", MatchAny) &&
3245  TailMatches("FROM"))
3246  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
3247 
3248 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
3249  /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
3250  else if (TailMatches("CREATE", "TEMP|TEMPORARY"))
3251  COMPLETE_WITH("SEQUENCE", "TABLE", "VIEW");
3252  /* Complete "CREATE UNLOGGED" with TABLE, SEQUENCE or MATVIEW */
3253  else if (TailMatches("CREATE", "UNLOGGED"))
3254  {
3255  /* but not MATVIEW in CREATE SCHEMA */
3256  if (HeadMatches("CREATE", "SCHEMA"))
3257  COMPLETE_WITH("TABLE", "SEQUENCE");
3258  else
3259  COMPLETE_WITH("TABLE", "SEQUENCE", "MATERIALIZED VIEW");
3260  }
3261  /* Complete PARTITION BY with RANGE ( or LIST ( or ... */
3262  else if (TailMatches("PARTITION", "BY"))
3263  COMPLETE_WITH("RANGE (", "LIST (", "HASH (");
3264  /* If we have xxx PARTITION OF, provide a list of partitioned tables */
3265  else if (TailMatches("PARTITION", "OF"))
3266  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables);
3267  /* Limited completion support for partition bound specification */
3268  else if (TailMatches("PARTITION", "OF", MatchAny))
3269  COMPLETE_WITH("FOR VALUES", "DEFAULT");
3270  /* Complete CREATE TABLE <name> with '(', AS, OF or PARTITION OF */
3271  else if (TailMatches("CREATE", "TABLE", MatchAny) ||
3272  TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny))
3273  COMPLETE_WITH("(", "AS", "OF", "PARTITION OF");
3274  /* Complete CREATE TABLE <name> OF with list of composite types */
3275  else if (TailMatches("CREATE", "TABLE", MatchAny, "OF") ||
3276  TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "OF"))
3277  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes);
3278  /* Complete CREATE TABLE <name> [ (...) ] AS with list of keywords */
3279  else if (TailMatches("CREATE", "TABLE", MatchAny, "AS") ||
3280  TailMatches("CREATE", "TABLE", MatchAny, "(*)", "AS") ||
3281  TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "AS") ||
3282  TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "AS"))
3283  COMPLETE_WITH("EXECUTE", "SELECT", "TABLE", "VALUES", "WITH");
3284  /* Complete CREATE TABLE name (...) with supported options */
3285  else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)") ||
3286  TailMatches("CREATE", "UNLOGGED", "TABLE", MatchAny, "(*)"))
3287  COMPLETE_WITH("AS", "INHERITS (", "PARTITION BY", "USING", "TABLESPACE", "WITH (");
3288  else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)"))
3289  COMPLETE_WITH("AS", "INHERITS (", "ON COMMIT", "PARTITION BY",
3290  "TABLESPACE", "WITH (");
3291  /* Complete CREATE TABLE (...) USING with table access methods */
3292  else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "USING") ||
3293  TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "USING"))
3294  COMPLETE_WITH_QUERY(Query_for_list_of_table_access_methods);
3295  /* Complete CREATE TABLE (...) WITH with storage parameters */
3296  else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "WITH", "(") ||
3297  TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "WITH", "("))
3298  COMPLETE_WITH_LIST(table_storage_parameters);
3299  /* Complete CREATE TABLE ON COMMIT with actions */
3300  else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)", "ON", "COMMIT"))
3301  COMPLETE_WITH("DELETE ROWS", "DROP", "PRESERVE ROWS");
3302 
3303 /* CREATE TABLESPACE */
3304  else if (Matches("CREATE", "TABLESPACE", MatchAny))
3305  COMPLETE_WITH("OWNER", "LOCATION");
3306  /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
3307  else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
3308  COMPLETE_WITH("LOCATION");
3309 
3310 /* CREATE TEXT SEARCH */
3311  else if (Matches("CREATE", "TEXT", "SEARCH"))
3312  COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
3313  else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
3314  COMPLETE_WITH("(");
3315 
3316 /* CREATE TRANSFORM */
3317  else if (Matches("CREATE", "TRANSFORM") ||
3318  Matches("CREATE", "OR", "REPLACE", "TRANSFORM"))
3319  COMPLETE_WITH("FOR");
3320  else if (Matches("CREATE", "TRANSFORM", "FOR") ||
3321  Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR"))
3322  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
3323  else if (Matches("CREATE", "TRANSFORM", "FOR", MatchAny) ||
3324  Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR", MatchAny))
3325  COMPLETE_WITH("LANGUAGE");
3326  else if (Matches("CREATE", "TRANSFORM", "FOR", MatchAny, "LANGUAGE") ||
3327  Matches("CREATE", "OR", "REPLACE", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"))
3328  {
3329  set_completion_reference(prev2_wd);
3330  COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3331  }
3332 
3333 /* CREATE SUBSCRIPTION */
3334  else if (Matches("CREATE", "SUBSCRIPTION", MatchAny))
3335  COMPLETE_WITH("CONNECTION");
3336  else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny))
3337  COMPLETE_WITH("PUBLICATION");
3338  else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",
3339  MatchAny, "PUBLICATION"))
3340  {
3341  /* complete with nothing here as this refers to remote publications */
3342  }
3343  else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("PUBLICATION", MatchAny))
3344  COMPLETE_WITH("WITH (");
3345  /* Complete "CREATE SUBSCRIPTION <name> ... WITH ( <opt>" */
3346  else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("WITH", "("))
3347  COMPLETE_WITH("binary", "connect", "copy_data", "create_slot",
3348  "disable_on_error", "enabled", "failover", "origin",
3349  "password_required", "run_as_owner", "slot_name",
3350  "streaming", "synchronous_commit", "two_phase");
3351 
3352 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
3353 
3354  /*
3355  * Complete CREATE [ OR REPLACE ] TRIGGER <name> with BEFORE|AFTER|INSTEAD
3356  * OF.
3357  */
3358  else if (TailMatches("CREATE", "TRIGGER", MatchAny) ||
3359  TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny))
3360  COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF");
3361 
3362  /*
3363  * Complete CREATE [ OR REPLACE ] TRIGGER <name> BEFORE,AFTER with an
3364  * event.
3365  */
3366  else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER") ||
3367  TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
3368  COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE");
3369  /* Complete CREATE [ OR REPLACE ] TRIGGER <name> INSTEAD OF with an event */
3370  else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF") ||
3371  TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
3372  COMPLETE_WITH("INSERT", "DELETE", "UPDATE");
3373 
3374  /*
3375  * Complete CREATE [ OR REPLACE ] TRIGGER <name> BEFORE,AFTER sth with
3376  * OR|ON.
3377  */
3378  else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
3379  TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
3380  TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny) ||
3381  TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
3382  COMPLETE_WITH("ON", "OR");
3383 
3384  /*
3385  * Complete CREATE [ OR REPLACE ] TRIGGER <name> BEFORE,AFTER event ON
3386  * with a list of tables. EXECUTE FUNCTION is the recommended grammar
3387  * instead of EXECUTE PROCEDURE in version 11 and upwards.
3388  */
3389  else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON") ||
3390  TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
3391  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
3392 
3393  /*
3394  * Complete CREATE [ OR REPLACE ] TRIGGER ... INSTEAD OF event ON with a
3395  * list of views.
3396  */
3397  else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON") ||
3398  TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
3399  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
3400  else if ((HeadMatches("CREATE", "TRIGGER") ||
3401  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3402  TailMatches("ON", MatchAny))
3403  {
3404  if (pset.sversion >= 110000)
3405  COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
3406  "REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
3407  else
3408  COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
3409  "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
3410  }
3411  else if ((HeadMatches("CREATE", "TRIGGER") ||
3412  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3413  (TailMatches("DEFERRABLE") || TailMatches("INITIALLY", "IMMEDIATE|DEFERRED")))
3414  {
3415  if (pset.sversion >= 110000)
3416  COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
3417  else
3418  COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
3419  }
3420  else if ((HeadMatches("CREATE", "TRIGGER") ||
3421  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3422  TailMatches("REFERENCING"))
3423  COMPLETE_WITH("OLD TABLE", "NEW TABLE");
3424  else if ((HeadMatches("CREATE", "TRIGGER") ||
3425  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3426  TailMatches("OLD|NEW", "TABLE"))
3427  COMPLETE_WITH("AS");
3428  else if ((HeadMatches("CREATE", "TRIGGER") ||
3429  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3430  (TailMatches("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
3431  TailMatches("REFERENCING", "OLD", "TABLE", MatchAny)))
3432  {
3433  if (pset.sversion >= 110000)
3434  COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
3435  else
3436  COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
3437  }
3438  else if ((HeadMatches("CREATE", "TRIGGER") ||
3439  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3440  (TailMatches("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
3441  TailMatches("REFERENCING", "NEW", "TABLE", MatchAny)))
3442  {
3443  if (pset.sversion >= 110000)
3444  COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
3445  else
3446  COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
3447  }
3448  else if ((HeadMatches("CREATE", "TRIGGER") ||
3449  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3450  (TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
3451  TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
3452  TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
3453  TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
3454  {
3455  if (pset.sversion >= 110000)
3456  COMPLETE_WITH("FOR", "WHEN (", "EXECUTE FUNCTION");
3457  else
3458  COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE");
3459  }
3460  else if ((HeadMatches("CREATE", "TRIGGER") ||
3461  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3462  TailMatches("FOR"))
3463  COMPLETE_WITH("EACH", "ROW", "STATEMENT");
3464  else if ((HeadMatches("CREATE", "TRIGGER") ||
3465  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3466  TailMatches("FOR", "EACH"))
3467  COMPLETE_WITH("ROW", "STATEMENT");
3468  else if ((HeadMatches("CREATE", "TRIGGER") ||
3469  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3470  (TailMatches("FOR", "EACH", "ROW|STATEMENT") ||
3471  TailMatches("FOR", "ROW|STATEMENT")))
3472  {
3473  if (pset.sversion >= 110000)
3474  COMPLETE_WITH("WHEN (", "EXECUTE FUNCTION");
3475  else
3476  COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE");
3477  }
3478  else if ((HeadMatches("CREATE", "TRIGGER") ||
3479  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3480  TailMatches("WHEN", "(*)"))
3481  {
3482  if (pset.sversion >= 110000)
3483  COMPLETE_WITH("EXECUTE FUNCTION");
3484  else
3485  COMPLETE_WITH("EXECUTE PROCEDURE");
3486  }
3487 
3488  /*
3489  * Complete CREATE [ OR REPLACE ] TRIGGER ... EXECUTE with
3490  * PROCEDURE|FUNCTION.
3491  */
3492  else if ((HeadMatches("CREATE", "TRIGGER") ||
3493  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3494  TailMatches("EXECUTE"))
3495  {
3496  if (pset.sversion >= 110000)
3497  COMPLETE_WITH("FUNCTION");
3498  else
3499  COMPLETE_WITH("PROCEDURE");
3500  }
3501  else if ((HeadMatches("CREATE", "TRIGGER") ||
3502  HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) &&
3503  TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
3504  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
3505 
3506 /* CREATE ROLE,USER,GROUP <name> */
3507  else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny) &&
3508  !TailMatches("USER", "MAPPING"))
3509  COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
3510  "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
3511  "LOGIN", "NOBYPASSRLS",
3512  "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
3513  "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
3514  "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
3515  "VALID UNTIL", "WITH");
3516 
3517 /* CREATE ROLE,USER,GROUP <name> WITH */
3518  else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
3519  /* Similar to the above, but don't complete "WITH" again. */
3520  COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
3521  "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
3522  "LOGIN", "NOBYPASSRLS",
3523  "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
3524  "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
3525  "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
3526  "VALID UNTIL");
3527 
3528  /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
3529  else if (Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
3530  COMPLETE_WITH("GROUP", "ROLE");
3531 
3532 /* CREATE TYPE */
3533  else if (Matches("CREATE", "TYPE", MatchAny))
3534  COMPLETE_WITH("(", "AS");
3535  else if (Matches("CREATE", "TYPE", MatchAny, "AS"))
3536  COMPLETE_WITH("ENUM", "RANGE", "(");
3537  else if (HeadMatches("CREATE", "TYPE", MatchAny, "AS", "("))
3538  {
3539  if (TailMatches("(|*,", MatchAny))
3540  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
3541  else if (TailMatches("(|*,", MatchAny, MatchAnyExcept("*)")))
3542  COMPLETE_WITH("COLLATE", ",", ")");
3543  }
3544  else if (Matches("CREATE", "TYPE", MatchAny, "AS", "ENUM|RANGE"))
3545  COMPLETE_WITH("(");
3546  else if (HeadMatches("CREATE", "TYPE", MatchAny, "("))
3547  {
3548  if (TailMatches("(|*,"))
3549  COMPLETE_WITH("INPUT", "OUTPUT", "RECEIVE", "SEND",
3550  "TYPMOD_IN", "TYPMOD_OUT", "ANALYZE", "SUBSCRIPT",
3551  "INTERNALLENGTH", "PASSEDBYVALUE", "ALIGNMENT",
3552  "STORAGE", "LIKE", "CATEGORY", "PREFERRED",
3553  "DEFAULT", "ELEMENT", "DELIMITER",
3554  "COLLATABLE");
3555  else if (TailMatches("(*|*,", MatchAnyExcept("*=")))
3556  COMPLETE_WITH("=");
3557  else if (TailMatches("=", MatchAnyExcept("*)")))
3558  COMPLETE_WITH(",", ")");
3559  }
3560  else if (HeadMatches("CREATE", "TYPE", MatchAny, "AS", "RANGE", "("))
3561  {
3562  if (TailMatches("(|*,"))
3563  COMPLETE_WITH("SUBTYPE", "SUBTYPE_OPCLASS", "COLLATION",
3564  "CANONICAL", "SUBTYPE_DIFF",
3565  "MULTIRANGE_TYPE_NAME");
3566  else if (TailMatches("(*|*,", MatchAnyExcept("*=")))
3567  COMPLETE_WITH("=");
3568  else if (TailMatches("=", MatchAnyExcept("*)")))
3569  COMPLETE_WITH(",", ")");
3570  }
3571 
3572 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
3573  /* Complete CREATE [ OR REPLACE ] VIEW <name> with AS or WITH */
3574  else if (TailMatches("CREATE", "VIEW", MatchAny) ||
3575  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny))
3576  COMPLETE_WITH("AS", "WITH");
3577  /* Complete "CREATE [ OR REPLACE ] VIEW <sth> AS with "SELECT" */
3578  else if (TailMatches("CREATE", "VIEW", MatchAny, "AS") ||
3579  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "AS"))
3580  COMPLETE_WITH("SELECT");
3581  /* CREATE [ OR REPLACE ] VIEW <name> WITH ( yyy [= zzz] ) */
3582  else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH") ||
3583  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH"))
3584  COMPLETE_WITH("(");
3585  else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(") ||
3586  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "("))
3587  COMPLETE_WITH_LIST(view_optional_parameters);
3588  else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option") ||
3589  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option"))
3590  COMPLETE_WITH("=");
3591  else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(", "check_option", "=") ||
3592  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(", "check_option", "="))
3593  COMPLETE_WITH("local", "cascaded");
3594  /* CREATE [ OR REPLACE ] VIEW <name> WITH ( ... ) AS */
3595  else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)") ||
3596  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)"))
3597  COMPLETE_WITH("AS");
3598  /* CREATE [ OR REPLACE ] VIEW <name> WITH ( ... ) AS SELECT */
3599  else if (TailMatches("CREATE", "VIEW", MatchAny, "WITH", "(*)", "AS") ||
3600  TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "WITH", "(*)", "AS"))
3601  COMPLETE_WITH("SELECT");
3602 
3603 /* CREATE MATERIALIZED VIEW */
3604  else if (Matches("CREATE", "MATERIALIZED"))
3605  COMPLETE_WITH("VIEW");
3606  /* Complete CREATE MATERIALIZED VIEW <name> with AS */
3607  else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny))
3608  COMPLETE_WITH("AS");
3609  /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
3610  else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
3611  COMPLETE_WITH("SELECT");
3612 
3613 /* CREATE EVENT TRIGGER */
3614  else if (Matches("CREATE", "EVENT"))
3615  COMPLETE_WITH("TRIGGER");
3616  /* Complete CREATE EVENT TRIGGER <name> with ON */
3617  else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny))
3618  COMPLETE_WITH("ON");
3619  /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
3620  else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
3621  COMPLETE_WITH("ddl_command_start", "ddl_command_end", "login",
3622  "sql_drop", "table_rewrite");
3623 
3624  /*
3625  * Complete CREATE EVENT TRIGGER <name> ON <event_type>. EXECUTE FUNCTION
3626  * is the recommended grammar instead of EXECUTE PROCEDURE in version 11
3627  * and upwards.
3628  */
3629  else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON", MatchAny))
3630  {
3631  if (pset.sversion >= 110000)
3632  COMPLETE_WITH("WHEN TAG IN (", "EXECUTE FUNCTION");
3633  else
3634  COMPLETE_WITH("WHEN TAG IN (", "EXECUTE PROCEDURE");
3635  }
3636  else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
3637  TailMatches("WHEN|AND", MatchAny, "IN", "(*)"))
3638  {
3639  if (pset.sversion >= 110000)
3640  COMPLETE_WITH("EXECUTE FUNCTION");
3641  else
3642  COMPLETE_WITH("EXECUTE PROCEDURE");
3643  }
3644  else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
3645  TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
3646  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
3647 
3648 /* DEALLOCATE */
3649  else if (Matches("DEALLOCATE"))
3650  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_prepared_statements,
3651  "ALL");
3652 
3653 /* DECLARE */
3654 
3655  /*
3656  * Complete DECLARE <name> with one of BINARY, ASENSITIVE, INSENSITIVE,
3657  * SCROLL, NO SCROLL, and CURSOR.
3658  */
3659  else if (Matches("DECLARE", MatchAny))
3660  COMPLETE_WITH("BINARY", "ASENSITIVE", "INSENSITIVE", "SCROLL", "NO SCROLL",
3661  "CURSOR");
3662 
3663  /*
3664  * Complete DECLARE ... <option> with other options. The PostgreSQL parser
3665  * allows DECLARE options to be specified in any order. But the
3666  * tab-completion follows the ordering of them that the SQL standard
3667  * provides, like the syntax of DECLARE command in the documentation
3668  * indicates.
3669  */
3670  else if (HeadMatches("DECLARE") && TailMatches("BINARY"))
3671  COMPLETE_WITH("ASENSITIVE", "INSENSITIVE", "SCROLL", "NO SCROLL", "CURSOR");
3672  else if (HeadMatches("DECLARE") && TailMatches("ASENSITIVE|INSENSITIVE"))
3673  COMPLETE_WITH("SCROLL", "NO SCROLL", "CURSOR");
3674  else if (HeadMatches("DECLARE") && TailMatches("SCROLL"))
3675  COMPLETE_WITH("CURSOR");
3676  /* Complete DECLARE ... [options] NO with SCROLL */
3677  else if (HeadMatches("DECLARE") && TailMatches("NO"))
3678  COMPLETE_WITH("SCROLL");
3679 
3680  /*
3681  * Complete DECLARE ... CURSOR with one of WITH HOLD, WITHOUT HOLD, and
3682  * FOR
3683  */
3684  else if (HeadMatches("DECLARE") && TailMatches("CURSOR"))
3685  COMPLETE_WITH("WITH HOLD", "WITHOUT HOLD", "FOR");
3686  /* Complete DECLARE ... CURSOR WITH|WITHOUT with HOLD */
3687  else if (HeadMatches("DECLARE") && TailMatches("CURSOR", "WITH|WITHOUT"))
3688  COMPLETE_WITH("HOLD");
3689  /* Complete DECLARE ... CURSOR WITH|WITHOUT HOLD with FOR */
3690  else if (HeadMatches("DECLARE") && TailMatches("CURSOR", "WITH|WITHOUT", "HOLD"))
3691  COMPLETE_WITH("FOR");
3692 
3693 /* DELETE --- can be inside EXPLAIN, RULE, etc */
3694  /* Complete DELETE with "FROM" */
3695  else if (Matches("DELETE"))
3696  COMPLETE_WITH("FROM");
3697  /* Complete DELETE FROM with a list of tables */
3698  else if (TailMatches("DELETE", "FROM"))
3699  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables);
3700  /* Complete DELETE FROM <table> */
3701  else if (TailMatches("DELETE", "FROM", MatchAny))
3702  COMPLETE_WITH("USING", "WHERE");
3703  /* XXX: implement tab completion for DELETE ... USING */
3704 
3705 /* DISCARD */
3706  else if (Matches("DISCARD"))
3707  COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP");
3708 
3709 /* DO */
3710  else if (Matches("DO"))
3711  COMPLETE_WITH("LANGUAGE");
3712 
3713 /* DROP */
3714  /* Complete DROP object with CASCADE / RESTRICT */
3715  else if (Matches("DROP",
3716  "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW",
3717  MatchAny) ||
3718  Matches("DROP", "ACCESS", "METHOD", MatchAny) ||
3719  (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) &&
3720  ends_with(prev_wd, ')')) ||
3721  Matches("DROP", "EVENT", "TRIGGER", MatchAny) ||
3722  Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
3723  Matches("DROP", "FOREIGN", "TABLE", MatchAny) ||
3724  Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
3725  COMPLETE_WITH("CASCADE", "RESTRICT");
3726 
3727  /* help completing some of the variants */
3728  else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
3729  COMPLETE_WITH("(");
3730  else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "("))
3731  COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
3732  else if (Matches("DROP", "FOREIGN"))
3733  COMPLETE_WITH("DATA WRAPPER", "TABLE");
3734  else if (Matches("DROP", "DATABASE", MatchAny))
3735  COMPLETE_WITH("WITH (");
3736  else if (HeadMatches("DROP", "DATABASE") && (ends_with(prev_wd, '(')))
3737  COMPLETE_WITH("FORCE");
3738 
3739  /* DROP INDEX */
3740  else if (Matches("DROP", "INDEX"))
3741  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
3742  "CONCURRENTLY");
3743  else if (Matches("DROP", "INDEX", "CONCURRENTLY"))
3744  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
3745  else if (Matches("DROP", "INDEX", MatchAny))
3746  COMPLETE_WITH("CASCADE", "RESTRICT");
3747  else if (Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny))
3748  COMPLETE_WITH("CASCADE", "RESTRICT");
3749 
3750  /* DROP MATERIALIZED VIEW */
3751  else if (Matches("DROP", "MATERIALIZED"))
3752  COMPLETE_WITH("VIEW");
3753  else if (Matches("DROP", "MATERIALIZED", "VIEW"))
3754  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
3755  else if (Matches("DROP", "MATERIALIZED", "VIEW", MatchAny))
3756  COMPLETE_WITH("CASCADE", "RESTRICT");
3757 
3758  /* DROP OWNED BY */
3759  else if (Matches("DROP", "OWNED"))
3760  COMPLETE_WITH("BY");
3761  else if (Matches("DROP", "OWNED", "BY"))
3762  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3763  else if (Matches("DROP", "OWNED", "BY", MatchAny))
3764  COMPLETE_WITH("CASCADE", "RESTRICT");
3765 
3766  /* DROP TEXT SEARCH */
3767  else if (Matches("DROP", "TEXT", "SEARCH"))
3768  COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
3769 
3770  /* DROP TRIGGER */
3771  else if (Matches("DROP", "TRIGGER", MatchAny))
3772  COMPLETE_WITH("ON");
3773  else if (Matches("DROP", "TRIGGER", MatchAny, "ON"))
3774  {
3775  set_completion_reference(prev2_wd);
3776  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_trigger);
3777  }
3778  else if (Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
3779  COMPLETE_WITH("CASCADE", "RESTRICT");
3780 
3781  /* DROP ACCESS METHOD */
3782  else if (Matches("DROP", "ACCESS"))
3783  COMPLETE_WITH("METHOD");
3784  else if (Matches("DROP", "ACCESS", "METHOD"))
3785  COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3786 
3787  /* DROP EVENT TRIGGER */
3788  else if (Matches("DROP", "EVENT"))
3789  COMPLETE_WITH("TRIGGER");
3790  else if (Matches("DROP", "EVENT", "TRIGGER"))
3791  COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3792 
3793  /* DROP POLICY <name> */
3794  else if (Matches("DROP", "POLICY"))
3795  COMPLETE_WITH_QUERY(Query_for_list_of_policies);
3796  /* DROP POLICY <name> ON */
3797  else if (Matches("DROP", "POLICY", MatchAny))
3798  COMPLETE_WITH("ON");
3799  /* DROP POLICY <name> ON <table> */
3800  else if (Matches("DROP", "POLICY", MatchAny, "ON"))
3801  {
3802  set_completion_reference(prev2_wd);
3803  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_policy);
3804  }
3805  else if (Matches("DROP", "POLICY", MatchAny, "ON", MatchAny))
3806  COMPLETE_WITH("CASCADE", "RESTRICT");
3807 
3808  /* DROP RULE */
3809  else if (Matches("DROP", "RULE", MatchAny))
3810  COMPLETE_WITH("ON");
3811  else if (Matches("DROP", "RULE", MatchAny, "ON"))
3812  {
3813  set_completion_reference(prev2_wd);
3814  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables_for_rule);
3815  }
3816  else if (Matches("DROP", "RULE", MatchAny, "ON", MatchAny))
3817  COMPLETE_WITH("CASCADE", "RESTRICT");
3818 
3819  /* DROP TRANSFORM */
3820  else if (Matches("DROP", "TRANSFORM"))
3821  COMPLETE_WITH("FOR");
3822  else if (Matches("DROP", "TRANSFORM", "FOR"))
3823  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
3824  else if (Matches("DROP", "TRANSFORM", "FOR", MatchAny))
3825  COMPLETE_WITH("LANGUAGE");
3826  else if (Matches("DROP", "TRANSFORM", "FOR", MatchAny, "LANGUAGE"))
3827  {
3828  set_completion_reference(prev2_wd);
3829  COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3830  }
3831  else if (Matches("DROP", "TRANSFORM", "FOR", MatchAny, "LANGUAGE", MatchAny))
3832  COMPLETE_WITH("CASCADE", "RESTRICT");
3833 
3834 /* EXECUTE */
3835  else if (Matches("EXECUTE"))
3836  COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
3837 
3838 /*
3839  * EXPLAIN [ ( option [, ...] ) ] statement
3840  * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
3841  */
3842  else if (Matches("EXPLAIN"))
3843  COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
3844  "MERGE INTO", "EXECUTE", "ANALYZE", "VERBOSE");
3845  else if (HeadMatches("EXPLAIN", "(*") &&
3846  !HeadMatches("EXPLAIN", "(*)"))
3847  {
3848  /*
3849  * This fires if we're in an unfinished parenthesized option list.
3850  * get_previous_words treats a completed parenthesized option list as
3851  * one word, so the above test is correct.
3852  */
3853  if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
3854  COMPLETE_WITH("ANALYZE", "VERBOSE", "COSTS", "SETTINGS", "GENERIC_PLAN",
3855  "BUFFERS", "WAL", "TIMING", "SUMMARY", "FORMAT");
3856  else if (TailMatches("ANALYZE|VERBOSE|COSTS|SETTINGS|GENERIC_PLAN|BUFFERS|WAL|TIMING|SUMMARY"))
3857  COMPLETE_WITH("ON", "OFF");
3858  else if (TailMatches("FORMAT"))
3859  COMPLETE_WITH("TEXT", "XML", "JSON", "YAML");
3860  }
3861  else if (Matches("EXPLAIN", "ANALYZE"))
3862  COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
3863  "MERGE INTO", "EXECUTE", "VERBOSE");
3864  else if (Matches("EXPLAIN", "(*)") ||
3865  Matches("EXPLAIN", "VERBOSE") ||
3866  Matches("EXPLAIN", "ANALYZE", "VERBOSE"))
3867  COMPLETE_WITH("SELECT", "INSERT INTO", "DELETE FROM", "UPDATE", "DECLARE",
3868  "MERGE INTO", "EXECUTE");
3869 
3870 /* FETCH && MOVE */
3871 
3872  /*
3873  * Complete FETCH with one of ABSOLUTE, BACKWARD, FORWARD, RELATIVE, ALL,
3874  * NEXT, PRIOR, FIRST, LAST, FROM, IN, and a list of cursors
3875  */
3876  else if (Matches("FETCH|MOVE"))
3877  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
3878  "ABSOLUTE",
3879  "BACKWARD",
3880  "FORWARD",
3881  "RELATIVE",
3882  "ALL",
3883  "NEXT",
3884  "PRIOR",
3885  "FIRST",
3886  "LAST",
3887  "FROM",
3888  "IN");
3889 
3890  /*
3891  * Complete FETCH BACKWARD or FORWARD with one of ALL, FROM, IN, and a
3892  * list of cursors
3893  */
3894  else if (Matches("FETCH|MOVE", "BACKWARD|FORWARD"))
3895  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
3896  "ALL",
3897  "FROM",
3898  "IN");
3899 
3900  /*
3901  * Complete FETCH <direction> with "FROM" or "IN". These are equivalent,
3902  * but we may as well tab-complete both: perhaps some users prefer one
3903  * variant or the other.
3904  */
3905  else if (Matches("FETCH|MOVE", "ABSOLUTE|BACKWARD|FORWARD|RELATIVE",
3906  MatchAnyExcept("FROM|IN")) ||
3907  Matches("FETCH|MOVE", "ALL|NEXT|PRIOR|FIRST|LAST"))
3908  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,
3909  "FROM",
3910  "IN");
3911  /* Complete FETCH <direction> "FROM" or "IN" with a list of cursors */
3912  else if (HeadMatches("FETCH|MOVE") &&
3913  TailMatches("FROM|IN"))
3914  COMPLETE_WITH_QUERY(Query_for_list_of_cursors);
3915 
3916 /* FOREIGN DATA WRAPPER */
3917  /* applies in ALTER/DROP FDW and in CREATE SERVER */
3918  else if (TailMatches("FOREIGN", "DATA", "WRAPPER") &&
3919  !TailMatches("CREATE", MatchAny, MatchAny, MatchAny))
3920  COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3921  /* applies in CREATE SERVER */
3922  else if (TailMatches("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
3923  HeadMatches("CREATE", "SERVER"))
3924  COMPLETE_WITH("OPTIONS");
3925 
3926 /* FOREIGN TABLE */
3927  else if (TailMatches("FOREIGN", "TABLE") &&
3928  !TailMatches("CREATE", MatchAny, MatchAny))
3929  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables);
3930 
3931 /* FOREIGN SERVER */
3932  else if (TailMatches("FOREIGN", "SERVER"))
3933  COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3934 
3935 /*
3936  * GRANT and REVOKE are allowed inside CREATE SCHEMA and
3937  * ALTER DEFAULT PRIVILEGES, so use TailMatches
3938  */
3939  /* Complete GRANT/REVOKE with a list of roles and privileges */
3940  else if (TailMatches("GRANT|REVOKE") ||
3941  TailMatches("REVOKE", "ADMIN|GRANT|INHERIT|SET", "OPTION", "FOR"))
3942  {
3943  /*
3944  * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable
3945  * privileges (can't grant roles)
3946  */
3947  if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
3948  COMPLETE_WITH("SELECT", "INSERT", "UPDATE",
3949  "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
3950  "CREATE", "EXECUTE", "USAGE", "MAINTAIN", "ALL");
3951  else if (TailMatches("GRANT"))
3952  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
3953  Privilege_options_of_grant_and_revoke);
3954  else if (TailMatches("REVOKE"))
3955  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
3956  Privilege_options_of_grant_and_revoke,
3957  "GRANT OPTION FOR",
3958  "ADMIN OPTION FOR",
3959  "INHERIT OPTION FOR",
3960  "SET OPTION FOR");
3961  else if (TailMatches("REVOKE", "GRANT", "OPTION", "FOR"))
3962  COMPLETE_WITH(Privilege_options_of_grant_and_revoke);
3963  else if (TailMatches("REVOKE", "ADMIN|INHERIT|SET", "OPTION", "FOR"))
3964  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3965  }
3966 
3967  else if (TailMatches("GRANT|REVOKE", "ALTER") ||
3968  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALTER"))
3969  COMPLETE_WITH("SYSTEM");
3970 
3971  else if (TailMatches("REVOKE", "SET"))
3972  COMPLETE_WITH("ON PARAMETER", "OPTION FOR");
3973  else if (TailMatches("GRANT", "SET") ||
3974  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "SET") ||
3975  TailMatches("GRANT|REVOKE", "ALTER", "SYSTEM") ||
3976  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", "ALTER", "SYSTEM"))
3977  COMPLETE_WITH("ON PARAMETER");
3978 
3979  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "PARAMETER") ||
3980  TailMatches("GRANT|REVOKE", MatchAny, MatchAny, "ON", "PARAMETER") ||
3981  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "PARAMETER") ||
3982  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, MatchAny, "ON", "PARAMETER"))
3983  COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_alter_system_set_vars);
3984 
3985  else if (TailMatches("GRANT", MatchAny, "ON", "PARAMETER", MatchAny) ||
3986  TailMatches("GRANT", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny))
3987  COMPLETE_WITH("TO");
3988 
3989  else if (TailMatches("REVOKE", MatchAny, "ON", "PARAMETER", MatchAny) ||
3990  TailMatches("REVOKE", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny) ||
3991  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "PARAMETER", MatchAny) ||
3992  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, MatchAny, "ON", "PARAMETER", MatchAny))
3993  COMPLETE_WITH("FROM");
3994 
3995  /*
3996  * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
3997  * TO/FROM
3998  */
3999  else if (TailMatches("GRANT|REVOKE", MatchAny) ||
4000  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny))
4001  {
4002  if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|MAINTAIN|ALL"))
4003  COMPLETE_WITH("ON");
4004  else if (TailMatches("GRANT", MatchAny))
4005  COMPLETE_WITH("TO");
4006  else
4007  COMPLETE_WITH("FROM");
4008  }
4009 
4010  /*
4011  * Complete GRANT/REVOKE <sth> ON with a list of appropriate relations.
4012  *
4013  * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
4014  * here will only work if the privilege list contains exactly one
4015  * privilege.
4016  */
4017  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON") ||
4018  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON"))
4019  {
4020  /*
4021  * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of
4022  * objects supported.
4023  */
4024  if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
4025  COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS");
4026  else
4027  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_grantables,
4028  "ALL FUNCTIONS IN SCHEMA",
4029  "ALL PROCEDURES IN SCHEMA",
4030  "ALL ROUTINES IN SCHEMA",
4031  "ALL SEQUENCES IN SCHEMA",
4032  "ALL TABLES IN SCHEMA",
4033  "DATABASE",
4034  "DOMAIN",
4035  "FOREIGN DATA WRAPPER",
4036  "FOREIGN SERVER",
4037  "FUNCTION",
4038  "LANGUAGE",
4039  "LARGE OBJECT",
4040  "PARAMETER",
4041  "PROCEDURE",
4042  "ROUTINE",
4043  "SCHEMA",
4044  "SEQUENCE",
4045  "TABLE",
4046  "TABLESPACE",
4047  "TYPE");
4048  }
4049  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL") ||
4050  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL"))
4051  COMPLETE_WITH("FUNCTIONS IN SCHEMA",
4052  "PROCEDURES IN SCHEMA",
4053  "ROUTINES IN SCHEMA",
4054  "SEQUENCES IN SCHEMA",
4055  "TABLES IN SCHEMA");
4056  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN") ||
4057  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN"))
4058  COMPLETE_WITH("DATA WRAPPER", "SERVER");
4059 
4060  /*
4061  * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
4062  * appropriate objects.
4063  *
4064  * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
4065  */
4066  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny) ||
4067  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", MatchAny))
4068  {
4069  if (TailMatches("DATABASE"))
4070  COMPLETE_WITH_QUERY(Query_for_list_of_databases);
4071  else if (TailMatches("DOMAIN"))
4072  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains);
4073  else if (TailMatches("FUNCTION"))
4074  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
4075  else if (TailMatches("LANGUAGE"))
4076  COMPLETE_WITH_QUERY(Query_for_list_of_languages);
4077  else if (TailMatches("PROCEDURE"))
4078  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures);
4079  else if (TailMatches("ROUTINE"))
4080  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines);
4081  else if (TailMatches("SCHEMA"))
4082  COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
4083  else if (TailMatches("SEQUENCE"))
4084  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences);
4085  else if (TailMatches("TABLE"))
4086  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables);
4087  else if (TailMatches("TABLESPACE"))
4088  COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
4089  else if (TailMatches("TYPE"))
4090  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
4091  else if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny))
4092  COMPLETE_WITH("TO");
4093  else
4094  COMPLETE_WITH("FROM");
4095  }
4096 
4097  /*
4098  * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
4099  * CURRENT_ROLE, CURRENT_USER, or SESSION_USER.
4100  */
4101  else if ((HeadMatches("GRANT") && TailMatches("TO")) ||
4102  (HeadMatches("REVOKE") && TailMatches("FROM")))
4103  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
4104  Keywords_for_list_of_grant_roles);
4105 
4106  /*
4107  * Offer grant options after that.
4108  */
4109  else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny))
4110  COMPLETE_WITH("WITH ADMIN",
4111  "WITH INHERIT",
4112  "WITH SET",
4113  "WITH GRANT OPTION",
4114  "GRANTED BY");
4115  else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny, "WITH"))
4116  COMPLETE_WITH("ADMIN",
4117  "INHERIT",
4118  "SET",
4119  "GRANT OPTION");
4120  else if (HeadMatches("GRANT") &&
4121  (TailMatches("TO", MatchAny, "WITH", "ADMIN|INHERIT|SET")))
4122  COMPLETE_WITH("OPTION", "TRUE", "FALSE");
4123  else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny, "WITH", MatchAny, "OPTION"))
4124  COMPLETE_WITH("GRANTED BY");
4125  else if (HeadMatches("GRANT") && TailMatches("TO", MatchAny, "WITH", MatchAny, "OPTION", "GRANTED", "BY"))
4126  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
4127  Keywords_for_list_of_grant_roles);
4128  /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
4129  else if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches("TO|FROM"))
4130  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
4131  Keywords_for_list_of_grant_roles);
4132  /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
4133  else if (HeadMatches("GRANT") && TailMatches("ON", MatchAny, MatchAny))
4134  COMPLETE_WITH("TO");
4135  else if (HeadMatches("REVOKE") && TailMatches("ON", MatchAny, MatchAny))
4136  COMPLETE_WITH("FROM");
4137 
4138  /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
4139  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny) ||
4140  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
4141  {
4142  if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
4143  COMPLETE_WITH("TO");
4144  else
4145  COMPLETE_WITH("FROM");
4146  }
4147 
4148  /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
4149  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
4150  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
4151  {
4152  if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
4153  COMPLETE_WITH("TO");
4154  else
4155  COMPLETE_WITH("FROM");
4156  }
4157 
4158  /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
4159  else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny) ||
4160  TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
4161  {
4162  if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
4163  COMPLETE_WITH("TO");
4164  else
4165  COMPLETE_WITH("FROM");
4166  }
4167 
4168 /* GROUP BY */
4169  else if (TailMatches("FROM", MatchAny, "GROUP"))
4170  COMPLETE_WITH("BY");
4171 
4172 /* IMPORT FOREIGN SCHEMA */
4173  else if (Matches("IMPORT"))
4174  COMPLETE_WITH("FOREIGN SCHEMA");
4175  else if (Matches("IMPORT", "FOREIGN"))
4176  COMPLETE_WITH("SCHEMA");
4177  else if (Matches("IMPORT", "FOREIGN", "SCHEMA", MatchAny))
4178  COMPLETE_WITH("EXCEPT (", "FROM SERVER", "LIMIT TO (");
4179  else if (TailMatches("LIMIT", "TO", "(*)") ||
4180  TailMatches("EXCEPT", "(*)"))
4181  COMPLETE_WITH("FROM SERVER");
4182  else if (TailMatches("FROM", "SERVER", MatchAny))
4183  COMPLETE_WITH("INTO");
4184  else if (TailMatches("FROM", "SERVER", MatchAny, "INTO"))
4185  COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
4186  else if (TailMatches("FROM", "SERVER", MatchAny, "INTO", MatchAny))
4187  COMPLETE_WITH("OPTIONS (");
4188 
4189 /* INSERT --- can be inside EXPLAIN, RULE, etc */
4190  /* Complete NOT MATCHED THEN INSERT */
4191  else if (TailMatches("NOT", "MATCHED", "THEN", "INSERT"))
4192  COMPLETE_WITH("VALUES", "(");
4193  /* Complete INSERT with "INTO" */
4194  else if (TailMatches("INSERT"))
4195  COMPLETE_WITH("INTO");
4196  /* Complete INSERT INTO with table names */
4197  else if (TailMatches("INSERT", "INTO"))
4198  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables);
4199  /* Complete "INSERT INTO <table> (" with attribute names */
4200  else if (TailMatches("INSERT", "INTO", MatchAny, "("))
4201  COMPLETE_WITH_ATTR(prev2_wd);
4202 
4203  /*
4204  * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
4205  * "TABLE" or "DEFAULT VALUES" or "OVERRIDING"
4206  */
4207  else if (TailMatches("INSERT", "INTO", MatchAny))
4208  COMPLETE_WITH("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING");
4209 
4210  /*
4211  * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
4212  * "TABLE" or "OVERRIDING"
4213  */
4214  else if (TailMatches("INSERT", "INTO", MatchAny, MatchAny) &&
4215  ends_with(prev_wd, ')'))
4216  COMPLETE_WITH("SELECT", "TABLE", "VALUES", "OVERRIDING");
4217 
4218  /* Complete OVERRIDING */
4219  else if (TailMatches("OVERRIDING"))
4220  COMPLETE_WITH("SYSTEM VALUE", "USER VALUE");
4221 
4222  /* Complete after OVERRIDING clause */
4223  else if (TailMatches("OVERRIDING", MatchAny, "VALUE"))
4224  COMPLETE_WITH("SELECT", "TABLE", "VALUES");
4225 
4226  /* Insert an open parenthesis after "VALUES" */
4227  else if (TailMatches("VALUES") && !TailMatches("DEFAULT", "VALUES"))
4228  COMPLETE_WITH("(");
4229 
4230 /* LOCK */
4231  /* Complete LOCK [TABLE] [ONLY] with a list of tables */
4232  else if (Matches("LOCK"))
4233  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables,
4234  "TABLE", "ONLY");
4235  else if (Matches("LOCK", "TABLE"))
4236  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_tables,
4237  "ONLY");
4238  else if (Matches("LOCK", "TABLE", "ONLY") || Matches("LOCK", "ONLY"))
4239  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
4240  /* For the following, handle the case of a single table only for now */
4241 
4242  /* Complete LOCK [TABLE] [ONLY] <table> with IN or NOWAIT */
4243  else if (Matches("LOCK", MatchAnyExcept("TABLE|ONLY")) ||
4244  Matches("LOCK", "TABLE", MatchAnyExcept("ONLY")) ||
4245  Matches("LOCK", "ONLY", MatchAny) ||
4246  Matches("LOCK", "TABLE", "ONLY", MatchAny))
4247  COMPLETE_WITH("IN", "NOWAIT");
4248 
4249  /* Complete LOCK [TABLE] [ONLY] <table> IN with a lock mode */
4250  else if (HeadMatches("LOCK") && TailMatches("IN"))
4251  COMPLETE_WITH("ACCESS SHARE MODE",
4252  "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
4253  "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
4254  "SHARE ROW EXCLUSIVE MODE",
4255  "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
4256 
4257  /*
4258  * Complete LOCK [TABLE][ONLY] <table> IN ACCESS|ROW with rest of lock
4259  * mode
4260  */
4261  else if (HeadMatches("LOCK") && TailMatches("IN", "ACCESS|ROW"))
4262  COMPLETE_WITH("EXCLUSIVE MODE", "SHARE MODE");
4263 
4264  /* Complete LOCK [TABLE] [ONLY] <table> IN SHARE with rest of lock mode */
4265  else if (HeadMatches("LOCK") && TailMatches("IN", "SHARE"))
4266  COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE",
4267  "UPDATE EXCLUSIVE MODE");
4268 
4269  /* Complete LOCK [TABLE] [ONLY] <table> [IN lockmode MODE] with "NOWAIT" */
4270  else if (HeadMatches("LOCK") && TailMatches("MODE"))
4271  COMPLETE_WITH("NOWAIT");
4272 
4273 /* MERGE --- can be inside EXPLAIN */
4274  else if (TailMatches("MERGE"))
4275  COMPLETE_WITH("INTO");
4276  else if (TailMatches("MERGE", "INTO"))
4277  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_mergetargets);
4278 
4279  /* Complete MERGE INTO <table> [[AS] <alias>] with USING */
4280  else if (TailMatches("MERGE", "INTO", MatchAny))
4281  COMPLETE_WITH("USING", "AS");
4282  else if (TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny) ||
4283  TailMatches("MERGE", "INTO", MatchAny, MatchAnyExcept("USING|AS")))
4284  COMPLETE_WITH("USING");
4285 
4286  /*
4287  * Complete MERGE INTO ... USING with a list of relations supporting
4288  * SELECT
4289  */
4290  else if (TailMatches("MERGE", "INTO", MatchAny, "USING") ||
4291  TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING") ||
4292  TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING"))
4293  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
4294 
4295  /*
4296  * Complete MERGE INTO <table> [[AS] <alias>] USING <relations> [[AS]
4297  * alias] with ON
4298  */
4299  else if (TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny) ||
4300  TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny) ||
4301  TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny))
4302  COMPLETE_WITH("AS", "ON");
4303  else if (TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny, "AS", MatchAny) ||
4304  TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny) ||
4305  TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny, "AS", MatchAny) ||
4306  TailMatches("MERGE", "INTO", MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")) ||
4307  TailMatches("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")) ||
4308  TailMatches("MERGE", "INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAnyExcept("ON|AS")))
4309  COMPLETE_WITH("ON");
4310 
4311  /* Complete MERGE INTO ... ON with target table attributes */
4312  else if (TailMatches("INTO", MatchAny, "USING", MatchAny, "ON"))
4313  COMPLETE_WITH_ATTR(prev4_wd);
4314  else if (TailMatches("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny, "ON"))
4315  COMPLETE_WITH_ATTR(prev8_wd);
4316  else if (TailMatches("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny, "ON"))
4317  COMPLETE_WITH_ATTR(prev6_wd);
4318 
4319  /*
4320  * Complete ... USING <relation> [[AS] alias] ON join condition
4321  * (consisting of one or three words typically used) with WHEN [NOT]
4322  * MATCHED
4323  */
4324  else if (TailMatches("USING", MatchAny, "ON", MatchAny) ||
4325  TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny) ||
4326  TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny) ||
4327  TailMatches("USING", MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")) ||
4328  TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")) ||
4329  TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, MatchAnyExcept("WHEN"), MatchAnyExcept("WHEN")))
4330  COMPLETE_WITH("WHEN MATCHED", "WHEN NOT MATCHED");
4331  else if (TailMatches("USING", MatchAny, "ON", MatchAny, "WHEN") ||
4332  TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, "WHEN") ||
4333  TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, "WHEN") ||
4334  TailMatches("USING", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN") ||
4335  TailMatches("USING", MatchAny, "AS", MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN") ||
4336  TailMatches("USING", MatchAny, MatchAny, "ON", MatchAny, MatchAny, MatchAny, "WHEN"))
4337  COMPLETE_WITH("MATCHED", "NOT MATCHED");
4338 
4339  /* Complete ... WHEN [NOT] MATCHED with THEN/AND */
4340  else if (TailMatches("WHEN", "MATCHED") ||
4341  TailMatches("WHEN", "NOT", "MATCHED"))
4342  COMPLETE_WITH("THEN", "AND");
4343 
4344  /* Complete ... WHEN MATCHED THEN with UPDATE SET/DELETE/DO NOTHING */
4345  else if (TailMatches("WHEN", "MATCHED", "THEN"))
4346  COMPLETE_WITH("UPDATE SET", "DELETE", "DO NOTHING");
4347 
4348  /* Complete ... WHEN NOT MATCHED THEN with INSERT/DO NOTHING */
4349  else if (TailMatches("WHEN", "NOT", "MATCHED", "THEN"))
4350  COMPLETE_WITH("INSERT", "DO NOTHING");
4351 
4352 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
4353  else if (TailMatches("NOTIFY"))
4354  COMPLETE_WITH_QUERY(Query_for_list_of_channels);
4355 
4356 /* OPTIONS */
4357  else if (TailMatches("OPTIONS"))
4358  COMPLETE_WITH("(");
4359 
4360 /* OWNER TO - complete with available roles */
4361  else if (TailMatches("OWNER", "TO"))
4362  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
4363  Keywords_for_list_of_owner_roles);
4364 
4365 /* ORDER BY */
4366  else if (TailMatches("FROM", MatchAny, "ORDER"))
4367  COMPLETE_WITH("BY");
4368  else if (TailMatches("FROM", MatchAny, "ORDER", "BY"))
4369  COMPLETE_WITH_ATTR(prev3_wd);
4370 
4371 /* PREPARE xx AS */
4372  else if (Matches("PREPARE", MatchAny, "AS"))
4373  COMPLETE_WITH("SELECT", "UPDATE", "INSERT INTO", "DELETE FROM");
4374 
4375 /*
4376  * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
4377  * managers, not for manual use in interactive sessions.
4378  */
4379 
4380 /* REASSIGN OWNED BY xxx TO yyy */
4381  else if (Matches("REASSIGN"))
4382  COMPLETE_WITH("OWNED BY");
4383  else if (Matches("REASSIGN", "OWNED"))
4384  COMPLETE_WITH("BY");
4385  else if (Matches("REASSIGN", "OWNED", "BY"))
4386  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
4387  else if (Matches("REASSIGN", "OWNED", "BY", MatchAny))
4388  COMPLETE_WITH("TO");
4389  else if (Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
4390  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
4391 
4392 /* REFRESH MATERIALIZED VIEW */
4393  else if (Matches("REFRESH"))
4394  COMPLETE_WITH("MATERIALIZED VIEW");
4395  else if (Matches("REFRESH", "MATERIALIZED"))
4396  COMPLETE_WITH("VIEW");
4397  else if (Matches("REFRESH", "MATERIALIZED", "VIEW"))
4398  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_matviews,
4399  "CONCURRENTLY");
4400  else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
4401  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
4402  else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
4403  COMPLETE_WITH("WITH");
4404  else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
4405  COMPLETE_WITH("WITH");
4406  else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
4407  COMPLETE_WITH("NO DATA", "DATA");
4408  else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
4409  COMPLETE_WITH("NO DATA", "DATA");
4410  else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
4411  COMPLETE_WITH("DATA");
4412  else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
4413  COMPLETE_WITH("DATA");
4414 
4415 /* REINDEX */
4416  else if (Matches("REINDEX") ||
4417  Matches("REINDEX", "(*)"))
4418  COMPLETE_WITH("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
4419  else if (Matches("REINDEX", "TABLE") ||
4420  Matches("REINDEX", "(*)", "TABLE"))
4421  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexables,
4422  "CONCURRENTLY");
4423  else if (Matches("REINDEX", "INDEX") ||
4424  Matches("REINDEX", "(*)", "INDEX"))
4425  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_indexes,
4426  "CONCURRENTLY");
4427  else if (Matches("REINDEX", "SCHEMA") ||
4428  Matches("REINDEX", "(*)", "SCHEMA"))
4429  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas,
4430  "CONCURRENTLY");
4431  else if (Matches("REINDEX", "SYSTEM|DATABASE") ||
4432  Matches("REINDEX", "(*)", "SYSTEM|DATABASE"))
4433  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_databases,
4434  "CONCURRENTLY");
4435  else if (Matches("REINDEX", "TABLE", "CONCURRENTLY") ||
4436  Matches("REINDEX", "(*)", "TABLE", "CONCURRENTLY"))
4437  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables);
4438  else if (Matches("REINDEX", "INDEX", "CONCURRENTLY") ||
4439  Matches("REINDEX", "(*)", "INDEX", "CONCURRENTLY"))
4440  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
4441  else if (Matches("REINDEX", "SCHEMA", "CONCURRENTLY") ||
4442  Matches("REINDEX", "(*)", "SCHEMA", "CONCURRENTLY"))
4443  COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
4444  else if (Matches("REINDEX", "SYSTEM|DATABASE", "CONCURRENTLY") ||
4445  Matches("REINDEX", "(*)", "SYSTEM|DATABASE", "CONCURRENTLY"))
4446  COMPLETE_WITH_QUERY(Query_for_list_of_databases);
4447  else if (HeadMatches("REINDEX", "(*") &&
4448  !HeadMatches("REINDEX", "(*)"))
4449  {
4450  /*
4451  * This fires if we're in an unfinished parenthesized option list.
4452  * get_previous_words treats a completed parenthesized option list as
4453  * one word, so the above test is correct.
4454  */
4455  if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
4456  COMPLETE_WITH("CONCURRENTLY", "TABLESPACE", "VERBOSE");
4457  else if (TailMatches("TABLESPACE"))
4458  COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
4459  }
4460 
4461 /* SECURITY LABEL */
4462  else if (Matches("SECURITY"))
4463  COMPLETE_WITH("LABEL");
4464  else if (Matches("SECURITY", "LABEL"))
4465  COMPLETE_WITH("ON", "FOR");
4466  else if (Matches("SECURITY", "LABEL", "FOR", MatchAny))
4467  COMPLETE_WITH("ON");
4468  else if (Matches("SECURITY", "LABEL", "ON") ||
4469  Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
4470  COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
4471  "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION",
4472  "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE",
4473  "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA",
4474  "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW");
4475  else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
4476  COMPLETE_WITH("IS");
4477 
4478 /* SELECT */
4479  /* naah . . . */
4480 
4481 /* SET, RESET, SHOW */
4482  /* Complete with a variable name */
4483  else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET"))
4484  COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_set_vars,
4485  "CONSTRAINTS",
4486  "TRANSACTION",
4487  "SESSION",
4488  "ROLE",
4489  "TABLESPACE",
4490  "ALL");
4491  else if (Matches("SHOW"))
4492  COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_show_vars,
4493  "SESSION AUTHORIZATION",
4494  "ALL");
4495  else if (Matches("SHOW", "SESSION"))
4496  COMPLETE_WITH("AUTHORIZATION");
4497  /* Complete "SET TRANSACTION" */
4498  else if (Matches("SET", "TRANSACTION"))
4499  COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
4500  else if (Matches("BEGIN|START", "TRANSACTION") ||
4501  Matches("BEGIN", "WORK") ||
4502  Matches("BEGIN") ||
4503  Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
4504  COMPLETE_WITH("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
4505  else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
4506  Matches("BEGIN", "NOT") ||
4507  Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
4508  COMPLETE_WITH("DEFERRABLE");
4509  else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
4510  Matches("BEGIN", "ISOLATION") ||
4511  Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
4512  COMPLETE_WITH("LEVEL");
4513  else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
4514  Matches("BEGIN", "ISOLATION", "LEVEL") ||
4515  Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
4516  COMPLETE_WITH("READ", "REPEATABLE READ", "SERIALIZABLE");
4517  else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
4518  Matches("BEGIN", "ISOLATION", "LEVEL", "READ") ||
4519  Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
4520  COMPLETE_WITH("UNCOMMITTED", "COMMITTED");
4521  else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
4522  Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
4523  Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
4524  COMPLETE_WITH("READ");
4525  else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
4526  Matches("BEGIN", "READ") ||
4527  Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
4528  COMPLETE_WITH("ONLY", "WRITE");
4529  /* SET CONSTRAINTS */
4530  else if (Matches("SET", "CONSTRAINTS"))
4531  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_constraints_with_schema,
4532  "ALL");
4533  /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
4534  else if (Matches("SET", "CONSTRAINTS", MatchAny))
4535  COMPLETE_WITH("DEFERRED", "IMMEDIATE");
4536  /* Complete SET ROLE */
4537  else if (Matches("SET", "ROLE"))
4538  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
4539  /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
4540  else if (Matches("SET", "SESSION"))
4541  COMPLETE_WITH("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
4542  /* Complete SET SESSION AUTHORIZATION with username */
4543  else if (Matches("SET", "SESSION", "AUTHORIZATION"))
4544  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
4545  "DEFAULT");
4546  /* Complete RESET SESSION with AUTHORIZATION */
4547  else if (Matches("RESET", "SESSION"))
4548  COMPLETE_WITH("AUTHORIZATION");
4549  /* Complete SET <var> with "TO" */
4550  else if (Matches("SET", MatchAny))
4551  COMPLETE_WITH("TO");
4552 
4553  /*
4554  * Complete ALTER DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER ... SET
4555  * <name>
4556  */
4557  else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") &&
4558  TailMatches("SET", MatchAny) &&
4559  !TailMatches("SCHEMA"))
4560  COMPLETE_WITH("FROM CURRENT", "TO");
4561 
4562  /*
4563  * Suggest possible variable values in SET variable TO|=, along with the
4564  * preceding ALTER syntaxes.
4565  */
4566  else if (TailMatches("SET", MatchAny, "TO|=") &&
4567  !TailMatches("UPDATE", MatchAny, "SET", MatchAny, "TO|="))
4568  {
4569  /* special cased code for individual GUCs */
4570  if (TailMatches("DateStyle", "TO|="))
4571  COMPLETE_WITH("ISO", "SQL", "Postgres", "German",
4572  "YMD", "DMY", "MDY",
4573  "US", "European", "NonEuropean",
4574  "DEFAULT");
4575  else if (TailMatches("search_path", "TO|="))
4576  {
4577  /* Here, we want to allow pg_catalog, so use narrower exclusion */
4578  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_schemas
4579  " AND nspname NOT LIKE E'pg\\\\_toast%%'"
4580  " AND nspname NOT LIKE E'pg\\\\_temp%%'",
4581  "DEFAULT");
4582  }
4583  else if (TailMatches("TimeZone", "TO|="))
4584  COMPLETE_WITH_TIMEZONE_NAME();
4585  else
4586  {
4587  /* generic, type based, GUC support */
4588  char *guctype = get_guctype(prev2_wd);
4589 
4590  /*
4591  * Note: if we don't recognize the GUC name, it's important to not
4592  * offer any completions, as most likely we've misinterpreted the
4593  * context and this isn't a GUC-setting command at all.
4594  */
4595  if (guctype)
4596  {
4597  if (strcmp(guctype, "enum") == 0)
4598  {
4599  set_completion_reference_verbatim(prev2_wd);
4600  COMPLETE_WITH_QUERY_PLUS(Query_for_values_of_enum_GUC,
4601  "DEFAULT");
4602  }
4603  else if (strcmp(guctype, "bool") == 0)
4604  COMPLETE_WITH("on", "off", "true", "false", "yes", "no",
4605  "1", "0", "DEFAULT");
4606  else
4607  COMPLETE_WITH("DEFAULT");
4608 
4609  free(guctype);
4610  }
4611  }
4612  }
4613 
4614 /* START TRANSACTION */
4615  else if (Matches("START"))
4616  COMPLETE_WITH("TRANSACTION");
4617 
4618 /* TABLE, but not TABLE embedded in other commands */
4619  else if (Matches("TABLE"))
4620  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
4621 
4622 /* TABLESAMPLE */
4623  else if (TailMatches("TABLESAMPLE"))
4624  COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
4625  else if (TailMatches("TABLESAMPLE", MatchAny))
4626  COMPLETE_WITH("(");
4627 
4628 /* TRUNCATE */
4629  else if (Matches("TRUNCATE"))
4630  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_truncatables,
4631  "TABLE", "ONLY");
4632  else if (Matches("TRUNCATE", "TABLE"))
4633  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_truncatables,
4634  "ONLY");
4635  else if (HeadMatches("TRUNCATE") && TailMatches("ONLY"))
4636  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_truncatables);
4637  else if (Matches("TRUNCATE", MatchAny) ||
4638  Matches("TRUNCATE", "TABLE|ONLY", MatchAny) ||
4639  Matches("TRUNCATE", "TABLE", "ONLY", MatchAny))
4640  COMPLETE_WITH("RESTART IDENTITY", "CONTINUE IDENTITY", "CASCADE", "RESTRICT");
4641  else if (HeadMatches("TRUNCATE") && TailMatches("IDENTITY"))
4642  COMPLETE_WITH("CASCADE", "RESTRICT");
4643 
4644 /* UNLISTEN */
4645  else if (Matches("UNLISTEN"))
4646  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_channels, "*");
4647 
4648 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
4649  /* If prev. word is UPDATE suggest a list of tables */
4650  else if (TailMatches("UPDATE"))
4651  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables);
4652  /* Complete UPDATE <table> with "SET" */
4653  else if (TailMatches("UPDATE", MatchAny))
4654  COMPLETE_WITH("SET");
4655  /* Complete UPDATE <table> SET with list of attributes */
4656  else if (TailMatches("UPDATE", MatchAny, "SET"))
4657  COMPLETE_WITH_ATTR(prev2_wd);
4658  /* UPDATE <table> SET <attr> = */
4659  else if (TailMatches("UPDATE", MatchAny, "SET", MatchAnyExcept("*=")))
4660  COMPLETE_WITH("=");
4661 
4662 /* USER MAPPING */
4663  else if (Matches("ALTER|CREATE|DROP", "USER", "MAPPING"))
4664  COMPLETE_WITH("FOR");
4665  else if (Matches("CREATE", "USER", "MAPPING", "FOR"))
4666  COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
4667  "CURRENT_ROLE",
4668  "CURRENT_USER",
4669  "PUBLIC",
4670  "USER");
4671  else if (Matches("ALTER|DROP", "USER", "MAPPING", "FOR"))
4672  COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
4673  else if (Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
4674  COMPLETE_WITH("SERVER");
4675  else if (Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
4676  COMPLETE_WITH("OPTIONS");
4677 
4678 /*
4679  * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
4680  * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
4681  */
4682  else if (Matches("VACUUM"))
4683  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
4684  "FULL",
4685  "FREEZE",
4686  "ANALYZE",
4687  "VERBOSE");
4688  else if (Matches("VACUUM", "FULL"))
4689  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
4690  "FREEZE",
4691  "ANALYZE",
4692  "VERBOSE");
4693  else if (Matches("VACUUM", "FREEZE") ||
4694  Matches("VACUUM", "FULL", "FREEZE"))
4695  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
4696  "VERBOSE",
4697  "ANALYZE");
4698  else if (Matches("VACUUM", "VERBOSE") ||
4699  Matches("VACUUM", "FULL|FREEZE", "VERBOSE") ||
4700  Matches("VACUUM", "FULL", "FREEZE", "VERBOSE"))
4701  COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_vacuumables,
4702  "ANALYZE");
4703  else if (HeadMatches("VACUUM", "(*") &&
4704  !HeadMatches("VACUUM", "(*)"))
4705  {
4706  /*
4707  * This fires if we're in an unfinished parenthesized option list.
4708  * get_previous_words treats a completed parenthesized option list as
4709  * one word, so the above test is correct.
4710  */
4711  if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
4712  COMPLETE_WITH("FULL", "FREEZE", "ANALYZE", "VERBOSE",
4713  "DISABLE_PAGE_SKIPPING", "SKIP_LOCKED",
4714  "INDEX_CLEANUP", "PROCESS_MAIN", "PROCESS_TOAST",
4715  "TRUNCATE", "PARALLEL", "SKIP_DATABASE_STATS",
4716  "ONLY_DATABASE_STATS", "BUFFER_USAGE_LIMIT");
4717  else if (TailMatches("FULL|FREEZE|ANALYZE|VERBOSE|DISABLE_PAGE_SKIPPING|SKIP_LOCKED|PROCESS_MAIN|PROCESS_TOAST|TRUNCATE|SKIP_DATABASE_STATS|ONLY_DATABASE_STATS"))
4718  COMPLETE_WITH("ON", "OFF");
4719  else if (TailMatches("INDEX_CLEANUP"))
4720  COMPLETE_WITH("AUTO", "ON", "OFF");
4721  }
4722  else if (HeadMatches("VACUUM") && TailMatches("("))
4723  /* "VACUUM (" should be caught above, so assume we want columns */
4724  COMPLETE_WITH_ATTR(prev2_wd);
4725  else if (HeadMatches("VACUUM"))
4726  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables);
4727 
4728 /* WITH [RECURSIVE] */
4729 
4730  /*
4731  * Only match when WITH is the first word, as WITH may appear in many
4732  * other contexts.
4733  */
4734  else if (Matches("WITH"))
4735  COMPLETE_WITH("RECURSIVE");
4736 
4737 /* WHERE */
4738  /* Simple case of the word before the where being the table name */
4739  else if (TailMatches(MatchAny, "WHERE"))
4740  COMPLETE_WITH_ATTR(prev2_wd);
4741 
4742 /* ... FROM ... */
4743 /* TODO: also include SRF ? */
4744  else if (TailMatches("FROM") && !Matches("COPY|\\copy", MatchAny, "FROM"))
4745  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
4746 
4747 /* ... JOIN ... */
4748  else if (TailMatches("JOIN"))
4749  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables);
4750 
4751 /* ... AT [ LOCAL | TIME ZONE ] ... */
4752  else if (TailMatches("AT"))
4753  COMPLETE_WITH("LOCAL", "TIME ZONE");
4754  else if (TailMatches("AT", "TIME", "ZONE"))
4755  COMPLETE_WITH_TIMEZONE_NAME();
4756 
4757 /* Backslash commands */
4758 /* TODO: \dc \dd \dl */
4759  else if (TailMatchesCS("\\?"))
4760  COMPLETE_WITH_CS("commands", "options", "variables");
4761  else if (TailMatchesCS("\\connect|\\c"))
4762  {
4764  COMPLETE_WITH_QUERY(Query_for_list_of_databases);
4765  }
4766  else if (TailMatchesCS("\\connect|\\c", MatchAny))
4767  {
4768  if (!recognized_connection_string(prev_wd))
4769  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
4770  }
4771  else if (TailMatchesCS("\\da*"))
4772  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates);
4773  else if (TailMatchesCS("\\dAc*", MatchAny) ||
4774  TailMatchesCS("\\dAf*", MatchAny))
4775  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
4776  else if (TailMatchesCS("\\dAo*", MatchAny) ||
4777  TailMatchesCS("\\dAp*", MatchAny))
4778  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_operator_families);
4779  else if (TailMatchesCS("\\dA*"))
4780  COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
4781  else if (TailMatchesCS("\\db*"))
4782  COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
4783  else if (TailMatchesCS("\\dconfig*"))
4784  COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_show_vars);
4785  else if (TailMatchesCS("\\dD*"))
4786  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains);
4787  else if (TailMatchesCS("\\des*"))
4788  COMPLETE_WITH_QUERY(Query_for_list_of_servers);
4789  else if (TailMatchesCS("\\deu*"))
4790  COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
4791  else if (TailMatchesCS("\\dew*"))
4792  COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
4793  else if (TailMatchesCS("\\df*"))
4794  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions);
4795  else if (HeadMatchesCS("\\df*"))
4796  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
4797 
4798  else if (TailMatchesCS("\\dFd*"))
4799  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_dictionaries);
4800  else if (TailMatchesCS("\\dFp*"))
4801  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_parsers);
4802  else if (TailMatchesCS("\\dFt*"))
4803  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_templates);
4804  /* must be at end of \dF alternatives: */
4805  else if (TailMatchesCS("\\dF*"))
4806  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_ts_configurations);
4807 
4808  else if (TailMatchesCS("\\di*"))
4809  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
4810  else if (TailMatchesCS("\\dL*"))
4811  COMPLETE_WITH_QUERY(Query_for_list_of_languages);
4812  else if (TailMatchesCS("\\dn*"))
4813  COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
4814  /* no support for completing operators, but we can complete types: */
4815  else if (HeadMatchesCS("\\do*", MatchAny))
4816  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
4817  else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z"))
4818  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables);
4819  else if (TailMatchesCS("\\dPi*"))
4820  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_indexes);
4821  else if (TailMatchesCS("\\dPt*"))
4822  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables);
4823  else if (TailMatchesCS("\\dP*"))
4824  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_relations);
4825  else if (TailMatchesCS("\\dRp*"))
4826  COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_publications);
4827  else if (TailMatchesCS("\\dRs*"))
4828  COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_subscriptions);
4829  else if (TailMatchesCS("\\ds*"))
4830  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences);
4831  else if (TailMatchesCS("\\dt*"))
4832  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
4833  else if (TailMatchesCS("\\dT*"))
4834  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
4835  else if (TailMatchesCS("\\du*") ||
4836  TailMatchesCS("\\dg*") ||
4837  TailMatchesCS("\\drg*"))
4838  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
4839  else if (TailMatchesCS("\\dv*"))
4840  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
4841  else if (TailMatchesCS("\\dx*"))
4842  COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
4843  else if (TailMatchesCS("\\dX*"))
4844  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_statistics);
4845  else if (TailMatchesCS("\\dm*"))
4846  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
4847  else if (TailMatchesCS("\\dE*"))
4848  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables);
4849  else if (TailMatchesCS("\\dy*"))
4850  COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
4851 
4852  /* must be at end of \d alternatives: */
4853  else if (TailMatchesCS("\\d*"))
4854  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations);
4855 
4856  else if (TailMatchesCS("\\ef"))
4857  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines);
4858  else if (TailMatchesCS("\\ev"))
4859  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
4860 
4861  else if (TailMatchesCS("\\encoding"))
4862  COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_encodings);
4863  else if (TailMatchesCS("\\h|\\help"))
4864  COMPLETE_WITH_LIST(sql_commands);
4865  else if (TailMatchesCS("\\h|\\help", MatchAny))
4866  {
4867  if (TailMatches("DROP"))
4868  matches = rl_completion_matches(text, drop_command_generator);
4869  else if (TailMatches("ALTER"))
4870  matches = rl_completion_matches(text, alter_command_generator);
4871 
4872  /*
4873  * CREATE is recognized by tail match elsewhere, so doesn't need to be
4874  * repeated here
4875  */
4876  }
4877  else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny))
4878  {
4879  if (TailMatches("CREATE|DROP", "ACCESS"))
4880  COMPLETE_WITH("METHOD");
4881  else if (TailMatches("ALTER", "DEFAULT"))
4882  COMPLETE_WITH("PRIVILEGES");
4883  else if (TailMatches("CREATE|ALTER|DROP", "EVENT"))
4884  COMPLETE_WITH("TRIGGER");
4885  else if (TailMatches("CREATE|ALTER|DROP", "FOREIGN"))
4886  COMPLETE_WITH("DATA WRAPPER", "TABLE");
4887  else if (TailMatches("ALTER", "LARGE"))
4888  COMPLETE_WITH("OBJECT");
4889  else if (TailMatches("CREATE|ALTER|DROP", "MATERIALIZED"))
4890  COMPLETE_WITH("VIEW");
4891  else if (TailMatches("CREATE|ALTER|DROP", "TEXT"))
4892  COMPLETE_WITH("SEARCH");
4893  else if (TailMatches("CREATE|ALTER|DROP", "USER"))
4894  COMPLETE_WITH("MAPPING FOR");
4895  }
4896  else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny))
4897  {
4898  if (TailMatches("CREATE|ALTER|DROP", "FOREIGN", "DATA"))
4899  COMPLETE_WITH("WRAPPER");
4900  else if (TailMatches("CREATE|ALTER|DROP", "TEXT", "SEARCH"))
4901  COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
4902  else if (TailMatches("CREATE|ALTER|DROP", "USER", "MAPPING"))
4903  COMPLETE_WITH("FOR");
4904  }
4905  else if (TailMatchesCS("\\l*") && !TailMatchesCS("\\lo*"))
4906  COMPLETE_WITH_QUERY(Query_for_list_of_databases);
4907  else if (TailMatchesCS("\\password"))
4908  COMPLETE_WITH_QUERY(Query_for_list_of_roles);
4909  else if (TailMatchesCS("\\pset"))
4910  COMPLETE_WITH_CS("border", "columns", "csv_fieldsep", "expanded",
4911  "fieldsep", "fieldsep_zero", "footer", "format",
4912  "linestyle", "null", "numericlocale",
4913  "pager", "pager_min_lines",
4914  "recordsep", "recordsep_zero",
4915  "tableattr", "title", "tuples_only",
4916  "unicode_border_linestyle",
4917  "unicode_column_linestyle",
4918  "unicode_header_linestyle",
4919  "xheader_width");
4920  else if (TailMatchesCS("\\pset", MatchAny))
4921  {
4922  if (TailMatchesCS("format"))
4923  COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex",
4924  "latex-longtable", "troff-ms", "unaligned",
4925  "wrapped");
4926  else if (TailMatchesCS("xheader_width"))
4927  COMPLETE_WITH_CS("full", "column", "page");
4928  else if (TailMatchesCS("linestyle"))
4929  COMPLETE_WITH_CS("ascii", "old-ascii", "unicode");
4930  else if (TailMatchesCS("pager"))
4931  COMPLETE_WITH_CS("on", "off", "always");
4932  else if (TailMatchesCS("unicode_border_linestyle|"
4933  "unicode_column_linestyle|"
4934  "unicode_header_linestyle"))
4935  COMPLETE_WITH_CS("single", "double");
4936  }
4937  else if (TailMatchesCS("\\unset"))
4938  matches = complete_from_variables(text, "", "", true);
4939  else if (TailMatchesCS("\\set"))
4940  matches = complete_from_variables(text, "", "", false);
4941  else if (TailMatchesCS("\\set", MatchAny))
4942  {
4943  if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|SHOW_ALL_RESULTS|"
4944  "SINGLELINE|SINGLESTEP"))
4945  COMPLETE_WITH_CS("on", "off");
4946  else if (TailMatchesCS("COMP_KEYWORD_CASE"))
4947  COMPLETE_WITH_CS("lower", "upper",
4948  "preserve-lower", "preserve-upper");
4949  else if (TailMatchesCS("ECHO"))
4950  COMPLETE_WITH_CS("errors", "queries", "all", "none");
4951  else if (TailMatchesCS("ECHO_HIDDEN"))
4952  COMPLETE_WITH_CS("noexec", "off", "on");
4953  else if (TailMatchesCS("HISTCONTROL"))
4954  COMPLETE_WITH_CS("ignorespace", "ignoredups",
4955  "ignoreboth", "none");
4956  else if (TailMatchesCS("ON_ERROR_ROLLBACK"))
4957  COMPLETE_WITH_CS("on", "off", "interactive");
4958  else if (TailMatchesCS("SHOW_CONTEXT"))
4959  COMPLETE_WITH_CS("never", "errors", "always");
4960  else if (TailMatchesCS("VERBOSITY"))
4961  COMPLETE_WITH_CS("default", "verbose", "terse", "sqlstate");
4962  }
4963  else if (TailMatchesCS("\\sf*"))
4964  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines);
4965  else if (TailMatchesCS("\\sv*"))
4966  COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
4967  else if (TailMatchesCS("\\cd|\\e|\\edit|\\g|\\gx|\\i|\\include|"
4968  "\\ir|\\include_relative|\\o|\\out|"
4969  "\\s|\\w|\\write|\\lo_import"))
4970  {
4971  completion_charp = "\\";
4972  completion_force_quote = false;
4973  matches = rl_completion_matches(text, complete_from_files);
4974  }
4975 
4976  /*
4977  * Finally, we look through the list of "things", such as TABLE, INDEX and
4978  * check if that was the previous word. If so, execute the query to get a
4979  * list of them.
4980  */
4981  else
4982  {
4983  const pgsql_thing_t *wac;
4984 
4985  for (wac = words_after_create; wac->name != NULL; wac++)
4986  {
4987  if (pg_strcasecmp(prev_wd, wac->name) == 0)
4988  {
4989  if (wac->query)
4990  COMPLETE_WITH_QUERY_LIST(wac->query,
4991  wac->keywords);
4992  else if (wac->vquery)
4993  COMPLETE_WITH_VERSIONED_QUERY_LIST(wac->vquery,
4994  wac->keywords);
4995  else if (wac->squery)
4996  COMPLETE_WITH_VERSIONED_SCHEMA_QUERY_LIST(wac->squery,
4997  wac->keywords);
4998  break;
4999  }
5000  }
5001  }
5002 
5003  /*
5004  * If we still don't have anything to match we have to fabricate some sort
5005  * of default list. If we were to just return NULL, readline automatically
5006  * attempts filename completion, and that's usually no good.
5007  */
5008  if (matches == NULL)
5009  {
5010  COMPLETE_WITH_CONST(true, "");
5011  /* Also, prevent Readline from appending stuff to the non-match */
5012  rl_completion_append_character = '\0';
5013 #ifdef HAVE_RL_COMPLETION_SUPPRESS_QUOTE
5014  rl_completion_suppress_quote = 1;
5015 #endif
5016  }
5017 
5018  /* free storage */
5019  free(previous_words);
5020  free(words_buffer);
5021  free(text_copy);
5022  free(completion_ref_object);
5023  completion_ref_object = NULL;
5024  free(completion_ref_schema);
5025  completion_ref_schema = NULL;
5026 
5027  /* Return our Grand List O' Matches */
5028  return matches;
5029 }
5030 
5031 
5032 /*
5033  * GENERATOR FUNCTIONS
5034  *
5035  * These functions do all the actual work of completing the input. They get
5036  * passed the text so far and the count how many times they have been called
5037  * so far with the same text.
5038  * If you read the above carefully, you'll see that these don't get called
5039  * directly but through the readline interface.
5040  * The return value is expected to be the full completion of the text, going
5041  * through a list each time, or NULL if there are no more matches. The string
5042  * will be free()'d by readline, so you must run it through strdup() or
5043  * something of that sort.
5044  */
5045 
5046 /*
5047  * Common routine for create_command_generator and drop_command_generator.
5048  * Entries that have 'excluded' flags are not returned.
5049  */
5050 static char *
5051 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
5052 {
5053  static int list_index,
5054  string_length;
5055  const char *name;
5056 
5057  /* If this is the first time for this completion, init some values */
5058  if (state == 0)
5059  {
5060  list_index = 0;
5061  string_length = strlen(text);
5062  }
5063 
5064  /* find something that matches */
5065  while ((name = words_after_create[list_index++].name))
5066  {
5067  if ((pg_strncasecmp(name, text, string_length) == 0) &&
5068  !(words_after_create[list_index - 1].flags & excluded))
5069  return pg_strdup_keyword_case(name, text);
5070  }
5071  /* if nothing matches, return NULL */
5072  return NULL;
5073 }
5074 
5075 /*
5076  * This one gives you one from a list of things you can put after CREATE
5077  * as defined above.
5078  */
5079 static char *
5080 create_command_generator(const char *text, int state)
5081 {
5082  return create_or_drop_command_generator(text, state, THING_NO_CREATE);
5083 }
5084 
5085 /*
5086  * This function gives you a list of things you can put after a DROP command.
5087  */
5088 static char *
5089 drop_command_generator(const char *text, int state)
5090 {
5091  return create_or_drop_command_generator(text, state, THING_NO_DROP);
5092 }
5093 
5094 /*
5095  * This function gives you a list of things you can put after an ALTER command.
5096  */
5097 static char *
5098 alter_command_generator(const char *text, int state)
5099 {
5100  return create_or_drop_command_generator(text, state, THING_NO_ALTER);
5101 }
5102 
5103 /*
5104  * These functions generate lists using server queries.
5105  * They are all wrappers for _complete_from_query.
5106  */
5107 
5108 static char *
5109 complete_from_query(const char *text, int state)
5110 {
5111  /* query is assumed to work for any server version */
5112  return _complete_from_query(completion_charp, NULL, completion_charpp,
5113  completion_verbatim, text, state);
5114 }
5115 
5116 static char *
5117 complete_from_versioned_query(const char *text, int state)
5118 {
5119  const VersionedQuery *vquery = completion_vquery;
5120 
5121  /* Find appropriate array element */
5122  while (pset.sversion < vquery->min_server_version)
5123  vquery++;
5124  /* Fail completion if server is too old */
5125  if (vquery->query == NULL)
5126  return NULL;
5127 
5128  return _complete_from_query(vquery->query, NULL, completion_charpp,
5129  completion_verbatim, text, state);
5130 }
5131 
5132 static char *
5133 complete_from_schema_query(const char *text, int state)
5134 {
5135  /* query is assumed to work for any server version */
5136  return _complete_from_query(NULL, completion_squery, completion_charpp,
5137  completion_verbatim, text, state);
5138 }
5139 
5140 static char *
5141 complete_from_versioned_schema_query(const char *text, int state)
5142 {
5143  const SchemaQuery *squery = completion_squery;
5144 
5145  /* Find appropriate array element */
5146  while (pset.sversion < squery->min_server_version)
5147  squery++;
5148  /* Fail completion if server is too old */
5149  if (squery->catname == NULL)
5150  return NULL;
5151 
5152  return _complete_from_query(NULL, squery, completion_charpp,
5153  completion_verbatim, text, state);
5154 }
5155 
5156 
5157 /*
5158  * This creates a list of matching things, according to a query described by
5159  * the initial arguments. The caller has already done any work needed to
5160  * select the appropriate query for the server's version.
5161  *
5162  * The query can be one of two kinds:
5163  *
5164  * 1. A simple query, which must contain a restriction clause of the form
5165  * output LIKE '%s'
5166  * where "output" is the same string that the query returns. The %s
5167  * will be replaced by a LIKE pattern to match the already-typed text.
5168  * There can be a second '%s', which will be replaced by a suitably-escaped
5169  * version of the string provided in completion_ref_object. If there is a
5170  * third '%s', it will be replaced by a suitably-escaped version of the string
5171  * provided in completion_ref_schema. Those strings should be set up
5172  * by calling set_completion_reference or set_completion_reference_verbatim.
5173  * Simple queries should return a single column of matches. If "verbatim"
5174  * is true, the matches are returned as-is; otherwise, they are taken to
5175  * be SQL identifiers and quoted if necessary.
5176  *
5177  * 2. A schema query used for completion of both schema and relation names.
5178  * This is represented by a SchemaQuery object; see that typedef for details.
5179  *
5180  * See top of file for examples of both kinds of query.
5181  *
5182  * In addition to the query itself, we accept a null-terminated array of
5183  * literal keywords, which will be returned if they match the input-so-far
5184  * (case insensitively). (These are in addition to keywords specified
5185  * within the schema_query, if any.)
5186  *
5187  * If "verbatim" is true, then we use the given text as-is to match the
5188  * query results; otherwise we parse it as a possibly-qualified identifier,
5189  * and reconstruct suitable quoting afterward.
5190  *
5191  * "text" and "state" are supplied by Readline. "text" is the word we are
5192  * trying to complete. "state" is zero on first call, nonzero later.
5193  *
5194  * readline will call this repeatedly with the same text and varying
5195  * state. On each call, we are supposed to return a malloc'd string
5196  * that is a candidate completion. Return NULL when done.
5197  */
5198 static char *
5199 _complete_from_query(const char *simple_query,
5200  const SchemaQuery *schema_query,
5201  const char *const *keywords,
5202  bool verbatim,
5203  const char *text, int state)
5204 {
5205  static int list_index,
5206  num_schema_only,
5207  num_query_other,
5208  num_keywords;
5209  static PGresult *result = NULL;
5210  static bool non_empty_object;
5211  static bool schemaquoted;
5212  static bool objectquoted;
5213 
5214  /*
5215  * If this is the first time for this completion, we fetch a list of our
5216  * "things" from the backend.
5217  */
5218  if (state == 0)
5219  {
5220  PQExpBufferData query_buffer;
5221  char *schemaname;
5222  char *objectname;
5223  char *e_object_like;
5224  char *e_schemaname;
5225  char *e_ref_object;
5226  char *e_ref_schema;
5227 
5228  /* Reset static state, ensuring no memory leaks */
5229  list_index = 0;
5230  num_schema_only = 0;
5231  num_query_other = 0;
5232  num_keywords = 0;
5233  PQclear(result);
5234  result = NULL;
5235 
5236  /* Parse text, splitting into schema and object name if needed */
5237  if (verbatim)
5238  {
5239  objectname = pg_strdup(text);
5240  schemaname = NULL;
5241  }
5242  else
5243  {
5244  parse_identifier(text,
5245  &schemaname, &objectname,
5246  &schemaquoted, &objectquoted);
5247  }
5248 
5249  /* Remember whether the user has typed anything in the object part */
5250  non_empty_object = (*objectname != '\0');
5251 
5252  /*
5253  * Convert objectname to a LIKE prefix pattern (e.g. 'foo%'), and set
5254  * up suitably-escaped copies of all the strings we need.
5255  */
5256  e_object_like = make_like_pattern(objectname);
5257 
5258  if (schemaname)
5259  e_schemaname = escape_string(schemaname);
5260  else
5261  e_schemaname = NULL;
5262 
5263  if (completion_ref_object)
5264  e_ref_object = escape_string(completion_ref_object);
5265  else
5266  e_ref_object = NULL;
5267 
5268  if (completion_ref_schema)
5269  e_ref_schema = escape_string(completion_ref_schema);
5270  else
5271  e_ref_schema = NULL;
5272 
5273  initPQExpBuffer(&query_buffer);
5274 
5275  if (schema_query)
5276  {
5277  Assert(simple_query == NULL);
5278 
5279  /*
5280  * We issue different queries depending on whether the input is
5281  * already qualified or not. schema_query gives us the pieces to
5282  * assemble.
5283  */
5284  if (schemaname == NULL || schema_query->namespace == NULL)
5285  {
5286  /* Get unqualified names matching the input-so-far */
5287  appendPQExpBufferStr(&query_buffer, "SELECT ");
5288  if (schema_query->use_distinct)
5289  appendPQExpBufferStr(&query_buffer, "DISTINCT ");
5290  appendPQExpBuffer(&query_buffer,
5291  "%s, NULL::pg_catalog.text FROM %s",
5292  schema_query->result,
5293  schema_query->catname);
5294  if (schema_query->refnamespace && completion_ref_schema)
5295  appendPQExpBufferStr(&query_buffer,
5296  ", pg_catalog.pg_namespace nr");
5297  appendPQExpBufferStr(&query_buffer, " WHERE ");
5298  if (schema_query->selcondition)
5299  appendPQExpBuffer(&query_buffer, "%s AND ",
5300  schema_query->selcondition);
5301  appendPQExpBuffer(&query_buffer, "(%s) LIKE '%s'",
5302  schema_query->result,
5303  e_object_like);
5304  if (schema_query->viscondition)
5305  appendPQExpBuffer(&query_buffer, " AND %s",
5306  schema_query->viscondition);
5307  if (schema_query->refname)
5308  {
5309  Assert(completion_ref_object);
5310  appendPQExpBuffer(&query_buffer, " AND %s = '%s'",
5311  schema_query->refname, e_ref_object);
5312  if (schema_query->refnamespace && completion_ref_schema)
5313  appendPQExpBuffer(&query_buffer,
5314  " AND %s = nr.oid AND nr.nspname = '%s'",
5315  schema_query->refnamespace,
5316  e_ref_schema);
5317  else if (schema_query->refviscondition)
5318  appendPQExpBuffer(&query_buffer,
5319  " AND %s",
5320  schema_query->refviscondition);
5321  }
5322 
5323  /*
5324  * When fetching relation names, suppress system catalogs
5325  * unless the input-so-far begins with "pg_". This is a
5326  * compromise between not offering system catalogs for
5327  * completion at all, and having them swamp the result when
5328  * the input is just "p".
5329  */
5330  if (strcmp(schema_query->catname,
5331  "pg_catalog.pg_class c") == 0 &&
5332  strncmp(objectname, "pg_", 3) != 0)
5333  {
5334  appendPQExpBufferStr(&query_buffer,
5335  " AND c.relnamespace <> (SELECT oid FROM"
5336  " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
5337  }
5338 
5339  /*
5340  * If the target object type can be schema-qualified, add in
5341  * schema names matching the input-so-far.
5342  */
5343  if (schema_query->namespace)
5344  {
5345  appendPQExpBuffer(&query_buffer, "\nUNION ALL\n"
5346  "SELECT NULL::pg_catalog.text, n.nspname "
5347  "FROM pg_catalog.pg_namespace n "
5348  "WHERE n.nspname LIKE '%s'",
5349  e_object_like);
5350 
5351  /*
5352  * Likewise, suppress system schemas unless the
5353  * input-so-far begins with "pg_".
5354  */
5355  if (strncmp(objectname, "pg_", 3) != 0)
5356  appendPQExpBufferStr(&query_buffer,
5357  " AND n.nspname NOT LIKE E'pg\\\\_%'");
5358 
5359  /*
5360  * Since we're matching these schema names to the object
5361  * name, handle their quoting using the object name's
5362  * quoting state.
5363  */
5364  schemaquoted = objectquoted;
5365  }
5366  }
5367  else
5368  {
5369  /* Input is qualified, so produce only qualified names */
5370  appendPQExpBufferStr(&query_buffer, "SELECT ");
5371  if (schema_query->use_distinct)
5372  appendPQExpBufferStr(&query_buffer, "DISTINCT ");
5373  appendPQExpBuffer(&query_buffer, "%s, n.nspname "
5374  "FROM %s, pg_catalog.pg_namespace n",
5375  schema_query->result,
5376  schema_query->catname);
5377  if (schema_query->refnamespace && completion_ref_schema)
5378  appendPQExpBufferStr(&query_buffer,
5379  ", pg_catalog.pg_namespace nr");
5380  appendPQExpBuffer(&query_buffer, " WHERE %s = n.oid AND ",
5381  schema_query->namespace);
5382  if (schema_query->selcondition)
5383  appendPQExpBuffer(&query_buffer, "%s AND ",
5384  schema_query->selcondition);
5385  appendPQExpBuffer(&query_buffer, "(%s) LIKE '%s' AND ",
5386  schema_query->result,
5387  e_object_like);
5388  appendPQExpBuffer(&query_buffer, "n.nspname = '%s'",
5389  e_schemaname);
5390  if (schema_query->refname)
5391  {
5392  Assert(completion_ref_object);
5393  appendPQExpBuffer(&query_buffer, " AND %s = '%s'",
5394  schema_query->refname, e_ref_object);
5395  if (schema_query->refnamespace && completion_ref_schema)
5396  appendPQExpBuffer(&query_buffer,
5397  " AND %s = nr.oid AND nr.nspname = '%s'",
5398  schema_query->refnamespace,
5399  e_ref_schema);
5400  else if (schema_query->refviscondition)
5401  appendPQExpBuffer(&query_buffer,
5402  " AND %s",
5403  schema_query->refviscondition);
5404  }
5405  }
5406  }
5407  else
5408  {
5409  Assert(simple_query);
5410  /* simple_query is an sprintf-style format string */
5411  appendPQExpBuffer(&query_buffer, simple_query,
5412  e_object_like,
5413  e_ref_object, e_ref_schema);
5414  }
5415 
5416  /* Limit the number of records in the result */
5417  appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
5418  completion_max_records);
5419 
5420  /* Finally, we can issue the query */
5421  result = exec_query(query_buffer.data);
5422 
5423  /* Clean up */
5424  termPQExpBuffer(&query_buffer);
5425  free(schemaname);
5426  free(objectname);
5427  free(e_object_like);
5428  free(e_schemaname);
5429  free(e_ref_object);
5430  free(e_ref_schema);
5431  }
5432 
5433  /* Return the next result, if any, but not if the query failed */
5434  if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
5435  {
5436  int nskip;
5437 
5438  while (list_index < PQntuples(result))
5439  {
5440  const char *item = NULL;
5441  const char *nsp = NULL;
5442 
5443  if (!PQgetisnull(result, list_index, 0))
5444  item = PQgetvalue(result, list_index, 0);
5445  if (PQnfields(result) > 1 &&
5446  !PQgetisnull(result, list_index, 1))
5447  nsp = PQgetvalue(result, list_index, 1);
5448  list_index++;
5449 
5450  /* In verbatim mode, we return all the items as-is */
5451  if (verbatim)
5452  {
5453  num_query_other++;
5454  return pg_strdup(item);
5455  }
5456 
5457  /*
5458  * In normal mode, a name requiring quoting will be returned only
5459  * if the input was empty or quoted. Otherwise the user might see
5460  * completion inserting a quote she didn't type, which is
5461  * surprising. This restriction also dodges some odd behaviors of
5462  * some versions of readline/libedit.
5463  */
5464  if (non_empty_object)
5465  {
5466  if (item && !objectquoted && identifier_needs_quotes(item))
5467  continue;
5468  if (nsp && !schemaquoted && identifier_needs_quotes(nsp))
5469  continue;
5470  }
5471 
5472  /* Count schema-only results for hack below */
5473  if (item == NULL && nsp != NULL)
5474  num_schema_only++;
5475  else
5476  num_query_other++;
5477 
5478  return requote_identifier(nsp, item, schemaquoted, objectquoted);
5479  }
5480 
5481  /*
5482  * When the query result is exhausted, check for hard-wired keywords.
5483  * These will only be returned if they match the input-so-far,
5484  * ignoring case.
5485  */
5486  nskip = list_index - PQntuples(result);
5487  if (schema_query && schema_query->keywords)
5488  {
5489  const char *const *itemp = schema_query->keywords;
5490 
5491  while (*itemp)
5492  {
5493  const char *item = *itemp++;
5494 
5495  if (nskip-- > 0)
5496  continue;
5497  list_index++;
5498  if (pg_strncasecmp(text, item, strlen(text)) == 0)
5499  {
5500  num_keywords++;
5501  return pg_strdup_keyword_case(item, text);
5502  }
5503  }
5504  }
5505  if (keywords)
5506  {
5507  const char *const *itemp = keywords;
5508 
5509  while (*itemp)
5510  {
5511  const char *item = *itemp++;
5512 
5513  if (nskip-- > 0)
5514  continue;
5515  list_index++;
5516  if (pg_strncasecmp(text, item, strlen(text)) == 0)
5517  {
5518  num_keywords++;
5519  return pg_strdup_keyword_case(item, text);
5520  }
5521  }
5522  }
5523  }
5524 
5525  /*
5526  * Hack: if we returned only bare schema names, don't let Readline add a
5527  * space afterwards. Otherwise the schema will stop being part of the
5528  * completion subject text, which is not what we want.
5529  */
5530  if (num_schema_only > 0 && num_query_other == 0 && num_keywords == 0)
5531  rl_completion_append_character = '\0';
5532 
5533  /* No more matches, so free the result structure and return null */
5534  PQclear(result);
5535  result = NULL;
5536  return NULL;
5537 }
5538 
5539 
5540 /*
5541  * Set up completion_ref_object and completion_ref_schema
5542  * by parsing the given word. These variables can then be
5543  * used in a query passed to _complete_from_query.
5544  */
5545 static void
5546 set_completion_reference(const char *word)
5547 {
5548  bool schemaquoted,
5549  objectquoted;
5550 
5551  parse_identifier(word,
5552  &completion_ref_schema, &completion_ref_object,
5553  &schemaquoted, &objectquoted);
5554 }
5555 
5556 /*
5557  * Set up completion_ref_object when it should just be
5558  * the given word verbatim.
5559  */
5560 static void
5561 set_completion_reference_verbatim(const char *word)
5562 {
5563  completion_ref_schema = NULL;
5564  completion_ref_object = pg_strdup(word);
5565 }
5566 
5567 
5568 /*
5569  * This function returns in order one of a fixed, NULL pointer terminated list
5570  * of strings (if matching). This can be used if there are only a fixed number
5571  * SQL words that can appear at certain spot.
5572  */
5573 static char *
5574 complete_from_list(const char *text, int state)
5575 {
5576  static int string_length,
5577  list_index,
5578  matches;
5579  static bool casesensitive;
5580  const char *item;
5581 
5582  /* need to have a list */
5583  Assert(completion_charpp != NULL);
5584 
5585  /* Initialization */
5586  if (state == 0)
5587  {
5588  list_index = 0;
5589  string_length = strlen(text);
5590  casesensitive = completion_case_sensitive;
5591  matches = 0;
5592  }
5593 
5594  while ((item = completion_charpp[list_index++]))
5595  {
5596  /* First pass is case sensitive */
5597  if (casesensitive && strncmp(text, item, string_length) == 0)
5598  {
5599  matches++;
5600  return pg_strdup(item);
5601  }
5602 
5603  /* Second pass is case insensitive, don't bother counting matches */
5604  if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
5605  {
5606  if (completion_case_sensitive)
5607  return pg_strdup(item);
5608  else
5609 
5610  /*
5611  * If case insensitive matching was requested initially,
5612  * adjust the case according to setting.
5613  */
5614  return pg_strdup_keyword_case(item, text);
5615  }
5616  }
5617 
5618  /*
5619  * No matches found. If we're not case insensitive already, lets switch to
5620  * being case insensitive and try again
5621  */
5622  if (casesensitive && matches == 0)
5623  {
5624  casesensitive = false;
5625  list_index = 0;
5626  state++;
5627  return complete_from_list(text, state);
5628  }
5629 
5630  /* If no more matches, return null. */
5631  return NULL;
5632 }
5633 
5634 
5635 /*
5636  * This function returns one fixed string the first time even if it doesn't
5637  * match what's there, and nothing the second time. The string
5638  * to be used must be in completion_charp.
5639  *
5640  * If the given string is "", this has the effect of preventing readline
5641  * from doing any completion. (Without this, readline tries to do filename
5642  * completion which is seldom the right thing.)
5643  *
5644  * If the given string is not empty, readline will replace whatever the
5645  * user typed with that string. This behavior might be useful if it's
5646  * completely certain that we know what must appear at a certain spot,
5647  * so that it's okay to overwrite misspellings. In practice, given the
5648  * relatively lame parsing technology used in this file, the level of
5649  * certainty is seldom that high, so that you probably don't want to
5650  * use this. Use complete_from_list with a one-element list instead;
5651  * that won't try to auto-correct "misspellings".
5652  */
5653 static char *
5654 complete_from_const(const char *text, int state)
5655 {
5656  Assert(completion_charp != NULL);
5657  if (state == 0)
5658  {
5659  if (completion_case_sensitive)
5660  return pg_strdup(completion_charp);
5661  else
5662 
5663  /*
5664  * If case insensitive matching was requested initially, adjust
5665  * the case according to setting.
5666  */
5667  return pg_strdup_keyword_case(completion_charp, text);
5668  }
5669  else
5670  return NULL;
5671 }
5672 
5673 
5674 /*
5675  * This function appends the variable name with prefix and suffix to
5676  * the variable names array.
5677  */
5678 static void
5679 append_variable_names(char ***varnames, int *nvars,
5680  int *maxvars, const char *varname,
5681  const char *prefix, const char *suffix)
5682 {
5683  if (*nvars >= *maxvars)
5684  {
5685  *maxvars *= 2;
5686  *varnames = (char **) pg_realloc(*varnames,
5687  ((*maxvars) + 1) * sizeof(char *));
5688  }
5689 
5690  (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
5691 }
5692 
5693 
5694 /*
5695  * This function supports completion with the name of a psql variable.
5696  * The variable names can be prefixed and suffixed with additional text
5697  * to support quoting usages. If need_value is true, only variables
5698  * that are currently set are included; otherwise, special variables
5699  * (those that have hooks) are included even if currently unset.
5700  */
5701 static char **
5702 complete_from_variables(const char *text, const char *prefix, const char *suffix,
5703  bool need_value)
5704 {
5705  char **matches;
5706  char **varnames;
5707  int nvars = 0;
5708  int maxvars = 100;
5709  int i;
5710  struct _variable *ptr;
5711 
5712  varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
5713 
5714  for (ptr = pset.vars->next; ptr; ptr = ptr->next)
5715  {
5716  if (need_value && !(ptr->value))
5717  continue;
5718  append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
5719  prefix, suffix);
5720  }
5721 
5722  varnames[nvars] = NULL;
5723  COMPLETE_WITH_LIST_CS((const char *const *) varnames);
5724 
5725  for (i = 0; i < nvars; i++)
5726  free(varnames[i]);
5727  free(varnames);
5728 
5729  return matches;
5730 }
5731 
5732 
5733 /*
5734  * This function wraps rl_filename_completion_function() to strip quotes from
5735  * the input before searching for matches and to quote any matches for which
5736  * the consuming command will require it.
5737  *
5738  * Caller must set completion_charp to a zero- or one-character string
5739  * containing the escape character. This is necessary since \copy has no
5740  * escape character, but every other backslash command recognizes "\" as an
5741  * escape character.
5742  *
5743  * Caller must also set completion_force_quote to indicate whether to force
5744  * quotes around the result. (The SQL COPY command requires that.)
5745  */
5746 static char *
5747 complete_from_files(const char *text, int state)
5748 {
5749 #ifdef USE_FILENAME_QUOTING_FUNCTIONS
5750 
5751  /*
5752  * If we're using a version of Readline that supports filename quoting
5753  * hooks, rely on those, and invoke rl_filename_completion_function()
5754  * without messing with its arguments. Readline does stuff internally
5755  * that does not work well at all if we try to handle dequoting here.
5756  * Instead, Readline will call quote_file_name() and dequote_file_name()
5757  * (see below) at appropriate times.
5758  *
5759  * ... or at least, mostly it will. There are some paths involving
5760  * unmatched file names in which Readline never calls quote_file_name(),
5761  * and if left to its own devices it will incorrectly append a quote
5762  * anyway. Set rl_completion_suppress_quote to prevent that. If we do
5763  * get to quote_file_name(), we'll clear this again. (Yes, this seems
5764  * like it's working around Readline bugs.)
5765  */
5766 #ifdef HAVE_RL_COMPLETION_SUPPRESS_QUOTE
5767  rl_completion_suppress_quote = 1;
5768 #endif
5769 
5770  /* If user typed a quote, force quoting (never remove user's quote) */
5771  if (*text == '\'')
5772  completion_force_quote = true;
5773 
5774  return rl_filename_completion_function(text, state);
5775 #else
5776 
5777  /*
5778  * Otherwise, we have to do the best we can.
5779  */
5780  static const char *unquoted_text;
5781  char *unquoted_match;
5782  char *ret = NULL;
5783 
5784  /* If user typed a quote, force quoting (never remove user's quote) */
5785  if (*text == '\'')
5786  completion_force_quote = true;
5787 
5788  if (state == 0)
5789  {
5790  /* Initialization: stash the unquoted input. */
5791  unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
5792  false, true, pset.encoding);
5793  /* expect a NULL return for the empty string only */
5794  if (!unquoted_text)
5795  {
5796  Assert(*text == '\0');
5797  unquoted_text = text;
5798  }
5799  }
5800 
5801  unquoted_match = rl_filename_completion_function(unquoted_text, state);
5802  if (unquoted_match)
5803  {
5804  struct stat statbuf;
5805  bool is_dir = (stat(unquoted_match, &statbuf) == 0 &&
5806  S_ISDIR(statbuf.st_mode) != 0);
5807 
5808  /* Re-quote the result, if needed. */
5809  ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
5810  '\'', *completion_charp,
5811  completion_force_quote,
5812  pset.encoding);
5813  if (ret)
5814  free(unquoted_match);
5815  else
5816  ret = unquoted_match;
5817 
5818  /*
5819  * If it's a directory, replace trailing quote with a slash; this is
5820  * usually more convenient. (If we didn't quote, leave this to
5821  * libedit.)
5822  */
5823  if (*ret == '\'' && is_dir)
5824  {
5825  char *retend = ret + strlen(ret) - 1;
5826 
5827  Assert(*retend == '\'');
5828  *retend = '/';
5829  /* Prevent libedit from adding a space, too */
5830  rl_completion_append_character = '\0';
5831  }
5832  }
5833 
5834  return ret;
5835 #endif /* USE_FILENAME_QUOTING_FUNCTIONS */
5836 }
5837 
5838 
5839 /* HELPER FUNCTIONS */
5840 
5841 
5842 /*
5843  * Make a pg_strdup copy of s and convert the case according to
5844  * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
5845  */
5846 static char *
5847 pg_strdup_keyword_case(const char *s, const char *ref)
5848 {
5849  char *ret,
5850  *p;
5851  unsigned char first = ref[0];
5852 
5853  ret = pg_strdup(s);
5854 
5857  pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
5858  (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
5859  {
5860  for (p = ret; *p; p++)
5861  *p = pg_tolower((unsigned char) *p);
5862  }
5863  else
5864  {
5865  for (p = ret; *p; p++)
5866  *p = pg_toupper((unsigned char) *p);
5867  }
5868 
5869  return ret;
5870 }
5871 
5872 
5873 /*
5874  * escape_string - Escape argument for use as string literal.
5875  *
5876  * The returned value has to be freed.
5877  */
5878 static char *
5879 escape_string(const char *text)
5880 {
5881  size_t text_length;
5882  char *result;
5883 
5884  text_length = strlen(text);
5885 
5886  result = pg_malloc(text_length * 2 + 1);
5887  PQescapeStringConn(pset.db, result, text, text_length, NULL);
5888 
5889  return result;
5890 }
5891 
5892 
5893 /*
5894  * make_like_pattern - Convert argument to a LIKE prefix pattern.
5895  *
5896  * We escape _ and % in the given text by backslashing, append a % to
5897  * represent "any subsequent characters", and then pass the string through
5898  * escape_string() so it's ready to insert in a query. The result needs
5899  * to be freed.
5900  */
5901 static char *
5902 make_like_pattern(const char *word)
5903 {
5904  char *result;
5905  char *buffer = pg_malloc(strlen(word) * 2 + 2);
5906  char *bptr = buffer;
5907 
5908  while (*word)
5909  {
5910  if (*word == '_' || *word == '%')
5911  *bptr++ = '\\';
5912  if (IS_HIGHBIT_SET(*word))
5913  {
5914  /*
5915  * Transfer multibyte characters without further processing, to
5916  * avoid getting confused in unsafe client encodings.
5917  */
5918  int chlen = PQmblenBounded(word, pset.encoding);
5919 
5920  while (chlen-- > 0)
5921  *bptr++ = *word++;
5922  }
5923  else
5924  *bptr++ = *word++;
5925  }
5926  *bptr++ = '%';
5927  *bptr = '\0';
5928 
5929  result = escape_string(buffer);
5930  free(buffer);
5931  return result;
5932 }
5933 
5934 
5935 /*
5936  * parse_identifier - Parse a possibly-schema-qualified SQL identifier.
5937  *
5938  * This involves splitting off the schema name if present, de-quoting,
5939  * and downcasing any unquoted text. We are a bit laxer than the backend
5940  * in that we allow just portions of a name to be quoted --- that's because
5941  * psql metacommands have traditionally behaved that way.
5942  *
5943  * Outputs are a malloc'd schema name (NULL if none), malloc'd object name,
5944  * and booleans telling whether any part of the schema and object name was
5945  * double-quoted.
5946  */
5947 static void
5948 parse_identifier(const char *ident,
5949  char **schemaname, char **objectname,
5950  bool *schemaquoted, bool *objectquoted)
5951 {
5952  size_t buflen = strlen(ident) + 1;
5953  bool enc_is_single_byte = (pg_encoding_max_length(pset.encoding) == 1);
5954  char *sname;
5955  char *oname;
5956  char *optr;
5957  bool inquotes;
5958 
5959  /* Initialize, making a certainly-large-enough output buffer */
5960  sname = NULL;
5961  oname = pg_malloc(buflen);
5962  *schemaquoted = *objectquoted = false;
5963  /* Scan */
5964  optr = oname;
5965  inquotes = false;
5966  while (*ident)
5967  {
5968  unsigned char ch = (unsigned char) *ident++;
5969 
5970  if (ch == '"')
5971  {
5972  if (inquotes && *ident == '"')
5973  {
5974  /* two quote marks within a quoted identifier = emit quote */
5975  *optr++ = '"';
5976  ident++;
5977  }
5978  else
5979  {
5980  inquotes = !inquotes;
5981  *objectquoted = true;
5982  }
5983  }
5984  else if (ch == '.' && !inquotes)
5985  {
5986  /* Found a schema name, transfer it to sname / *schemaquoted */
5987  *optr = '\0';
5988  free(sname); /* drop any catalog name */
5989  sname = oname;
5990  oname = pg_malloc(buflen);
5991  optr = oname;
5992  *schemaquoted = *objectquoted;
5993  *objectquoted = false;
5994  }
5995  else if (!enc_is_single_byte && IS_HIGHBIT_SET(ch))
5996  {
5997  /*
5998  * Transfer multibyte characters without further processing. They
5999  * wouldn't be affected by our downcasing rule anyway, and this
6000  * avoids possibly doing the wrong thing in unsafe client
6001  * encodings.
6002  */
6003  int chlen = PQmblenBounded(ident - 1, pset.encoding);
6004 
6005  *optr++ = (char) ch;
6006  while (--chlen > 0)
6007  *optr++ = *ident++;
6008  }
6009  else
6010  {
6011  if (!inquotes)
6012  {
6013  /*
6014  * This downcasing transformation should match the backend's
6015  * downcase_identifier() as best we can. We do not know the
6016  * backend's locale, though, so it's necessarily approximate.
6017  * We assume that psql is operating in the same locale and
6018  * encoding as the backend.
6019  */
6020  if (ch >= 'A' && ch <= 'Z')
6021  ch += 'a' - 'A';
6022  else if (enc_is_single_byte && IS_HIGHBIT_SET(ch) && isupper(ch))
6023  ch = tolower(ch);
6024  }
6025  *optr++ = (char) ch;
6026  }
6027  }
6028 
6029  *optr = '\0';
6030  *schemaname = sname;
6031  *objectname = oname;
6032 }
6033 
6034 
6035 /*
6036  * requote_identifier - Reconstruct a possibly-schema-qualified SQL identifier.
6037  *
6038  * Build a malloc'd string containing the identifier, with quoting applied
6039  * as necessary. This is more or less the inverse of parse_identifier;
6040  * in particular, if an input component was quoted, we'll quote the output
6041  * even when that isn't strictly required.
6042  *
6043  * Unlike parse_identifier, we handle the case where a schema and no
6044  * object name is provided, producing just "schema.".
6045  */
6046 static char *
6047 requote_identifier(const char *schemaname, const char *objectname,
6048  bool quote_schema, bool quote_object)
6049 {
6050  char *result;
6051  size_t buflen = 1; /* count the trailing \0 */
6052  char *ptr;
6053 
6054  /*
6055  * We could use PQescapeIdentifier for some of this, but not all, and it
6056  * adds more notational cruft than it seems worth.
6057  */
6058  if (schemaname)
6059  {
6060  buflen += strlen(schemaname) + 1; /* +1 for the dot */
6061  if (!quote_schema)
6062  quote_schema = identifier_needs_quotes(schemaname);
6063  if (quote_schema)
6064  {
6065  buflen += 2; /* account for quote marks */
6066  for (const char *p = schemaname; *p; p++)
6067  {
6068  if (*p == '"')
6069  buflen++;
6070  }
6071  }
6072  }
6073  if (objectname)
6074  {
6075  buflen += strlen(objectname);
6076  if (!quote_object)
6077  quote_object = identifier_needs_quotes(objectname);
6078  if (quote_object)
6079  {
6080  buflen += 2; /* account for quote marks */
6081  for (const char *p = objectname; *p; p++)
6082  {
6083  if (*p == '"')
6084  buflen++;
6085  }
6086  }
6087  }
6088  result = pg_malloc(buflen);
6089  ptr = result;
6090  if (schemaname)
6091  {
6092  if (quote_schema)
6093  *ptr++ = '"';
6094  for (const char *p = schemaname; *p; p++)
6095  {
6096  *ptr++ = *p;
6097  if (*p == '"')
6098  *ptr++ = '"';
6099  }
6100  if (quote_schema)
6101  *ptr++ = '"';
6102  *ptr++ = '.';
6103  }
6104  if (objectname)
6105  {
6106  if (quote_object)
6107  *ptr++ = '"';
6108  for (const char *p = objectname; *p; p++)
6109  {
6110  *ptr++ = *p;
6111  if (*p == '"')
6112  *ptr++ = '"';
6113  }
6114  if (quote_object)
6115  *ptr++ = '"';
6116  }
6117  *ptr = '\0';
6118  return result;
6119 }
6120 
6121 
6122 /*
6123  * Detect whether an identifier must be double-quoted.
6124  *
6125  * Note we'll quote anything that's not ASCII; the backend's quote_ident()
6126  * does the same. Perhaps this could be relaxed in future.
6127  */
6128 static bool
6129 identifier_needs_quotes(const char *ident)
6130 {
6131  int kwnum;
6132 
6133  /* Check syntax. */
6134  if (!((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_'))
6135  return true;
6136  if (strspn(ident, "abcdefghijklmnopqrstuvwxyz0123456789_$") != strlen(ident))
6137  return true;
6138 
6139  /*
6140  * Check for keyword. We quote keywords except for unreserved ones.
6141  *
6142  * It is possible that our keyword list doesn't quite agree with the
6143  * server's, but this should be close enough for tab-completion purposes.
6144  *
6145  * Note: ScanKeywordLookup() does case-insensitive comparison, but that's
6146  * fine, since we already know we have all-lower-case.
6147  */
6149 
6150  if (kwnum >= 0 && ScanKeywordCategories[kwnum] != UNRESERVED_KEYWORD)
6151  return true;
6152 
6153  return false;
6154 }
6155 
6156 
6157 /*
6158  * Execute a query, returning NULL if there was any error.
6159  * This should be the preferred way of talking to the database in this file.
6160  */
6161 static PGresult *
6162 exec_query(const char *query)
6163 {
6164  PGresult *result;
6165 
6166  if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
6167  return NULL;
6168 
6169  result = PQexec(pset.db, query);
6170 
6171  if (PQresultStatus(result) != PGRES_TUPLES_OK)
6172  {
6173  /*
6174  * Printing an error while the user is typing would be quite annoying,
6175  * so we don't. This does complicate debugging of this code; but you
6176  * can look in the server log instead.
6177  */
6178 #ifdef NOT_USED
6179  pg_log_error("tab completion query failed: %s\nQuery was:\n%s",
6180  PQerrorMessage(pset.db), query);
6181 #endif
6182  PQclear(result);
6183  result = NULL;
6184  }
6185 
6186  return result;
6187 }
6188 
6189 
6190 /*
6191  * Parse all the word(s) before point.
6192  *
6193  * Returns a malloc'd array of character pointers that point into the malloc'd
6194  * data array returned to *buffer; caller must free() both of these when done.
6195  * *nwords receives the number of words found, ie, the valid length of the
6196  * return array.
6197  *
6198  * Words are returned right to left, that is, previous_words[0] gets the last
6199  * word before point, previous_words[1] the next-to-last, etc.
6200  */
6201 static char **
6202 get_previous_words(int point, char **buffer, int *nwords)
6203 {
6204  char **previous_words;
6205  char *buf;
6206  char *outptr;
6207  int words_found = 0;
6208  int i;
6209 
6210  /*
6211  * If we have anything in tab_completion_query_buf, paste it together with
6212  * rl_line_buffer to construct the full query. Otherwise we can just use
6213  * rl_line_buffer as the input string.
6214  */
6216  {
6218  buf = pg_malloc(point + i + 2);
6219  memcpy(buf, tab_completion_query_buf->data, i);
6220  buf[i++] = '\n';
6221  memcpy(buf + i, rl_line_buffer, point);
6222  i += point;
6223  buf[i] = '\0';
6224  /* Readjust point to reference appropriate offset in buf */
6225  point = i;
6226  }
6227  else
6228  buf = rl_line_buffer;
6229 
6230  /*
6231  * Allocate an array of string pointers and a buffer to hold the strings
6232  * themselves. The worst case is that the line contains only
6233  * non-whitespace WORD_BREAKS characters, making each one a separate word.
6234  * This is usually much more space than we need, but it's cheaper than
6235  * doing a separate malloc() for each word.
6236  */
6237  previous_words = (char **) pg_malloc(point * sizeof(char *));
6238  *buffer = outptr = (char *) pg_malloc(point * 2);
6239 
6240  /*
6241  * First we look for a non-word char before the current point. (This is
6242  * probably useless, if readline is on the same page as we are about what
6243  * is a word, but if so it's cheap.)
6244  */
6245  for (i = point - 1; i >= 0; i--)
6246  {
6247  if (strchr(WORD_BREAKS, buf[i]))
6248  break;
6249  }
6250  point = i;
6251 
6252  /*
6253  * Now parse words, working backwards, until we hit start of line. The
6254  * backwards scan has some interesting but intentional properties
6255  * concerning parenthesis handling.
6256  */
6257  while (point >= 0)
6258  {
6259  int start,
6260  end;
6261  bool inquotes = false;
6262  int parentheses = 0;
6263 
6264  /* now find the first non-space which then constitutes the end */
6265  end = -1;
6266  for (i = point; i >= 0; i--)
6267  {
6268  if (!isspace((unsigned char) buf[i]))
6269  {
6270  end = i;
6271  break;
6272  }
6273  }
6274  /* if no end found, we're done */
6275  if (end < 0)
6276  break;
6277 
6278  /*
6279  * Otherwise we now look for the start. The start is either the last
6280  * character before any word-break character going backwards from the
6281  * end, or it's simply character 0. We also handle open quotes and
6282  * parentheses.
6283  */
6284  for (start = end; start > 0; start--)
6285  {
6286  if (buf[start] == '"')
6287  inquotes = !inquotes;
6288  if (!inquotes)
6289  {
6290  if (buf[start] == ')')
6291  parentheses++;
6292  else if (buf[start] == '(')
6293  {
6294  if (--parentheses <= 0)
6295  break;
6296  }
6297  else if (parentheses == 0 &&
6298  strchr(WORD_BREAKS, buf[start - 1]))
6299  break;
6300  }
6301  }
6302 
6303  /* Return the word located at start to end inclusive */
6304  previous_words[words_found++] = outptr;
6305  i = end - start + 1;
6306  memcpy(outptr, &buf[start], i);
6307  outptr += i;
6308  *outptr++ = '\0';
6309 
6310  /* Continue searching */
6311  point = start - 1;
6312  }
6313 
6314  /* Release parsing input workspace, if we made one above */
6315  if (buf != rl_line_buffer)
6316  free(buf);
6317 
6318  *nwords = words_found;
6319  return previous_words;
6320 }
6321 
6322 /*
6323  * Look up the type for the GUC variable with the passed name.
6324  *
6325  * Returns NULL if the variable is unknown. Otherwise the returned string,
6326  * containing the type, has to be freed.
6327  */
6328 static char *
6329 get_guctype(const char *varname)
6330 {
6331  PQExpBufferData query_buffer;
6332  char *e_varname;
6333  PGresult *result;
6334  char *guctype = NULL;
6335 
6336  e_varname = escape_string(varname);
6337 
6338  initPQExpBuffer(&query_buffer);
6339  appendPQExpBuffer(&query_buffer,
6340  "SELECT vartype FROM pg_catalog.pg_settings "
6341  "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
6342  e_varname);
6343 
6344  result = exec_query(query_buffer.data);
6345  termPQExpBuffer(&query_buffer);
6346  free(e_varname);
6347 
6348  if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
6349  guctype = pg_strdup(PQgetvalue(result, 0, 0));
6350 
6351  PQclear(result);
6352 
6353  return guctype;
6354 }
6355 
6356 #ifdef USE_FILENAME_QUOTING_FUNCTIONS
6357 
6358 /*
6359  * Quote a filename according to SQL rules, returning a malloc'd string.
6360  * completion_charp must point to escape character or '\0', and
6361  * completion_force_quote must be set correctly, as per comments for
6362  * complete_from_files().
6363  */
6364 static char *
6365 quote_file_name(char *fname, int match_type, char *quote_pointer)
6366 {
6367  char *s;
6368  struct stat statbuf;
6369 
6370  /* Quote if needed. */
6371  s = quote_if_needed(fname, " \t\r\n\"`",
6372  '\'', *completion_charp,
6373  completion_force_quote,
6374  pset.encoding);
6375  if (!s)
6376  s = pg_strdup(fname);
6377 
6378  /*
6379  * However, some of the time we have to strip the trailing quote from what
6380  * we send back. Never strip the trailing quote if the user already typed
6381  * one; otherwise, suppress the trailing quote if we have multiple/no
6382  * matches (because we don't want to add a quote if the input is seemingly
6383  * unfinished), or if the input was already quoted (because Readline will
6384  * do arguably-buggy things otherwise), or if the file does not exist, or
6385  * if it's a directory.
6386  */
6387  if (*s == '\'' &&
6388  completion_last_char != '\'' &&
6389  (match_type != SINGLE_MATCH ||
6390  (quote_pointer && *quote_pointer == '\'') ||
6391  stat(fname, &statbuf) != 0 ||
6392  S_ISDIR(statbuf.st_mode)))
6393  {
6394  char *send = s + strlen(s) - 1;
6395 
6396  Assert(*send == '\'');
6397  *send = '\0';
6398  }
6399 
6400  /*
6401  * And now we can let Readline do its thing with possibly adding a quote
6402  * on its own accord. (This covers some additional cases beyond those
6403  * dealt with above.)
6404  */
6405 #ifdef HAVE_RL_COMPLETION_SUPPRESS_QUOTE
6406  rl_completion_suppress_quote = 0;
6407 #endif
6408 
6409  /*
6410  * If user typed a leading quote character other than single quote (i.e.,
6411  * double quote), zap it, so that we replace it with the correct single
6412  * quote.
6413  */
6414  if (quote_pointer && *quote_pointer != '\'')
6415  *quote_pointer = '\0';
6416 
6417  return s;
6418 }
6419 
6420 /*
6421  * Dequote a filename, if it's quoted.
6422  * completion_charp must point to escape character or '\0', as per
6423  * comments for complete_from_files().
6424  */
6425 static char *
6426 dequote_file_name(char *fname, int quote_char)
6427 {
6428  char *unquoted_fname;
6429 
6430  /*
6431  * If quote_char is set, it's not included in "fname". We have to add it
6432  * or strtokx will not interpret the string correctly (notably, it won't
6433  * recognize escapes).
6434  */
6435  if (quote_char == '\'')
6436  {
6437  char *workspace = (char *) pg_malloc(strlen(fname) + 2);
6438 
6439  workspace[0] = quote_char;
6440  strcpy(workspace + 1, fname);
6441  unquoted_fname = strtokx(workspace, "", NULL, "'", *completion_charp,
6442  false, true, pset.encoding);
6443  free(workspace);
6444  }
6445  else
6446  unquoted_fname = strtokx(fname, "", NULL, "'", *completion_charp,
6447  false, true, pset.encoding);
6448 
6449  /* expect a NULL return for the empty string only */
6450  if (!unquoted_fname)
6451  {
6452  Assert(*fname == '\0');
6453  unquoted_fname = fname;
6454  }
6455 
6456  /* readline expects a malloc'd result that it is to free */
6457  return pg_strdup(unquoted_fname);
6458 }
6459 
6460 #endif /* USE_FILENAME_QUOTING_FUNCTIONS */
6461 
6462 #endif /* USE_READLINE */
bool recognized_connection_string(const char *connstr)
Definition: common.c:2437
struct varlena text
Definition: c.h:687
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1142
uint32 bits32
Definition: c.h:502
#define CppAsString2(x)
Definition: c.h:314
const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS]
Definition: keywords.c:29
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6948
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6895
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:4105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3371
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3441
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2224
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3836
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3861
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3449
int PQmblenBounded(const char *s, int encoding)
Definition: fe-misc.c:1187
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
#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:60
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:103
va_end(args)
Assert(fmt[strlen(fmt) - 1] !='\n')
va_start(args, fmt)
#define pg_log_error(...)
Definition: logging.h:106
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1694
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:674
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