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