2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2019, PostgreSQL Global Development Group
6 * src/bin/psql/tab-complete.c
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.
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:
24 * set disable-completion on
27 * See `man 3 readline' or `info readline' for the full details.
30 * - Quotes, parentheses, and other funny characters are not handled
31 * all that gracefully.
32 *----------------------------------------------------------------------
35 #include "postgres_fe.h"
36 #include "tab-complete.h"
39 /* If we don't have this, we might as well forget about the whole thing: */
44 #include "catalog/pg_class_d.h"
47 #include "pqexpbuffer.h"
50 #include "stringutils.h"
52 #ifdef HAVE_RL_FILENAME_COMPLETION_FUNCTION
53 #define filename_completion_function rl_filename_completion_function
55 /* missing in some header files */
56 extern char *filename_completion_function();
59 #ifdef HAVE_RL_COMPLETION_MATCHES
60 #define completion_matches rl_completion_matches
63 /* word break characters */
64 #define WORD_BREAKS "\t\n@$><=;|&{() "
67 * Since readline doesn't let us pass any state through to the tab completion
68 * callback, we have to use this global variable to let get_previous_words()
69 * get at the previous lines of the current command. Ick.
71 PQExpBuffer tab_completion_query_buf = NULL;
74 * In some situations, the query to find out what names are available to
75 * complete with must vary depending on server version. We handle this by
76 * storing a list of queries, each tagged with the minimum server version
77 * it will work for. Each list must be stored in descending server version
78 * order, so that the first satisfactory query is the one to use.
80 * When the query string is otherwise constant, an array of VersionedQuery
81 * suffices. Terminate the array with an entry having min_server_version = 0.
82 * That entry's query string can be a query that works in all supported older
83 * server versions, or NULL to give up and do no completion.
85 typedef struct VersionedQuery
87 int min_server_version;
92 * This struct is used to define "schema queries", which are custom-built
93 * to obtain possibly-schema-qualified names of database objects. There is
94 * enough similarity in the structure that we don't want to repeat it each
95 * time. So we put the components of each query into this struct and
96 * assemble them with the common boilerplate in _complete_from_query().
98 * As with VersionedQuery, we can use an array of these if the query details
99 * must vary across versions.
101 typedef struct SchemaQuery
104 * If not zero, minimum server version this struct applies to. If not
105 * zero, there should be a following struct with a smaller minimum server
106 * version; use catname == NULL in the last entry if we should do nothing.
108 int min_server_version;
111 * Name of catalog or catalogs to be queried, with alias, eg.
112 * "pg_catalog.pg_class c". Note that "pg_namespace n" will be added.
117 * Selection condition --- only rows meeting this condition are candidates
118 * to display. If catname mentions multiple tables, include the necessary
119 * join condition here. For example, this might look like "c.relkind = "
120 * CppAsString2(RELKIND_RELATION). Write NULL (not an empty string) if
123 const char *selcondition;
126 * Visibility condition --- which rows are visible without schema
127 * qualification? For example, "pg_catalog.pg_table_is_visible(c.oid)".
129 const char *viscondition;
132 * Namespace --- name of field to join to pg_namespace.oid. For example,
135 const char *namespace;
138 * Result --- the appropriately-quoted name to return, in the case of an
139 * unqualified name. For example, "pg_catalog.quote_ident(c.relname)".
144 * In some cases a different result must be used for qualified names.
145 * Enter that here, or write NULL if result can be used.
147 const char *qualresult;
151 /* Store maximum number of records we want from database queries
152 * (implemented via SELECT ... LIMIT xx).
154 static int completion_max_records;
157 * Communication variables set by COMPLETE_WITH_FOO macros and then used by
158 * the completion callback functions. Ugly but there is no better way.
160 static const char *completion_charp; /* to pass a string */
161 static const char *const *completion_charpp; /* to pass a list of strings */
162 static const char *completion_info_charp; /* to pass a second string */
163 static const char *completion_info_charp2; /* to pass a third string */
164 static const VersionedQuery *completion_vquery; /* to pass a VersionedQuery */
165 static const SchemaQuery *completion_squery; /* to pass a SchemaQuery */
166 static bool completion_case_sensitive; /* completion is case sensitive */
169 * A few macros to ease typing. You can use these to complete the given
171 * 1) The results from a query you pass it. (Perhaps one of those below?)
172 * We support both simple and versioned queries.
173 * 2) The results from a schema query you pass it.
174 * We support both simple and versioned schema queries.
175 * 3) The items from a null-pointer-terminated list (with or without
176 * case-sensitive comparison); if the list is constant you can build it
177 * with COMPLETE_WITH() or COMPLETE_WITH_CS().
178 * 4) The list of attributes of the given table (possibly schema-qualified).
179 * 5) The list of arguments to the given function (possibly schema-qualified).
181 #define COMPLETE_WITH_QUERY(query) \
183 completion_charp = query; \
184 matches = completion_matches(text, complete_from_query); \
187 #define COMPLETE_WITH_VERSIONED_QUERY(query) \
189 completion_vquery = query; \
190 matches = completion_matches(text, complete_from_versioned_query); \
193 #define COMPLETE_WITH_SCHEMA_QUERY(query, addon) \
195 completion_squery = &(query); \
196 completion_charp = addon; \
197 matches = completion_matches(text, complete_from_schema_query); \
200 #define COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(query, addon) \
202 completion_squery = query; \
203 completion_vquery = addon; \
204 matches = completion_matches(text, complete_from_versioned_schema_query); \
207 #define COMPLETE_WITH_LIST_INT(cs, list) \
209 completion_case_sensitive = (cs); \
212 completion_charp = (list)[0]; \
213 matches = completion_matches(text, complete_from_const); \
217 completion_charpp = (list); \
218 matches = completion_matches(text, complete_from_list); \
222 #define COMPLETE_WITH_LIST(list) COMPLETE_WITH_LIST_INT(false, list)
223 #define COMPLETE_WITH_LIST_CS(list) COMPLETE_WITH_LIST_INT(true, list)
225 #define COMPLETE_WITH(...) \
227 static const char *const list[] = { __VA_ARGS__, NULL }; \
228 COMPLETE_WITH_LIST(list); \
231 #define COMPLETE_WITH_CS(...) \
233 static const char *const list[] = { __VA_ARGS__, NULL }; \
234 COMPLETE_WITH_LIST_CS(list); \
237 #define COMPLETE_WITH_ATTR(relation, addon) \
239 char *_completion_schema; \
240 char *_completion_table; \
242 _completion_schema = strtokx(relation, " \t\n\r", ".", "\"", 0, \
243 false, false, pset.encoding); \
244 (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
245 false, false, pset.encoding); \
246 _completion_table = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
247 false, false, pset.encoding); \
248 if (_completion_table == NULL) \
250 completion_charp = Query_for_list_of_attributes addon; \
251 completion_info_charp = relation; \
255 completion_charp = Query_for_list_of_attributes_with_schema addon; \
256 completion_info_charp = _completion_table; \
257 completion_info_charp2 = _completion_schema; \
259 matches = completion_matches(text, complete_from_query); \
262 #define COMPLETE_WITH_ENUM_VALUE(type) \
264 char *_completion_schema; \
265 char *_completion_type; \
267 _completion_schema = strtokx(type, " \t\n\r", ".", "\"", 0, \
268 false, false, pset.encoding); \
269 (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
270 false, false, pset.encoding); \
271 _completion_type = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
272 false, false, pset.encoding); \
273 if (_completion_type == NULL)\
275 completion_charp = Query_for_list_of_enum_values; \
276 completion_info_charp = type; \
280 completion_charp = Query_for_list_of_enum_values_with_schema; \
281 completion_info_charp = _completion_type; \
282 completion_info_charp2 = _completion_schema; \
284 matches = completion_matches(text, complete_from_query); \
287 #define COMPLETE_WITH_FUNCTION_ARG(function) \
289 char *_completion_schema; \
290 char *_completion_function; \
292 _completion_schema = strtokx(function, " \t\n\r", ".", "\"", 0, \
293 false, false, pset.encoding); \
294 (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
295 false, false, pset.encoding); \
296 _completion_function = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
297 false, false, pset.encoding); \
298 if (_completion_function == NULL) \
300 completion_charp = Query_for_list_of_arguments; \
301 completion_info_charp = function; \
305 completion_charp = Query_for_list_of_arguments_with_schema; \
306 completion_info_charp = _completion_function; \
307 completion_info_charp2 = _completion_schema; \
309 matches = completion_matches(text, complete_from_query); \
313 * Assembly instructions for schema queries
316 static const SchemaQuery Query_for_list_of_aggregates[] = {
318 .min_server_version = 110000,
319 .catname = "pg_catalog.pg_proc p",
320 .selcondition = "p.prokind = 'a'",
321 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
322 .namespace = "p.pronamespace",
323 .result = "pg_catalog.quote_ident(p.proname)",
326 .catname = "pg_catalog.pg_proc p",
327 .selcondition = "p.proisagg",
328 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
329 .namespace = "p.pronamespace",
330 .result = "pg_catalog.quote_ident(p.proname)",
334 static const SchemaQuery Query_for_list_of_datatypes = {
335 .catname = "pg_catalog.pg_type t",
336 /* selcondition --- ignore table rowtypes and array types */
337 .selcondition = "(t.typrelid = 0 "
338 " OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
339 " FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) "
340 "AND t.typname !~ '^_'",
341 .viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
342 .namespace = "t.typnamespace",
343 .result = "pg_catalog.format_type(t.oid, NULL)",
344 .qualresult = "pg_catalog.quote_ident(t.typname)",
347 static const SchemaQuery Query_for_list_of_composite_datatypes = {
348 .catname = "pg_catalog.pg_type t",
349 /* selcondition --- only get composite types */
350 .selcondition = "(SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
351 " FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid) "
352 "AND t.typname !~ '^_'",
353 .viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
354 .namespace = "t.typnamespace",
355 .result = "pg_catalog.format_type(t.oid, NULL)",
356 .qualresult = "pg_catalog.quote_ident(t.typname)",
359 static const SchemaQuery Query_for_list_of_domains = {
360 .catname = "pg_catalog.pg_type t",
361 .selcondition = "t.typtype = 'd'",
362 .viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
363 .namespace = "t.typnamespace",
364 .result = "pg_catalog.quote_ident(t.typname)",
367 /* Note: this intentionally accepts aggregates as well as plain functions */
368 static const SchemaQuery Query_for_list_of_functions[] = {
370 .min_server_version = 110000,
371 .catname = "pg_catalog.pg_proc p",
372 .selcondition = "p.prokind != 'p'",
373 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
374 .namespace = "p.pronamespace",
375 .result = "pg_catalog.quote_ident(p.proname)",
378 .catname = "pg_catalog.pg_proc p",
379 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
380 .namespace = "p.pronamespace",
381 .result = "pg_catalog.quote_ident(p.proname)",
385 static const SchemaQuery Query_for_list_of_procedures[] = {
387 .min_server_version = 110000,
388 .catname = "pg_catalog.pg_proc p",
389 .selcondition = "p.prokind = 'p'",
390 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
391 .namespace = "p.pronamespace",
392 .result = "pg_catalog.quote_ident(p.proname)",
395 /* not supported in older versions */
400 static const SchemaQuery Query_for_list_of_routines = {
401 .catname = "pg_catalog.pg_proc p",
402 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
403 .namespace = "p.pronamespace",
404 .result = "pg_catalog.quote_ident(p.proname)",
407 static const SchemaQuery Query_for_list_of_sequences = {
408 .catname = "pg_catalog.pg_class c",
409 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_SEQUENCE) ")",
410 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
411 .namespace = "c.relnamespace",
412 .result = "pg_catalog.quote_ident(c.relname)",
415 static const SchemaQuery Query_for_list_of_foreign_tables = {
416 .catname = "pg_catalog.pg_class c",
417 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_FOREIGN_TABLE) ")",
418 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
419 .namespace = "c.relnamespace",
420 .result = "pg_catalog.quote_ident(c.relname)",
423 static const SchemaQuery Query_for_list_of_tables = {
424 .catname = "pg_catalog.pg_class c",
426 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
427 CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
428 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
429 .namespace = "c.relnamespace",
430 .result = "pg_catalog.quote_ident(c.relname)",
433 static const SchemaQuery Query_for_list_of_partitioned_tables = {
434 .catname = "pg_catalog.pg_class c",
435 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
436 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
437 .namespace = "c.relnamespace",
438 .result = "pg_catalog.quote_ident(c.relname)",
441 static const SchemaQuery Query_for_list_of_views = {
442 .catname = "pg_catalog.pg_class c",
443 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_VIEW) ")",
444 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
445 .namespace = "c.relnamespace",
446 .result = "pg_catalog.quote_ident(c.relname)",
449 static const SchemaQuery Query_for_list_of_matviews = {
450 .catname = "pg_catalog.pg_class c",
451 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_MATVIEW) ")",
452 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
453 .namespace = "c.relnamespace",
454 .result = "pg_catalog.quote_ident(c.relname)",
457 static const SchemaQuery Query_for_list_of_indexes = {
458 .catname = "pg_catalog.pg_class c",
460 "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", "
461 CppAsString2(RELKIND_PARTITIONED_INDEX) ")",
462 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
463 .namespace = "c.relnamespace",
464 .result = "pg_catalog.quote_ident(c.relname)",
468 static const SchemaQuery Query_for_list_of_relations = {
469 .catname = "pg_catalog.pg_class c",
470 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
471 .namespace = "c.relnamespace",
472 .result = "pg_catalog.quote_ident(c.relname)",
475 /* Relations supporting INSERT, UPDATE or DELETE */
476 static const SchemaQuery Query_for_list_of_updatables = {
477 .catname = "pg_catalog.pg_class c",
479 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
480 CppAsString2(RELKIND_FOREIGN_TABLE) ", "
481 CppAsString2(RELKIND_VIEW) ", "
482 CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
483 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
484 .namespace = "c.relnamespace",
485 .result = "pg_catalog.quote_ident(c.relname)",
488 /* Relations supporting SELECT */
489 static const SchemaQuery Query_for_list_of_selectables = {
490 .catname = "pg_catalog.pg_class c",
492 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
493 CppAsString2(RELKIND_SEQUENCE) ", "
494 CppAsString2(RELKIND_VIEW) ", "
495 CppAsString2(RELKIND_MATVIEW) ", "
496 CppAsString2(RELKIND_FOREIGN_TABLE) ", "
497 CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
498 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
499 .namespace = "c.relnamespace",
500 .result = "pg_catalog.quote_ident(c.relname)",
503 /* Relations supporting GRANT are currently same as those supporting SELECT */
504 #define Query_for_list_of_grantables Query_for_list_of_selectables
506 /* Relations supporting ANALYZE */
507 static const SchemaQuery Query_for_list_of_analyzables = {
508 .catname = "pg_catalog.pg_class c",
510 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
511 CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
512 CppAsString2(RELKIND_MATVIEW) ", "
513 CppAsString2(RELKIND_FOREIGN_TABLE) ")",
514 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
515 .namespace = "c.relnamespace",
516 .result = "pg_catalog.quote_ident(c.relname)",
519 /* Relations supporting index creation */
520 static const SchemaQuery Query_for_list_of_indexables = {
521 .catname = "pg_catalog.pg_class c",
523 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
524 CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
525 CppAsString2(RELKIND_MATVIEW) ")",
526 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
527 .namespace = "c.relnamespace",
528 .result = "pg_catalog.quote_ident(c.relname)",
531 /* Relations supporting VACUUM */
532 static const SchemaQuery Query_for_list_of_vacuumables = {
533 .catname = "pg_catalog.pg_class c",
535 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
536 CppAsString2(RELKIND_MATVIEW) ")",
537 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
538 .namespace = "c.relnamespace",
539 .result = "pg_catalog.quote_ident(c.relname)",
542 /* Relations supporting CLUSTER are currently same as those supporting VACUUM */
543 #define Query_for_list_of_clusterables Query_for_list_of_vacuumables
545 static const SchemaQuery Query_for_list_of_constraints_with_schema = {
546 .catname = "pg_catalog.pg_constraint c",
547 .selcondition = "c.conrelid <> 0",
548 .viscondition = "true", /* there is no pg_constraint_is_visible */
549 .namespace = "c.connamespace",
550 .result = "pg_catalog.quote_ident(c.conname)",
553 static const SchemaQuery Query_for_list_of_statistics = {
554 .catname = "pg_catalog.pg_statistic_ext s",
555 .viscondition = "pg_catalog.pg_statistics_obj_is_visible(s.oid)",
556 .namespace = "s.stxnamespace",
557 .result = "pg_catalog.quote_ident(s.stxname)",
562 * Queries to get lists of names of various kinds of things, possibly
563 * restricted to names matching a partially entered name. In these queries,
564 * the first %s will be replaced by the text entered so far (suitably escaped
565 * to become a SQL literal string). %d will be replaced by the length of the
566 * string (in unescaped form). A second and third %s, if present, will be
567 * replaced by a suitably-escaped version of the string provided in
568 * completion_info_charp. A fourth and fifth %s are similarly replaced by
569 * completion_info_charp2.
571 * Beware that the allowed sequences of %s and %d are determined by
572 * _complete_from_query().
575 #define Query_for_list_of_attributes \
576 "SELECT pg_catalog.quote_ident(attname) "\
577 " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\
578 " WHERE c.oid = a.attrelid "\
579 " AND a.attnum > 0 "\
580 " AND NOT a.attisdropped "\
581 " AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\
582 " AND (pg_catalog.quote_ident(relname)='%s' "\
583 " OR '\"' || relname || '\"'='%s') "\
584 " AND pg_catalog.pg_table_is_visible(c.oid)"
586 #define Query_for_list_of_attribute_numbers \
588 " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\
589 " WHERE c.oid = a.attrelid "\
590 " AND a.attnum > 0 "\
591 " AND NOT a.attisdropped "\
592 " AND substring(attnum::pg_catalog.text,1,%d)='%s' "\
593 " AND (pg_catalog.quote_ident(relname)='%s' "\
594 " OR '\"' || relname || '\"'='%s') "\
595 " AND pg_catalog.pg_table_is_visible(c.oid)"
597 #define Query_for_list_of_attributes_with_schema \
598 "SELECT pg_catalog.quote_ident(attname) "\
599 " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c, pg_catalog.pg_namespace n "\
600 " WHERE c.oid = a.attrelid "\
601 " AND n.oid = c.relnamespace "\
602 " AND a.attnum > 0 "\
603 " AND NOT a.attisdropped "\
604 " AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\
605 " AND (pg_catalog.quote_ident(relname)='%s' "\
606 " OR '\"' || relname || '\"' ='%s') "\
607 " AND (pg_catalog.quote_ident(nspname)='%s' "\
608 " OR '\"' || nspname || '\"' ='%s') "
610 #define Query_for_list_of_enum_values \
611 "SELECT pg_catalog.quote_literal(enumlabel) "\
612 " FROM pg_catalog.pg_enum e, pg_catalog.pg_type t "\
613 " WHERE t.oid = e.enumtypid "\
614 " AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
615 " AND (pg_catalog.quote_ident(typname)='%s' "\
616 " OR '\"' || typname || '\"'='%s') "\
617 " AND pg_catalog.pg_type_is_visible(t.oid)"
619 #define Query_for_list_of_enum_values_with_schema \
620 "SELECT pg_catalog.quote_literal(enumlabel) "\
621 " FROM pg_catalog.pg_enum e, pg_catalog.pg_type t, pg_catalog.pg_namespace n "\
622 " WHERE t.oid = e.enumtypid "\
623 " AND n.oid = t.typnamespace "\
624 " AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
625 " AND (pg_catalog.quote_ident(typname)='%s' "\
626 " OR '\"' || typname || '\"'='%s') "\
627 " AND (pg_catalog.quote_ident(nspname)='%s' "\
628 " OR '\"' || nspname || '\"' ='%s') "
630 #define Query_for_list_of_template_databases \
631 "SELECT pg_catalog.quote_ident(d.datname) "\
632 " FROM pg_catalog.pg_database d "\
633 " WHERE substring(pg_catalog.quote_ident(d.datname),1,%d)='%s' "\
634 " AND (d.datistemplate OR pg_catalog.pg_has_role(d.datdba, 'USAGE'))"
636 #define Query_for_list_of_databases \
637 "SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\
638 " WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'"
640 #define Query_for_list_of_tablespaces \
641 "SELECT pg_catalog.quote_ident(spcname) FROM pg_catalog.pg_tablespace "\
642 " WHERE substring(pg_catalog.quote_ident(spcname),1,%d)='%s'"
644 #define Query_for_list_of_encodings \
645 " SELECT DISTINCT pg_catalog.pg_encoding_to_char(conforencoding) "\
646 " FROM pg_catalog.pg_conversion "\
647 " WHERE substring(pg_catalog.pg_encoding_to_char(conforencoding),1,%d)=UPPER('%s')"
649 #define Query_for_list_of_languages \
650 "SELECT pg_catalog.quote_ident(lanname) "\
651 " FROM pg_catalog.pg_language "\
652 " WHERE lanname != 'internal' "\
653 " AND substring(pg_catalog.quote_ident(lanname),1,%d)='%s'"
655 #define Query_for_list_of_schemas \
656 "SELECT pg_catalog.quote_ident(nspname) FROM pg_catalog.pg_namespace "\
657 " WHERE substring(pg_catalog.quote_ident(nspname),1,%d)='%s'"
659 #define Query_for_list_of_alter_system_set_vars \
661 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
662 " WHERE context != 'internal' "\
663 " UNION ALL SELECT 'all') ss "\
664 " WHERE substring(name,1,%d)='%s'"
666 #define Query_for_list_of_set_vars \
668 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
669 " WHERE context IN ('user', 'superuser') "\
670 " UNION ALL SELECT 'constraints' "\
671 " UNION ALL SELECT 'transaction' "\
672 " UNION ALL SELECT 'session' "\
673 " UNION ALL SELECT 'role' "\
674 " UNION ALL SELECT 'tablespace' "\
675 " UNION ALL SELECT 'all') ss "\
676 " WHERE substring(name,1,%d)='%s'"
678 #define Query_for_list_of_show_vars \
680 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
681 " UNION ALL SELECT 'session authorization' "\
682 " UNION ALL SELECT 'all') ss "\
683 " WHERE substring(name,1,%d)='%s'"
685 #define Query_for_list_of_roles \
686 " SELECT pg_catalog.quote_ident(rolname) "\
687 " FROM pg_catalog.pg_roles "\
688 " WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"
690 #define Query_for_list_of_grant_roles \
691 " SELECT pg_catalog.quote_ident(rolname) "\
692 " FROM pg_catalog.pg_roles "\
693 " WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\
694 " UNION ALL SELECT 'PUBLIC'"\
695 " UNION ALL SELECT 'CURRENT_USER'"\
696 " UNION ALL SELECT 'SESSION_USER'"
698 /* the silly-looking length condition is just to eat up the current word */
699 #define Query_for_index_of_table \
700 "SELECT pg_catalog.quote_ident(c2.relname) "\
701 " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
702 " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
703 " and (%d = pg_catalog.length('%s'))"\
704 " and pg_catalog.quote_ident(c1.relname)='%s'"\
705 " and pg_catalog.pg_table_is_visible(c2.oid)"
707 /* the silly-looking length condition is just to eat up the current word */
708 #define Query_for_constraint_of_table \
709 "SELECT pg_catalog.quote_ident(conname) "\
710 " FROM pg_catalog.pg_class c1, pg_catalog.pg_constraint con "\
711 " WHERE c1.oid=conrelid and (%d = pg_catalog.length('%s'))"\
712 " and pg_catalog.quote_ident(c1.relname)='%s'"\
713 " and pg_catalog.pg_table_is_visible(c1.oid)"
715 #define Query_for_all_table_constraints \
716 "SELECT pg_catalog.quote_ident(conname) "\
717 " FROM pg_catalog.pg_constraint c "\
718 " WHERE c.conrelid <> 0 "
720 /* the silly-looking length condition is just to eat up the current word */
721 #define Query_for_constraint_of_type \
722 "SELECT pg_catalog.quote_ident(conname) "\
723 " FROM pg_catalog.pg_type t, pg_catalog.pg_constraint con "\
724 " WHERE t.oid=contypid and (%d = pg_catalog.length('%s'))"\
725 " and pg_catalog.quote_ident(t.typname)='%s'"\
726 " and pg_catalog.pg_type_is_visible(t.oid)"
728 /* the silly-looking length condition is just to eat up the current word */
729 #define Query_for_list_of_tables_for_constraint \
730 "SELECT pg_catalog.quote_ident(relname) "\
731 " FROM pg_catalog.pg_class"\
732 " WHERE (%d = pg_catalog.length('%s'))"\
734 " (SELECT conrelid FROM pg_catalog.pg_constraint "\
735 " WHERE pg_catalog.quote_ident(conname)='%s')"
737 /* the silly-looking length condition is just to eat up the current word */
738 #define Query_for_rule_of_table \
739 "SELECT pg_catalog.quote_ident(rulename) "\
740 " FROM pg_catalog.pg_class c1, pg_catalog.pg_rewrite "\
741 " WHERE c1.oid=ev_class and (%d = pg_catalog.length('%s'))"\
742 " and pg_catalog.quote_ident(c1.relname)='%s'"\
743 " and pg_catalog.pg_table_is_visible(c1.oid)"
745 /* the silly-looking length condition is just to eat up the current word */
746 #define Query_for_list_of_tables_for_rule \
747 "SELECT pg_catalog.quote_ident(relname) "\
748 " FROM pg_catalog.pg_class"\
749 " WHERE (%d = pg_catalog.length('%s'))"\
751 " (SELECT ev_class FROM pg_catalog.pg_rewrite "\
752 " WHERE pg_catalog.quote_ident(rulename)='%s')"
754 /* the silly-looking length condition is just to eat up the current word */
755 #define Query_for_trigger_of_table \
756 "SELECT pg_catalog.quote_ident(tgname) "\
757 " FROM pg_catalog.pg_class c1, pg_catalog.pg_trigger "\
758 " WHERE c1.oid=tgrelid and (%d = pg_catalog.length('%s'))"\
759 " and pg_catalog.quote_ident(c1.relname)='%s'"\
760 " and pg_catalog.pg_table_is_visible(c1.oid)"\
761 " and not tgisinternal"
763 /* the silly-looking length condition is just to eat up the current word */
764 #define Query_for_list_of_tables_for_trigger \
765 "SELECT pg_catalog.quote_ident(relname) "\
766 " FROM pg_catalog.pg_class"\
767 " WHERE (%d = pg_catalog.length('%s'))"\
769 " (SELECT tgrelid FROM pg_catalog.pg_trigger "\
770 " WHERE pg_catalog.quote_ident(tgname)='%s')"
772 #define Query_for_list_of_ts_configurations \
773 "SELECT pg_catalog.quote_ident(cfgname) FROM pg_catalog.pg_ts_config "\
774 " WHERE substring(pg_catalog.quote_ident(cfgname),1,%d)='%s'"
776 #define Query_for_list_of_ts_dictionaries \
777 "SELECT pg_catalog.quote_ident(dictname) FROM pg_catalog.pg_ts_dict "\
778 " WHERE substring(pg_catalog.quote_ident(dictname),1,%d)='%s'"
780 #define Query_for_list_of_ts_parsers \
781 "SELECT pg_catalog.quote_ident(prsname) FROM pg_catalog.pg_ts_parser "\
782 " WHERE substring(pg_catalog.quote_ident(prsname),1,%d)='%s'"
784 #define Query_for_list_of_ts_templates \
785 "SELECT pg_catalog.quote_ident(tmplname) FROM pg_catalog.pg_ts_template "\
786 " WHERE substring(pg_catalog.quote_ident(tmplname),1,%d)='%s'"
788 #define Query_for_list_of_fdws \
789 " SELECT pg_catalog.quote_ident(fdwname) "\
790 " FROM pg_catalog.pg_foreign_data_wrapper "\
791 " WHERE substring(pg_catalog.quote_ident(fdwname),1,%d)='%s'"
793 #define Query_for_list_of_servers \
794 " SELECT pg_catalog.quote_ident(srvname) "\
795 " FROM pg_catalog.pg_foreign_server "\
796 " WHERE substring(pg_catalog.quote_ident(srvname),1,%d)='%s'"
798 #define Query_for_list_of_user_mappings \
799 " SELECT pg_catalog.quote_ident(usename) "\
800 " FROM pg_catalog.pg_user_mappings "\
801 " WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'"
803 #define Query_for_list_of_access_methods \
804 " SELECT pg_catalog.quote_ident(amname) "\
805 " FROM pg_catalog.pg_am "\
806 " WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'"
808 /* the silly-looking length condition is just to eat up the current word */
809 #define Query_for_list_of_arguments \
810 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
811 " FROM pg_catalog.pg_proc "\
812 " WHERE (%d = pg_catalog.length('%s'))"\
813 " AND (pg_catalog.quote_ident(proname)='%s'"\
814 " OR '\"' || proname || '\"'='%s') "\
815 " AND (pg_catalog.pg_function_is_visible(pg_proc.oid))"
817 /* the silly-looking length condition is just to eat up the current word */
818 #define Query_for_list_of_arguments_with_schema \
819 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
820 " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "\
821 " WHERE (%d = pg_catalog.length('%s'))"\
822 " AND n.oid = p.pronamespace "\
823 " AND (pg_catalog.quote_ident(proname)='%s' "\
824 " OR '\"' || proname || '\"' ='%s') "\
825 " AND (pg_catalog.quote_ident(nspname)='%s' "\
826 " OR '\"' || nspname || '\"' ='%s') "
828 #define Query_for_list_of_extensions \
829 " SELECT pg_catalog.quote_ident(extname) "\
830 " FROM pg_catalog.pg_extension "\
831 " WHERE substring(pg_catalog.quote_ident(extname),1,%d)='%s'"
833 #define Query_for_list_of_available_extensions \
834 " SELECT pg_catalog.quote_ident(name) "\
835 " FROM pg_catalog.pg_available_extensions "\
836 " WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s' AND installed_version IS NULL"
838 /* the silly-looking length condition is just to eat up the current word */
839 #define Query_for_list_of_available_extension_versions \
840 " SELECT pg_catalog.quote_ident(version) "\
841 " FROM pg_catalog.pg_available_extension_versions "\
842 " WHERE (%d = pg_catalog.length('%s'))"\
843 " AND pg_catalog.quote_ident(name)='%s'"
845 /* the silly-looking length condition is just to eat up the current word */
846 #define Query_for_list_of_available_extension_versions_with_TO \
847 " SELECT 'TO ' || pg_catalog.quote_ident(version) "\
848 " FROM pg_catalog.pg_available_extension_versions "\
849 " WHERE (%d = pg_catalog.length('%s'))"\
850 " AND pg_catalog.quote_ident(name)='%s'"
852 #define Query_for_list_of_prepared_statements \
853 " SELECT pg_catalog.quote_ident(name) "\
854 " FROM pg_catalog.pg_prepared_statements "\
855 " WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s'"
857 #define Query_for_list_of_event_triggers \
858 " SELECT pg_catalog.quote_ident(evtname) "\
859 " FROM pg_catalog.pg_event_trigger "\
860 " WHERE substring(pg_catalog.quote_ident(evtname),1,%d)='%s'"
862 #define Query_for_list_of_tablesample_methods \
863 " SELECT pg_catalog.quote_ident(proname) "\
864 " FROM pg_catalog.pg_proc "\
865 " WHERE prorettype = 'pg_catalog.tsm_handler'::pg_catalog.regtype AND "\
866 " proargtypes[0] = 'pg_catalog.internal'::pg_catalog.regtype AND "\
867 " substring(pg_catalog.quote_ident(proname),1,%d)='%s'"
869 #define Query_for_list_of_policies \
870 " SELECT pg_catalog.quote_ident(polname) "\
871 " FROM pg_catalog.pg_policy "\
872 " WHERE substring(pg_catalog.quote_ident(polname),1,%d)='%s'"
874 #define Query_for_list_of_tables_for_policy \
875 "SELECT pg_catalog.quote_ident(relname) "\
876 " FROM pg_catalog.pg_class"\
877 " WHERE (%d = pg_catalog.length('%s'))"\
879 " (SELECT polrelid FROM pg_catalog.pg_policy "\
880 " WHERE pg_catalog.quote_ident(polname)='%s')"
882 #define Query_for_enum \
883 " SELECT name FROM ( "\
884 " SELECT pg_catalog.quote_ident(pg_catalog.unnest(enumvals)) AS name "\
885 " FROM pg_catalog.pg_settings "\
886 " WHERE pg_catalog.lower(name)=pg_catalog.lower('%s') "\
888 " SELECT 'DEFAULT' ) ss "\
889 " WHERE pg_catalog.substring(name,1,%%d)='%%s'"
891 /* the silly-looking length condition is just to eat up the current word */
892 #define Query_for_partition_of_table \
893 "SELECT pg_catalog.quote_ident(c2.relname) "\
894 " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_inherits i"\
895 " WHERE c1.oid=i.inhparent and i.inhrelid=c2.oid"\
896 " and (%d = pg_catalog.length('%s'))"\
897 " and pg_catalog.quote_ident(c1.relname)='%s'"\
898 " and pg_catalog.pg_table_is_visible(c2.oid)"\
899 " and c2.relispartition = 'true'"
902 * These object types were introduced later than our support cutoff of
903 * server version 7.4. We use the VersionedQuery infrastructure so that
904 * we don't send certain-to-fail queries to older servers.
907 static const VersionedQuery Query_for_list_of_publications[] = {
909 " SELECT pg_catalog.quote_ident(pubname) "
910 " FROM pg_catalog.pg_publication "
911 " WHERE substring(pg_catalog.quote_ident(pubname),1,%d)='%s'"
916 static const VersionedQuery Query_for_list_of_subscriptions[] = {
918 " SELECT pg_catalog.quote_ident(s.subname) "
919 " FROM pg_catalog.pg_subscription s, pg_catalog.pg_database d "
920 " WHERE substring(pg_catalog.quote_ident(s.subname),1,%d)='%s' "
921 " AND d.datname = pg_catalog.current_database() "
922 " AND s.subdbid = d.oid"
928 * This is a list of all "things" in Pgsql, which can show up after CREATE or
929 * DROP; and there is also a query to get a list of them.
935 const char *query; /* simple query, or NULL */
936 const VersionedQuery *vquery; /* versioned query, or NULL */
937 const SchemaQuery *squery; /* schema query, or NULL */
938 const bits32 flags; /* visibility flags, see below */
941 #define THING_NO_CREATE (1 << 0) /* should not show up after CREATE */
942 #define THING_NO_DROP (1 << 1) /* should not show up after DROP */
943 #define THING_NO_ALTER (1 << 2) /* should not show up after ALTER */
944 #define THING_NO_SHOW (THING_NO_CREATE | THING_NO_DROP | THING_NO_ALTER)
946 static const pgsql_thing_t words_after_create[] = {
947 {"ACCESS METHOD", NULL, NULL, NULL, THING_NO_ALTER},
948 {"AGGREGATE", NULL, NULL, Query_for_list_of_aggregates},
949 {"CAST", NULL, NULL, NULL}, /* Casts have complex structures for names, so
951 {"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'"},
954 * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
955 * to be used only by pg_dump.
957 {"CONFIGURATION", Query_for_list_of_ts_configurations, NULL, NULL, THING_NO_SHOW},
958 {"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"},
959 {"DATABASE", Query_for_list_of_databases},
960 {"DEFAULT PRIVILEGES", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
961 {"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, NULL, THING_NO_SHOW},
962 {"DOMAIN", NULL, NULL, &Query_for_list_of_domains},
963 {"EVENT TRIGGER", NULL, NULL, NULL},
964 {"EXTENSION", Query_for_list_of_extensions},
965 {"FOREIGN DATA WRAPPER", NULL, NULL, NULL},
966 {"FOREIGN TABLE", NULL, NULL, NULL},
967 {"FUNCTION", NULL, NULL, Query_for_list_of_functions},
968 {"GROUP", Query_for_list_of_roles},
969 {"INDEX", NULL, NULL, &Query_for_list_of_indexes},
970 {"LANGUAGE", Query_for_list_of_languages},
971 {"LARGE OBJECT", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
972 {"MATERIALIZED VIEW", NULL, NULL, &Query_for_list_of_matviews},
973 {"OPERATOR", NULL, NULL, NULL}, /* Querying for this is probably not such
975 {"OWNED", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_ALTER}, /* for DROP OWNED BY ... */
976 {"PARSER", Query_for_list_of_ts_parsers, NULL, NULL, THING_NO_SHOW},
977 {"POLICY", NULL, NULL, NULL},
978 {"PROCEDURE", NULL, NULL, Query_for_list_of_procedures},
979 {"PUBLICATION", NULL, Query_for_list_of_publications},
980 {"ROLE", Query_for_list_of_roles},
981 {"ROUTINE", NULL, NULL, &Query_for_list_of_routines, THING_NO_CREATE},
982 {"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
983 {"SCHEMA", Query_for_list_of_schemas},
984 {"SEQUENCE", NULL, NULL, &Query_for_list_of_sequences},
985 {"SERVER", Query_for_list_of_servers},
986 {"STATISTICS", NULL, NULL, &Query_for_list_of_statistics},
987 {"SUBSCRIPTION", NULL, Query_for_list_of_subscriptions},
988 {"SYSTEM", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
989 {"TABLE", NULL, NULL, &Query_for_list_of_tables},
990 {"TABLESPACE", Query_for_list_of_tablespaces},
991 {"TEMP", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMP TABLE
993 {"TEMPLATE", Query_for_list_of_ts_templates, NULL, NULL, THING_NO_SHOW},
994 {"TEMPORARY", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMPORARY
996 {"TEXT SEARCH", NULL, NULL, NULL},
997 {"TRANSFORM", NULL, NULL, NULL},
998 {"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"},
999 {"TYPE", NULL, NULL, &Query_for_list_of_datatypes},
1000 {"UNIQUE", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNIQUE
1002 {"UNLOGGED", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNLOGGED
1004 {"USER", Query_for_list_of_roles " UNION SELECT 'MAPPING FOR'"},
1005 {"USER MAPPING FOR", NULL, NULL, NULL},
1006 {"VIEW", NULL, NULL, &Query_for_list_of_views},
1007 {NULL} /* end of list */
1010 /* Storage parameters for CREATE TABLE and ALTER TABLE */
1011 static const char *const table_storage_parameters[] = {
1012 "autovacuum_analyze_scale_factor",
1013 "autovacuum_analyze_threshold",
1014 "autovacuum_enabled",
1015 "autovacuum_freeze_max_age",
1016 "autovacuum_freeze_min_age",
1017 "autovacuum_freeze_table_age",
1018 "autovacuum_multixact_freeze_max_age",
1019 "autovacuum_multixact_freeze_min_age",
1020 "autovacuum_multixact_freeze_table_age",
1021 "autovacuum_vacuum_cost_delay",
1022 "autovacuum_vacuum_cost_limit",
1023 "autovacuum_vacuum_scale_factor",
1024 "autovacuum_vacuum_threshold",
1026 "log_autovacuum_min_duration",
1028 "toast.autovacuum_enabled",
1029 "toast.autovacuum_freeze_max_age",
1030 "toast.autovacuum_freeze_min_age",
1031 "toast.autovacuum_freeze_table_age",
1032 "toast.autovacuum_multixact_freeze_max_age",
1033 "toast.autovacuum_multixact_freeze_min_age",
1034 "toast.autovacuum_multixact_freeze_table_age",
1035 "toast.autovacuum_vacuum_cost_delay",
1036 "toast.autovacuum_vacuum_cost_limit",
1037 "toast.autovacuum_vacuum_scale_factor",
1038 "toast.autovacuum_vacuum_threshold",
1039 "toast.log_autovacuum_min_duration",
1040 "toast_tuple_target",
1041 "user_catalog_table",
1042 "vacuum_index_cleanup",
1047 /* Forward declaration of functions */
1048 static char **psql_completion(const char *text, int start, int end);
1049 static char *create_command_generator(const char *text, int state);
1050 static char *drop_command_generator(const char *text, int state);
1051 static char *alter_command_generator(const char *text, int state);
1052 static char *complete_from_query(const char *text, int state);
1053 static char *complete_from_versioned_query(const char *text, int state);
1054 static char *complete_from_schema_query(const char *text, int state);
1055 static char *complete_from_versioned_schema_query(const char *text, int state);
1056 static char *_complete_from_query(const char *simple_query,
1057 const SchemaQuery *schema_query,
1058 const char *text, int state);
1059 static char *complete_from_list(const char *text, int state);
1060 static char *complete_from_const(const char *text, int state);
1061 static void append_variable_names(char ***varnames, int *nvars,
1062 int *maxvars, const char *varname,
1063 const char *prefix, const char *suffix);
1064 static char **complete_from_variables(const char *text,
1065 const char *prefix, const char *suffix, bool need_value);
1066 static char *complete_from_files(const char *text, int state);
1068 static char *pg_strdup_keyword_case(const char *s, const char *ref);
1069 static char *escape_string(const char *text);
1070 static PGresult *exec_query(const char *query);
1072 static char **get_previous_words(int point, char **buffer, int *nwords);
1074 static char *get_guctype(const char *varname);
1077 static char *quote_file_name(char *text, int match_type, char *quote_pointer);
1078 static char *dequote_file_name(char *text, char quote_char);
1083 * Initialize the readline library for our purposes.
1086 initialize_readline(void)
1088 rl_readline_name = (char *) pset.progname;
1089 rl_attempted_completion_function = psql_completion;
1091 rl_basic_word_break_characters = WORD_BREAKS;
1093 completion_max_records = 1000;
1096 * There is a variable rl_completion_query_items for this but apparently
1097 * it's not defined everywhere.
1102 * Check if 'word' matches any of the '|'-separated strings in 'pattern',
1103 * using case-insensitive or case-sensitive comparisons.
1105 * If pattern is NULL, it's a wild card that matches any word.
1106 * If pattern begins with '!', the result is negated, ie we check that 'word'
1107 * does *not* match any alternative appearing in the rest of 'pattern'.
1108 * Any alternative can contain '*' which is a wild card, i.e., it can match
1109 * any substring; however, we allow at most one '*' per alternative.
1111 * For readability, callers should use the macros MatchAny and MatchAnyExcept
1112 * to invoke those two special cases for 'pattern'. (But '|' and '*' must
1113 * just be written directly in patterns.)
1115 #define MatchAny NULL
1116 #define MatchAnyExcept(pattern) ("!" pattern)
1119 word_matches(const char *pattern,
1121 bool case_sensitive)
1125 #define cimatch(s1, s2, n) \
1126 (case_sensitive ? strncmp(s1, s2, n) == 0 : pg_strncasecmp(s1, s2, n) == 0)
1128 /* NULL pattern matches anything. */
1129 if (pattern == NULL)
1132 /* Handle negated patterns from the MatchAnyExcept macro. */
1133 if (*pattern == '!')
1134 return !word_matches(pattern + 1, word, case_sensitive);
1136 /* Else consider each alternative in the pattern. */
1137 wordlen = strlen(word);
1140 const char *star = NULL;
1143 /* Find end of current alternative, and locate any wild card. */
1145 while (*c != '\0' && *c != '|')
1151 /* Was there a wild card? */
1154 /* Yes, wildcard match? */
1155 size_t beforelen = star - pattern,
1156 afterlen = c - star - 1;
1158 if (wordlen >= (beforelen + afterlen) &&
1159 cimatch(word, pattern, beforelen) &&
1160 cimatch(word + wordlen - afterlen, star + 1, afterlen))
1165 /* No, plain match? */
1166 if (wordlen == (c - pattern) &&
1167 cimatch(word, pattern, wordlen))
1170 /* Out of alternatives? */
1173 /* Nope, try next alternative. */
1181 * Implementation of TailMatches and TailMatchesCS macros: do the last N words
1182 * in previous_words match the variadic arguments?
1184 * The array indexing might look backwards, but remember that
1185 * previous_words[0] contains the *last* word on the line, not the first.
1188 TailMatchesImpl(bool case_sensitive,
1189 int previous_words_count, char **previous_words,
1194 if (previous_words_count < narg)
1197 va_start(args, narg);
1199 for (int argno = 0; argno < narg; argno++)
1201 const char *arg = va_arg(args, const char *);
1203 if (!word_matches(arg, previous_words[narg - argno - 1],
1217 * Implementation of Matches and MatchesCS macros: do all of the words
1218 * in previous_words match the variadic arguments?
1221 MatchesImpl(bool case_sensitive,
1222 int previous_words_count, char **previous_words,
1227 if (previous_words_count != narg)
1230 va_start(args, narg);
1232 for (int argno = 0; argno < narg; argno++)
1234 const char *arg = va_arg(args, const char *);
1236 if (!word_matches(arg, previous_words[narg - argno - 1],
1250 * Implementation of HeadMatches and HeadMatchesCS macros: do the first N
1251 * words in previous_words match the variadic arguments?
1254 HeadMatchesImpl(bool case_sensitive,
1255 int previous_words_count, char **previous_words,
1260 if (previous_words_count < narg)
1263 va_start(args, narg);
1265 for (int argno = 0; argno < narg; argno++)
1267 const char *arg = va_arg(args, const char *);
1269 if (!word_matches(arg, previous_words[previous_words_count - argno - 1],
1283 * Check if the final character of 's' is 'c'.
1286 ends_with(const char *s, char c)
1288 size_t length = strlen(s);
1290 return (length > 0 && s[length - 1] == c);
1294 * The completion function.
1296 * According to readline spec this gets passed the text entered so far and its
1297 * start and end positions in the readline buffer. The return value is some
1298 * partially obscure list format that can be generated by readline's
1299 * completion_matches() function, so we don't have to worry about it.
1302 psql_completion(const char *text, int start, int end)
1304 /* This is the variable we'll return. */
1305 char **matches = NULL;
1307 /* Workspace for parsed words. */
1310 /* This array will contain pointers to parsed words. */
1311 char **previous_words;
1313 /* The number of words found on the input line. */
1314 int previous_words_count;
1317 * For compactness, we use these macros to reference previous_words[].
1318 * Caution: do not access a previous_words[] entry without having checked
1319 * previous_words_count to be sure it's valid. In most cases below, that
1320 * check is implicit in a TailMatches() or similar macro, but in some
1321 * places we have to check it explicitly.
1323 #define prev_wd (previous_words[0])
1324 #define prev2_wd (previous_words[1])
1325 #define prev3_wd (previous_words[2])
1326 #define prev4_wd (previous_words[3])
1327 #define prev5_wd (previous_words[4])
1328 #define prev6_wd (previous_words[5])
1329 #define prev7_wd (previous_words[6])
1330 #define prev8_wd (previous_words[7])
1331 #define prev9_wd (previous_words[8])
1333 /* Match the last N words before point, case-insensitively. */
1334 #define TailMatches(...) \
1335 TailMatchesImpl(false, previous_words_count, previous_words, \
1336 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1338 /* Match the last N words before point, case-sensitively. */
1339 #define TailMatchesCS(...) \
1340 TailMatchesImpl(true, previous_words_count, previous_words, \
1341 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1343 /* Match N words representing all of the line, case-insensitively. */
1344 #define Matches(...) \
1345 MatchesImpl(false, previous_words_count, previous_words, \
1346 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1348 /* Match N words representing all of the line, case-sensitively. */
1349 #define MatchesCS(...) \
1350 MatchesImpl(true, previous_words_count, previous_words, \
1351 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1353 /* Match the first N words on the line, case-insensitively. */
1354 #define HeadMatches(...) \
1355 HeadMatchesImpl(false, previous_words_count, previous_words, \
1356 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1358 /* Match the first N words on the line, case-sensitively. */
1359 #define HeadMatchesCS(...) \
1360 HeadMatchesImpl(true, previous_words_count, previous_words, \
1361 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1363 /* Known command-starting keywords. */
1364 static const char *const sql_commands[] = {
1365 "ABORT", "ALTER", "ANALYZE", "BEGIN", "CALL", "CHECKPOINT", "CLOSE", "CLUSTER",
1366 "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
1367 "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
1368 "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK",
1369 "MOVE", "NOTIFY", "PREPARE",
1370 "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
1371 "RESET", "REVOKE", "ROLLBACK",
1372 "SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
1373 "TABLE", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", "VALUES", "WITH",
1377 /* psql's backslash commands. */
1378 static const char *const backslash_commands[] = {
1380 "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
1381 "\\copyright", "\\crosstabview",
1382 "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
1383 "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
1384 "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
1385 "\\dm", "\\dn", "\\do", "\\dO", "\\dp",
1386 "\\drds", "\\dRs", "\\dRp", "\\ds", "\\dS",
1387 "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
1388 "\\e", "\\echo", "\\ef", "\\elif", "\\else", "\\encoding",
1389 "\\endif", "\\errverbose", "\\ev",
1391 "\\g", "\\gdesc", "\\gexec", "\\gset", "\\gx",
1392 "\\h", "\\help", "\\H",
1393 "\\i", "\\if", "\\ir",
1394 "\\l", "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
1396 "\\p", "\\password", "\\prompt", "\\pset",
1399 "\\s", "\\set", "\\setenv", "\\sf", "\\sv",
1400 "\\t", "\\T", "\\timing",
1409 (void) end; /* "end" is not used */
1411 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1412 rl_completion_append_character = ' ';
1415 /* Clear a few things. */
1416 completion_charp = NULL;
1417 completion_charpp = NULL;
1418 completion_info_charp = NULL;
1419 completion_info_charp2 = NULL;
1422 * Scan the input line to extract the words before our current position.
1423 * According to those we'll make some smart decisions on what the user is
1424 * probably intending to type.
1426 previous_words = get_previous_words(start,
1428 &previous_words_count);
1430 /* If current word is a backslash command, offer completions for that */
1431 if (text[0] == '\\')
1432 COMPLETE_WITH_LIST_CS(backslash_commands);
1434 /* If current word is a variable interpolation, handle that case */
1435 else if (text[0] == ':' && text[1] != ':')
1437 if (text[1] == '\'')
1438 matches = complete_from_variables(text, ":'", "'", true);
1439 else if (text[1] == '"')
1440 matches = complete_from_variables(text, ":\"", "\"", true);
1442 matches = complete_from_variables(text, ":", "", true);
1445 /* If no previous word, suggest one of the basic sql commands */
1446 else if (previous_words_count == 0)
1447 COMPLETE_WITH_LIST(sql_commands);
1450 /* complete with something you can create */
1451 else if (TailMatches("CREATE"))
1452 matches = completion_matches(text, create_command_generator);
1454 /* DROP, but not DROP embedded in other commands */
1455 /* complete with something you can drop */
1456 else if (Matches("DROP"))
1457 matches = completion_matches(text, drop_command_generator);
1462 else if (Matches("ALTER", "TABLE"))
1463 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
1464 "UNION SELECT 'ALL IN TABLESPACE'");
1466 /* ALTER something */
1467 else if (Matches("ALTER"))
1468 matches = completion_matches(text, alter_command_generator);
1469 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */
1470 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny))
1471 COMPLETE_WITH("SET TABLESPACE", "OWNED BY");
1472 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */
1473 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"))
1474 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1475 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */
1476 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny))
1477 COMPLETE_WITH("SET TABLESPACE");
1478 /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> */
1479 else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
1481 /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> (...) */
1482 else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny))
1484 if (ends_with(prev_wd, ')'))
1485 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1487 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
1489 /* ALTER PUBLICATION <name> */
1490 else if (Matches("ALTER", "PUBLICATION", MatchAny))
1491 COMPLETE_WITH("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET");
1492 /* ALTER PUBLICATION <name> SET */
1493 else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET"))
1494 COMPLETE_WITH("(", "TABLE");
1495 /* ALTER PUBLICATION <name> SET ( */
1496 else if (HeadMatches("ALTER", "PUBLICATION", MatchAny) && TailMatches("SET", "("))
1497 COMPLETE_WITH("publish");
1498 /* ALTER SUBSCRIPTION <name> */
1499 else if (Matches("ALTER", "SUBSCRIPTION", MatchAny))
1500 COMPLETE_WITH("CONNECTION", "ENABLE", "DISABLE", "OWNER TO",
1501 "RENAME TO", "REFRESH PUBLICATION", "SET");
1502 /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION */
1503 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1504 TailMatches("REFRESH", "PUBLICATION"))
1505 COMPLETE_WITH("WITH (");
1506 /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION WITH ( */
1507 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1508 TailMatches("REFRESH", "PUBLICATION", "WITH", "("))
1509 COMPLETE_WITH("copy_data");
1510 /* ALTER SUBSCRIPTION <name> SET */
1511 else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, "SET"))
1512 COMPLETE_WITH("(", "PUBLICATION");
1513 /* ALTER SUBSCRIPTION <name> SET ( */
1514 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "("))
1515 COMPLETE_WITH("slot_name", "synchronous_commit");
1516 /* ALTER SUBSCRIPTION <name> SET PUBLICATION */
1517 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "PUBLICATION"))
1519 /* complete with nothing here as this refers to remote publications */
1521 /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> */
1522 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1523 TailMatches("SET", "PUBLICATION", MatchAny))
1524 COMPLETE_WITH("WITH (");
1525 /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> WITH ( */
1526 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1527 TailMatches("SET", "PUBLICATION", MatchAny, "WITH", "("))
1528 COMPLETE_WITH("copy_data", "refresh");
1529 /* ALTER SCHEMA <name> */
1530 else if (Matches("ALTER", "SCHEMA", MatchAny))
1531 COMPLETE_WITH("OWNER TO", "RENAME TO");
1533 /* ALTER COLLATION <name> */
1534 else if (Matches("ALTER", "COLLATION", MatchAny))
1535 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1537 /* ALTER CONVERSION <name> */
1538 else if (Matches("ALTER", "CONVERSION", MatchAny))
1539 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1541 /* ALTER DATABASE <name> */
1542 else if (Matches("ALTER", "DATABASE", MatchAny))
1543 COMPLETE_WITH("RESET", "SET", "OWNER TO", "RENAME TO",
1544 "IS_TEMPLATE", "ALLOW_CONNECTIONS",
1545 "CONNECTION LIMIT");
1547 /* ALTER DATABASE <name> SET TABLESPACE */
1548 else if (Matches("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE"))
1549 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1551 /* ALTER EVENT TRIGGER */
1552 else if (Matches("ALTER", "EVENT", "TRIGGER"))
1553 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
1555 /* ALTER EVENT TRIGGER <name> */
1556 else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny))
1557 COMPLETE_WITH("DISABLE", "ENABLE", "OWNER TO", "RENAME TO");
1559 /* ALTER EVENT TRIGGER <name> ENABLE */
1560 else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"))
1561 COMPLETE_WITH("REPLICA", "ALWAYS");
1563 /* ALTER EXTENSION <name> */
1564 else if (Matches("ALTER", "EXTENSION", MatchAny))
1565 COMPLETE_WITH("ADD", "DROP", "UPDATE", "SET SCHEMA");
1567 /* ALTER EXTENSION <name> UPDATE */
1568 else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE"))
1570 completion_info_charp = prev2_wd;
1571 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO);
1574 /* ALTER EXTENSION <name> UPDATE TO */
1575 else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"))
1577 completion_info_charp = prev3_wd;
1578 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
1582 else if (Matches("ALTER", "FOREIGN"))
1583 COMPLETE_WITH("DATA WRAPPER", "TABLE");
1585 /* ALTER FOREIGN DATA WRAPPER <name> */
1586 else if (Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
1587 COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO");
1589 /* ALTER FOREIGN TABLE <name> */
1590 else if (Matches("ALTER", "FOREIGN", "TABLE", MatchAny))
1591 COMPLETE_WITH("ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE",
1592 "INHERIT", "NO INHERIT", "OPTIONS", "OWNER TO",
1593 "RENAME", "SET", "VALIDATE CONSTRAINT");
1596 else if (Matches("ALTER", "INDEX"))
1597 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
1598 "UNION SELECT 'ALL IN TABLESPACE'");
1599 /* ALTER INDEX <name> */
1600 else if (Matches("ALTER", "INDEX", MatchAny))
1601 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET",
1602 "RESET", "ATTACH PARTITION");
1603 else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH"))
1604 COMPLETE_WITH("PARTITION");
1605 else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION"))
1606 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
1607 /* ALTER INDEX <name> ALTER */
1608 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER"))
1609 COMPLETE_WITH("COLUMN");
1610 /* ALTER INDEX <name> ALTER COLUMN */
1611 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN"))
1613 completion_info_charp = prev3_wd;
1614 COMPLETE_WITH_QUERY(Query_for_list_of_attribute_numbers);
1616 /* ALTER INDEX <name> ALTER COLUMN <colnum> */
1617 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny))
1618 COMPLETE_WITH("SET STATISTICS");
1619 /* ALTER INDEX <name> ALTER COLUMN <colnum> SET */
1620 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET"))
1621 COMPLETE_WITH("STATISTICS");
1622 /* ALTER INDEX <name> ALTER COLUMN <colnum> SET STATISTICS */
1623 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS"))
1625 /* Enforce no completion here, as an integer has to be specified */
1627 /* ALTER INDEX <name> SET */
1628 else if (Matches("ALTER", "INDEX", MatchAny, "SET"))
1629 COMPLETE_WITH("(", "TABLESPACE");
1630 /* ALTER INDEX <name> RESET */
1631 else if (Matches("ALTER", "INDEX", MatchAny, "RESET"))
1633 /* ALTER INDEX <foo> SET|RESET ( */
1634 else if (Matches("ALTER", "INDEX", MatchAny, "RESET", "("))
1635 COMPLETE_WITH("fillfactor",
1636 "vacuum_cleanup_index_scale_factor", /* BTREE */
1637 "fastupdate", "gin_pending_list_limit", /* GIN */
1638 "buffering", /* GiST */
1639 "pages_per_range", "autosummarize" /* BRIN */
1641 else if (Matches("ALTER", "INDEX", MatchAny, "SET", "("))
1642 COMPLETE_WITH("fillfactor =",
1643 "vacuum_cleanup_index_scale_factor =", /* BTREE */
1644 "fastupdate =", "gin_pending_list_limit =", /* GIN */
1645 "buffering =", /* GiST */
1646 "pages_per_range =", "autosummarize =" /* BRIN */
1649 /* ALTER LANGUAGE <name> */
1650 else if (Matches("ALTER", "LANGUAGE", MatchAny))
1651 COMPLETE_WITH("OWNER_TO", "RENAME TO");
1653 /* ALTER LARGE OBJECT <oid> */
1654 else if (Matches("ALTER", "LARGE", "OBJECT", MatchAny))
1655 COMPLETE_WITH("OWNER TO");
1657 /* ALTER MATERIALIZED VIEW */
1658 else if (Matches("ALTER", "MATERIALIZED", "VIEW"))
1659 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
1660 "UNION SELECT 'ALL IN TABLESPACE'");
1662 /* ALTER USER,ROLE <name> */
1663 else if (Matches("ALTER", "USER|ROLE", MatchAny) &&
1664 !TailMatches("USER", "MAPPING"))
1665 COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1666 "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1667 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1668 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
1669 "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
1670 "VALID UNTIL", "WITH");
1672 /* ALTER USER,ROLE <name> WITH */
1673 else if (Matches("ALTER", "USER|ROLE", MatchAny, "WITH"))
1674 /* Similar to the above, but don't complete "WITH" again. */
1675 COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1676 "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1677 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1678 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
1679 "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
1682 /* ALTER DEFAULT PRIVILEGES */
1683 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES"))
1684 COMPLETE_WITH("FOR ROLE", "IN SCHEMA");
1685 /* ALTER DEFAULT PRIVILEGES FOR */
1686 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
1687 COMPLETE_WITH("ROLE");
1688 /* ALTER DEFAULT PRIVILEGES IN */
1689 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
1690 COMPLETE_WITH("SCHEMA");
1691 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
1692 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1694 COMPLETE_WITH("GRANT", "REVOKE", "IN SCHEMA");
1695 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
1696 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1698 COMPLETE_WITH("GRANT", "REVOKE", "FOR ROLE");
1699 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
1700 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1702 COMPLETE_WITH("ROLE");
1703 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
1704 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
1705 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1706 MatchAny, "IN", "SCHEMA", MatchAny) ||
1707 Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1708 MatchAny, "FOR", "ROLE|USER", MatchAny))
1709 COMPLETE_WITH("GRANT", "REVOKE");
1710 /* ALTER DOMAIN <name> */
1711 else if (Matches("ALTER", "DOMAIN", MatchAny))
1712 COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME", "SET",
1713 "VALIDATE CONSTRAINT");
1714 /* ALTER DOMAIN <sth> DROP */
1715 else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP"))
1716 COMPLETE_WITH("CONSTRAINT", "DEFAULT", "NOT NULL");
1717 /* ALTER DOMAIN <sth> DROP|RENAME|VALIDATE CONSTRAINT */
1718 else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
1720 completion_info_charp = prev3_wd;
1721 COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
1723 /* ALTER DOMAIN <sth> RENAME */
1724 else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME"))
1725 COMPLETE_WITH("CONSTRAINT", "TO");
1726 /* ALTER DOMAIN <sth> RENAME CONSTRAINT <sth> */
1727 else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny))
1728 COMPLETE_WITH("TO");
1730 /* ALTER DOMAIN <sth> SET */
1731 else if (Matches("ALTER", "DOMAIN", MatchAny, "SET"))
1732 COMPLETE_WITH("DEFAULT", "NOT NULL", "SCHEMA");
1733 /* ALTER SEQUENCE <name> */
1734 else if (Matches("ALTER", "SEQUENCE", MatchAny))
1735 COMPLETE_WITH("INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO",
1736 "CACHE", "CYCLE", "SET SCHEMA", "OWNED BY", "OWNER TO",
1738 /* ALTER SEQUENCE <name> NO */
1739 else if (Matches("ALTER", "SEQUENCE", MatchAny, "NO"))
1740 COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
1741 /* ALTER SERVER <name> */
1742 else if (Matches("ALTER", "SERVER", MatchAny))
1743 COMPLETE_WITH("VERSION", "OPTIONS", "OWNER TO", "RENAME TO");
1744 /* ALTER SERVER <name> VERSION <version> */
1745 else if (Matches("ALTER", "SERVER", MatchAny, "VERSION", MatchAny))
1746 COMPLETE_WITH("OPTIONS");
1747 /* ALTER SYSTEM SET, RESET, RESET ALL */
1748 else if (Matches("ALTER", "SYSTEM"))
1749 COMPLETE_WITH("SET", "RESET");
1750 else if (Matches("ALTER", "SYSTEM", "SET|RESET"))
1751 COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars);
1752 else if (Matches("ALTER", "SYSTEM", "SET", MatchAny))
1753 COMPLETE_WITH("TO");
1754 /* ALTER VIEW <name> */
1755 else if (Matches("ALTER", "VIEW", MatchAny))
1756 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO",
1758 /* ALTER MATERIALIZED VIEW <name> */
1759 else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny))
1760 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO",
1763 /* ALTER POLICY <name> */
1764 else if (Matches("ALTER", "POLICY"))
1765 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
1766 /* ALTER POLICY <name> ON */
1767 else if (Matches("ALTER", "POLICY", MatchAny))
1768 COMPLETE_WITH("ON");
1769 /* ALTER POLICY <name> ON <table> */
1770 else if (Matches("ALTER", "POLICY", MatchAny, "ON"))
1772 completion_info_charp = prev2_wd;
1773 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
1775 /* ALTER POLICY <name> ON <table> - show options */
1776 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny))
1777 COMPLETE_WITH("RENAME TO", "TO", "USING (", "WITH CHECK (");
1778 /* ALTER POLICY <name> ON <table> TO <role> */
1779 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
1780 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
1781 /* ALTER POLICY <name> ON <table> USING ( */
1782 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
1784 /* ALTER POLICY <name> ON <table> WITH CHECK ( */
1785 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
1788 /* ALTER RULE <name>, add ON */
1789 else if (Matches("ALTER", "RULE", MatchAny))
1790 COMPLETE_WITH("ON");
1792 /* If we have ALTER RULE <name> ON, then add the correct tablename */
1793 else if (Matches("ALTER", "RULE", MatchAny, "ON"))
1795 completion_info_charp = prev2_wd;
1796 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1799 /* ALTER RULE <name> ON <name> */
1800 else if (Matches("ALTER", "RULE", MatchAny, "ON", MatchAny))
1801 COMPLETE_WITH("RENAME TO");
1803 /* ALTER STATISTICS <name> */
1804 else if (Matches("ALTER", "STATISTICS", MatchAny))
1805 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1807 /* ALTER TRIGGER <name>, add ON */
1808 else if (Matches("ALTER", "TRIGGER", MatchAny))
1809 COMPLETE_WITH("ON");
1811 else if (Matches("ALTER", "TRIGGER", MatchAny, MatchAny))
1813 completion_info_charp = prev2_wd;
1814 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
1818 * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
1820 else if (Matches("ALTER", "TRIGGER", MatchAny, "ON"))
1821 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
1823 /* ALTER TRIGGER <name> ON <name> */
1824 else if (Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
1825 COMPLETE_WITH("RENAME TO");
1828 * If we detect ALTER TABLE <name>, suggest sub commands
1830 else if (Matches("ALTER", "TABLE", MatchAny))
1831 COMPLETE_WITH("ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP",
1832 "ENABLE", "INHERIT", "NO INHERIT", "RENAME", "RESET",
1833 "OWNER TO", "SET", "VALIDATE CONSTRAINT",
1834 "REPLICA IDENTITY", "ATTACH PARTITION",
1835 "DETACH PARTITION");
1836 /* ALTER TABLE xxx ENABLE */
1837 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE"))
1838 COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
1840 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
1841 COMPLETE_WITH("RULE", "TRIGGER");
1842 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
1844 completion_info_charp = prev3_wd;
1845 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1847 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
1849 completion_info_charp = prev4_wd;
1850 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1852 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
1854 completion_info_charp = prev3_wd;
1855 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1857 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
1859 completion_info_charp = prev4_wd;
1860 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1862 /* ALTER TABLE xxx INHERIT */
1863 else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT"))
1864 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1865 /* ALTER TABLE xxx NO INHERIT */
1866 else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
1867 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1868 /* ALTER TABLE xxx DISABLE */
1869 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE"))
1870 COMPLETE_WITH("ROW LEVEL SECURITY", "RULE", "TRIGGER");
1871 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
1873 completion_info_charp = prev3_wd;
1874 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1876 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
1878 completion_info_charp = prev3_wd;
1879 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1882 /* ALTER TABLE xxx ALTER */
1883 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER"))
1884 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'");
1886 /* ALTER TABLE xxx RENAME */
1887 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME"))
1888 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'");
1889 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
1890 COMPLETE_WITH_ATTR(prev3_wd, "");
1892 /* ALTER TABLE xxx RENAME yyy */
1893 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
1894 COMPLETE_WITH("TO");
1896 /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
1897 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
1898 COMPLETE_WITH("TO");
1900 /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
1901 else if (Matches("ALTER", "TABLE", MatchAny, "DROP"))
1902 COMPLETE_WITH("COLUMN", "CONSTRAINT");
1903 /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
1904 else if (Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
1905 COMPLETE_WITH_ATTR(prev3_wd, "");
1908 * If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
1909 * provide list of constraints
1911 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
1913 completion_info_charp = prev3_wd;
1914 COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
1916 /* ALTER TABLE ALTER [COLUMN] <foo> */
1917 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
1918 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
1919 COMPLETE_WITH("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP");
1920 /* ALTER TABLE ALTER [COLUMN] <foo> SET */
1921 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
1922 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
1923 COMPLETE_WITH("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE");
1924 /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
1925 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
1926 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
1927 COMPLETE_WITH("n_distinct", "n_distinct_inherited");
1928 /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
1929 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
1930 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
1931 COMPLETE_WITH("PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
1932 /* ALTER TABLE ALTER [COLUMN] <foo> SET STATISTICS */
1933 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS") ||
1934 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STATISTICS"))
1936 /* Enforce no completion here, as an integer has to be specified */
1938 /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
1939 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
1940 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
1941 COMPLETE_WITH("DEFAULT", "IDENTITY", "NOT NULL");
1942 else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER"))
1943 COMPLETE_WITH("ON");
1944 else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
1946 completion_info_charp = prev3_wd;
1947 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1949 /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
1950 else if (Matches("ALTER", "TABLE", MatchAny, "SET"))
1951 COMPLETE_WITH("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED",
1955 * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
1958 else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
1959 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1960 /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
1961 else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
1962 COMPLETE_WITH("CLUSTER", "OIDS");
1963 /* ALTER TABLE <foo> RESET */
1964 else if (Matches("ALTER", "TABLE", MatchAny, "RESET"))
1966 /* ALTER TABLE <foo> SET|RESET ( */
1967 else if (Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
1968 COMPLETE_WITH_LIST(table_storage_parameters);
1969 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
1971 completion_info_charp = prev5_wd;
1972 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1974 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
1975 COMPLETE_WITH("INDEX");
1976 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
1977 COMPLETE_WITH("FULL", "NOTHING", "DEFAULT", "USING");
1978 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA"))
1979 COMPLETE_WITH("IDENTITY");
1982 * If we have ALTER TABLE <foo> ATTACH PARTITION, provide a list of
1985 else if (Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION"))
1986 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1987 /* Limited completion support for partition bound specification */
1988 else if (TailMatches("ATTACH", "PARTITION", MatchAny))
1989 COMPLETE_WITH("FOR VALUES", "DEFAULT");
1990 else if (TailMatches("FOR", "VALUES"))
1991 COMPLETE_WITH("FROM (", "IN (", "WITH (");
1994 * If we have ALTER TABLE <foo> DETACH PARTITION, provide a list of
1995 * partitions of <foo>.
1997 else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION"))
1999 completion_info_charp = prev3_wd;
2000 COMPLETE_WITH_QUERY(Query_for_partition_of_table);
2003 /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
2004 else if (Matches("ALTER", "TABLESPACE", MatchAny))
2005 COMPLETE_WITH("RENAME TO", "OWNER TO", "SET", "RESET");
2006 /* ALTER TABLESPACE <foo> SET|RESET */
2007 else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
2009 /* ALTER TABLESPACE <foo> SET|RESET ( */
2010 else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
2011 COMPLETE_WITH("seq_page_cost", "random_page_cost",
2012 "effective_io_concurrency");
2014 /* ALTER TEXT SEARCH */
2015 else if (Matches("ALTER", "TEXT", "SEARCH"))
2016 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2017 else if (Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
2018 COMPLETE_WITH("RENAME TO", "SET SCHEMA");
2019 else if (Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
2020 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
2021 else if (Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2022 COMPLETE_WITH("ADD MAPPING FOR", "ALTER MAPPING",
2024 "OWNER TO", "RENAME TO", "SET SCHEMA");
2026 /* complete ALTER TYPE <foo> with actions */
2027 else if (Matches("ALTER", "TYPE", MatchAny))
2028 COMPLETE_WITH("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
2030 "OWNER TO", "RENAME", "SET SCHEMA");
2031 /* complete ALTER TYPE <foo> ADD with actions */
2032 else if (Matches("ALTER", "TYPE", MatchAny, "ADD"))
2033 COMPLETE_WITH("ATTRIBUTE", "VALUE");
2034 /* ALTER TYPE <foo> RENAME */
2035 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME"))
2036 COMPLETE_WITH("ATTRIBUTE", "TO", "VALUE");
2037 /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
2038 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
2039 COMPLETE_WITH("TO");
2042 * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
2045 else if (Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
2046 COMPLETE_WITH_ATTR(prev3_wd, "");
2047 /* ALTER TYPE ALTER ATTRIBUTE <foo> */
2048 else if (Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
2049 COMPLETE_WITH("TYPE");
2050 /* complete ALTER GROUP <foo> */
2051 else if (Matches("ALTER", "GROUP", MatchAny))
2052 COMPLETE_WITH("ADD USER", "DROP USER", "RENAME TO");
2053 /* complete ALTER GROUP <foo> ADD|DROP with USER */
2054 else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP"))
2055 COMPLETE_WITH("USER");
2056 /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
2057 else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
2058 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2061 * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
2063 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
2064 COMPLETE_WITH_ENUM_VALUE(prev3_wd);
2067 * ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
2068 * ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]
2070 else if (Matches("ANALYZE"))
2071 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables,
2072 " UNION SELECT 'VERBOSE'");
2073 else if (HeadMatches("ANALYZE", "(*") &&
2074 !HeadMatches("ANALYZE", "(*)"))
2077 * This fires if we're in an unfinished parenthesized option list.
2078 * get_previous_words treats a completed parenthesized option list as
2079 * one word, so the above test is correct.
2081 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
2082 COMPLETE_WITH("VERBOSE", "SKIP_LOCKED");
2084 else if (HeadMatches("ANALYZE") && TailMatches("("))
2085 /* "ANALYZE (" should be caught above, so assume we want columns */
2086 COMPLETE_WITH_ATTR(prev2_wd, "");
2087 else if (HeadMatches("ANALYZE"))
2088 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables, NULL);
2091 else if (Matches("BEGIN"))
2092 COMPLETE_WITH("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2094 else if (Matches("END|ABORT"))
2095 COMPLETE_WITH("AND", "WORK", "TRANSACTION");
2097 else if (Matches("COMMIT"))
2098 COMPLETE_WITH("AND", "WORK", "TRANSACTION", "PREPARED");
2099 /* RELEASE SAVEPOINT */
2100 else if (Matches("RELEASE"))
2101 COMPLETE_WITH("SAVEPOINT");
2103 else if (Matches("ROLLBACK"))
2104 COMPLETE_WITH("AND", "WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
2105 else if (Matches("ABORT|END|COMMIT|ROLLBACK", "AND"))
2106 COMPLETE_WITH("CHAIN");
2108 else if (Matches("CALL"))
2109 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
2110 else if (Matches("CALL", MatchAny))
2113 else if (Matches("CLUSTER"))
2114 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'");
2115 else if (Matches("CLUSTER", "VERBOSE"))
2116 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL);
2117 /* If we have CLUSTER <sth>, then add "USING" */
2118 else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON")))
2119 COMPLETE_WITH("USING");
2120 /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
2121 else if (Matches("CLUSTER", "VERBOSE", MatchAny))
2122 COMPLETE_WITH("USING");
2123 /* If we have CLUSTER <sth> USING, then add the index as well */
2124 else if (Matches("CLUSTER", MatchAny, "USING") ||
2125 Matches("CLUSTER", "VERBOSE", MatchAny, "USING"))
2127 completion_info_charp = prev2_wd;
2128 COMPLETE_WITH_QUERY(Query_for_index_of_table);
2132 else if (Matches("COMMENT"))
2133 COMPLETE_WITH("ON");
2134 else if (Matches("COMMENT", "ON"))
2135 COMPLETE_WITH("ACCESS METHOD", "CAST", "COLLATION", "CONVERSION",
2136 "DATABASE", "EVENT TRIGGER", "EXTENSION",
2137 "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "SERVER",
2138 "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE",
2139 "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION",
2140 "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW",
2141 "COLUMN", "AGGREGATE", "FUNCTION",
2142 "PROCEDURE", "ROUTINE",
2143 "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN",
2144 "LARGE OBJECT", "TABLESPACE", "TEXT SEARCH", "ROLE");
2145 else if (Matches("COMMENT", "ON", "ACCESS", "METHOD"))
2146 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2147 else if (Matches("COMMENT", "ON", "FOREIGN"))
2148 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2149 else if (Matches("COMMENT", "ON", "TEXT", "SEARCH"))
2150 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2151 else if (Matches("COMMENT", "ON", "CONSTRAINT"))
2152 COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2153 else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny))
2154 COMPLETE_WITH("ON");
2155 else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2157 completion_info_charp = prev2_wd;
2158 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint);
2160 else if (Matches("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2161 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2162 else if (Matches("COMMENT", "ON", "EVENT", "TRIGGER"))
2163 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2164 else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2165 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2166 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2167 COMPLETE_WITH("IS");
2172 * If we have COPY, offer list of tables or "(" (Also cover the analogous
2173 * backslash command).
2175 else if (Matches("COPY|\\copy"))
2176 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2177 " UNION ALL SELECT '('");
2178 /* If we have COPY BINARY, complete with list of tables */
2179 else if (Matches("COPY", "BINARY"))
2180 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2181 /* If we have COPY (, complete it with legal commands */
2182 else if (Matches("COPY|\\copy", "("))
2183 COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH");
2184 /* If we have COPY [BINARY] <sth>, complete it with "TO" or "FROM" */
2185 else if (Matches("COPY|\\copy", MatchAny) ||
2186 Matches("COPY", "BINARY", MatchAny))
2187 COMPLETE_WITH("FROM", "TO");
2188 /* If we have COPY [BINARY] <sth> FROM|TO, complete with filename */
2189 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO") ||
2190 Matches("COPY", "BINARY", MatchAny, "FROM|TO"))
2192 completion_charp = "";
2193 matches = completion_matches(text, complete_from_files);
2196 /* Handle COPY [BINARY] <sth> FROM|TO filename */
2197 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
2198 Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
2199 COMPLETE_WITH("BINARY", "DELIMITER", "NULL", "CSV",
2202 /* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
2203 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") ||
2204 Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV"))
2205 COMPLETE_WITH("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE",
2208 /* CREATE ACCESS METHOD */
2209 /* Complete "CREATE ACCESS METHOD <name>" */
2210 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny))
2211 COMPLETE_WITH("TYPE");
2212 /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2213 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2214 COMPLETE_WITH("INDEX");
2215 /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2216 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2217 COMPLETE_WITH("HANDLER");
2219 /* CREATE DATABASE */
2220 else if (Matches("CREATE", "DATABASE", MatchAny))
2221 COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2223 "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2224 "LC_COLLATE", "LC_CTYPE");
2226 else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2227 COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2229 /* CREATE EXTENSION */
2230 /* Complete with available extensions rather than installed ones. */
2231 else if (Matches("CREATE", "EXTENSION"))
2232 COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2233 /* CREATE EXTENSION <name> */
2234 else if (Matches("CREATE", "EXTENSION", MatchAny))
2235 COMPLETE_WITH("WITH SCHEMA", "CASCADE", "VERSION");
2236 /* CREATE EXTENSION <name> VERSION */
2237 else if (Matches("CREATE", "EXTENSION", MatchAny, "VERSION"))
2239 completion_info_charp = prev2_wd;
2240 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2243 /* CREATE FOREIGN */
2244 else if (Matches("CREATE", "FOREIGN"))
2245 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2247 /* CREATE FOREIGN DATA WRAPPER */
2248 else if (Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2249 COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS");
2251 /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2252 /* First off we complete CREATE UNIQUE with "INDEX" */
2253 else if (TailMatches("CREATE", "UNIQUE"))
2254 COMPLETE_WITH("INDEX");
2257 * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
2260 else if (TailMatches("CREATE|UNIQUE", "INDEX"))
2261 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2262 " UNION SELECT 'ON'"
2263 " UNION SELECT 'CONCURRENTLY'");
2266 * Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of relations
2267 * that indexes can be created on
2269 else if (TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON") ||
2270 TailMatches("INDEX|CONCURRENTLY", "ON"))
2271 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL);
2274 * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
2277 else if (TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
2278 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2279 " UNION SELECT 'ON'");
2280 /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
2281 else if (TailMatches("CREATE|UNIQUE", "INDEX", MatchAny) ||
2282 TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
2283 COMPLETE_WITH("ON");
2286 * Complete INDEX <name> ON <table> with a list of table columns (which
2287 * should really be in parens)
2289 else if (TailMatches("INDEX", MatchAny, "ON", MatchAny) ||
2290 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny))
2291 COMPLETE_WITH("(", "USING");
2292 else if (TailMatches("INDEX", MatchAny, "ON", MatchAny, "(") ||
2293 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
2294 COMPLETE_WITH_ATTR(prev2_wd, "");
2295 /* same if you put in USING */
2296 else if (TailMatches("ON", MatchAny, "USING", MatchAny, "("))
2297 COMPLETE_WITH_ATTR(prev4_wd, "");
2298 /* Complete USING with an index method */
2299 else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
2300 TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") ||
2301 TailMatches("INDEX", "ON", MatchAny, "USING"))
2302 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2303 else if (TailMatches("ON", MatchAny, "USING", MatchAny) &&
2304 !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
2305 !TailMatches("FOR", MatchAny, MatchAny, MatchAny))
2309 /* Complete "CREATE POLICY <name> ON" */
2310 else if (Matches("CREATE", "POLICY", MatchAny))
2311 COMPLETE_WITH("ON");
2312 /* Complete "CREATE POLICY <name> ON <table>" */
2313 else if (Matches("CREATE", "POLICY", MatchAny, "ON"))
2314 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2315 /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
2316 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny))
2317 COMPLETE_WITH("AS", "FOR", "TO", "USING (", "WITH CHECK (");
2318 /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
2319 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
2320 COMPLETE_WITH("PERMISSIVE", "RESTRICTIVE");
2323 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2324 * FOR|TO|USING|WITH CHECK
2326 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
2327 COMPLETE_WITH("FOR", "TO", "USING", "WITH CHECK");
2328 /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2329 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
2330 COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2331 /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
2332 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
2333 COMPLETE_WITH("TO", "WITH CHECK (");
2334 /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
2335 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
2336 COMPLETE_WITH("TO", "USING (");
2337 /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
2338 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
2339 COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
2340 /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
2341 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
2342 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2343 /* Complete "CREATE POLICY <name> ON <table> USING (" */
2344 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
2348 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2349 * ALL|SELECT|INSERT|UPDATE|DELETE
2351 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
2352 COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2355 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2356 * INSERT TO|WITH CHECK"
2358 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
2359 COMPLETE_WITH("TO", "WITH CHECK (");
2362 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2363 * SELECT|DELETE TO|USING"
2365 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
2366 COMPLETE_WITH("TO", "USING (");
2369 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2370 * ALL|UPDATE TO|USING|WITH CHECK
2372 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
2373 COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
2376 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO
2379 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
2380 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2383 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2386 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
2390 /* CREATE PUBLICATION */
2391 else if (Matches("CREATE", "PUBLICATION", MatchAny))
2392 COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "WITH (");
2393 else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR"))
2394 COMPLETE_WITH("TABLE", "ALL TABLES");
2395 /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>, ..." */
2396 else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"))
2397 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2398 /* Complete "CREATE PUBLICATION <name> [...] WITH" */
2399 else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "("))
2400 COMPLETE_WITH("publish");
2403 /* Complete "CREATE RULE <sth>" with "AS ON" */
2404 else if (Matches("CREATE", "RULE", MatchAny))
2405 COMPLETE_WITH("AS ON");
2406 /* Complete "CREATE RULE <sth> AS" with "ON" */
2407 else if (Matches("CREATE", "RULE", MatchAny, "AS"))
2408 COMPLETE_WITH("ON");
2409 /* Complete "CREATE RULE <sth> AS ON" with SELECT|UPDATE|INSERT|DELETE */
2410 else if (Matches("CREATE", "RULE", MatchAny, "AS", "ON"))
2411 COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE");
2412 /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
2413 else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
2414 COMPLETE_WITH("TO");
2415 /* Complete "AS ON <sth> TO" with a table name */
2416 else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
2417 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2419 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2420 else if (TailMatches("CREATE", "SEQUENCE", MatchAny) ||
2421 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
2422 COMPLETE_WITH("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE",
2423 "CYCLE", "OWNED BY", "START WITH");
2424 else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "NO") ||
2425 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
2426 COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
2428 /* CREATE SERVER <name> */
2429 else if (Matches("CREATE", "SERVER", MatchAny))
2430 COMPLETE_WITH("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
2432 /* CREATE STATISTICS <name> */
2433 else if (Matches("CREATE", "STATISTICS", MatchAny))
2434 COMPLETE_WITH("(", "ON");
2435 else if (Matches("CREATE", "STATISTICS", MatchAny, "("))
2436 COMPLETE_WITH("ndistinct", "dependencies", "mcv");
2437 else if (Matches("CREATE", "STATISTICS", MatchAny, "(*)"))
2438 COMPLETE_WITH("ON");
2439 else if (HeadMatches("CREATE", "STATISTICS", MatchAny) &&
2440 TailMatches("FROM"))
2441 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2443 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2444 /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
2445 else if (TailMatches("CREATE", "TEMP|TEMPORARY"))
2446 COMPLETE_WITH("SEQUENCE", "TABLE", "VIEW");
2447 /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
2448 else if (TailMatches("CREATE", "UNLOGGED"))
2449 COMPLETE_WITH("TABLE", "MATERIALIZED VIEW");
2450 /* Complete PARTITION BY with RANGE ( or LIST ( or ... */
2451 else if (TailMatches("PARTITION", "BY"))
2452 COMPLETE_WITH("RANGE (", "LIST (", "HASH (");
2453 /* If we have xxx PARTITION OF, provide a list of partitioned tables */
2454 else if (TailMatches("PARTITION", "OF"))
2455 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, "");
2456 /* Limited completion support for partition bound specification */
2457 else if (TailMatches("PARTITION", "OF", MatchAny))
2458 COMPLETE_WITH("FOR VALUES", "DEFAULT");
2459 /* Complete CREATE TABLE <name> with '(', OF or PARTITION OF */
2460 else if (TailMatches("CREATE", "TABLE", MatchAny) ||
2461 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny))
2462 COMPLETE_WITH("(", "OF", "PARTITION OF");
2463 /* Complete CREATE TABLE <name> OF with list of composite types */
2464 else if (TailMatches("CREATE", "TABLE", MatchAny, "OF") ||
2465 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "OF"))
2466 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes, NULL);
2467 /* Complete CREATE TABLE name (...) with supported options */
2468 else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)") ||
2469 TailMatches("CREATE", "UNLOGGED", "TABLE", MatchAny, "(*)"))
2470 COMPLETE_WITH("INHERITS (", "PARTITION BY", "TABLESPACE", "WITH (");
2471 else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)"))
2472 COMPLETE_WITH("INHERITS (", "ON COMMIT", "PARTITION BY",
2473 "TABLESPACE", "WITH (");
2474 /* Complete CREATE TABLE (...) WITH with storage parameters */
2475 else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "WITH", "(") ||
2476 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "WITH", "("))
2477 COMPLETE_WITH_LIST(table_storage_parameters);
2478 /* Complete CREATE TABLE ON COMMIT with actions */
2479 else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)", "ON", "COMMIT"))
2480 COMPLETE_WITH("DELETE ROWS", "DROP", "PRESERVE ROWS");
2482 /* CREATE TABLESPACE */
2483 else if (Matches("CREATE", "TABLESPACE", MatchAny))
2484 COMPLETE_WITH("OWNER", "LOCATION");
2485 /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
2486 else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
2487 COMPLETE_WITH("LOCATION");
2489 /* CREATE TEXT SEARCH */
2490 else if (Matches("CREATE", "TEXT", "SEARCH"))
2491 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2492 else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2495 /* CREATE SUBSCRIPTION */
2496 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny))
2497 COMPLETE_WITH("CONNECTION");
2498 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny))
2499 COMPLETE_WITH("PUBLICATION");
2500 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",
2501 MatchAny, "PUBLICATION"))
2503 /* complete with nothing here as this refers to remote publications */
2505 else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("PUBLICATION", MatchAny))
2506 COMPLETE_WITH("WITH (");
2507 /* Complete "CREATE SUBSCRIPTION <name> ... WITH ( <opt>" */
2508 else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("WITH", "("))
2509 COMPLETE_WITH("copy_data", "connect", "create_slot", "enabled",
2510 "slot_name", "synchronous_commit");
2512 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
2513 /* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
2514 else if (TailMatches("CREATE", "TRIGGER", MatchAny))
2515 COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF");
2516 /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
2517 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
2518 COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE");
2519 /* complete CREATE TRIGGER <name> INSTEAD OF with an event */
2520 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
2521 COMPLETE_WITH("INSERT", "DELETE", "UPDATE");
2522 /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
2523 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
2524 TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
2525 COMPLETE_WITH("ON", "OR");
2528 * complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of
2529 * tables. EXECUTE FUNCTION is the recommended grammar instead of EXECUTE
2530 * PROCEDURE in version 11 and upwards.
2532 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
2533 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2534 /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */
2535 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
2536 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
2537 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("ON", MatchAny))
2539 if (pset.sversion >= 110000)
2540 COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2541 "REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
2543 COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2544 "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2546 else if (HeadMatches("CREATE", "TRIGGER") &&
2547 (TailMatches("DEFERRABLE") || TailMatches("INITIALLY", "IMMEDIATE|DEFERRED")))
2549 if (pset.sversion >= 110000)
2550 COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
2552 COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2554 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("REFERENCING"))
2555 COMPLETE_WITH("OLD TABLE", "NEW TABLE");
2556 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("OLD|NEW", "TABLE"))
2557 COMPLETE_WITH("AS");
2558 else if (HeadMatches("CREATE", "TRIGGER") &&
2559 (TailMatches("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
2560 TailMatches("REFERENCING", "OLD", "TABLE", MatchAny)))
2562 if (pset.sversion >= 110000)
2563 COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
2565 COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2567 else if (HeadMatches("CREATE", "TRIGGER") &&
2568 (TailMatches("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
2569 TailMatches("REFERENCING", "NEW", "TABLE", MatchAny)))
2571 if (pset.sversion >= 110000)
2572 COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
2574 COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2576 else if (HeadMatches("CREATE", "TRIGGER") &&
2577 (TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2578 TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2579 TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
2580 TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
2582 if (pset.sversion >= 110000)
2583 COMPLETE_WITH("FOR", "WHEN (", "EXECUTE FUNCTION");
2585 COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE");
2587 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR"))
2588 COMPLETE_WITH("EACH", "ROW", "STATEMENT");
2589 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR", "EACH"))
2590 COMPLETE_WITH("ROW", "STATEMENT");
2591 else if (HeadMatches("CREATE", "TRIGGER") &&
2592 (TailMatches("FOR", "EACH", "ROW|STATEMENT") ||
2593 TailMatches("FOR", "ROW|STATEMENT")))
2595 if (pset.sversion >= 110000)
2596 COMPLETE_WITH("WHEN (", "EXECUTE FUNCTION");
2598 COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE");
2600 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("WHEN", "(*)"))
2602 if (pset.sversion >= 110000)
2603 COMPLETE_WITH("EXECUTE FUNCTION");
2605 COMPLETE_WITH("EXECUTE PROCEDURE");
2607 /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE|FUNCTION */
2608 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("EXECUTE"))
2610 if (pset.sversion >= 110000)
2611 COMPLETE_WITH("FUNCTION");
2613 COMPLETE_WITH("PROCEDURE");
2615 else if (HeadMatches("CREATE", "TRIGGER") &&
2616 TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
2617 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2619 /* CREATE ROLE,USER,GROUP <name> */
2620 else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny) &&
2621 !TailMatches("USER", "MAPPING"))
2622 COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
2623 "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
2624 "LOGIN", "NOBYPASSRLS",
2625 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2626 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2627 "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2628 "VALID UNTIL", "WITH");
2630 /* CREATE ROLE,USER,GROUP <name> WITH */
2631 else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
2632 /* Similar to the above, but don't complete "WITH" again. */
2633 COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
2634 "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
2635 "LOGIN", "NOBYPASSRLS",
2636 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2637 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2638 "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2641 /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
2642 else if (Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
2643 COMPLETE_WITH("GROUP", "ROLE");
2645 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
2646 /* Complete CREATE VIEW <name> with AS */
2647 else if (TailMatches("CREATE", "VIEW", MatchAny))
2648 COMPLETE_WITH("AS");
2649 /* Complete "CREATE VIEW <sth> AS with "SELECT" */
2650 else if (TailMatches("CREATE", "VIEW", MatchAny, "AS"))
2651 COMPLETE_WITH("SELECT");
2653 /* CREATE MATERIALIZED VIEW */
2654 else if (Matches("CREATE", "MATERIALIZED"))
2655 COMPLETE_WITH("VIEW");
2656 /* Complete CREATE MATERIALIZED VIEW <name> with AS */
2657 else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny))
2658 COMPLETE_WITH("AS");
2659 /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
2660 else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
2661 COMPLETE_WITH("SELECT");
2663 /* CREATE EVENT TRIGGER */
2664 else if (Matches("CREATE", "EVENT"))
2665 COMPLETE_WITH("TRIGGER");
2666 /* Complete CREATE EVENT TRIGGER <name> with ON */
2667 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny))
2668 COMPLETE_WITH("ON");
2669 /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
2670 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
2671 COMPLETE_WITH("ddl_command_start", "ddl_command_end", "sql_drop");
2674 * Complete CREATE EVENT TRIGGER <name> ON <event_type>. EXECUTE FUNCTION
2675 * is the recommended grammar instead of EXECUTE PROCEDURE in version 11
2678 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON", MatchAny))
2680 if (pset.sversion >= 110000)
2681 COMPLETE_WITH("WHEN TAG IN (", "EXECUTE FUNCTION");
2683 COMPLETE_WITH("WHEN TAG IN (", "EXECUTE PROCEDURE");
2685 else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
2686 TailMatches("WHEN|AND", MatchAny, "IN", "(*)"))
2688 if (pset.sversion >= 110000)
2689 COMPLETE_WITH("EXECUTE FUNCTION");
2691 COMPLETE_WITH("EXECUTE PROCEDURE");
2693 else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
2694 TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
2695 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2698 else if (Matches("DEALLOCATE"))
2699 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2702 else if (Matches("DECLARE", MatchAny))
2703 COMPLETE_WITH("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL",
2705 else if (HeadMatches("DECLARE") && TailMatches("CURSOR"))
2706 COMPLETE_WITH("WITH HOLD", "WITHOUT HOLD", "FOR");
2708 /* DELETE --- can be inside EXPLAIN, RULE, etc */
2709 /* ... despite which, only complete DELETE with FROM at start of line */
2710 else if (Matches("DELETE"))
2711 COMPLETE_WITH("FROM");
2712 /* Complete DELETE FROM with a list of tables */
2713 else if (TailMatches("DELETE", "FROM"))
2714 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2715 /* Complete DELETE FROM <table> */
2716 else if (TailMatches("DELETE", "FROM", MatchAny))
2717 COMPLETE_WITH("USING", "WHERE");
2718 /* XXX: implement tab completion for DELETE ... USING */
2721 else if (Matches("DISCARD"))
2722 COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP");
2725 else if (Matches("DO"))
2726 COMPLETE_WITH("LANGUAGE");
2729 /* Complete DROP object with CASCADE / RESTRICT */
2730 else if (Matches("DROP",
2731 "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW",
2733 Matches("DROP", "ACCESS", "METHOD", MatchAny) ||
2734 (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) &&
2735 ends_with(prev_wd, ')')) ||
2736 Matches("DROP", "EVENT", "TRIGGER", MatchAny) ||
2737 Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
2738 Matches("DROP", "FOREIGN", "TABLE", MatchAny) ||
2739 Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
2740 COMPLETE_WITH("CASCADE", "RESTRICT");
2742 /* help completing some of the variants */
2743 else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
2745 else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "("))
2746 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
2747 else if (Matches("DROP", "FOREIGN"))
2748 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2751 else if (Matches("DROP", "INDEX"))
2752 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2753 " UNION SELECT 'CONCURRENTLY'");
2754 else if (Matches("DROP", "INDEX", "CONCURRENTLY"))
2755 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2756 else if (Matches("DROP", "INDEX", MatchAny))
2757 COMPLETE_WITH("CASCADE", "RESTRICT");
2758 else if (Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny))
2759 COMPLETE_WITH("CASCADE", "RESTRICT");
2761 /* DROP MATERIALIZED VIEW */
2762 else if (Matches("DROP", "MATERIALIZED"))
2763 COMPLETE_WITH("VIEW");
2764 else if (Matches("DROP", "MATERIALIZED", "VIEW"))
2765 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2768 else if (Matches("DROP", "OWNED"))
2769 COMPLETE_WITH("BY");
2770 else if (Matches("DROP", "OWNED", "BY"))
2771 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2773 /* DROP TEXT SEARCH */
2774 else if (Matches("DROP", "TEXT", "SEARCH"))
2775 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2778 else if (Matches("DROP", "TRIGGER", MatchAny))
2779 COMPLETE_WITH("ON");
2780 else if (Matches("DROP", "TRIGGER", MatchAny, "ON"))
2782 completion_info_charp = prev2_wd;
2783 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2785 else if (Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
2786 COMPLETE_WITH("CASCADE", "RESTRICT");
2788 /* DROP ACCESS METHOD */
2789 else if (Matches("DROP", "ACCESS"))
2790 COMPLETE_WITH("METHOD");
2791 else if (Matches("DROP", "ACCESS", "METHOD"))
2792 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2794 /* DROP EVENT TRIGGER */
2795 else if (Matches("DROP", "EVENT"))
2796 COMPLETE_WITH("TRIGGER");
2797 else if (Matches("DROP", "EVENT", "TRIGGER"))
2798 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2800 /* DROP POLICY <name> */
2801 else if (Matches("DROP", "POLICY"))
2802 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2803 /* DROP POLICY <name> ON */
2804 else if (Matches("DROP", "POLICY", MatchAny))
2805 COMPLETE_WITH("ON");
2806 /* DROP POLICY <name> ON <table> */
2807 else if (Matches("DROP", "POLICY", MatchAny, "ON"))
2809 completion_info_charp = prev2_wd;
2810 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
2814 else if (Matches("DROP", "RULE", MatchAny))
2815 COMPLETE_WITH("ON");
2816 else if (Matches("DROP", "RULE", MatchAny, "ON"))
2818 completion_info_charp = prev2_wd;
2819 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2821 else if (Matches("DROP", "RULE", MatchAny, "ON", MatchAny))
2822 COMPLETE_WITH("CASCADE", "RESTRICT");
2825 else if (Matches("EXECUTE"))
2826 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2829 * EXPLAIN [ ( option [, ...] ) ] statement
2830 * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
2832 else if (Matches("EXPLAIN"))
2833 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2834 "ANALYZE", "VERBOSE");
2835 else if (HeadMatches("EXPLAIN", "(*") &&
2836 !HeadMatches("EXPLAIN", "(*)"))
2839 * This fires if we're in an unfinished parenthesized option list.
2840 * get_previous_words treats a completed parenthesized option list as
2841 * one word, so the above test is correct.
2843 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
2844 COMPLETE_WITH("ANALYZE", "VERBOSE", "COSTS", "BUFFERS",
2845 "TIMING", "SUMMARY", "FORMAT");
2846 else if (TailMatches("ANALYZE|VERBOSE|COSTS|BUFFERS|TIMING|SUMMARY"))
2847 COMPLETE_WITH("ON", "OFF");
2848 else if (TailMatches("FORMAT"))
2849 COMPLETE_WITH("TEXT", "XML", "JSON", "YAML");
2851 else if (Matches("EXPLAIN", "ANALYZE"))
2852 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2854 else if (Matches("EXPLAIN", "(*)") ||
2855 Matches("EXPLAIN", "VERBOSE") ||
2856 Matches("EXPLAIN", "ANALYZE", "VERBOSE"))
2857 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE");
2860 /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
2861 else if (Matches("FETCH|MOVE"))
2862 COMPLETE_WITH("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE");
2863 /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
2864 else if (Matches("FETCH|MOVE", MatchAny))
2865 COMPLETE_WITH("ALL", "NEXT", "PRIOR");
2868 * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
2869 * but we may as well tab-complete both: perhaps some users prefer one
2870 * variant or the other.
2872 else if (Matches("FETCH|MOVE", MatchAny, MatchAny))
2873 COMPLETE_WITH("FROM", "IN");
2875 /* FOREIGN DATA WRAPPER */
2876 /* applies in ALTER/DROP FDW and in CREATE SERVER */
2877 else if (TailMatches("FOREIGN", "DATA", "WRAPPER") &&
2878 !TailMatches("CREATE", MatchAny, MatchAny, MatchAny))
2879 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
2880 /* applies in CREATE SERVER */
2881 else if (TailMatches("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
2882 HeadMatches("CREATE", "SERVER"))
2883 COMPLETE_WITH("OPTIONS");
2886 else if (TailMatches("FOREIGN", "TABLE") &&
2887 !TailMatches("CREATE", MatchAny, MatchAny))
2888 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
2890 /* FOREIGN SERVER */
2891 else if (TailMatches("FOREIGN", "SERVER"))
2892 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
2895 * GRANT and REVOKE are allowed inside CREATE SCHEMA and
2896 * ALTER DEFAULT PRIVILEGES, so use TailMatches
2898 /* Complete GRANT/REVOKE with a list of roles and privileges */
2899 else if (TailMatches("GRANT|REVOKE"))
2902 * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable
2903 * privileges (can't grant roles)
2905 if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
2906 COMPLETE_WITH("SELECT", "INSERT", "UPDATE",
2907 "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2908 "EXECUTE", "USAGE", "ALL");
2910 COMPLETE_WITH_QUERY(Query_for_list_of_roles
2911 " UNION SELECT 'SELECT'"
2912 " UNION SELECT 'INSERT'"
2913 " UNION SELECT 'UPDATE'"
2914 " UNION SELECT 'DELETE'"
2915 " UNION SELECT 'TRUNCATE'"
2916 " UNION SELECT 'REFERENCES'"
2917 " UNION SELECT 'TRIGGER'"
2918 " UNION SELECT 'CREATE'"
2919 " UNION SELECT 'CONNECT'"
2920 " UNION SELECT 'TEMPORARY'"
2921 " UNION SELECT 'EXECUTE'"
2922 " UNION SELECT 'USAGE'"
2923 " UNION SELECT 'ALL'");
2927 * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
2930 else if (TailMatches("GRANT|REVOKE", MatchAny))
2932 if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
2933 COMPLETE_WITH("ON");
2934 else if (TailMatches("GRANT", MatchAny))
2935 COMPLETE_WITH("TO");
2937 COMPLETE_WITH("FROM");
2941 * Complete GRANT/REVOKE <sth> ON with a list of appropriate relations.
2943 * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query
2944 * result via UNION; seems to work intuitively.
2946 * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
2947 * here will only work if the privilege list contains exactly one
2950 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON"))
2953 * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of
2954 * objects supported.
2956 if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
2957 COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS");
2959 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables,
2960 " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
2961 " UNION SELECT 'ALL PROCEDURES IN SCHEMA'"
2962 " UNION SELECT 'ALL ROUTINES IN SCHEMA'"
2963 " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
2964 " UNION SELECT 'ALL TABLES IN SCHEMA'"
2965 " UNION SELECT 'DATABASE'"
2966 " UNION SELECT 'DOMAIN'"
2967 " UNION SELECT 'FOREIGN DATA WRAPPER'"
2968 " UNION SELECT 'FOREIGN SERVER'"
2969 " UNION SELECT 'FUNCTION'"
2970 " UNION SELECT 'LANGUAGE'"
2971 " UNION SELECT 'LARGE OBJECT'"
2972 " UNION SELECT 'PROCEDURE'"
2973 " UNION SELECT 'ROUTINE'"
2974 " UNION SELECT 'SCHEMA'"
2975 " UNION SELECT 'SEQUENCE'"
2976 " UNION SELECT 'TABLE'"
2977 " UNION SELECT 'TABLESPACE'"
2978 " UNION SELECT 'TYPE'");
2980 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL"))
2981 COMPLETE_WITH("FUNCTIONS IN SCHEMA",
2982 "PROCEDURES IN SCHEMA",
2983 "ROUTINES IN SCHEMA",
2984 "SEQUENCES IN SCHEMA",
2985 "TABLES IN SCHEMA");
2986 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"))
2987 COMPLETE_WITH("DATA WRAPPER", "SERVER");
2990 * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
2991 * appropriate objects.
2993 * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
2995 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny))
2997 if (TailMatches("DATABASE"))
2998 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2999 else if (TailMatches("DOMAIN"))
3000 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3001 else if (TailMatches("FUNCTION"))
3002 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3003 else if (TailMatches("LANGUAGE"))
3004 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3005 else if (TailMatches("PROCEDURE"))
3006 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
3007 else if (TailMatches("ROUTINE"))
3008 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3009 else if (TailMatches("SCHEMA"))
3010 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3011 else if (TailMatches("SEQUENCE"))
3012 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3013 else if (TailMatches("TABLE"))
3014 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL);
3015 else if (TailMatches("TABLESPACE"))
3016 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3017 else if (TailMatches("TYPE"))
3018 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3019 else if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny))
3020 COMPLETE_WITH("TO");
3022 COMPLETE_WITH("FROM");
3026 * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
3027 * CURRENT_USER, or SESSION_USER.
3029 else if ((HeadMatches("GRANT") && TailMatches("TO")) ||
3030 (HeadMatches("REVOKE") && TailMatches("FROM")))
3031 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
3032 /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
3033 else if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches("TO|FROM"))
3034 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
3035 /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
3036 else if (HeadMatches("GRANT") && TailMatches("ON", MatchAny, MatchAny))
3037 COMPLETE_WITH("TO");
3038 else if (HeadMatches("REVOKE") && TailMatches("ON", MatchAny, MatchAny))
3039 COMPLETE_WITH("FROM");
3041 /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
3042 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
3044 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3045 COMPLETE_WITH("TO");
3047 COMPLETE_WITH("FROM");
3050 /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
3051 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
3053 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3054 COMPLETE_WITH("TO");
3056 COMPLETE_WITH("FROM");
3059 /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
3060 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
3062 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3063 COMPLETE_WITH("TO");
3065 COMPLETE_WITH("FROM");
3069 else if (TailMatches("FROM", MatchAny, "GROUP"))
3070 COMPLETE_WITH("BY");
3072 /* IMPORT FOREIGN SCHEMA */
3073 else if (Matches("IMPORT"))
3074 COMPLETE_WITH("FOREIGN SCHEMA");
3075 else if (Matches("IMPORT", "FOREIGN"))
3076 COMPLETE_WITH("SCHEMA");
3078 /* INSERT --- can be inside EXPLAIN, RULE, etc */
3079 /* Complete INSERT with "INTO" */
3080 else if (TailMatches("INSERT"))
3081 COMPLETE_WITH("INTO");
3082 /* Complete INSERT INTO with table names */
3083 else if (TailMatches("INSERT", "INTO"))
3084 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3085 /* Complete "INSERT INTO <table> (" with attribute names */
3086 else if (TailMatches("INSERT", "INTO", MatchAny, "("))
3087 COMPLETE_WITH_ATTR(prev2_wd, "");
3090 * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
3091 * "TABLE" or "DEFAULT VALUES" or "OVERRIDING"
3093 else if (TailMatches("INSERT", "INTO", MatchAny))
3094 COMPLETE_WITH("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING");
3097 * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
3098 * "TABLE" or "OVERRIDING"
3100 else if (TailMatches("INSERT", "INTO", MatchAny, MatchAny) &&
3101 ends_with(prev_wd, ')'))
3102 COMPLETE_WITH("SELECT", "TABLE", "VALUES", "OVERRIDING");
3104 /* Complete OVERRIDING */
3105 else if (TailMatches("OVERRIDING"))
3106 COMPLETE_WITH("SYSTEM VALUE", "USER VALUE");
3108 /* Complete after OVERRIDING clause */
3109 else if (TailMatches("OVERRIDING", MatchAny, "VALUE"))
3110 COMPLETE_WITH("SELECT", "TABLE", "VALUES");
3112 /* Insert an open parenthesis after "VALUES" */
3113 else if (TailMatches("VALUES") && !TailMatches("DEFAULT", "VALUES"))
3117 /* Complete LOCK [TABLE] with a list of tables */
3118 else if (Matches("LOCK"))
3119 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
3120 " UNION SELECT 'TABLE'");
3121 else if (Matches("LOCK", "TABLE"))
3122 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
3124 /* For the following, handle the case of a single table only for now */
3126 /* Complete LOCK [TABLE] <table> with "IN" */
3127 else if (Matches("LOCK", MatchAnyExcept("TABLE")) ||
3128 Matches("LOCK", "TABLE", MatchAny))
3129 COMPLETE_WITH("IN");
3131 /* Complete LOCK [TABLE] <table> IN with a lock mode */
3132 else if (Matches("LOCK", MatchAny, "IN") ||
3133 Matches("LOCK", "TABLE", MatchAny, "IN"))
3134 COMPLETE_WITH("ACCESS SHARE MODE",
3135 "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
3136 "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
3137 "SHARE ROW EXCLUSIVE MODE",
3138 "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
3140 /* Complete LOCK [TABLE] <table> IN ACCESS|ROW with rest of lock mode */
3141 else if (Matches("LOCK", MatchAny, "IN", "ACCESS|ROW") ||
3142 Matches("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW"))
3143 COMPLETE_WITH("EXCLUSIVE MODE", "SHARE MODE");
3145 /* Complete LOCK [TABLE] <table> IN SHARE with rest of lock mode */
3146 else if (Matches("LOCK", MatchAny, "IN", "SHARE") ||
3147 Matches("LOCK", "TABLE", MatchAny, "IN", "SHARE"))
3148 COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE",
3149 "UPDATE EXCLUSIVE MODE");
3151 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
3152 else if (TailMatches("NOTIFY"))
3153 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'");
3156 else if (TailMatches("OPTIONS"))
3159 /* OWNER TO - complete with available roles */
3160 else if (TailMatches("OWNER", "TO"))
3161 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3164 else if (TailMatches("FROM", MatchAny, "ORDER"))
3165 COMPLETE_WITH("BY");
3166 else if (TailMatches("FROM", MatchAny, "ORDER", "BY"))
3167 COMPLETE_WITH_ATTR(prev3_wd, "");
3170 else if (Matches("PREPARE", MatchAny, "AS"))
3171 COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE FROM");
3174 * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
3175 * managers, not for manual use in interactive sessions.
3178 /* REASSIGN OWNED BY xxx TO yyy */
3179 else if (Matches("REASSIGN"))
3180 COMPLETE_WITH("OWNED BY");
3181 else if (Matches("REASSIGN", "OWNED"))
3182 COMPLETE_WITH("BY");
3183 else if (Matches("REASSIGN", "OWNED", "BY"))
3184 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3185 else if (Matches("REASSIGN", "OWNED", "BY", MatchAny))
3186 COMPLETE_WITH("TO");
3187 else if (Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
3188 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3190 /* REFRESH MATERIALIZED VIEW */
3191 else if (Matches("REFRESH"))
3192 COMPLETE_WITH("MATERIALIZED VIEW");
3193 else if (Matches("REFRESH", "MATERIALIZED"))
3194 COMPLETE_WITH("VIEW");
3195 else if (Matches("REFRESH", "MATERIALIZED", "VIEW"))
3196 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
3197 " UNION SELECT 'CONCURRENTLY'");
3198 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
3199 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3200 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
3201 COMPLETE_WITH("WITH");
3202 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
3203 COMPLETE_WITH("WITH");
3204 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
3205 COMPLETE_WITH("NO DATA", "DATA");
3206 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
3207 COMPLETE_WITH("NO DATA", "DATA");
3208 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
3209 COMPLETE_WITH("DATA");
3210 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
3211 COMPLETE_WITH("DATA");
3214 else if (Matches("REINDEX"))
3215 COMPLETE_WITH("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
3216 else if (Matches("REINDEX", "TABLE"))
3217 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables,
3218 " UNION SELECT 'CONCURRENTLY'");
3219 else if (Matches("REINDEX", "INDEX"))
3220 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
3221 " UNION SELECT 'CONCURRENTLY'");
3222 else if (Matches("REINDEX", "SCHEMA"))
3223 COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3224 " UNION SELECT 'CONCURRENTLY'");
3225 else if (Matches("REINDEX", "SYSTEM|DATABASE"))
3226 COMPLETE_WITH_QUERY(Query_for_list_of_databases
3227 " UNION SELECT 'CONCURRENTLY'");
3228 else if (Matches("REINDEX", "TABLE", "CONCURRENTLY"))
3229 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL);
3230 else if (Matches("REINDEX", "INDEX", "CONCURRENTLY"))
3231 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3232 else if (Matches("REINDEX", "SCHEMA", "CONCURRENTLY"))
3233 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3234 else if (Matches("REINDEX", "SYSTEM|DATABASE", "CONCURRENTLY"))
3235 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3237 /* SECURITY LABEL */
3238 else if (Matches("SECURITY"))
3239 COMPLETE_WITH("LABEL");
3240 else if (Matches("SECURITY", "LABEL"))
3241 COMPLETE_WITH("ON", "FOR");
3242 else if (Matches("SECURITY", "LABEL", "FOR", MatchAny))
3243 COMPLETE_WITH("ON");
3244 else if (Matches("SECURITY", "LABEL", "ON") ||
3245 Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
3246 COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
3247 "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION",
3248 "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE",
3249 "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA",
3250 "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW");
3251 else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
3252 COMPLETE_WITH("IS");
3257 /* SET, RESET, SHOW */
3258 /* Complete with a variable name */
3259 else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET"))
3260 COMPLETE_WITH_QUERY(Query_for_list_of_set_vars);
3261 else if (Matches("SHOW"))
3262 COMPLETE_WITH_QUERY(Query_for_list_of_show_vars);
3263 /* Complete "SET TRANSACTION" */
3264 else if (Matches("SET", "TRANSACTION"))
3265 COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3266 else if (Matches("BEGIN|START", "TRANSACTION") ||
3267 Matches("BEGIN", "WORK") ||
3269 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
3270 COMPLETE_WITH("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3271 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
3272 Matches("BEGIN", "NOT") ||
3273 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
3274 COMPLETE_WITH("DEFERRABLE");
3275 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
3276 Matches("BEGIN", "ISOLATION") ||
3277 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
3278 COMPLETE_WITH("LEVEL");
3279 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
3280 Matches("BEGIN", "ISOLATION", "LEVEL") ||
3281 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
3282 COMPLETE_WITH("READ", "REPEATABLE READ", "SERIALIZABLE");
3283 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
3284 Matches("BEGIN", "ISOLATION", "LEVEL", "READ") ||
3285 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
3286 COMPLETE_WITH("UNCOMMITTED", "COMMITTED");
3287 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
3288 Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
3289 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
3290 COMPLETE_WITH("READ");
3291 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
3292 Matches("BEGIN", "READ") ||
3293 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
3294 COMPLETE_WITH("ONLY", "WRITE");
3295 /* SET CONSTRAINTS */
3296 else if (Matches("SET", "CONSTRAINTS"))
3297 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'");
3298 /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
3299 else if (Matches("SET", "CONSTRAINTS", MatchAny))
3300 COMPLETE_WITH("DEFERRED", "IMMEDIATE");
3301 /* Complete SET ROLE */
3302 else if (Matches("SET", "ROLE"))
3303 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3304 /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
3305 else if (Matches("SET", "SESSION"))
3306 COMPLETE_WITH("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
3307 /* Complete SET SESSION AUTHORIZATION with username */
3308 else if (Matches("SET", "SESSION", "AUTHORIZATION"))
3309 COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'");
3310 /* Complete RESET SESSION with AUTHORIZATION */
3311 else if (Matches("RESET", "SESSION"))
3312 COMPLETE_WITH("AUTHORIZATION");
3313 /* Complete SET <var> with "TO" */
3314 else if (Matches("SET", MatchAny))
3315 COMPLETE_WITH("TO");
3318 * Complete ALTER DATABASE|FUNCTION||PROCEDURE|ROLE|ROUTINE|USER ... SET
3321 else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") &&
3322 TailMatches("SET", MatchAny))
3323 COMPLETE_WITH("FROM CURRENT", "TO");
3324 /* Suggest possible variable values */
3325 else if (TailMatches("SET", MatchAny, "TO|="))
3327 /* special cased code for individual GUCs */
3328 if (TailMatches("DateStyle", "TO|="))
3329 COMPLETE_WITH("ISO", "SQL", "Postgres", "German",
3330 "YMD", "DMY", "MDY",
3331 "US", "European", "NonEuropean",
3333 else if (TailMatches("search_path", "TO|="))
3334 COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3335 " AND nspname not like 'pg\\_toast%%' "
3336 " AND nspname not like 'pg\\_temp%%' "
3337 " UNION SELECT 'DEFAULT' ");
3340 /* generic, type based, GUC support */
3341 char *guctype = get_guctype(prev2_wd);
3343 if (guctype && strcmp(guctype, "enum") == 0)
3345 char querybuf[1024];
3347 snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd);
3348 COMPLETE_WITH_QUERY(querybuf);
3350 else if (guctype && strcmp(guctype, "bool") == 0)
3351 COMPLETE_WITH("on", "off", "true", "false", "yes", "no",
3352 "1", "0", "DEFAULT");
3354 COMPLETE_WITH("DEFAULT");
3361 /* START TRANSACTION */
3362 else if (Matches("START"))
3363 COMPLETE_WITH("TRANSACTION");
3365 /* TABLE, but not TABLE embedded in other commands */
3366 else if (Matches("TABLE"))
3367 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3370 else if (TailMatches("TABLESAMPLE"))
3371 COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
3372 else if (TailMatches("TABLESAMPLE", MatchAny))
3376 else if (Matches("TRUNCATE"))
3377 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3380 else if (Matches("UNLISTEN"))
3381 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 '*'");
3383 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
3384 /* If prev. word is UPDATE suggest a list of tables */
3385 else if (TailMatches("UPDATE"))
3386 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3387 /* Complete UPDATE <table> with "SET" */
3388 else if (TailMatches("UPDATE", MatchAny))
3389 COMPLETE_WITH("SET");
3390 /* Complete UPDATE <table> SET with list of attributes */
3391 else if (TailMatches("UPDATE", MatchAny, "SET"))
3392 COMPLETE_WITH_ATTR(prev2_wd, "");
3393 /* UPDATE <table> SET <attr> = */
3394 else if (TailMatches("UPDATE", MatchAny, "SET", MatchAny))
3398 else if (Matches("ALTER|CREATE|DROP", "USER", "MAPPING"))
3399 COMPLETE_WITH("FOR");
3400 else if (Matches("CREATE", "USER", "MAPPING", "FOR"))
3401 COMPLETE_WITH_QUERY(Query_for_list_of_roles
3402 " UNION SELECT 'CURRENT_USER'"
3403 " UNION SELECT 'PUBLIC'"
3404 " UNION SELECT 'USER'");
3405 else if (Matches("ALTER|DROP", "USER", "MAPPING", "FOR"))
3406 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3407 else if (Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
3408 COMPLETE_WITH("SERVER");
3409 else if (Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
3410 COMPLETE_WITH("OPTIONS");
3413 * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
3414 * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
3416 else if (Matches("VACUUM"))
3417 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3418 " UNION SELECT 'FULL'"
3419 " UNION SELECT 'FREEZE'"
3420 " UNION SELECT 'ANALYZE'"
3421 " UNION SELECT 'VERBOSE'");
3422 else if (Matches("VACUUM", "FULL"))
3423 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3424 " UNION SELECT 'FREEZE'"
3425 " UNION SELECT 'ANALYZE'"
3426 " UNION SELECT 'VERBOSE'");
3427 else if (Matches("VACUUM", "FREEZE") ||
3428 Matches("VACUUM", "FULL", "FREEZE"))
3429 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3430 " UNION SELECT 'VERBOSE'"
3431 " UNION SELECT 'ANALYZE'");
3432 else if (Matches("VACUUM", "VERBOSE") ||
3433 Matches("VACUUM", "FULL|FREEZE", "VERBOSE") ||
3434 Matches("VACUUM", "FULL", "FREEZE", "VERBOSE"))
3435 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3436 " UNION SELECT 'ANALYZE'");
3437 else if (HeadMatches("VACUUM", "(*") &&
3438 !HeadMatches("VACUUM", "(*)"))
3441 * This fires if we're in an unfinished parenthesized option list.
3442 * get_previous_words treats a completed parenthesized option list as
3443 * one word, so the above test is correct.
3445 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
3446 COMPLETE_WITH("FULL", "FREEZE", "ANALYZE", "VERBOSE",
3447 "DISABLE_PAGE_SKIPPING", "SKIP_LOCKED",
3449 else if (TailMatches("FULL|FREEZE|ANALYZE|VERBOSE|DISABLE_PAGE_SKIPPING|SKIP_LOCKED|INDEX_CLEANUP"))
3450 COMPLETE_WITH("ON", "OFF");
3452 else if (HeadMatches("VACUUM") && TailMatches("("))
3453 /* "VACUUM (" should be caught above, so assume we want columns */
3454 COMPLETE_WITH_ATTR(prev2_wd, "");
3455 else if (HeadMatches("VACUUM"))
3456 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, NULL);
3458 /* WITH [RECURSIVE] */
3461 * Only match when WITH is the first word, as WITH may appear in many
3464 else if (Matches("WITH"))
3465 COMPLETE_WITH("RECURSIVE");
3468 /* Simple case of the word before the where being the table name */
3469 else if (TailMatches(MatchAny, "WHERE"))
3470 COMPLETE_WITH_ATTR(prev2_wd, "");
3473 /* TODO: also include SRF ? */
3474 else if (TailMatches("FROM") && !Matches("COPY|\\copy", MatchAny, "FROM"))
3475 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3478 else if (TailMatches("JOIN"))
3479 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3481 /* Backslash commands */
3482 /* TODO: \dc \dd \dl */
3483 else if (TailMatchesCS("\\?"))
3484 COMPLETE_WITH_CS("commands", "options", "variables");
3485 else if (TailMatchesCS("\\connect|\\c"))
3487 if (!recognized_connection_string(text))
3488 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3490 else if (TailMatchesCS("\\connect|\\c", MatchAny))
3492 if (!recognized_connection_string(prev_wd))
3493 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3495 else if (TailMatchesCS("\\da*"))
3496 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
3497 else if (TailMatchesCS("\\dA*"))
3498 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3499 else if (TailMatchesCS("\\db*"))
3500 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3501 else if (TailMatchesCS("\\dD*"))
3502 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3503 else if (TailMatchesCS("\\des*"))
3504 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3505 else if (TailMatchesCS("\\deu*"))
3506 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3507 else if (TailMatchesCS("\\dew*"))
3508 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3509 else if (TailMatchesCS("\\df*"))
3510 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3512 else if (TailMatchesCS("\\dFd*"))
3513 COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
3514 else if (TailMatchesCS("\\dFp*"))
3515 COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
3516 else if (TailMatchesCS("\\dFt*"))
3517 COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
3518 /* must be at end of \dF alternatives: */
3519 else if (TailMatchesCS("\\dF*"))
3520 COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
3522 else if (TailMatchesCS("\\di*"))
3523 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3524 else if (TailMatchesCS("\\dL*"))
3525 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3526 else if (TailMatchesCS("\\dn*"))
3527 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3528 else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z"))
3529 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL);
3530 else if (TailMatchesCS("\\ds*"))
3531 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3532 else if (TailMatchesCS("\\dt*"))
3533 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3534 else if (TailMatchesCS("\\dT*"))
3535 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3536 else if (TailMatchesCS("\\du*") || TailMatchesCS("\\dg*"))
3537 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3538 else if (TailMatchesCS("\\dv*"))
3539 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3540 else if (TailMatchesCS("\\dx*"))
3541 COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
3542 else if (TailMatchesCS("\\dm*"))
3543 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3544 else if (TailMatchesCS("\\dE*"))
3545 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
3546 else if (TailMatchesCS("\\dy*"))
3547 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3549 /* must be at end of \d alternatives: */
3550 else if (TailMatchesCS("\\d*"))
3551 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3553 else if (TailMatchesCS("\\ef"))
3554 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3555 else if (TailMatchesCS("\\ev"))
3556 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3558 else if (TailMatchesCS("\\encoding"))
3559 COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
3560 else if (TailMatchesCS("\\h|\\help"))
3561 COMPLETE_WITH_LIST(sql_commands);
3562 else if (TailMatchesCS("\\h|\\help", MatchAny))
3564 if (TailMatches("DROP"))
3565 matches = completion_matches(text, drop_command_generator);
3566 else if (TailMatches("ALTER"))
3567 matches = completion_matches(text, alter_command_generator);
3570 * CREATE is recognized by tail match elsewhere, so doesn't need to be
3574 else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny))
3576 if (TailMatches("CREATE|DROP", "ACCESS"))
3577 COMPLETE_WITH("METHOD");
3578 else if (TailMatches("ALTER", "DEFAULT"))
3579 COMPLETE_WITH("PRIVILEGES");
3580 else if (TailMatches("CREATE|ALTER|DROP", "EVENT"))
3581 COMPLETE_WITH("TRIGGER");
3582 else if (TailMatches("CREATE|ALTER|DROP", "FOREIGN"))
3583 COMPLETE_WITH("DATA WRAPPER", "TABLE");
3584 else if (TailMatches("ALTER", "LARGE"))
3585 COMPLETE_WITH("OBJECT");
3586 else if (TailMatches("CREATE|ALTER|DROP", "MATERIALIZED"))
3587 COMPLETE_WITH("VIEW");
3588 else if (TailMatches("CREATE|ALTER|DROP", "TEXT"))
3589 COMPLETE_WITH("SEARCH");
3590 else if (TailMatches("CREATE|ALTER|DROP", "USER"))
3591 COMPLETE_WITH("MAPPING FOR");
3593 else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny))
3595 if (TailMatches("CREATE|ALTER|DROP", "FOREIGN", "DATA"))
3596 COMPLETE_WITH("WRAPPER");
3597 else if (TailMatches("CREATE|ALTER|DROP", "TEXT", "SEARCH"))
3598 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
3599 else if (TailMatches("CREATE|ALTER|DROP", "USER", "MAPPING"))
3600 COMPLETE_WITH("FOR");
3602 else if (TailMatchesCS("\\l*") && !TailMatchesCS("\\lo*"))
3603 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3604 else if (TailMatchesCS("\\password"))
3605 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3606 else if (TailMatchesCS("\\pset"))
3607 COMPLETE_WITH_CS("border", "columns", "csv_fieldsep", "expanded",
3608 "fieldsep", "fieldsep_zero", "footer", "format",
3609 "linestyle", "null", "numericlocale",
3610 "pager", "pager_min_lines",
3611 "recordsep", "recordsep_zero",
3612 "tableattr", "title", "tuples_only",
3613 "unicode_border_linestyle",
3614 "unicode_column_linestyle",
3615 "unicode_header_linestyle");
3616 else if (TailMatchesCS("\\pset", MatchAny))
3618 if (TailMatchesCS("format"))
3619 COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex",
3620 "latex-longtable", "troff-ms", "unaligned",
3622 else if (TailMatchesCS("linestyle"))
3623 COMPLETE_WITH_CS("ascii", "old-ascii", "unicode");
3624 else if (TailMatchesCS("pager"))
3625 COMPLETE_WITH_CS("on", "off", "always");
3626 else if (TailMatchesCS("unicode_border_linestyle|"
3627 "unicode_column_linestyle|"
3628 "unicode_header_linestyle"))
3629 COMPLETE_WITH_CS("single", "double");
3631 else if (TailMatchesCS("\\unset"))
3632 matches = complete_from_variables(text, "", "", true);
3633 else if (TailMatchesCS("\\set"))
3634 matches = complete_from_variables(text, "", "", false);
3635 else if (TailMatchesCS("\\set", MatchAny))
3637 if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
3638 "SINGLELINE|SINGLESTEP"))
3639 COMPLETE_WITH_CS("on", "off");
3640 else if (TailMatchesCS("COMP_KEYWORD_CASE"))
3641 COMPLETE_WITH_CS("lower", "upper",
3642 "preserve-lower", "preserve-upper");
3643 else if (TailMatchesCS("ECHO"))
3644 COMPLETE_WITH_CS("errors", "queries", "all", "none");
3645 else if (TailMatchesCS("ECHO_HIDDEN"))
3646 COMPLETE_WITH_CS("noexec", "off", "on");
3647 else if (TailMatchesCS("HISTCONTROL"))
3648 COMPLETE_WITH_CS("ignorespace", "ignoredups",
3649 "ignoreboth", "none");
3650 else if (TailMatchesCS("ON_ERROR_ROLLBACK"))
3651 COMPLETE_WITH_CS("on", "off", "interactive");
3652 else if (TailMatchesCS("SHOW_CONTEXT"))
3653 COMPLETE_WITH_CS("never", "errors", "always");
3654 else if (TailMatchesCS("VERBOSITY"))
3655 COMPLETE_WITH_CS("default", "verbose", "terse");
3657 else if (TailMatchesCS("\\sf*"))
3658 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3659 else if (TailMatchesCS("\\sv*"))
3660 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3661 else if (TailMatchesCS("\\cd|\\e|\\edit|\\g|\\i|\\include|"
3662 "\\ir|\\include_relative|\\o|\\out|"
3663 "\\s|\\w|\\write|\\lo_import"))
3665 completion_charp = "\\";
3666 matches = completion_matches(text, complete_from_files);
3670 * Finally, we look through the list of "things", such as TABLE, INDEX and
3671 * check if that was the previous word. If so, execute the query to get a
3678 for (i = 0; words_after_create[i].name; i++)
3680 if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
3682 if (words_after_create[i].query)
3683 COMPLETE_WITH_QUERY(words_after_create[i].query);
3684 else if (words_after_create[i].vquery)
3685 COMPLETE_WITH_VERSIONED_QUERY(words_after_create[i].vquery);
3686 else if (words_after_create[i].squery)
3687 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(words_after_create[i].squery,
3695 * If we still don't have anything to match we have to fabricate some sort
3696 * of default list. If we were to just return NULL, readline automatically
3697 * attempts filename completion, and that's usually no good.
3699 if (matches == NULL)
3702 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
3703 rl_completion_append_character = '\0';
3708 free(previous_words);
3711 /* Return our Grand List O' Matches */
3717 * GENERATOR FUNCTIONS
3719 * These functions do all the actual work of completing the input. They get
3720 * passed the text so far and the count how many times they have been called
3721 * so far with the same text.
3722 * If you read the above carefully, you'll see that these don't get called
3723 * directly but through the readline interface.
3724 * The return value is expected to be the full completion of the text, going
3725 * through a list each time, or NULL if there are no more matches. The string
3726 * will be free()'d by readline, so you must run it through strdup() or
3727 * something of that sort.
3731 * Common routine for create_command_generator and drop_command_generator.
3732 * Entries that have 'excluded' flags are not returned.
3735 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
3737 static int list_index,
3741 /* If this is the first time for this completion, init some values */
3745 string_length = strlen(text);
3748 /* find something that matches */
3749 while ((name = words_after_create[list_index++].name))
3751 if ((pg_strncasecmp(name, text, string_length) == 0) &&
3752 !(words_after_create[list_index - 1].flags & excluded))
3753 return pg_strdup_keyword_case(name, text);
3755 /* if nothing matches, return NULL */
3760 * This one gives you one from a list of things you can put after CREATE
3764 create_command_generator(const char *text, int state)
3766 return create_or_drop_command_generator(text, state, THING_NO_CREATE);
3770 * This function gives you a list of things you can put after a DROP command.
3773 drop_command_generator(const char *text, int state)
3775 return create_or_drop_command_generator(text, state, THING_NO_DROP);
3779 * This function gives you a list of things you can put after an ALTER command.
3782 alter_command_generator(const char *text, int state)
3784 return create_or_drop_command_generator(text, state, THING_NO_ALTER);
3788 * These functions generate lists using server queries.
3789 * They are all wrappers for _complete_from_query.
3793 complete_from_query(const char *text, int state)
3795 /* query is assumed to work for any server version */
3796 return _complete_from_query(completion_charp, NULL, text, state);
3800 complete_from_versioned_query(const char *text, int state)
3802 const VersionedQuery *vquery = completion_vquery;
3804 /* Find appropriate array element */
3805 while (pset.sversion < vquery->min_server_version)
3807 /* Fail completion if server is too old */
3808 if (vquery->query == NULL)
3811 return _complete_from_query(vquery->query, NULL, text, state);
3815 complete_from_schema_query(const char *text, int state)
3817 /* query is assumed to work for any server version */
3818 return _complete_from_query(completion_charp, completion_squery,
3823 complete_from_versioned_schema_query(const char *text, int state)
3825 const SchemaQuery *squery = completion_squery;
3826 const VersionedQuery *vquery = completion_vquery;
3828 /* Find appropriate array element */
3829 while (pset.sversion < squery->min_server_version)
3831 /* Fail completion if server is too old */
3832 if (squery->catname == NULL)
3835 /* Likewise for the add-on text, if any */
3838 while (pset.sversion < vquery->min_server_version)
3840 if (vquery->query == NULL)
3844 return _complete_from_query(vquery ? vquery->query : NULL,
3845 squery, text, state);
3850 * This creates a list of matching things, according to a query described by
3851 * the initial arguments. The caller has already done any work needed to
3852 * select the appropriate query for the server's version.
3854 * The query can be one of two kinds:
3856 * 1. A simple query which must contain a %d and a %s, which will be replaced
3857 * by the string length of the text and the text itself. The query may also
3858 * have up to four more %s in it; the first two such will be replaced by the
3859 * value of completion_info_charp, the next two by the value of
3860 * completion_info_charp2.
3862 * 2. A schema query used for completion of both schema and relation names.
3863 * These are more complex and must contain in the following order:
3864 * %d %s %d %s %d %s %s %d %s
3865 * where %d is the string length of the text and %s the text itself.
3867 * If both simple_query and schema_query are non-NULL, then we construct
3868 * a schema query and append the (uninterpreted) string simple_query to it.
3870 * It is assumed that strings should be escaped to become SQL literals
3871 * (that is, what is in the query is actually ... '%s' ...)
3873 * See top of file for examples of both kinds of query.
3875 * "text" and "state" are supplied by readline.
3878 _complete_from_query(const char *simple_query,
3879 const SchemaQuery *schema_query,
3880 const char *text, int state)
3882 static int list_index,
3884 static PGresult *result = NULL;
3887 * If this is the first time for this completion, we fetch a list of our
3888 * "things" from the backend.
3892 PQExpBufferData query_buffer;
3895 char *e_info_charp2;
3896 const char *pstr = text;
3897 int char_length = 0;
3900 byte_length = strlen(text);
3903 * Count length as number of characters (not bytes), for passing to
3909 pstr += PQmblen(pstr, pset.encoding);
3912 /* Free any prior result */
3916 /* Set up suitably-escaped copies of textual inputs */
3917 e_text = escape_string(text);
3919 if (completion_info_charp)
3920 e_info_charp = escape_string(completion_info_charp);
3922 e_info_charp = NULL;
3924 if (completion_info_charp2)
3925 e_info_charp2 = escape_string(completion_info_charp2);
3927 e_info_charp2 = NULL;
3929 initPQExpBuffer(&query_buffer);
3933 /* schema_query gives us the pieces to assemble */
3934 const char *qualresult = schema_query->qualresult;
3936 if (qualresult == NULL)
3937 qualresult = schema_query->result;
3939 /* Get unqualified names matching the input-so-far */
3940 appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
3941 schema_query->result,
3942 schema_query->catname);
3943 if (schema_query->selcondition)
3944 appendPQExpBuffer(&query_buffer, "%s AND ",
3945 schema_query->selcondition);
3946 appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
3947 schema_query->result,
3948 char_length, e_text);
3949 appendPQExpBuffer(&query_buffer, " AND %s",
3950 schema_query->viscondition);
3953 * When fetching relation names, suppress system catalogs unless
3954 * the input-so-far begins with "pg_". This is a compromise
3955 * between not offering system catalogs for completion at all, and
3956 * having them swamp the result when the input is just "p".
3958 if (strcmp(schema_query->catname,
3959 "pg_catalog.pg_class c") == 0 &&
3960 strncmp(text, "pg_", 3) !=0)
3962 appendPQExpBufferStr(&query_buffer,
3963 " AND c.relnamespace <> (SELECT oid FROM"
3964 " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
3968 * Add in matching schema names, but only if there is more than
3969 * one potential match among schema names.
3971 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3972 "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
3973 "FROM pg_catalog.pg_namespace n "
3974 "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
3975 char_length, e_text);
3976 appendPQExpBuffer(&query_buffer,
3977 " AND (SELECT pg_catalog.count(*)"
3978 " FROM pg_catalog.pg_namespace"
3979 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3980 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
3981 char_length, e_text);
3984 * Add in matching qualified names, but only if there is exactly
3985 * one schema matching the input-so-far.
3987 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3988 "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
3989 "FROM %s, pg_catalog.pg_namespace n "
3990 "WHERE %s = n.oid AND ",
3992 schema_query->catname,
3993 schema_query->namespace);
3994 if (schema_query->selcondition)
3995 appendPQExpBuffer(&query_buffer, "%s AND ",
3996 schema_query->selcondition);
3997 appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
3999 char_length, e_text);
4002 * This condition exploits the single-matching-schema rule to
4003 * speed up the query
4005 appendPQExpBuffer(&query_buffer,
4006 " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
4007 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
4008 char_length, e_text);
4009 appendPQExpBuffer(&query_buffer,
4010 " AND (SELECT pg_catalog.count(*)"
4011 " FROM pg_catalog.pg_namespace"
4012 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
4013 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
4014 char_length, e_text);
4016 /* If an addon query was provided, use it */
4018 appendPQExpBuffer(&query_buffer, "\n%s", simple_query);
4022 Assert(simple_query);
4023 /* simple_query is an sprintf-style format string */
4024 appendPQExpBuffer(&query_buffer, simple_query,
4025 char_length, e_text,
4026 e_info_charp, e_info_charp,
4027 e_info_charp2, e_info_charp2);
4030 /* Limit the number of records in the result */
4031 appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
4032 completion_max_records);
4034 result = exec_query(query_buffer.data);
4036 termPQExpBuffer(&query_buffer);
4041 free(e_info_charp2);
4044 /* Find something that matches */
4045 if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
4049 while (list_index < PQntuples(result) &&
4050 (item = PQgetvalue(result, list_index++, 0)))
4051 if (pg_strncasecmp(text, item, byte_length) == 0)
4052 return pg_strdup(item);
4055 /* If nothing matches, free the db structure and return null */
4063 * This function returns in order one of a fixed, NULL pointer terminated list
4064 * of strings (if matching). This can be used if there are only a fixed number
4065 * SQL words that can appear at certain spot.
4068 complete_from_list(const char *text, int state)
4070 static int string_length,
4073 static bool casesensitive;
4076 /* need to have a list */
4077 Assert(completion_charpp != NULL);
4079 /* Initialization */
4083 string_length = strlen(text);
4084 casesensitive = completion_case_sensitive;
4088 while ((item = completion_charpp[list_index++]))
4090 /* First pass is case sensitive */
4091 if (casesensitive && strncmp(text, item, string_length) == 0)
4094 return pg_strdup(item);
4097 /* Second pass is case insensitive, don't bother counting matches */
4098 if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
4100 if (completion_case_sensitive)
4101 return pg_strdup(item);
4105 * If case insensitive matching was requested initially,
4106 * adjust the case according to setting.
4108 return pg_strdup_keyword_case(item, text);
4113 * No matches found. If we're not case insensitive already, lets switch to
4114 * being case insensitive and try again
4116 if (casesensitive && matches == 0)
4118 casesensitive = false;
4121 return complete_from_list(text, state);
4124 /* If no more matches, return null. */
4130 * This function returns one fixed string the first time even if it doesn't
4131 * match what's there, and nothing the second time. This should be used if
4132 * there is only one possibility that can appear at a certain spot, so
4133 * misspellings will be overwritten. The string to be passed must be in
4137 complete_from_const(const char *text, int state)
4139 Assert(completion_charp != NULL);
4142 if (completion_case_sensitive)
4143 return pg_strdup(completion_charp);
4147 * If case insensitive matching was requested initially, adjust
4148 * the case according to setting.
4150 return pg_strdup_keyword_case(completion_charp, text);
4158 * This function appends the variable name with prefix and suffix to
4159 * the variable names array.
4162 append_variable_names(char ***varnames, int *nvars,
4163 int *maxvars, const char *varname,
4164 const char *prefix, const char *suffix)
4166 if (*nvars >= *maxvars)
4169 *varnames = (char **) pg_realloc(*varnames,
4170 ((*maxvars) + 1) * sizeof(char *));
4173 (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
4178 * This function supports completion with the name of a psql variable.
4179 * The variable names can be prefixed and suffixed with additional text
4180 * to support quoting usages. If need_value is true, only variables
4181 * that are currently set are included; otherwise, special variables
4182 * (those that have hooks) are included even if currently unset.
4185 complete_from_variables(const char *text, const char *prefix, const char *suffix,
4193 struct _variable *ptr;
4195 varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
4197 for (ptr = pset.vars->next; ptr; ptr = ptr->next)
4199 if (need_value && !(ptr->value))
4201 append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
4205 varnames[nvars] = NULL;
4206 COMPLETE_WITH_LIST_CS((const char *const *) varnames);
4208 for (i = 0; i < nvars; i++)
4217 * This function wraps rl_filename_completion_function() to strip quotes from
4218 * the input before searching for matches and to quote any matches for which
4219 * the consuming command will require it.
4222 complete_from_files(const char *text, int state)
4224 static const char *unquoted_text;
4225 char *unquoted_match;
4230 /* Initialization: stash the unquoted input. */
4231 unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
4232 false, true, pset.encoding);
4233 /* expect a NULL return for the empty string only */
4236 Assert(*text == '\0');
4237 unquoted_text = text;
4241 unquoted_match = filename_completion_function(unquoted_text, state);
4245 * Caller sets completion_charp to a zero- or one-character string
4246 * containing the escape character. This is necessary since \copy has
4247 * no escape character, but every other backslash command recognizes
4248 * "\" as an escape character. Since we have only two callers, don't
4249 * bother providing a macro to simplify this.
4251 ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
4252 '\'', *completion_charp, pset.encoding);
4254 free(unquoted_match);
4256 ret = unquoted_match;
4263 /* HELPER FUNCTIONS */
4267 * Make a pg_strdup copy of s and convert the case according to
4268 * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
4271 pg_strdup_keyword_case(const char *s, const char *ref)
4275 unsigned char first = ref[0];
4279 if (pset.comp_case == PSQL_COMP_CASE_LOWER ||
4280 ((pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER ||
4281 pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
4282 (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
4284 for (p = ret; *p; p++)
4285 *p = pg_tolower((unsigned char) *p);
4289 for (p = ret; *p; p++)
4290 *p = pg_toupper((unsigned char) *p);
4298 * escape_string - Escape argument for use as string literal.
4300 * The returned value has to be freed.
4303 escape_string(const char *text)
4308 text_length = strlen(text);
4310 result = pg_malloc(text_length * 2 + 1);
4311 PQescapeStringConn(pset.db, result, text, text_length, NULL);
4318 * Execute a query and report any errors. This should be the preferred way of
4319 * talking to the database in this file.
4322 exec_query(const char *query)
4326 if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
4329 result = PQexec(pset.db, query);
4331 if (PQresultStatus(result) != PGRES_TUPLES_OK)
4334 pg_log_error("tab completion query failed: %s\nQuery was:\n%s",
4335 PQerrorMessage(pset.db), query);
4346 * Parse all the word(s) before point.
4348 * Returns a malloc'd array of character pointers that point into the malloc'd
4349 * data array returned to *buffer; caller must free() both of these when done.
4350 * *nwords receives the number of words found, ie, the valid length of the
4353 * Words are returned right to left, that is, previous_words[0] gets the last
4354 * word before point, previous_words[1] the next-to-last, etc.
4357 get_previous_words(int point, char **buffer, int *nwords)
4359 char **previous_words;
4362 int words_found = 0;
4366 * If we have anything in tab_completion_query_buf, paste it together with
4367 * rl_line_buffer to construct the full query. Otherwise we can just use
4368 * rl_line_buffer as the input string.
4370 if (tab_completion_query_buf && tab_completion_query_buf->len > 0)
4372 i = tab_completion_query_buf->len;
4373 buf = pg_malloc(point + i + 2);
4374 memcpy(buf, tab_completion_query_buf->data, i);
4376 memcpy(buf + i, rl_line_buffer, point);
4379 /* Readjust point to reference appropriate offset in buf */
4383 buf = rl_line_buffer;
4386 * Allocate an array of string pointers and a buffer to hold the strings
4387 * themselves. The worst case is that the line contains only
4388 * non-whitespace WORD_BREAKS characters, making each one a separate word.
4389 * This is usually much more space than we need, but it's cheaper than
4390 * doing a separate malloc() for each word.
4392 previous_words = (char **) pg_malloc(point * sizeof(char *));
4393 *buffer = outptr = (char *) pg_malloc(point * 2);
4396 * First we look for a non-word char before the current point. (This is
4397 * probably useless, if readline is on the same page as we are about what
4398 * is a word, but if so it's cheap.)
4400 for (i = point - 1; i >= 0; i--)
4402 if (strchr(WORD_BREAKS, buf[i]))
4408 * Now parse words, working backwards, until we hit start of line. The
4409 * backwards scan has some interesting but intentional properties
4410 * concerning parenthesis handling.
4416 bool inquotes = false;
4417 int parentheses = 0;
4419 /* now find the first non-space which then constitutes the end */
4421 for (i = point; i >= 0; i--)
4423 if (!isspace((unsigned char) buf[i]))
4429 /* if no end found, we're done */
4434 * Otherwise we now look for the start. The start is either the last
4435 * character before any word-break character going backwards from the
4436 * end, or it's simply character 0. We also handle open quotes and
4439 for (start = end; start > 0; start--)
4441 if (buf[start] == '"')
4442 inquotes = !inquotes;
4445 if (buf[start] == ')')
4447 else if (buf[start] == '(')
4449 if (--parentheses <= 0)
4452 else if (parentheses == 0 &&
4453 strchr(WORD_BREAKS, buf[start - 1]))
4458 /* Return the word located at start to end inclusive */
4459 previous_words[words_found++] = outptr;
4460 i = end - start + 1;
4461 memcpy(outptr, &buf[start], i);
4465 /* Continue searching */
4469 /* Release parsing input workspace, if we made one above */
4470 if (buf != rl_line_buffer)
4473 *nwords = words_found;
4474 return previous_words;
4478 * Look up the type for the GUC variable with the passed name.
4480 * Returns NULL if the variable is unknown. Otherwise the returned string,
4481 * containing the type, has to be freed.
4484 get_guctype(const char *varname)
4486 PQExpBufferData query_buffer;
4489 char *guctype = NULL;
4491 e_varname = escape_string(varname);
4493 initPQExpBuffer(&query_buffer);
4494 appendPQExpBuffer(&query_buffer,
4495 "SELECT vartype FROM pg_catalog.pg_settings "
4496 "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4499 result = exec_query(query_buffer.data);
4500 termPQExpBuffer(&query_buffer);
4503 if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
4504 guctype = pg_strdup(PQgetvalue(result, 0, 0));
4514 * Surround a string with single quotes. This works for both SQL and
4515 * psql internal. Currently disabled because it is reported not to
4516 * cooperate with certain versions of readline.
4519 quote_file_name(char *text, int match_type, char *quote_pointer)
4524 (void) quote_pointer; /* not used */
4526 length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
4527 s = pg_malloc(length);
4529 strcpy(s + 1, text);
4530 if (match_type == SINGLE_MATCH)
4531 s[length - 2] = '\'';
4532 s[length - 1] = '\0';
4537 dequote_file_name(char *text, char quote_char)
4543 return pg_strdup(text);
4545 length = strlen(text);
4546 s = pg_malloc(length - 2 + 1);
4547 strlcpy(s, text +1, length - 2 + 1);
4551 #endif /* NOT_USED */
4553 #endif /* USE_READLINE */