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