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