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