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