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",
1046 /* Forward declaration of functions */
1047 static char **psql_completion(const char *text, int start, int end);
1048 static char *create_command_generator(const char *text, int state);
1049 static char *drop_command_generator(const char *text, int state);
1050 static char *alter_command_generator(const char *text, int state);
1051 static char *complete_from_query(const char *text, int state);
1052 static char *complete_from_versioned_query(const char *text, int state);
1053 static char *complete_from_schema_query(const char *text, int state);
1054 static char *complete_from_versioned_schema_query(const char *text, int state);
1055 static char *_complete_from_query(const char *simple_query,
1056 const SchemaQuery *schema_query,
1057 const char *text, int state);
1058 static char *complete_from_list(const char *text, int state);
1059 static char *complete_from_const(const char *text, int state);
1060 static void append_variable_names(char ***varnames, int *nvars,
1061 int *maxvars, const char *varname,
1062 const char *prefix, const char *suffix);
1063 static char **complete_from_variables(const char *text,
1064 const char *prefix, const char *suffix, bool need_value);
1065 static char *complete_from_files(const char *text, int state);
1067 static char *pg_strdup_keyword_case(const char *s, const char *ref);
1068 static char *escape_string(const char *text);
1069 static PGresult *exec_query(const char *query);
1071 static char **get_previous_words(int point, char **buffer, int *nwords);
1073 static char *get_guctype(const char *varname);
1076 static char *quote_file_name(char *text, int match_type, char *quote_pointer);
1077 static char *dequote_file_name(char *text, char quote_char);
1082 * Initialize the readline library for our purposes.
1085 initialize_readline(void)
1087 rl_readline_name = (char *) pset.progname;
1088 rl_attempted_completion_function = psql_completion;
1090 rl_basic_word_break_characters = WORD_BREAKS;
1092 completion_max_records = 1000;
1095 * There is a variable rl_completion_query_items for this but apparently
1096 * it's not defined everywhere.
1101 * Check if 'word' matches any of the '|'-separated strings in 'pattern',
1102 * using case-insensitive or case-sensitive comparisons.
1104 * If pattern is NULL, it's a wild card that matches any word.
1105 * If pattern begins with '!', the result is negated, ie we check that 'word'
1106 * does *not* match any alternative appearing in the rest of 'pattern'.
1107 * Any alternative can contain '*' which is a wild card, i.e., it can match
1108 * any substring; however, we allow at most one '*' per alternative.
1110 * For readability, callers should use the macros MatchAny and MatchAnyExcept
1111 * to invoke those two special cases for 'pattern'. (But '|' and '*' must
1112 * just be written directly in patterns.)
1114 #define MatchAny NULL
1115 #define MatchAnyExcept(pattern) ("!" pattern)
1118 word_matches(const char *pattern,
1120 bool case_sensitive)
1124 #define cimatch(s1, s2, n) \
1125 (case_sensitive ? strncmp(s1, s2, n) == 0 : pg_strncasecmp(s1, s2, n) == 0)
1127 /* NULL pattern matches anything. */
1128 if (pattern == NULL)
1131 /* Handle negated patterns from the MatchAnyExcept macro. */
1132 if (*pattern == '!')
1133 return !word_matches(pattern + 1, word, case_sensitive);
1135 /* Else consider each alternative in the pattern. */
1136 wordlen = strlen(word);
1139 const char *star = NULL;
1142 /* Find end of current alternative, and locate any wild card. */
1144 while (*c != '\0' && *c != '|')
1150 /* Was there a wild card? */
1153 /* Yes, wildcard match? */
1154 size_t beforelen = star - pattern,
1155 afterlen = c - star - 1;
1157 if (wordlen >= (beforelen + afterlen) &&
1158 cimatch(word, pattern, beforelen) &&
1159 cimatch(word + wordlen - afterlen, star + 1, afterlen))
1164 /* No, plain match? */
1165 if (wordlen == (c - pattern) &&
1166 cimatch(word, pattern, wordlen))
1169 /* Out of alternatives? */
1172 /* Nope, try next alternative. */
1180 * Implementation of TailMatches and TailMatchesCS macros: do the last N words
1181 * in previous_words match the variadic arguments?
1183 * The array indexing might look backwards, but remember that
1184 * previous_words[0] contains the *last* word on the line, not the first.
1187 TailMatchesImpl(bool case_sensitive,
1188 int previous_words_count, char **previous_words,
1193 if (previous_words_count < narg)
1196 va_start(args, narg);
1198 for (int argno = 0; argno < narg; argno++)
1200 const char *arg = va_arg(args, const char *);
1202 if (!word_matches(arg, previous_words[narg - argno - 1],
1216 * Implementation of Matches and MatchesCS macros: do all of the words
1217 * in previous_words match the variadic arguments?
1220 MatchesImpl(bool case_sensitive,
1221 int previous_words_count, char **previous_words,
1226 if (previous_words_count != narg)
1229 va_start(args, narg);
1231 for (int argno = 0; argno < narg; argno++)
1233 const char *arg = va_arg(args, const char *);
1235 if (!word_matches(arg, previous_words[narg - argno - 1],
1249 * Implementation of HeadMatches and HeadMatchesCS macros: do the first N
1250 * words in previous_words match the variadic arguments?
1253 HeadMatchesImpl(bool case_sensitive,
1254 int previous_words_count, char **previous_words,
1259 if (previous_words_count < narg)
1262 va_start(args, narg);
1264 for (int argno = 0; argno < narg; argno++)
1266 const char *arg = va_arg(args, const char *);
1268 if (!word_matches(arg, previous_words[previous_words_count - argno - 1],
1282 * Check if the final character of 's' is 'c'.
1285 ends_with(const char *s, char c)
1287 size_t length = strlen(s);
1289 return (length > 0 && s[length - 1] == c);
1293 * The completion function.
1295 * According to readline spec this gets passed the text entered so far and its
1296 * start and end positions in the readline buffer. The return value is some
1297 * partially obscure list format that can be generated by readline's
1298 * completion_matches() function, so we don't have to worry about it.
1301 psql_completion(const char *text, int start, int end)
1303 /* This is the variable we'll return. */
1304 char **matches = NULL;
1306 /* Workspace for parsed words. */
1309 /* This array will contain pointers to parsed words. */
1310 char **previous_words;
1312 /* The number of words found on the input line. */
1313 int previous_words_count;
1316 * For compactness, we use these macros to reference previous_words[].
1317 * Caution: do not access a previous_words[] entry without having checked
1318 * previous_words_count to be sure it's valid. In most cases below, that
1319 * check is implicit in a TailMatches() or similar macro, but in some
1320 * places we have to check it explicitly.
1322 #define prev_wd (previous_words[0])
1323 #define prev2_wd (previous_words[1])
1324 #define prev3_wd (previous_words[2])
1325 #define prev4_wd (previous_words[3])
1326 #define prev5_wd (previous_words[4])
1327 #define prev6_wd (previous_words[5])
1328 #define prev7_wd (previous_words[6])
1329 #define prev8_wd (previous_words[7])
1330 #define prev9_wd (previous_words[8])
1332 /* Match the last N words before point, case-insensitively. */
1333 #define TailMatches(...) \
1334 TailMatchesImpl(false, previous_words_count, previous_words, \
1335 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1337 /* Match the last N words before point, case-sensitively. */
1338 #define TailMatchesCS(...) \
1339 TailMatchesImpl(true, previous_words_count, previous_words, \
1340 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1342 /* Match N words representing all of the line, case-insensitively. */
1343 #define Matches(...) \
1344 MatchesImpl(false, previous_words_count, previous_words, \
1345 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1347 /* Match N words representing all of the line, case-sensitively. */
1348 #define MatchesCS(...) \
1349 MatchesImpl(true, previous_words_count, previous_words, \
1350 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1352 /* Match the first N words on the line, case-insensitively. */
1353 #define HeadMatches(...) \
1354 HeadMatchesImpl(false, previous_words_count, previous_words, \
1355 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1357 /* Match the first N words on the line, case-sensitively. */
1358 #define HeadMatchesCS(...) \
1359 HeadMatchesImpl(true, previous_words_count, previous_words, \
1360 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1362 /* Known command-starting keywords. */
1363 static const char *const sql_commands[] = {
1364 "ABORT", "ALTER", "ANALYZE", "BEGIN", "CALL", "CHECKPOINT", "CLOSE", "CLUSTER",
1365 "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
1366 "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
1367 "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK",
1368 "MOVE", "NOTIFY", "PREPARE",
1369 "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
1370 "RESET", "REVOKE", "ROLLBACK",
1371 "SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
1372 "TABLE", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", "VALUES", "WITH",
1376 /* psql's backslash commands. */
1377 static const char *const backslash_commands[] = {
1379 "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
1380 "\\copyright", "\\crosstabview",
1381 "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
1382 "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
1383 "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
1384 "\\dm", "\\dn", "\\do", "\\dO", "\\dp",
1385 "\\drds", "\\dRs", "\\dRp", "\\ds", "\\dS",
1386 "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
1387 "\\e", "\\echo", "\\ef", "\\elif", "\\else", "\\encoding",
1388 "\\endif", "\\errverbose", "\\ev",
1390 "\\g", "\\gdesc", "\\gexec", "\\gset", "\\gx",
1391 "\\h", "\\help", "\\H",
1392 "\\i", "\\if", "\\ir",
1393 "\\l", "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
1395 "\\p", "\\password", "\\prompt", "\\pset",
1398 "\\s", "\\set", "\\setenv", "\\sf", "\\sv",
1399 "\\t", "\\T", "\\timing",
1408 (void) end; /* "end" is not used */
1410 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1411 rl_completion_append_character = ' ';
1414 /* Clear a few things. */
1415 completion_charp = NULL;
1416 completion_charpp = NULL;
1417 completion_info_charp = NULL;
1418 completion_info_charp2 = NULL;
1421 * Scan the input line to extract the words before our current position.
1422 * According to those we'll make some smart decisions on what the user is
1423 * probably intending to type.
1425 previous_words = get_previous_words(start,
1427 &previous_words_count);
1429 /* If current word is a backslash command, offer completions for that */
1430 if (text[0] == '\\')
1431 COMPLETE_WITH_LIST_CS(backslash_commands);
1433 /* If current word is a variable interpolation, handle that case */
1434 else if (text[0] == ':' && text[1] != ':')
1436 if (text[1] == '\'')
1437 matches = complete_from_variables(text, ":'", "'", true);
1438 else if (text[1] == '"')
1439 matches = complete_from_variables(text, ":\"", "\"", true);
1441 matches = complete_from_variables(text, ":", "", true);
1444 /* If no previous word, suggest one of the basic sql commands */
1445 else if (previous_words_count == 0)
1446 COMPLETE_WITH_LIST(sql_commands);
1449 /* complete with something you can create */
1450 else if (TailMatches("CREATE"))
1451 matches = completion_matches(text, create_command_generator);
1453 /* DROP, but not DROP embedded in other commands */
1454 /* complete with something you can drop */
1455 else if (Matches("DROP"))
1456 matches = completion_matches(text, drop_command_generator);
1461 else if (Matches("ALTER", "TABLE"))
1462 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
1463 "UNION SELECT 'ALL IN TABLESPACE'");
1465 /* ALTER something */
1466 else if (Matches("ALTER"))
1467 matches = completion_matches(text, alter_command_generator);
1468 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */
1469 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny))
1470 COMPLETE_WITH("SET TABLESPACE", "OWNED BY");
1471 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */
1472 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"))
1473 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1474 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */
1475 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny))
1476 COMPLETE_WITH("SET TABLESPACE");
1477 /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> */
1478 else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
1480 /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> (...) */
1481 else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny))
1483 if (ends_with(prev_wd, ')'))
1484 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1486 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
1488 /* ALTER PUBLICATION <name> */
1489 else if (Matches("ALTER", "PUBLICATION", MatchAny))
1490 COMPLETE_WITH("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET");
1491 /* ALTER PUBLICATION <name> SET */
1492 else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET"))
1493 COMPLETE_WITH("(", "TABLE");
1494 /* ALTER PUBLICATION <name> SET ( */
1495 else if (HeadMatches("ALTER", "PUBLICATION", MatchAny) && TailMatches("SET", "("))
1496 COMPLETE_WITH("publish");
1497 /* ALTER SUBSCRIPTION <name> */
1498 else if (Matches("ALTER", "SUBSCRIPTION", MatchAny))
1499 COMPLETE_WITH("CONNECTION", "ENABLE", "DISABLE", "OWNER TO",
1500 "RENAME TO", "REFRESH PUBLICATION", "SET");
1501 /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION */
1502 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1503 TailMatches("REFRESH", "PUBLICATION"))
1504 COMPLETE_WITH("WITH (");
1505 /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION WITH ( */
1506 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1507 TailMatches("REFRESH", "PUBLICATION", "WITH", "("))
1508 COMPLETE_WITH("copy_data");
1509 /* ALTER SUBSCRIPTION <name> SET */
1510 else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, "SET"))
1511 COMPLETE_WITH("(", "PUBLICATION");
1512 /* ALTER SUBSCRIPTION <name> SET ( */
1513 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "("))
1514 COMPLETE_WITH("slot_name", "synchronous_commit");
1515 /* ALTER SUBSCRIPTION <name> SET PUBLICATION */
1516 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "PUBLICATION"))
1518 /* complete with nothing here as this refers to remote publications */
1520 /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> */
1521 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1522 TailMatches("SET", "PUBLICATION", MatchAny))
1523 COMPLETE_WITH("WITH (");
1524 /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> WITH ( */
1525 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1526 TailMatches("SET", "PUBLICATION", MatchAny, "WITH", "("))
1527 COMPLETE_WITH("copy_data", "refresh");
1528 /* ALTER SCHEMA <name> */
1529 else if (Matches("ALTER", "SCHEMA", MatchAny))
1530 COMPLETE_WITH("OWNER TO", "RENAME TO");
1532 /* ALTER COLLATION <name> */
1533 else if (Matches("ALTER", "COLLATION", MatchAny))
1534 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1536 /* ALTER CONVERSION <name> */
1537 else if (Matches("ALTER", "CONVERSION", MatchAny))
1538 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1540 /* ALTER DATABASE <name> */
1541 else if (Matches("ALTER", "DATABASE", MatchAny))
1542 COMPLETE_WITH("RESET", "SET", "OWNER TO", "RENAME TO",
1543 "IS_TEMPLATE", "ALLOW_CONNECTIONS",
1544 "CONNECTION LIMIT");
1546 /* ALTER DATABASE <name> SET TABLESPACE */
1547 else if (Matches("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE"))
1548 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1550 /* ALTER EVENT TRIGGER */
1551 else if (Matches("ALTER", "EVENT", "TRIGGER"))
1552 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
1554 /* ALTER EVENT TRIGGER <name> */
1555 else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny))
1556 COMPLETE_WITH("DISABLE", "ENABLE", "OWNER TO", "RENAME TO");
1558 /* ALTER EVENT TRIGGER <name> ENABLE */
1559 else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"))
1560 COMPLETE_WITH("REPLICA", "ALWAYS");
1562 /* ALTER EXTENSION <name> */
1563 else if (Matches("ALTER", "EXTENSION", MatchAny))
1564 COMPLETE_WITH("ADD", "DROP", "UPDATE", "SET SCHEMA");
1566 /* ALTER EXTENSION <name> UPDATE */
1567 else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE"))
1569 completion_info_charp = prev2_wd;
1570 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO);
1573 /* ALTER EXTENSION <name> UPDATE TO */
1574 else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"))
1576 completion_info_charp = prev3_wd;
1577 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
1581 else if (Matches("ALTER", "FOREIGN"))
1582 COMPLETE_WITH("DATA WRAPPER", "TABLE");
1584 /* ALTER FOREIGN DATA WRAPPER <name> */
1585 else if (Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
1586 COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO");
1588 /* ALTER FOREIGN TABLE <name> */
1589 else if (Matches("ALTER", "FOREIGN", "TABLE", MatchAny))
1590 COMPLETE_WITH("ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE",
1591 "INHERIT", "NO INHERIT", "OPTIONS", "OWNER TO",
1592 "RENAME", "SET", "VALIDATE CONSTRAINT");
1595 else if (Matches("ALTER", "INDEX"))
1596 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
1597 "UNION SELECT 'ALL IN TABLESPACE'");
1598 /* ALTER INDEX <name> */
1599 else if (Matches("ALTER", "INDEX", MatchAny))
1600 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET",
1601 "RESET", "ATTACH PARTITION");
1602 else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH"))
1603 COMPLETE_WITH("PARTITION");
1604 else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION"))
1605 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
1606 /* ALTER INDEX <name> ALTER */
1607 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER"))
1608 COMPLETE_WITH("COLUMN");
1609 /* ALTER INDEX <name> ALTER COLUMN */
1610 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN"))
1612 completion_info_charp = prev3_wd;
1613 COMPLETE_WITH_QUERY(Query_for_list_of_attribute_numbers);
1615 /* ALTER INDEX <name> ALTER COLUMN <colnum> */
1616 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny))
1617 COMPLETE_WITH("SET STATISTICS");
1618 /* ALTER INDEX <name> ALTER COLUMN <colnum> SET */
1619 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET"))
1620 COMPLETE_WITH("STATISTICS");
1621 /* ALTER INDEX <name> ALTER COLUMN <colnum> SET STATISTICS */
1622 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS"))
1624 /* Enforce no completion here, as an integer has to be specified */
1626 /* ALTER INDEX <name> SET */
1627 else if (Matches("ALTER", "INDEX", MatchAny, "SET"))
1628 COMPLETE_WITH("(", "TABLESPACE");
1629 /* ALTER INDEX <name> RESET */
1630 else if (Matches("ALTER", "INDEX", MatchAny, "RESET"))
1632 /* ALTER INDEX <foo> SET|RESET ( */
1633 else if (Matches("ALTER", "INDEX", MatchAny, "RESET", "("))
1634 COMPLETE_WITH("fillfactor",
1635 "vacuum_cleanup_index_scale_factor", /* BTREE */
1636 "fastupdate", "gin_pending_list_limit", /* GIN */
1637 "buffering", /* GiST */
1638 "pages_per_range", "autosummarize" /* BRIN */
1640 else if (Matches("ALTER", "INDEX", MatchAny, "SET", "("))
1641 COMPLETE_WITH("fillfactor =",
1642 "vacuum_cleanup_index_scale_factor =", /* BTREE */
1643 "fastupdate =", "gin_pending_list_limit =", /* GIN */
1644 "buffering =", /* GiST */
1645 "pages_per_range =", "autosummarize =" /* BRIN */
1648 /* ALTER LANGUAGE <name> */
1649 else if (Matches("ALTER", "LANGUAGE", MatchAny))
1650 COMPLETE_WITH("OWNER_TO", "RENAME TO");
1652 /* ALTER LARGE OBJECT <oid> */
1653 else if (Matches("ALTER", "LARGE", "OBJECT", MatchAny))
1654 COMPLETE_WITH("OWNER TO");
1656 /* ALTER MATERIALIZED VIEW */
1657 else if (Matches("ALTER", "MATERIALIZED", "VIEW"))
1658 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
1659 "UNION SELECT 'ALL IN TABLESPACE'");
1661 /* ALTER USER,ROLE <name> */
1662 else if (Matches("ALTER", "USER|ROLE", MatchAny) &&
1663 !TailMatches("USER", "MAPPING"))
1664 COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1665 "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1666 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1667 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
1668 "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
1669 "VALID UNTIL", "WITH");
1671 /* ALTER USER,ROLE <name> WITH */
1672 else if (Matches("ALTER", "USER|ROLE", MatchAny, "WITH"))
1673 /* Similar to the above, but don't complete "WITH" again. */
1674 COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1675 "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1676 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1677 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
1678 "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
1681 /* ALTER DEFAULT PRIVILEGES */
1682 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES"))
1683 COMPLETE_WITH("FOR ROLE", "IN SCHEMA");
1684 /* ALTER DEFAULT PRIVILEGES FOR */
1685 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
1686 COMPLETE_WITH("ROLE");
1687 /* ALTER DEFAULT PRIVILEGES IN */
1688 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
1689 COMPLETE_WITH("SCHEMA");
1690 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
1691 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1693 COMPLETE_WITH("GRANT", "REVOKE", "IN SCHEMA");
1694 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
1695 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1697 COMPLETE_WITH("GRANT", "REVOKE", "FOR ROLE");
1698 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
1699 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1701 COMPLETE_WITH("ROLE");
1702 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
1703 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
1704 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1705 MatchAny, "IN", "SCHEMA", MatchAny) ||
1706 Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1707 MatchAny, "FOR", "ROLE|USER", MatchAny))
1708 COMPLETE_WITH("GRANT", "REVOKE");
1709 /* ALTER DOMAIN <name> */
1710 else if (Matches("ALTER", "DOMAIN", MatchAny))
1711 COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME", "SET",
1712 "VALIDATE CONSTRAINT");
1713 /* ALTER DOMAIN <sth> DROP */
1714 else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP"))
1715 COMPLETE_WITH("CONSTRAINT", "DEFAULT", "NOT NULL");
1716 /* ALTER DOMAIN <sth> DROP|RENAME|VALIDATE CONSTRAINT */
1717 else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
1719 completion_info_charp = prev3_wd;
1720 COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
1722 /* ALTER DOMAIN <sth> RENAME */
1723 else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME"))
1724 COMPLETE_WITH("CONSTRAINT", "TO");
1725 /* ALTER DOMAIN <sth> RENAME CONSTRAINT <sth> */
1726 else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny))
1727 COMPLETE_WITH("TO");
1729 /* ALTER DOMAIN <sth> SET */
1730 else if (Matches("ALTER", "DOMAIN", MatchAny, "SET"))
1731 COMPLETE_WITH("DEFAULT", "NOT NULL", "SCHEMA");
1732 /* ALTER SEQUENCE <name> */
1733 else if (Matches("ALTER", "SEQUENCE", MatchAny))
1734 COMPLETE_WITH("INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO",
1735 "CACHE", "CYCLE", "SET SCHEMA", "OWNED BY", "OWNER TO",
1737 /* ALTER SEQUENCE <name> NO */
1738 else if (Matches("ALTER", "SEQUENCE", MatchAny, "NO"))
1739 COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
1740 /* ALTER SERVER <name> */
1741 else if (Matches("ALTER", "SERVER", MatchAny))
1742 COMPLETE_WITH("VERSION", "OPTIONS", "OWNER TO", "RENAME TO");
1743 /* ALTER SERVER <name> VERSION <version> */
1744 else if (Matches("ALTER", "SERVER", MatchAny, "VERSION", MatchAny))
1745 COMPLETE_WITH("OPTIONS");
1746 /* ALTER SYSTEM SET, RESET, RESET ALL */
1747 else if (Matches("ALTER", "SYSTEM"))
1748 COMPLETE_WITH("SET", "RESET");
1749 else if (Matches("ALTER", "SYSTEM", "SET|RESET"))
1750 COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars);
1751 else if (Matches("ALTER", "SYSTEM", "SET", MatchAny))
1752 COMPLETE_WITH("TO");
1753 /* ALTER VIEW <name> */
1754 else if (Matches("ALTER", "VIEW", MatchAny))
1755 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO",
1757 /* ALTER MATERIALIZED VIEW <name> */
1758 else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny))
1759 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO",
1762 /* ALTER POLICY <name> */
1763 else if (Matches("ALTER", "POLICY"))
1764 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
1765 /* ALTER POLICY <name> ON */
1766 else if (Matches("ALTER", "POLICY", MatchAny))
1767 COMPLETE_WITH("ON");
1768 /* ALTER POLICY <name> ON <table> */
1769 else if (Matches("ALTER", "POLICY", MatchAny, "ON"))
1771 completion_info_charp = prev2_wd;
1772 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
1774 /* ALTER POLICY <name> ON <table> - show options */
1775 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny))
1776 COMPLETE_WITH("RENAME TO", "TO", "USING (", "WITH CHECK (");
1777 /* ALTER POLICY <name> ON <table> TO <role> */
1778 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
1779 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
1780 /* ALTER POLICY <name> ON <table> USING ( */
1781 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
1783 /* ALTER POLICY <name> ON <table> WITH CHECK ( */
1784 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
1787 /* ALTER RULE <name>, add ON */
1788 else if (Matches("ALTER", "RULE", MatchAny))
1789 COMPLETE_WITH("ON");
1791 /* If we have ALTER RULE <name> ON, then add the correct tablename */
1792 else if (Matches("ALTER", "RULE", MatchAny, "ON"))
1794 completion_info_charp = prev2_wd;
1795 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1798 /* ALTER RULE <name> ON <name> */
1799 else if (Matches("ALTER", "RULE", MatchAny, "ON", MatchAny))
1800 COMPLETE_WITH("RENAME TO");
1802 /* ALTER STATISTICS <name> */
1803 else if (Matches("ALTER", "STATISTICS", MatchAny))
1804 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1806 /* ALTER TRIGGER <name>, add ON */
1807 else if (Matches("ALTER", "TRIGGER", MatchAny))
1808 COMPLETE_WITH("ON");
1810 else if (Matches("ALTER", "TRIGGER", MatchAny, MatchAny))
1812 completion_info_charp = prev2_wd;
1813 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
1817 * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
1819 else if (Matches("ALTER", "TRIGGER", MatchAny, "ON"))
1820 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
1822 /* ALTER TRIGGER <name> ON <name> */
1823 else if (Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
1824 COMPLETE_WITH("RENAME TO");
1827 * If we detect ALTER TABLE <name>, suggest sub commands
1829 else if (Matches("ALTER", "TABLE", MatchAny))
1830 COMPLETE_WITH("ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP",
1831 "ENABLE", "INHERIT", "NO INHERIT", "RENAME", "RESET",
1832 "OWNER TO", "SET", "VALIDATE CONSTRAINT",
1833 "REPLICA IDENTITY", "ATTACH PARTITION",
1834 "DETACH PARTITION");
1835 /* ALTER TABLE xxx ENABLE */
1836 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE"))
1837 COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
1839 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
1840 COMPLETE_WITH("RULE", "TRIGGER");
1841 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
1843 completion_info_charp = prev3_wd;
1844 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1846 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
1848 completion_info_charp = prev4_wd;
1849 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1851 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
1853 completion_info_charp = prev3_wd;
1854 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1856 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
1858 completion_info_charp = prev4_wd;
1859 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1861 /* ALTER TABLE xxx INHERIT */
1862 else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT"))
1863 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1864 /* ALTER TABLE xxx NO INHERIT */
1865 else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
1866 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1867 /* ALTER TABLE xxx DISABLE */
1868 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE"))
1869 COMPLETE_WITH("ROW LEVEL SECURITY", "RULE", "TRIGGER");
1870 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
1872 completion_info_charp = prev3_wd;
1873 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1875 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
1877 completion_info_charp = prev3_wd;
1878 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1881 /* ALTER TABLE xxx ALTER */
1882 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER"))
1883 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'");
1885 /* ALTER TABLE xxx RENAME */
1886 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME"))
1887 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'");
1888 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
1889 COMPLETE_WITH_ATTR(prev3_wd, "");
1891 /* ALTER TABLE xxx RENAME yyy */
1892 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
1893 COMPLETE_WITH("TO");
1895 /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
1896 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
1897 COMPLETE_WITH("TO");
1899 /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
1900 else if (Matches("ALTER", "TABLE", MatchAny, "DROP"))
1901 COMPLETE_WITH("COLUMN", "CONSTRAINT");
1902 /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
1903 else if (Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
1904 COMPLETE_WITH_ATTR(prev3_wd, "");
1907 * If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
1908 * provide list of constraints
1910 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
1912 completion_info_charp = prev3_wd;
1913 COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
1915 /* ALTER TABLE ALTER [COLUMN] <foo> */
1916 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
1917 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
1918 COMPLETE_WITH("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP");
1919 /* ALTER TABLE ALTER [COLUMN] <foo> SET */
1920 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
1921 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
1922 COMPLETE_WITH("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE");
1923 /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
1924 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
1925 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
1926 COMPLETE_WITH("n_distinct", "n_distinct_inherited");
1927 /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
1928 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
1929 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
1930 COMPLETE_WITH("PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
1931 /* ALTER TABLE ALTER [COLUMN] <foo> SET STATISTICS */
1932 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS") ||
1933 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STATISTICS"))
1935 /* Enforce no completion here, as an integer has to be specified */
1937 /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
1938 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
1939 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
1940 COMPLETE_WITH("DEFAULT", "IDENTITY", "NOT NULL");
1941 else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER"))
1942 COMPLETE_WITH("ON");
1943 else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
1945 completion_info_charp = prev3_wd;
1946 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1948 /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
1949 else if (Matches("ALTER", "TABLE", MatchAny, "SET"))
1950 COMPLETE_WITH("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED",
1954 * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
1957 else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
1958 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1959 /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
1960 else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
1961 COMPLETE_WITH("CLUSTER", "OIDS");
1962 /* ALTER TABLE <foo> RESET */
1963 else if (Matches("ALTER", "TABLE", MatchAny, "RESET"))
1965 /* ALTER TABLE <foo> SET|RESET ( */
1966 else if (Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
1967 COMPLETE_WITH_LIST(table_storage_parameters);
1968 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
1970 completion_info_charp = prev5_wd;
1971 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1973 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
1974 COMPLETE_WITH("INDEX");
1975 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
1976 COMPLETE_WITH("FULL", "NOTHING", "DEFAULT", "USING");
1977 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA"))
1978 COMPLETE_WITH("IDENTITY");
1981 * If we have ALTER TABLE <foo> ATTACH PARTITION, provide a list of
1984 else if (Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION"))
1985 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1986 /* Limited completion support for partition bound specification */
1987 else if (TailMatches("ATTACH", "PARTITION", MatchAny))
1988 COMPLETE_WITH("FOR VALUES", "DEFAULT");
1989 else if (TailMatches("FOR", "VALUES"))
1990 COMPLETE_WITH("FROM (", "IN (", "WITH (");
1993 * If we have ALTER TABLE <foo> DETACH PARTITION, provide a list of
1994 * partitions of <foo>.
1996 else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION"))
1998 completion_info_charp = prev3_wd;
1999 COMPLETE_WITH_QUERY(Query_for_partition_of_table);
2002 /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
2003 else if (Matches("ALTER", "TABLESPACE", MatchAny))
2004 COMPLETE_WITH("RENAME TO", "OWNER TO", "SET", "RESET");
2005 /* ALTER TABLESPACE <foo> SET|RESET */
2006 else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
2008 /* ALTER TABLESPACE <foo> SET|RESET ( */
2009 else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
2010 COMPLETE_WITH("seq_page_cost", "random_page_cost",
2011 "effective_io_concurrency");
2013 /* ALTER TEXT SEARCH */
2014 else if (Matches("ALTER", "TEXT", "SEARCH"))
2015 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2016 else if (Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
2017 COMPLETE_WITH("RENAME TO", "SET SCHEMA");
2018 else if (Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
2019 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
2020 else if (Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2021 COMPLETE_WITH("ADD MAPPING FOR", "ALTER MAPPING",
2023 "OWNER TO", "RENAME TO", "SET SCHEMA");
2025 /* complete ALTER TYPE <foo> with actions */
2026 else if (Matches("ALTER", "TYPE", MatchAny))
2027 COMPLETE_WITH("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
2029 "OWNER TO", "RENAME", "SET SCHEMA");
2030 /* complete ALTER TYPE <foo> ADD with actions */
2031 else if (Matches("ALTER", "TYPE", MatchAny, "ADD"))
2032 COMPLETE_WITH("ATTRIBUTE", "VALUE");
2033 /* ALTER TYPE <foo> RENAME */
2034 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME"))
2035 COMPLETE_WITH("ATTRIBUTE", "TO", "VALUE");
2036 /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
2037 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
2038 COMPLETE_WITH("TO");
2041 * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
2044 else if (Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
2045 COMPLETE_WITH_ATTR(prev3_wd, "");
2046 /* ALTER TYPE ALTER ATTRIBUTE <foo> */
2047 else if (Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
2048 COMPLETE_WITH("TYPE");
2049 /* complete ALTER GROUP <foo> */
2050 else if (Matches("ALTER", "GROUP", MatchAny))
2051 COMPLETE_WITH("ADD USER", "DROP USER", "RENAME TO");
2052 /* complete ALTER GROUP <foo> ADD|DROP with USER */
2053 else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP"))
2054 COMPLETE_WITH("USER");
2055 /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
2056 else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
2057 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2060 * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
2062 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
2063 COMPLETE_WITH_ENUM_VALUE(prev3_wd);
2066 * ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
2067 * ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]
2069 else if (Matches("ANALYZE"))
2070 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables,
2071 " UNION SELECT 'VERBOSE'");
2072 else if (HeadMatches("ANALYZE", "(*") &&
2073 !HeadMatches("ANALYZE", "(*)"))
2076 * This fires if we're in an unfinished parenthesized option list.
2077 * get_previous_words treats a completed parenthesized option list as
2078 * one word, so the above test is correct.
2080 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
2081 COMPLETE_WITH("VERBOSE", "SKIP_LOCKED");
2083 else if (HeadMatches("ANALYZE") && TailMatches("("))
2084 /* "ANALYZE (" should be caught above, so assume we want columns */
2085 COMPLETE_WITH_ATTR(prev2_wd, "");
2086 else if (HeadMatches("ANALYZE"))
2087 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables, NULL);
2090 else if (Matches("BEGIN"))
2091 COMPLETE_WITH("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2093 else if (Matches("END|ABORT"))
2094 COMPLETE_WITH("AND", "WORK", "TRANSACTION");
2096 else if (Matches("COMMIT"))
2097 COMPLETE_WITH("AND", "WORK", "TRANSACTION", "PREPARED");
2098 /* RELEASE SAVEPOINT */
2099 else if (Matches("RELEASE"))
2100 COMPLETE_WITH("SAVEPOINT");
2102 else if (Matches("ROLLBACK"))
2103 COMPLETE_WITH("AND", "WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
2104 else if (Matches("ABORT|END|COMMIT|ROLLBACK", "AND"))
2105 COMPLETE_WITH("CHAIN");
2107 else if (Matches("CALL"))
2108 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
2109 else if (Matches("CALL", MatchAny))
2112 else if (Matches("CLUSTER"))
2113 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'");
2114 else if (Matches("CLUSTER", "VERBOSE"))
2115 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL);
2116 /* If we have CLUSTER <sth>, then add "USING" */
2117 else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON")))
2118 COMPLETE_WITH("USING");
2119 /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
2120 else if (Matches("CLUSTER", "VERBOSE", MatchAny))
2121 COMPLETE_WITH("USING");
2122 /* If we have CLUSTER <sth> USING, then add the index as well */
2123 else if (Matches("CLUSTER", MatchAny, "USING") ||
2124 Matches("CLUSTER", "VERBOSE", MatchAny, "USING"))
2126 completion_info_charp = prev2_wd;
2127 COMPLETE_WITH_QUERY(Query_for_index_of_table);
2131 else if (Matches("COMMENT"))
2132 COMPLETE_WITH("ON");
2133 else if (Matches("COMMENT", "ON"))
2134 COMPLETE_WITH("ACCESS METHOD", "CAST", "COLLATION", "CONVERSION",
2135 "DATABASE", "EVENT TRIGGER", "EXTENSION",
2136 "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "SERVER",
2137 "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE",
2138 "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION",
2139 "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW",
2140 "COLUMN", "AGGREGATE", "FUNCTION",
2141 "PROCEDURE", "ROUTINE",
2142 "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN",
2143 "LARGE OBJECT", "TABLESPACE", "TEXT SEARCH", "ROLE");
2144 else if (Matches("COMMENT", "ON", "ACCESS", "METHOD"))
2145 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2146 else if (Matches("COMMENT", "ON", "FOREIGN"))
2147 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2148 else if (Matches("COMMENT", "ON", "TEXT", "SEARCH"))
2149 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2150 else if (Matches("COMMENT", "ON", "CONSTRAINT"))
2151 COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2152 else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny))
2153 COMPLETE_WITH("ON");
2154 else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2156 completion_info_charp = prev2_wd;
2157 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint);
2159 else if (Matches("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2160 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2161 else if (Matches("COMMENT", "ON", "EVENT", "TRIGGER"))
2162 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2163 else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2164 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2165 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2166 COMPLETE_WITH("IS");
2171 * If we have COPY, offer list of tables or "(" (Also cover the analogous
2172 * backslash command).
2174 else if (Matches("COPY|\\copy"))
2175 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2176 " UNION ALL SELECT '('");
2177 /* If we have COPY BINARY, complete with list of tables */
2178 else if (Matches("COPY", "BINARY"))
2179 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2180 /* If we have COPY (, complete it with legal commands */
2181 else if (Matches("COPY|\\copy", "("))
2182 COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH");
2183 /* If we have COPY [BINARY] <sth>, complete it with "TO" or "FROM" */
2184 else if (Matches("COPY|\\copy", MatchAny) ||
2185 Matches("COPY", "BINARY", MatchAny))
2186 COMPLETE_WITH("FROM", "TO");
2187 /* If we have COPY [BINARY] <sth> FROM|TO, complete with filename */
2188 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO") ||
2189 Matches("COPY", "BINARY", MatchAny, "FROM|TO"))
2191 completion_charp = "";
2192 matches = completion_matches(text, complete_from_files);
2195 /* Handle COPY [BINARY] <sth> FROM|TO filename */
2196 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
2197 Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
2198 COMPLETE_WITH("BINARY", "DELIMITER", "NULL", "CSV",
2201 /* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
2202 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") ||
2203 Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV"))
2204 COMPLETE_WITH("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE",
2207 /* CREATE ACCESS METHOD */
2208 /* Complete "CREATE ACCESS METHOD <name>" */
2209 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny))
2210 COMPLETE_WITH("TYPE");
2211 /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2212 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2213 COMPLETE_WITH("INDEX");
2214 /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2215 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2216 COMPLETE_WITH("HANDLER");
2218 /* CREATE DATABASE */
2219 else if (Matches("CREATE", "DATABASE", MatchAny))
2220 COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2222 "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2223 "LC_COLLATE", "LC_CTYPE");
2225 else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2226 COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2228 /* CREATE EXTENSION */
2229 /* Complete with available extensions rather than installed ones. */
2230 else if (Matches("CREATE", "EXTENSION"))
2231 COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2232 /* CREATE EXTENSION <name> */
2233 else if (Matches("CREATE", "EXTENSION", MatchAny))
2234 COMPLETE_WITH("WITH SCHEMA", "CASCADE", "VERSION");
2235 /* CREATE EXTENSION <name> VERSION */
2236 else if (Matches("CREATE", "EXTENSION", MatchAny, "VERSION"))
2238 completion_info_charp = prev2_wd;
2239 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2242 /* CREATE FOREIGN */
2243 else if (Matches("CREATE", "FOREIGN"))
2244 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2246 /* CREATE FOREIGN DATA WRAPPER */
2247 else if (Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2248 COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS");
2250 /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2251 /* First off we complete CREATE UNIQUE with "INDEX" */
2252 else if (TailMatches("CREATE", "UNIQUE"))
2253 COMPLETE_WITH("INDEX");
2256 * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
2259 else if (TailMatches("CREATE|UNIQUE", "INDEX"))
2260 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2261 " UNION SELECT 'ON'"
2262 " UNION SELECT 'CONCURRENTLY'");
2265 * Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of relations
2266 * that indexes can be created on
2268 else if (TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON") ||
2269 TailMatches("INDEX|CONCURRENTLY", "ON"))
2270 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL);
2273 * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
2276 else if (TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
2277 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2278 " UNION SELECT 'ON'");
2279 /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
2280 else if (TailMatches("CREATE|UNIQUE", "INDEX", MatchAny) ||
2281 TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
2282 COMPLETE_WITH("ON");
2285 * Complete INDEX <name> ON <table> with a list of table columns (which
2286 * should really be in parens)
2288 else if (TailMatches("INDEX", MatchAny, "ON", MatchAny) ||
2289 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny))
2290 COMPLETE_WITH("(", "USING");
2291 else if (TailMatches("INDEX", MatchAny, "ON", MatchAny, "(") ||
2292 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
2293 COMPLETE_WITH_ATTR(prev2_wd, "");
2294 /* same if you put in USING */
2295 else if (TailMatches("ON", MatchAny, "USING", MatchAny, "("))
2296 COMPLETE_WITH_ATTR(prev4_wd, "");
2297 /* Complete USING with an index method */
2298 else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
2299 TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") ||
2300 TailMatches("INDEX", "ON", MatchAny, "USING"))
2301 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2302 else if (TailMatches("ON", MatchAny, "USING", MatchAny) &&
2303 !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
2304 !TailMatches("FOR", MatchAny, MatchAny, MatchAny))
2308 /* Complete "CREATE POLICY <name> ON" */
2309 else if (Matches("CREATE", "POLICY", MatchAny))
2310 COMPLETE_WITH("ON");
2311 /* Complete "CREATE POLICY <name> ON <table>" */
2312 else if (Matches("CREATE", "POLICY", MatchAny, "ON"))
2313 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2314 /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
2315 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny))
2316 COMPLETE_WITH("AS", "FOR", "TO", "USING (", "WITH CHECK (");
2317 /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
2318 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
2319 COMPLETE_WITH("PERMISSIVE", "RESTRICTIVE");
2322 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2323 * FOR|TO|USING|WITH CHECK
2325 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
2326 COMPLETE_WITH("FOR", "TO", "USING", "WITH CHECK");
2327 /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2328 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
2329 COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2330 /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
2331 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
2332 COMPLETE_WITH("TO", "WITH CHECK (");
2333 /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
2334 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
2335 COMPLETE_WITH("TO", "USING (");
2336 /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
2337 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
2338 COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
2339 /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
2340 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
2341 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2342 /* Complete "CREATE POLICY <name> ON <table> USING (" */
2343 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
2347 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2348 * ALL|SELECT|INSERT|UPDATE|DELETE
2350 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
2351 COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2354 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2355 * INSERT TO|WITH CHECK"
2357 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
2358 COMPLETE_WITH("TO", "WITH CHECK (");
2361 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2362 * SELECT|DELETE TO|USING"
2364 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
2365 COMPLETE_WITH("TO", "USING (");
2368 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2369 * ALL|UPDATE TO|USING|WITH CHECK
2371 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
2372 COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
2375 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO
2378 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
2379 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2382 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2385 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
2389 /* CREATE PUBLICATION */
2390 else if (Matches("CREATE", "PUBLICATION", MatchAny))
2391 COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "WITH (");
2392 else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR"))
2393 COMPLETE_WITH("TABLE", "ALL TABLES");
2394 /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>, ..." */
2395 else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"))
2396 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2397 /* Complete "CREATE PUBLICATION <name> [...] WITH" */
2398 else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "("))
2399 COMPLETE_WITH("publish");
2402 /* Complete "CREATE RULE <sth>" with "AS ON" */
2403 else if (Matches("CREATE", "RULE", MatchAny))
2404 COMPLETE_WITH("AS ON");
2405 /* Complete "CREATE RULE <sth> AS" with "ON" */
2406 else if (Matches("CREATE", "RULE", MatchAny, "AS"))
2407 COMPLETE_WITH("ON");
2408 /* Complete "CREATE RULE <sth> AS ON" with SELECT|UPDATE|INSERT|DELETE */
2409 else if (Matches("CREATE", "RULE", MatchAny, "AS", "ON"))
2410 COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE");
2411 /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
2412 else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
2413 COMPLETE_WITH("TO");
2414 /* Complete "AS ON <sth> TO" with a table name */
2415 else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
2416 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2418 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2419 else if (TailMatches("CREATE", "SEQUENCE", MatchAny) ||
2420 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
2421 COMPLETE_WITH("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE",
2422 "CYCLE", "OWNED BY", "START WITH");
2423 else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "NO") ||
2424 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
2425 COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
2427 /* CREATE SERVER <name> */
2428 else if (Matches("CREATE", "SERVER", MatchAny))
2429 COMPLETE_WITH("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
2431 /* CREATE STATISTICS <name> */
2432 else if (Matches("CREATE", "STATISTICS", MatchAny))
2433 COMPLETE_WITH("(", "ON");
2434 else if (Matches("CREATE", "STATISTICS", MatchAny, "("))
2435 COMPLETE_WITH("ndistinct", "dependencies", "mcv");
2436 else if (Matches("CREATE", "STATISTICS", MatchAny, "(*)"))
2437 COMPLETE_WITH("ON");
2438 else if (HeadMatches("CREATE", "STATISTICS", MatchAny) &&
2439 TailMatches("FROM"))
2440 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2442 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2443 /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
2444 else if (TailMatches("CREATE", "TEMP|TEMPORARY"))
2445 COMPLETE_WITH("SEQUENCE", "TABLE", "VIEW");
2446 /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
2447 else if (TailMatches("CREATE", "UNLOGGED"))
2448 COMPLETE_WITH("TABLE", "MATERIALIZED VIEW");
2449 /* Complete PARTITION BY with RANGE ( or LIST ( or ... */
2450 else if (TailMatches("PARTITION", "BY"))
2451 COMPLETE_WITH("RANGE (", "LIST (", "HASH (");
2452 /* If we have xxx PARTITION OF, provide a list of partitioned tables */
2453 else if (TailMatches("PARTITION", "OF"))
2454 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, "");
2455 /* Limited completion support for partition bound specification */
2456 else if (TailMatches("PARTITION", "OF", MatchAny))
2457 COMPLETE_WITH("FOR VALUES", "DEFAULT");
2458 /* Complete CREATE TABLE <name> with '(', OF or PARTITION OF */
2459 else if (TailMatches("CREATE", "TABLE", MatchAny) ||
2460 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny))
2461 COMPLETE_WITH("(", "OF", "PARTITION OF");
2462 /* Complete CREATE TABLE <name> OF with list of composite types */
2463 else if (TailMatches("CREATE", "TABLE", MatchAny, "OF") ||
2464 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "OF"))
2465 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes, NULL);
2466 /* Complete CREATE TABLE name (...) with supported options */
2467 else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)") ||
2468 TailMatches("CREATE", "UNLOGGED", "TABLE", MatchAny, "(*)"))
2469 COMPLETE_WITH("INHERITS (", "PARTITION BY", "TABLESPACE", "WITH (");
2470 else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)"))
2471 COMPLETE_WITH("INHERITS (", "ON COMMIT", "PARTITION BY",
2472 "TABLESPACE", "WITH (");
2473 /* Complete CREATE TABLE (...) WITH with storage parameters */
2474 else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "WITH", "(") ||
2475 TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "WITH", "("))
2476 COMPLETE_WITH_LIST(table_storage_parameters);
2477 /* Complete CREATE TABLE ON COMMIT with actions */
2478 else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)", "ON", "COMMIT"))
2479 COMPLETE_WITH("DELETE ROWS", "DROP", "PRESERVE ROWS");
2481 /* CREATE TABLESPACE */
2482 else if (Matches("CREATE", "TABLESPACE", MatchAny))
2483 COMPLETE_WITH("OWNER", "LOCATION");
2484 /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
2485 else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
2486 COMPLETE_WITH("LOCATION");
2488 /* CREATE TEXT SEARCH */
2489 else if (Matches("CREATE", "TEXT", "SEARCH"))
2490 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2491 else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2494 /* CREATE SUBSCRIPTION */
2495 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny))
2496 COMPLETE_WITH("CONNECTION");
2497 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny))
2498 COMPLETE_WITH("PUBLICATION");
2499 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",
2500 MatchAny, "PUBLICATION"))
2502 /* complete with nothing here as this refers to remote publications */
2504 else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("PUBLICATION", MatchAny))
2505 COMPLETE_WITH("WITH (");
2506 /* Complete "CREATE SUBSCRIPTION <name> ... WITH ( <opt>" */
2507 else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("WITH", "("))
2508 COMPLETE_WITH("copy_data", "connect", "create_slot", "enabled",
2509 "slot_name", "synchronous_commit");
2511 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
2512 /* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
2513 else if (TailMatches("CREATE", "TRIGGER", MatchAny))
2514 COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF");
2515 /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
2516 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
2517 COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE");
2518 /* complete CREATE TRIGGER <name> INSTEAD OF with an event */
2519 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
2520 COMPLETE_WITH("INSERT", "DELETE", "UPDATE");
2521 /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
2522 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
2523 TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
2524 COMPLETE_WITH("ON", "OR");
2527 * complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of
2528 * tables. EXECUTE FUNCTION is the recommended grammar instead of EXECUTE
2529 * PROCEDURE in version 11 and upwards.
2531 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
2532 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2533 /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */
2534 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
2535 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
2536 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("ON", MatchAny))
2538 if (pset.sversion >= 110000)
2539 COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2540 "REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
2542 COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2543 "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2545 else if (HeadMatches("CREATE", "TRIGGER") &&
2546 (TailMatches("DEFERRABLE") || TailMatches("INITIALLY", "IMMEDIATE|DEFERRED")))
2548 if (pset.sversion >= 110000)
2549 COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
2551 COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2553 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("REFERENCING"))
2554 COMPLETE_WITH("OLD TABLE", "NEW TABLE");
2555 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("OLD|NEW", "TABLE"))
2556 COMPLETE_WITH("AS");
2557 else if (HeadMatches("CREATE", "TRIGGER") &&
2558 (TailMatches("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
2559 TailMatches("REFERENCING", "OLD", "TABLE", MatchAny)))
2561 if (pset.sversion >= 110000)
2562 COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
2564 COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2566 else if (HeadMatches("CREATE", "TRIGGER") &&
2567 (TailMatches("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
2568 TailMatches("REFERENCING", "NEW", "TABLE", MatchAny)))
2570 if (pset.sversion >= 110000)
2571 COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
2573 COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2575 else if (HeadMatches("CREATE", "TRIGGER") &&
2576 (TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2577 TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2578 TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
2579 TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
2581 if (pset.sversion >= 110000)
2582 COMPLETE_WITH("FOR", "WHEN (", "EXECUTE FUNCTION");
2584 COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE");
2586 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR"))
2587 COMPLETE_WITH("EACH", "ROW", "STATEMENT");
2588 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR", "EACH"))
2589 COMPLETE_WITH("ROW", "STATEMENT");
2590 else if (HeadMatches("CREATE", "TRIGGER") &&
2591 (TailMatches("FOR", "EACH", "ROW|STATEMENT") ||
2592 TailMatches("FOR", "ROW|STATEMENT")))
2594 if (pset.sversion >= 110000)
2595 COMPLETE_WITH("WHEN (", "EXECUTE FUNCTION");
2597 COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE");
2599 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("WHEN", "(*)"))
2601 if (pset.sversion >= 110000)
2602 COMPLETE_WITH("EXECUTE FUNCTION");
2604 COMPLETE_WITH("EXECUTE PROCEDURE");
2606 /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE|FUNCTION */
2607 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("EXECUTE"))
2609 if (pset.sversion >= 110000)
2610 COMPLETE_WITH("FUNCTION");
2612 COMPLETE_WITH("PROCEDURE");
2614 else if (HeadMatches("CREATE", "TRIGGER") &&
2615 TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
2616 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2618 /* CREATE ROLE,USER,GROUP <name> */
2619 else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny) &&
2620 !TailMatches("USER", "MAPPING"))
2621 COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
2622 "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
2623 "LOGIN", "NOBYPASSRLS",
2624 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2625 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2626 "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2627 "VALID UNTIL", "WITH");
2629 /* CREATE ROLE,USER,GROUP <name> WITH */
2630 else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
2631 /* Similar to the above, but don't complete "WITH" again. */
2632 COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
2633 "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
2634 "LOGIN", "NOBYPASSRLS",
2635 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2636 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2637 "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2640 /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
2641 else if (Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
2642 COMPLETE_WITH("GROUP", "ROLE");
2644 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
2645 /* Complete CREATE VIEW <name> with AS */
2646 else if (TailMatches("CREATE", "VIEW", MatchAny))
2647 COMPLETE_WITH("AS");
2648 /* Complete "CREATE VIEW <sth> AS with "SELECT" */
2649 else if (TailMatches("CREATE", "VIEW", MatchAny, "AS"))
2650 COMPLETE_WITH("SELECT");
2652 /* CREATE MATERIALIZED VIEW */
2653 else if (Matches("CREATE", "MATERIALIZED"))
2654 COMPLETE_WITH("VIEW");
2655 /* Complete CREATE MATERIALIZED VIEW <name> with AS */
2656 else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny))
2657 COMPLETE_WITH("AS");
2658 /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
2659 else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
2660 COMPLETE_WITH("SELECT");
2662 /* CREATE EVENT TRIGGER */
2663 else if (Matches("CREATE", "EVENT"))
2664 COMPLETE_WITH("TRIGGER");
2665 /* Complete CREATE EVENT TRIGGER <name> with ON */
2666 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny))
2667 COMPLETE_WITH("ON");
2668 /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
2669 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
2670 COMPLETE_WITH("ddl_command_start", "ddl_command_end", "sql_drop");
2673 * Complete CREATE EVENT TRIGGER <name> ON <event_type>. EXECUTE FUNCTION
2674 * is the recommended grammar instead of EXECUTE PROCEDURE in version 11
2677 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON", MatchAny))
2679 if (pset.sversion >= 110000)
2680 COMPLETE_WITH("WHEN TAG IN (", "EXECUTE FUNCTION");
2682 COMPLETE_WITH("WHEN TAG IN (", "EXECUTE PROCEDURE");
2684 else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
2685 TailMatches("WHEN|AND", MatchAny, "IN", "(*)"))
2687 if (pset.sversion >= 110000)
2688 COMPLETE_WITH("EXECUTE FUNCTION");
2690 COMPLETE_WITH("EXECUTE PROCEDURE");
2692 else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
2693 TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
2694 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2697 else if (Matches("DEALLOCATE"))
2698 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2701 else if (Matches("DECLARE", MatchAny))
2702 COMPLETE_WITH("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL",
2704 else if (HeadMatches("DECLARE") && TailMatches("CURSOR"))
2705 COMPLETE_WITH("WITH HOLD", "WITHOUT HOLD", "FOR");
2707 /* DELETE --- can be inside EXPLAIN, RULE, etc */
2708 /* ... despite which, only complete DELETE with FROM at start of line */
2709 else if (Matches("DELETE"))
2710 COMPLETE_WITH("FROM");
2711 /* Complete DELETE FROM with a list of tables */
2712 else if (TailMatches("DELETE", "FROM"))
2713 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2714 /* Complete DELETE FROM <table> */
2715 else if (TailMatches("DELETE", "FROM", MatchAny))
2716 COMPLETE_WITH("USING", "WHERE");
2717 /* XXX: implement tab completion for DELETE ... USING */
2720 else if (Matches("DISCARD"))
2721 COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP");
2724 else if (Matches("DO"))
2725 COMPLETE_WITH("LANGUAGE");
2728 /* Complete DROP object with CASCADE / RESTRICT */
2729 else if (Matches("DROP",
2730 "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW",
2732 Matches("DROP", "ACCESS", "METHOD", MatchAny) ||
2733 (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) &&
2734 ends_with(prev_wd, ')')) ||
2735 Matches("DROP", "EVENT", "TRIGGER", MatchAny) ||
2736 Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
2737 Matches("DROP", "FOREIGN", "TABLE", MatchAny) ||
2738 Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
2739 COMPLETE_WITH("CASCADE", "RESTRICT");
2741 /* help completing some of the variants */
2742 else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
2744 else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "("))
2745 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
2746 else if (Matches("DROP", "FOREIGN"))
2747 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2750 else if (Matches("DROP", "INDEX"))
2751 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2752 " UNION SELECT 'CONCURRENTLY'");
2753 else if (Matches("DROP", "INDEX", "CONCURRENTLY"))
2754 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2755 else if (Matches("DROP", "INDEX", MatchAny))
2756 COMPLETE_WITH("CASCADE", "RESTRICT");
2757 else if (Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny))
2758 COMPLETE_WITH("CASCADE", "RESTRICT");
2760 /* DROP MATERIALIZED VIEW */
2761 else if (Matches("DROP", "MATERIALIZED"))
2762 COMPLETE_WITH("VIEW");
2763 else if (Matches("DROP", "MATERIALIZED", "VIEW"))
2764 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2767 else if (Matches("DROP", "OWNED"))
2768 COMPLETE_WITH("BY");
2769 else if (Matches("DROP", "OWNED", "BY"))
2770 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2772 /* DROP TEXT SEARCH */
2773 else if (Matches("DROP", "TEXT", "SEARCH"))
2774 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2777 else if (Matches("DROP", "TRIGGER", MatchAny))
2778 COMPLETE_WITH("ON");
2779 else if (Matches("DROP", "TRIGGER", MatchAny, "ON"))
2781 completion_info_charp = prev2_wd;
2782 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2784 else if (Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
2785 COMPLETE_WITH("CASCADE", "RESTRICT");
2787 /* DROP ACCESS METHOD */
2788 else if (Matches("DROP", "ACCESS"))
2789 COMPLETE_WITH("METHOD");
2790 else if (Matches("DROP", "ACCESS", "METHOD"))
2791 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2793 /* DROP EVENT TRIGGER */
2794 else if (Matches("DROP", "EVENT"))
2795 COMPLETE_WITH("TRIGGER");
2796 else if (Matches("DROP", "EVENT", "TRIGGER"))
2797 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2799 /* DROP POLICY <name> */
2800 else if (Matches("DROP", "POLICY"))
2801 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2802 /* DROP POLICY <name> ON */
2803 else if (Matches("DROP", "POLICY", MatchAny))
2804 COMPLETE_WITH("ON");
2805 /* DROP POLICY <name> ON <table> */
2806 else if (Matches("DROP", "POLICY", MatchAny, "ON"))
2808 completion_info_charp = prev2_wd;
2809 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
2813 else if (Matches("DROP", "RULE", MatchAny))
2814 COMPLETE_WITH("ON");
2815 else if (Matches("DROP", "RULE", MatchAny, "ON"))
2817 completion_info_charp = prev2_wd;
2818 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2820 else if (Matches("DROP", "RULE", MatchAny, "ON", MatchAny))
2821 COMPLETE_WITH("CASCADE", "RESTRICT");
2824 else if (Matches("EXECUTE"))
2825 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2828 * EXPLAIN [ ( option [, ...] ) ] statement
2829 * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
2831 else if (Matches("EXPLAIN"))
2832 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2833 "ANALYZE", "VERBOSE");
2834 else if (HeadMatches("EXPLAIN", "(*") &&
2835 !HeadMatches("EXPLAIN", "(*)"))
2838 * This fires if we're in an unfinished parenthesized option list.
2839 * get_previous_words treats a completed parenthesized option list as
2840 * one word, so the above test is correct.
2842 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
2843 COMPLETE_WITH("ANALYZE", "VERBOSE", "COSTS", "BUFFERS",
2844 "TIMING", "SUMMARY", "FORMAT");
2845 else if (TailMatches("ANALYZE|VERBOSE|COSTS|BUFFERS|TIMING|SUMMARY"))
2846 COMPLETE_WITH("ON", "OFF");
2847 else if (TailMatches("FORMAT"))
2848 COMPLETE_WITH("TEXT", "XML", "JSON", "YAML");
2850 else if (Matches("EXPLAIN", "ANALYZE"))
2851 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2853 else if (Matches("EXPLAIN", "(*)") ||
2854 Matches("EXPLAIN", "VERBOSE") ||
2855 Matches("EXPLAIN", "ANALYZE", "VERBOSE"))
2856 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE");
2859 /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
2860 else if (Matches("FETCH|MOVE"))
2861 COMPLETE_WITH("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE");
2862 /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
2863 else if (Matches("FETCH|MOVE", MatchAny))
2864 COMPLETE_WITH("ALL", "NEXT", "PRIOR");
2867 * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
2868 * but we may as well tab-complete both: perhaps some users prefer one
2869 * variant or the other.
2871 else if (Matches("FETCH|MOVE", MatchAny, MatchAny))
2872 COMPLETE_WITH("FROM", "IN");
2874 /* FOREIGN DATA WRAPPER */
2875 /* applies in ALTER/DROP FDW and in CREATE SERVER */
2876 else if (TailMatches("FOREIGN", "DATA", "WRAPPER") &&
2877 !TailMatches("CREATE", MatchAny, MatchAny, MatchAny))
2878 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
2879 /* applies in CREATE SERVER */
2880 else if (TailMatches("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
2881 HeadMatches("CREATE", "SERVER"))
2882 COMPLETE_WITH("OPTIONS");
2885 else if (TailMatches("FOREIGN", "TABLE") &&
2886 !TailMatches("CREATE", MatchAny, MatchAny))
2887 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
2889 /* FOREIGN SERVER */
2890 else if (TailMatches("FOREIGN", "SERVER"))
2891 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
2894 * GRANT and REVOKE are allowed inside CREATE SCHEMA and
2895 * ALTER DEFAULT PRIVILEGES, so use TailMatches
2897 /* Complete GRANT/REVOKE with a list of roles and privileges */
2898 else if (TailMatches("GRANT|REVOKE"))
2901 * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable
2902 * privileges (can't grant roles)
2904 if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
2905 COMPLETE_WITH("SELECT", "INSERT", "UPDATE",
2906 "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2907 "EXECUTE", "USAGE", "ALL");
2909 COMPLETE_WITH_QUERY(Query_for_list_of_roles
2910 " UNION SELECT 'SELECT'"
2911 " UNION SELECT 'INSERT'"
2912 " UNION SELECT 'UPDATE'"
2913 " UNION SELECT 'DELETE'"
2914 " UNION SELECT 'TRUNCATE'"
2915 " UNION SELECT 'REFERENCES'"
2916 " UNION SELECT 'TRIGGER'"
2917 " UNION SELECT 'CREATE'"
2918 " UNION SELECT 'CONNECT'"
2919 " UNION SELECT 'TEMPORARY'"
2920 " UNION SELECT 'EXECUTE'"
2921 " UNION SELECT 'USAGE'"
2922 " UNION SELECT 'ALL'");
2926 * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
2929 else if (TailMatches("GRANT|REVOKE", MatchAny))
2931 if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
2932 COMPLETE_WITH("ON");
2933 else if (TailMatches("GRANT", MatchAny))
2934 COMPLETE_WITH("TO");
2936 COMPLETE_WITH("FROM");
2940 * Complete GRANT/REVOKE <sth> ON with a list of appropriate relations.
2942 * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query
2943 * result via UNION; seems to work intuitively.
2945 * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
2946 * here will only work if the privilege list contains exactly one
2949 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON"))
2952 * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of
2953 * objects supported.
2955 if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
2956 COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS");
2958 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables,
2959 " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
2960 " UNION SELECT 'ALL PROCEDURES IN SCHEMA'"
2961 " UNION SELECT 'ALL ROUTINES IN SCHEMA'"
2962 " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
2963 " UNION SELECT 'ALL TABLES IN SCHEMA'"
2964 " UNION SELECT 'DATABASE'"
2965 " UNION SELECT 'DOMAIN'"
2966 " UNION SELECT 'FOREIGN DATA WRAPPER'"
2967 " UNION SELECT 'FOREIGN SERVER'"
2968 " UNION SELECT 'FUNCTION'"
2969 " UNION SELECT 'LANGUAGE'"
2970 " UNION SELECT 'LARGE OBJECT'"
2971 " UNION SELECT 'PROCEDURE'"
2972 " UNION SELECT 'ROUTINE'"
2973 " UNION SELECT 'SCHEMA'"
2974 " UNION SELECT 'SEQUENCE'"
2975 " UNION SELECT 'TABLE'"
2976 " UNION SELECT 'TABLESPACE'"
2977 " UNION SELECT 'TYPE'");
2979 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL"))
2980 COMPLETE_WITH("FUNCTIONS IN SCHEMA",
2981 "PROCEDURES IN SCHEMA",
2982 "ROUTINES IN SCHEMA",
2983 "SEQUENCES IN SCHEMA",
2984 "TABLES IN SCHEMA");
2985 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"))
2986 COMPLETE_WITH("DATA WRAPPER", "SERVER");
2989 * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
2990 * appropriate objects.
2992 * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
2994 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny))
2996 if (TailMatches("DATABASE"))
2997 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2998 else if (TailMatches("DOMAIN"))
2999 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3000 else if (TailMatches("FUNCTION"))
3001 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3002 else if (TailMatches("LANGUAGE"))
3003 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3004 else if (TailMatches("PROCEDURE"))
3005 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
3006 else if (TailMatches("ROUTINE"))
3007 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3008 else if (TailMatches("SCHEMA"))
3009 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3010 else if (TailMatches("SEQUENCE"))
3011 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3012 else if (TailMatches("TABLE"))
3013 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL);
3014 else if (TailMatches("TABLESPACE"))
3015 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3016 else if (TailMatches("TYPE"))
3017 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3018 else if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny))
3019 COMPLETE_WITH("TO");
3021 COMPLETE_WITH("FROM");
3025 * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
3026 * CURRENT_USER, or SESSION_USER.
3028 else if ((HeadMatches("GRANT") && TailMatches("TO")) ||
3029 (HeadMatches("REVOKE") && TailMatches("FROM")))
3030 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
3031 /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
3032 else if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches("TO|FROM"))
3033 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
3034 /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
3035 else if (HeadMatches("GRANT") && TailMatches("ON", MatchAny, MatchAny))
3036 COMPLETE_WITH("TO");
3037 else if (HeadMatches("REVOKE") && TailMatches("ON", MatchAny, MatchAny))
3038 COMPLETE_WITH("FROM");
3040 /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
3041 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
3043 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3044 COMPLETE_WITH("TO");
3046 COMPLETE_WITH("FROM");
3049 /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
3050 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
3052 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3053 COMPLETE_WITH("TO");
3055 COMPLETE_WITH("FROM");
3058 /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
3059 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
3061 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
3062 COMPLETE_WITH("TO");
3064 COMPLETE_WITH("FROM");
3068 else if (TailMatches("FROM", MatchAny, "GROUP"))
3069 COMPLETE_WITH("BY");
3071 /* IMPORT FOREIGN SCHEMA */
3072 else if (Matches("IMPORT"))
3073 COMPLETE_WITH("FOREIGN SCHEMA");
3074 else if (Matches("IMPORT", "FOREIGN"))
3075 COMPLETE_WITH("SCHEMA");
3077 /* INSERT --- can be inside EXPLAIN, RULE, etc */
3078 /* Complete INSERT with "INTO" */
3079 else if (TailMatches("INSERT"))
3080 COMPLETE_WITH("INTO");
3081 /* Complete INSERT INTO with table names */
3082 else if (TailMatches("INSERT", "INTO"))
3083 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3084 /* Complete "INSERT INTO <table> (" with attribute names */
3085 else if (TailMatches("INSERT", "INTO", MatchAny, "("))
3086 COMPLETE_WITH_ATTR(prev2_wd, "");
3089 * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
3090 * "TABLE" or "DEFAULT VALUES" or "OVERRIDING"
3092 else if (TailMatches("INSERT", "INTO", MatchAny))
3093 COMPLETE_WITH("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING");
3096 * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
3097 * "TABLE" or "OVERRIDING"
3099 else if (TailMatches("INSERT", "INTO", MatchAny, MatchAny) &&
3100 ends_with(prev_wd, ')'))
3101 COMPLETE_WITH("SELECT", "TABLE", "VALUES", "OVERRIDING");
3103 /* Complete OVERRIDING */
3104 else if (TailMatches("OVERRIDING"))
3105 COMPLETE_WITH("SYSTEM VALUE", "USER VALUE");
3107 /* Complete after OVERRIDING clause */
3108 else if (TailMatches("OVERRIDING", MatchAny, "VALUE"))
3109 COMPLETE_WITH("SELECT", "TABLE", "VALUES");
3111 /* Insert an open parenthesis after "VALUES" */
3112 else if (TailMatches("VALUES") && !TailMatches("DEFAULT", "VALUES"))
3116 /* Complete LOCK [TABLE] with a list of tables */
3117 else if (Matches("LOCK"))
3118 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
3119 " UNION SELECT 'TABLE'");
3120 else if (Matches("LOCK", "TABLE"))
3121 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
3123 /* For the following, handle the case of a single table only for now */
3125 /* Complete LOCK [TABLE] <table> with "IN" */
3126 else if (Matches("LOCK", MatchAnyExcept("TABLE")) ||
3127 Matches("LOCK", "TABLE", MatchAny))
3128 COMPLETE_WITH("IN");
3130 /* Complete LOCK [TABLE] <table> IN with a lock mode */
3131 else if (Matches("LOCK", MatchAny, "IN") ||
3132 Matches("LOCK", "TABLE", MatchAny, "IN"))
3133 COMPLETE_WITH("ACCESS SHARE MODE",
3134 "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
3135 "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
3136 "SHARE ROW EXCLUSIVE MODE",
3137 "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
3139 /* Complete LOCK [TABLE] <table> IN ACCESS|ROW with rest of lock mode */
3140 else if (Matches("LOCK", MatchAny, "IN", "ACCESS|ROW") ||
3141 Matches("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW"))
3142 COMPLETE_WITH("EXCLUSIVE MODE", "SHARE MODE");
3144 /* Complete LOCK [TABLE] <table> IN SHARE with rest of lock mode */
3145 else if (Matches("LOCK", MatchAny, "IN", "SHARE") ||
3146 Matches("LOCK", "TABLE", MatchAny, "IN", "SHARE"))
3147 COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE",
3148 "UPDATE EXCLUSIVE MODE");
3150 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
3151 else if (TailMatches("NOTIFY"))
3152 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'");
3155 else if (TailMatches("OPTIONS"))
3158 /* OWNER TO - complete with available roles */
3159 else if (TailMatches("OWNER", "TO"))
3160 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3163 else if (TailMatches("FROM", MatchAny, "ORDER"))
3164 COMPLETE_WITH("BY");
3165 else if (TailMatches("FROM", MatchAny, "ORDER", "BY"))
3166 COMPLETE_WITH_ATTR(prev3_wd, "");
3169 else if (Matches("PREPARE", MatchAny, "AS"))
3170 COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE FROM");
3173 * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
3174 * managers, not for manual use in interactive sessions.
3177 /* REASSIGN OWNED BY xxx TO yyy */
3178 else if (Matches("REASSIGN"))
3179 COMPLETE_WITH("OWNED BY");
3180 else if (Matches("REASSIGN", "OWNED"))
3181 COMPLETE_WITH("BY");
3182 else if (Matches("REASSIGN", "OWNED", "BY"))
3183 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3184 else if (Matches("REASSIGN", "OWNED", "BY", MatchAny))
3185 COMPLETE_WITH("TO");
3186 else if (Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
3187 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3189 /* REFRESH MATERIALIZED VIEW */
3190 else if (Matches("REFRESH"))
3191 COMPLETE_WITH("MATERIALIZED VIEW");
3192 else if (Matches("REFRESH", "MATERIALIZED"))
3193 COMPLETE_WITH("VIEW");
3194 else if (Matches("REFRESH", "MATERIALIZED", "VIEW"))
3195 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
3196 " UNION SELECT 'CONCURRENTLY'");
3197 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
3198 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3199 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
3200 COMPLETE_WITH("WITH");
3201 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
3202 COMPLETE_WITH("WITH");
3203 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
3204 COMPLETE_WITH("NO DATA", "DATA");
3205 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
3206 COMPLETE_WITH("NO DATA", "DATA");
3207 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
3208 COMPLETE_WITH("DATA");
3209 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
3210 COMPLETE_WITH("DATA");
3213 else if (Matches("REINDEX"))
3214 COMPLETE_WITH("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
3215 else if (Matches("REINDEX", "TABLE"))
3216 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables,
3217 " UNION SELECT 'CONCURRENTLY'");
3218 else if (Matches("REINDEX", "INDEX"))
3219 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
3220 " UNION SELECT 'CONCURRENTLY'");
3221 else if (Matches("REINDEX", "SCHEMA"))
3222 COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3223 " UNION SELECT 'CONCURRENTLY'");
3224 else if (Matches("REINDEX", "SYSTEM|DATABASE"))
3225 COMPLETE_WITH_QUERY(Query_for_list_of_databases
3226 " UNION SELECT 'CONCURRENTLY'");
3227 else if (Matches("REINDEX", "TABLE", "CONCURRENTLY"))
3228 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL);
3229 else if (Matches("REINDEX", "INDEX", "CONCURRENTLY"))
3230 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3231 else if (Matches("REINDEX", "SCHEMA", "CONCURRENTLY"))
3232 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3233 else if (Matches("REINDEX", "SYSTEM|DATABASE", "CONCURRENTLY"))
3234 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3236 /* SECURITY LABEL */
3237 else if (Matches("SECURITY"))
3238 COMPLETE_WITH("LABEL");
3239 else if (Matches("SECURITY", "LABEL"))
3240 COMPLETE_WITH("ON", "FOR");
3241 else if (Matches("SECURITY", "LABEL", "FOR", MatchAny))
3242 COMPLETE_WITH("ON");
3243 else if (Matches("SECURITY", "LABEL", "ON") ||
3244 Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
3245 COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
3246 "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION",
3247 "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE",
3248 "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA",
3249 "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW");
3250 else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
3251 COMPLETE_WITH("IS");
3256 /* SET, RESET, SHOW */
3257 /* Complete with a variable name */
3258 else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET"))
3259 COMPLETE_WITH_QUERY(Query_for_list_of_set_vars);
3260 else if (Matches("SHOW"))
3261 COMPLETE_WITH_QUERY(Query_for_list_of_show_vars);
3262 /* Complete "SET TRANSACTION" */
3263 else if (Matches("SET", "TRANSACTION"))
3264 COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3265 else if (Matches("BEGIN|START", "TRANSACTION") ||
3266 Matches("BEGIN", "WORK") ||
3268 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
3269 COMPLETE_WITH("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3270 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
3271 Matches("BEGIN", "NOT") ||
3272 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
3273 COMPLETE_WITH("DEFERRABLE");
3274 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
3275 Matches("BEGIN", "ISOLATION") ||
3276 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
3277 COMPLETE_WITH("LEVEL");
3278 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
3279 Matches("BEGIN", "ISOLATION", "LEVEL") ||
3280 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
3281 COMPLETE_WITH("READ", "REPEATABLE READ", "SERIALIZABLE");
3282 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
3283 Matches("BEGIN", "ISOLATION", "LEVEL", "READ") ||
3284 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
3285 COMPLETE_WITH("UNCOMMITTED", "COMMITTED");
3286 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
3287 Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
3288 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
3289 COMPLETE_WITH("READ");
3290 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
3291 Matches("BEGIN", "READ") ||
3292 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
3293 COMPLETE_WITH("ONLY", "WRITE");
3294 /* SET CONSTRAINTS */
3295 else if (Matches("SET", "CONSTRAINTS"))
3296 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'");
3297 /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
3298 else if (Matches("SET", "CONSTRAINTS", MatchAny))
3299 COMPLETE_WITH("DEFERRED", "IMMEDIATE");
3300 /* Complete SET ROLE */
3301 else if (Matches("SET", "ROLE"))
3302 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3303 /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
3304 else if (Matches("SET", "SESSION"))
3305 COMPLETE_WITH("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
3306 /* Complete SET SESSION AUTHORIZATION with username */
3307 else if (Matches("SET", "SESSION", "AUTHORIZATION"))
3308 COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'");
3309 /* Complete RESET SESSION with AUTHORIZATION */
3310 else if (Matches("RESET", "SESSION"))
3311 COMPLETE_WITH("AUTHORIZATION");
3312 /* Complete SET <var> with "TO" */
3313 else if (Matches("SET", MatchAny))
3314 COMPLETE_WITH("TO");
3317 * Complete ALTER DATABASE|FUNCTION||PROCEDURE|ROLE|ROUTINE|USER ... SET
3320 else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") &&
3321 TailMatches("SET", MatchAny))
3322 COMPLETE_WITH("FROM CURRENT", "TO");
3323 /* Suggest possible variable values */
3324 else if (TailMatches("SET", MatchAny, "TO|="))
3326 /* special cased code for individual GUCs */
3327 if (TailMatches("DateStyle", "TO|="))
3328 COMPLETE_WITH("ISO", "SQL", "Postgres", "German",
3329 "YMD", "DMY", "MDY",
3330 "US", "European", "NonEuropean",
3332 else if (TailMatches("search_path", "TO|="))
3333 COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3334 " AND nspname not like 'pg\\_toast%%' "
3335 " AND nspname not like 'pg\\_temp%%' "
3336 " UNION SELECT 'DEFAULT' ");
3339 /* generic, type based, GUC support */
3340 char *guctype = get_guctype(prev2_wd);
3342 if (guctype && strcmp(guctype, "enum") == 0)
3344 char querybuf[1024];
3346 snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd);
3347 COMPLETE_WITH_QUERY(querybuf);
3349 else if (guctype && strcmp(guctype, "bool") == 0)
3350 COMPLETE_WITH("on", "off", "true", "false", "yes", "no",
3351 "1", "0", "DEFAULT");
3353 COMPLETE_WITH("DEFAULT");
3360 /* START TRANSACTION */
3361 else if (Matches("START"))
3362 COMPLETE_WITH("TRANSACTION");
3364 /* TABLE, but not TABLE embedded in other commands */
3365 else if (Matches("TABLE"))
3366 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3369 else if (TailMatches("TABLESAMPLE"))
3370 COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
3371 else if (TailMatches("TABLESAMPLE", MatchAny))
3375 else if (Matches("TRUNCATE"))
3376 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3379 else if (Matches("UNLISTEN"))
3380 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 '*'");
3382 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
3383 /* If prev. word is UPDATE suggest a list of tables */
3384 else if (TailMatches("UPDATE"))
3385 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3386 /* Complete UPDATE <table> with "SET" */
3387 else if (TailMatches("UPDATE", MatchAny))
3388 COMPLETE_WITH("SET");
3389 /* Complete UPDATE <table> SET with list of attributes */
3390 else if (TailMatches("UPDATE", MatchAny, "SET"))
3391 COMPLETE_WITH_ATTR(prev2_wd, "");
3392 /* UPDATE <table> SET <attr> = */
3393 else if (TailMatches("UPDATE", MatchAny, "SET", MatchAny))
3397 else if (Matches("ALTER|CREATE|DROP", "USER", "MAPPING"))
3398 COMPLETE_WITH("FOR");
3399 else if (Matches("CREATE", "USER", "MAPPING", "FOR"))
3400 COMPLETE_WITH_QUERY(Query_for_list_of_roles
3401 " UNION SELECT 'CURRENT_USER'"
3402 " UNION SELECT 'PUBLIC'"
3403 " UNION SELECT 'USER'");
3404 else if (Matches("ALTER|DROP", "USER", "MAPPING", "FOR"))
3405 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3406 else if (Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
3407 COMPLETE_WITH("SERVER");
3408 else if (Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
3409 COMPLETE_WITH("OPTIONS");
3412 * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
3413 * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
3415 else if (Matches("VACUUM"))
3416 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3417 " UNION SELECT 'FULL'"
3418 " UNION SELECT 'FREEZE'"
3419 " UNION SELECT 'ANALYZE'"
3420 " UNION SELECT 'VERBOSE'");
3421 else if (Matches("VACUUM", "FULL"))
3422 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3423 " UNION SELECT 'FREEZE'"
3424 " UNION SELECT 'ANALYZE'"
3425 " UNION SELECT 'VERBOSE'");
3426 else if (Matches("VACUUM", "FREEZE") ||
3427 Matches("VACUUM", "FULL", "FREEZE"))
3428 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3429 " UNION SELECT 'VERBOSE'"
3430 " UNION SELECT 'ANALYZE'");
3431 else if (Matches("VACUUM", "VERBOSE") ||
3432 Matches("VACUUM", "FULL|FREEZE", "VERBOSE") ||
3433 Matches("VACUUM", "FULL", "FREEZE", "VERBOSE"))
3434 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3435 " UNION SELECT 'ANALYZE'");
3436 else if (HeadMatches("VACUUM", "(*") &&
3437 !HeadMatches("VACUUM", "(*)"))
3440 * This fires if we're in an unfinished parenthesized option list.
3441 * get_previous_words treats a completed parenthesized option list as
3442 * one word, so the above test is correct.
3444 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
3445 COMPLETE_WITH("FULL", "FREEZE", "ANALYZE", "VERBOSE",
3446 "DISABLE_PAGE_SKIPPING", "SKIP_LOCKED");
3447 else if (TailMatches("FULL|FREEZE|ANALYZE|VERBOSE|DISABLE_PAGE_SKIPPING|SKIP_LOCKED"))
3448 COMPLETE_WITH("ON", "OFF");
3450 else if (HeadMatches("VACUUM") && TailMatches("("))
3451 /* "VACUUM (" should be caught above, so assume we want columns */
3452 COMPLETE_WITH_ATTR(prev2_wd, "");
3453 else if (HeadMatches("VACUUM"))
3454 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, NULL);
3456 /* WITH [RECURSIVE] */
3459 * Only match when WITH is the first word, as WITH may appear in many
3462 else if (Matches("WITH"))
3463 COMPLETE_WITH("RECURSIVE");
3466 /* Simple case of the word before the where being the table name */
3467 else if (TailMatches(MatchAny, "WHERE"))
3468 COMPLETE_WITH_ATTR(prev2_wd, "");
3471 /* TODO: also include SRF ? */
3472 else if (TailMatches("FROM") && !Matches("COPY|\\copy", MatchAny, "FROM"))
3473 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3476 else if (TailMatches("JOIN"))
3477 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3479 /* Backslash commands */
3480 /* TODO: \dc \dd \dl */
3481 else if (TailMatchesCS("\\?"))
3482 COMPLETE_WITH_CS("commands", "options", "variables");
3483 else if (TailMatchesCS("\\connect|\\c"))
3485 if (!recognized_connection_string(text))
3486 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3488 else if (TailMatchesCS("\\connect|\\c", MatchAny))
3490 if (!recognized_connection_string(prev_wd))
3491 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3493 else if (TailMatchesCS("\\da*"))
3494 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
3495 else if (TailMatchesCS("\\dA*"))
3496 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3497 else if (TailMatchesCS("\\db*"))
3498 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3499 else if (TailMatchesCS("\\dD*"))
3500 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3501 else if (TailMatchesCS("\\des*"))
3502 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3503 else if (TailMatchesCS("\\deu*"))
3504 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3505 else if (TailMatchesCS("\\dew*"))
3506 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3507 else if (TailMatchesCS("\\df*"))
3508 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3510 else if (TailMatchesCS("\\dFd*"))
3511 COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
3512 else if (TailMatchesCS("\\dFp*"))
3513 COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
3514 else if (TailMatchesCS("\\dFt*"))
3515 COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
3516 /* must be at end of \dF alternatives: */
3517 else if (TailMatchesCS("\\dF*"))
3518 COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
3520 else if (TailMatchesCS("\\di*"))
3521 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3522 else if (TailMatchesCS("\\dL*"))
3523 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3524 else if (TailMatchesCS("\\dn*"))
3525 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3526 else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z"))
3527 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL);
3528 else if (TailMatchesCS("\\ds*"))
3529 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3530 else if (TailMatchesCS("\\dt*"))
3531 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3532 else if (TailMatchesCS("\\dT*"))
3533 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3534 else if (TailMatchesCS("\\du*") || TailMatchesCS("\\dg*"))
3535 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3536 else if (TailMatchesCS("\\dv*"))
3537 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3538 else if (TailMatchesCS("\\dx*"))
3539 COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
3540 else if (TailMatchesCS("\\dm*"))
3541 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3542 else if (TailMatchesCS("\\dE*"))
3543 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
3544 else if (TailMatchesCS("\\dy*"))
3545 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3547 /* must be at end of \d alternatives: */
3548 else if (TailMatchesCS("\\d*"))
3549 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3551 else if (TailMatchesCS("\\ef"))
3552 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3553 else if (TailMatchesCS("\\ev"))
3554 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3556 else if (TailMatchesCS("\\encoding"))
3557 COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
3558 else if (TailMatchesCS("\\h|\\help"))
3559 COMPLETE_WITH_LIST(sql_commands);
3560 else if (TailMatchesCS("\\h|\\help", MatchAny))
3562 if (TailMatches("DROP"))
3563 matches = completion_matches(text, drop_command_generator);
3564 else if (TailMatches("ALTER"))
3565 matches = completion_matches(text, alter_command_generator);
3568 * CREATE is recognized by tail match elsewhere, so doesn't need to be
3572 else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny))
3574 if (TailMatches("CREATE|DROP", "ACCESS"))
3575 COMPLETE_WITH("METHOD");
3576 else if (TailMatches("ALTER", "DEFAULT"))
3577 COMPLETE_WITH("PRIVILEGES");
3578 else if (TailMatches("CREATE|ALTER|DROP", "EVENT"))
3579 COMPLETE_WITH("TRIGGER");
3580 else if (TailMatches("CREATE|ALTER|DROP", "FOREIGN"))
3581 COMPLETE_WITH("DATA WRAPPER", "TABLE");
3582 else if (TailMatches("ALTER", "LARGE"))
3583 COMPLETE_WITH("OBJECT");
3584 else if (TailMatches("CREATE|ALTER|DROP", "MATERIALIZED"))
3585 COMPLETE_WITH("VIEW");
3586 else if (TailMatches("CREATE|ALTER|DROP", "TEXT"))
3587 COMPLETE_WITH("SEARCH");
3588 else if (TailMatches("CREATE|ALTER|DROP", "USER"))
3589 COMPLETE_WITH("MAPPING FOR");
3591 else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny))
3593 if (TailMatches("CREATE|ALTER|DROP", "FOREIGN", "DATA"))
3594 COMPLETE_WITH("WRAPPER");
3595 else if (TailMatches("CREATE|ALTER|DROP", "TEXT", "SEARCH"))
3596 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
3597 else if (TailMatches("CREATE|ALTER|DROP", "USER", "MAPPING"))
3598 COMPLETE_WITH("FOR");
3600 else if (TailMatchesCS("\\l*") && !TailMatchesCS("\\lo*"))
3601 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3602 else if (TailMatchesCS("\\password"))
3603 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3604 else if (TailMatchesCS("\\pset"))
3605 COMPLETE_WITH_CS("border", "columns", "csv_fieldsep", "expanded",
3606 "fieldsep", "fieldsep_zero", "footer", "format",
3607 "linestyle", "null", "numericlocale",
3608 "pager", "pager_min_lines",
3609 "recordsep", "recordsep_zero",
3610 "tableattr", "title", "tuples_only",
3611 "unicode_border_linestyle",
3612 "unicode_column_linestyle",
3613 "unicode_header_linestyle");
3614 else if (TailMatchesCS("\\pset", MatchAny))
3616 if (TailMatchesCS("format"))
3617 COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex",
3618 "latex-longtable", "troff-ms", "unaligned",
3620 else if (TailMatchesCS("linestyle"))
3621 COMPLETE_WITH_CS("ascii", "old-ascii", "unicode");
3622 else if (TailMatchesCS("pager"))
3623 COMPLETE_WITH_CS("on", "off", "always");
3624 else if (TailMatchesCS("unicode_border_linestyle|"
3625 "unicode_column_linestyle|"
3626 "unicode_header_linestyle"))
3627 COMPLETE_WITH_CS("single", "double");
3629 else if (TailMatchesCS("\\unset"))
3630 matches = complete_from_variables(text, "", "", true);
3631 else if (TailMatchesCS("\\set"))
3632 matches = complete_from_variables(text, "", "", false);
3633 else if (TailMatchesCS("\\set", MatchAny))
3635 if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
3636 "SINGLELINE|SINGLESTEP"))
3637 COMPLETE_WITH_CS("on", "off");
3638 else if (TailMatchesCS("COMP_KEYWORD_CASE"))
3639 COMPLETE_WITH_CS("lower", "upper",
3640 "preserve-lower", "preserve-upper");
3641 else if (TailMatchesCS("ECHO"))
3642 COMPLETE_WITH_CS("errors", "queries", "all", "none");
3643 else if (TailMatchesCS("ECHO_HIDDEN"))
3644 COMPLETE_WITH_CS("noexec", "off", "on");
3645 else if (TailMatchesCS("HISTCONTROL"))
3646 COMPLETE_WITH_CS("ignorespace", "ignoredups",
3647 "ignoreboth", "none");
3648 else if (TailMatchesCS("ON_ERROR_ROLLBACK"))
3649 COMPLETE_WITH_CS("on", "off", "interactive");
3650 else if (TailMatchesCS("SHOW_CONTEXT"))
3651 COMPLETE_WITH_CS("never", "errors", "always");
3652 else if (TailMatchesCS("VERBOSITY"))
3653 COMPLETE_WITH_CS("default", "verbose", "terse");
3655 else if (TailMatchesCS("\\sf*"))
3656 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3657 else if (TailMatchesCS("\\sv*"))
3658 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3659 else if (TailMatchesCS("\\cd|\\e|\\edit|\\g|\\i|\\include|"
3660 "\\ir|\\include_relative|\\o|\\out|"
3661 "\\s|\\w|\\write|\\lo_import"))
3663 completion_charp = "\\";
3664 matches = completion_matches(text, complete_from_files);
3668 * Finally, we look through the list of "things", such as TABLE, INDEX and
3669 * check if that was the previous word. If so, execute the query to get a
3676 for (i = 0; words_after_create[i].name; i++)
3678 if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
3680 if (words_after_create[i].query)
3681 COMPLETE_WITH_QUERY(words_after_create[i].query);
3682 else if (words_after_create[i].vquery)
3683 COMPLETE_WITH_VERSIONED_QUERY(words_after_create[i].vquery);
3684 else if (words_after_create[i].squery)
3685 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(words_after_create[i].squery,
3693 * If we still don't have anything to match we have to fabricate some sort
3694 * of default list. If we were to just return NULL, readline automatically
3695 * attempts filename completion, and that's usually no good.
3697 if (matches == NULL)
3700 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
3701 rl_completion_append_character = '\0';
3706 free(previous_words);
3709 /* Return our Grand List O' Matches */
3715 * GENERATOR FUNCTIONS
3717 * These functions do all the actual work of completing the input. They get
3718 * passed the text so far and the count how many times they have been called
3719 * so far with the same text.
3720 * If you read the above carefully, you'll see that these don't get called
3721 * directly but through the readline interface.
3722 * The return value is expected to be the full completion of the text, going
3723 * through a list each time, or NULL if there are no more matches. The string
3724 * will be free()'d by readline, so you must run it through strdup() or
3725 * something of that sort.
3729 * Common routine for create_command_generator and drop_command_generator.
3730 * Entries that have 'excluded' flags are not returned.
3733 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
3735 static int list_index,
3739 /* If this is the first time for this completion, init some values */
3743 string_length = strlen(text);
3746 /* find something that matches */
3747 while ((name = words_after_create[list_index++].name))
3749 if ((pg_strncasecmp(name, text, string_length) == 0) &&
3750 !(words_after_create[list_index - 1].flags & excluded))
3751 return pg_strdup_keyword_case(name, text);
3753 /* if nothing matches, return NULL */
3758 * This one gives you one from a list of things you can put after CREATE
3762 create_command_generator(const char *text, int state)
3764 return create_or_drop_command_generator(text, state, THING_NO_CREATE);
3768 * This function gives you a list of things you can put after a DROP command.
3771 drop_command_generator(const char *text, int state)
3773 return create_or_drop_command_generator(text, state, THING_NO_DROP);
3777 * This function gives you a list of things you can put after an ALTER command.
3780 alter_command_generator(const char *text, int state)
3782 return create_or_drop_command_generator(text, state, THING_NO_ALTER);
3786 * These functions generate lists using server queries.
3787 * They are all wrappers for _complete_from_query.
3791 complete_from_query(const char *text, int state)
3793 /* query is assumed to work for any server version */
3794 return _complete_from_query(completion_charp, NULL, text, state);
3798 complete_from_versioned_query(const char *text, int state)
3800 const VersionedQuery *vquery = completion_vquery;
3802 /* Find appropriate array element */
3803 while (pset.sversion < vquery->min_server_version)
3805 /* Fail completion if server is too old */
3806 if (vquery->query == NULL)
3809 return _complete_from_query(vquery->query, NULL, text, state);
3813 complete_from_schema_query(const char *text, int state)
3815 /* query is assumed to work for any server version */
3816 return _complete_from_query(completion_charp, completion_squery,
3821 complete_from_versioned_schema_query(const char *text, int state)
3823 const SchemaQuery *squery = completion_squery;
3824 const VersionedQuery *vquery = completion_vquery;
3826 /* Find appropriate array element */
3827 while (pset.sversion < squery->min_server_version)
3829 /* Fail completion if server is too old */
3830 if (squery->catname == NULL)
3833 /* Likewise for the add-on text, if any */
3836 while (pset.sversion < vquery->min_server_version)
3838 if (vquery->query == NULL)
3842 return _complete_from_query(vquery ? vquery->query : NULL,
3843 squery, text, state);
3848 * This creates a list of matching things, according to a query described by
3849 * the initial arguments. The caller has already done any work needed to
3850 * select the appropriate query for the server's version.
3852 * The query can be one of two kinds:
3854 * 1. A simple query which must contain a %d and a %s, which will be replaced
3855 * by the string length of the text and the text itself. The query may also
3856 * have up to four more %s in it; the first two such will be replaced by the
3857 * value of completion_info_charp, the next two by the value of
3858 * completion_info_charp2.
3860 * 2. A schema query used for completion of both schema and relation names.
3861 * These are more complex and must contain in the following order:
3862 * %d %s %d %s %d %s %s %d %s
3863 * where %d is the string length of the text and %s the text itself.
3865 * If both simple_query and schema_query are non-NULL, then we construct
3866 * a schema query and append the (uninterpreted) string simple_query to it.
3868 * It is assumed that strings should be escaped to become SQL literals
3869 * (that is, what is in the query is actually ... '%s' ...)
3871 * See top of file for examples of both kinds of query.
3873 * "text" and "state" are supplied by readline.
3876 _complete_from_query(const char *simple_query,
3877 const SchemaQuery *schema_query,
3878 const char *text, int state)
3880 static int list_index,
3882 static PGresult *result = NULL;
3885 * If this is the first time for this completion, we fetch a list of our
3886 * "things" from the backend.
3890 PQExpBufferData query_buffer;
3893 char *e_info_charp2;
3894 const char *pstr = text;
3895 int char_length = 0;
3898 byte_length = strlen(text);
3901 * Count length as number of characters (not bytes), for passing to
3907 pstr += PQmblen(pstr, pset.encoding);
3910 /* Free any prior result */
3914 /* Set up suitably-escaped copies of textual inputs */
3915 e_text = escape_string(text);
3917 if (completion_info_charp)
3918 e_info_charp = escape_string(completion_info_charp);
3920 e_info_charp = NULL;
3922 if (completion_info_charp2)
3923 e_info_charp2 = escape_string(completion_info_charp2);
3925 e_info_charp2 = NULL;
3927 initPQExpBuffer(&query_buffer);
3931 /* schema_query gives us the pieces to assemble */
3932 const char *qualresult = schema_query->qualresult;
3934 if (qualresult == NULL)
3935 qualresult = schema_query->result;
3937 /* Get unqualified names matching the input-so-far */
3938 appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
3939 schema_query->result,
3940 schema_query->catname);
3941 if (schema_query->selcondition)
3942 appendPQExpBuffer(&query_buffer, "%s AND ",
3943 schema_query->selcondition);
3944 appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
3945 schema_query->result,
3946 char_length, e_text);
3947 appendPQExpBuffer(&query_buffer, " AND %s",
3948 schema_query->viscondition);
3951 * When fetching relation names, suppress system catalogs unless
3952 * the input-so-far begins with "pg_". This is a compromise
3953 * between not offering system catalogs for completion at all, and
3954 * having them swamp the result when the input is just "p".
3956 if (strcmp(schema_query->catname,
3957 "pg_catalog.pg_class c") == 0 &&
3958 strncmp(text, "pg_", 3) !=0)
3960 appendPQExpBufferStr(&query_buffer,
3961 " AND c.relnamespace <> (SELECT oid FROM"
3962 " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
3966 * Add in matching schema names, but only if there is more than
3967 * one potential match among schema names.
3969 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3970 "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
3971 "FROM pg_catalog.pg_namespace n "
3972 "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
3973 char_length, e_text);
3974 appendPQExpBuffer(&query_buffer,
3975 " AND (SELECT pg_catalog.count(*)"
3976 " FROM pg_catalog.pg_namespace"
3977 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3978 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
3979 char_length, e_text);
3982 * Add in matching qualified names, but only if there is exactly
3983 * one schema matching the input-so-far.
3985 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3986 "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
3987 "FROM %s, pg_catalog.pg_namespace n "
3988 "WHERE %s = n.oid AND ",
3990 schema_query->catname,
3991 schema_query->namespace);
3992 if (schema_query->selcondition)
3993 appendPQExpBuffer(&query_buffer, "%s AND ",
3994 schema_query->selcondition);
3995 appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
3997 char_length, e_text);
4000 * This condition exploits the single-matching-schema rule to
4001 * speed up the query
4003 appendPQExpBuffer(&query_buffer,
4004 " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
4005 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
4006 char_length, e_text);
4007 appendPQExpBuffer(&query_buffer,
4008 " AND (SELECT pg_catalog.count(*)"
4009 " FROM pg_catalog.pg_namespace"
4010 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
4011 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
4012 char_length, e_text);
4014 /* If an addon query was provided, use it */
4016 appendPQExpBuffer(&query_buffer, "\n%s", simple_query);
4020 Assert(simple_query);
4021 /* simple_query is an sprintf-style format string */
4022 appendPQExpBuffer(&query_buffer, simple_query,
4023 char_length, e_text,
4024 e_info_charp, e_info_charp,
4025 e_info_charp2, e_info_charp2);
4028 /* Limit the number of records in the result */
4029 appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
4030 completion_max_records);
4032 result = exec_query(query_buffer.data);
4034 termPQExpBuffer(&query_buffer);
4039 free(e_info_charp2);
4042 /* Find something that matches */
4043 if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
4047 while (list_index < PQntuples(result) &&
4048 (item = PQgetvalue(result, list_index++, 0)))
4049 if (pg_strncasecmp(text, item, byte_length) == 0)
4050 return pg_strdup(item);
4053 /* If nothing matches, free the db structure and return null */
4061 * This function returns in order one of a fixed, NULL pointer terminated list
4062 * of strings (if matching). This can be used if there are only a fixed number
4063 * SQL words that can appear at certain spot.
4066 complete_from_list(const char *text, int state)
4068 static int string_length,
4071 static bool casesensitive;
4074 /* need to have a list */
4075 Assert(completion_charpp != NULL);
4077 /* Initialization */
4081 string_length = strlen(text);
4082 casesensitive = completion_case_sensitive;
4086 while ((item = completion_charpp[list_index++]))
4088 /* First pass is case sensitive */
4089 if (casesensitive && strncmp(text, item, string_length) == 0)
4092 return pg_strdup(item);
4095 /* Second pass is case insensitive, don't bother counting matches */
4096 if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
4098 if (completion_case_sensitive)
4099 return pg_strdup(item);
4103 * If case insensitive matching was requested initially,
4104 * adjust the case according to setting.
4106 return pg_strdup_keyword_case(item, text);
4111 * No matches found. If we're not case insensitive already, lets switch to
4112 * being case insensitive and try again
4114 if (casesensitive && matches == 0)
4116 casesensitive = false;
4119 return complete_from_list(text, state);
4122 /* If no more matches, return null. */
4128 * This function returns one fixed string the first time even if it doesn't
4129 * match what's there, and nothing the second time. This should be used if
4130 * there is only one possibility that can appear at a certain spot, so
4131 * misspellings will be overwritten. The string to be passed must be in
4135 complete_from_const(const char *text, int state)
4137 Assert(completion_charp != NULL);
4140 if (completion_case_sensitive)
4141 return pg_strdup(completion_charp);
4145 * If case insensitive matching was requested initially, adjust
4146 * the case according to setting.
4148 return pg_strdup_keyword_case(completion_charp, text);
4156 * This function appends the variable name with prefix and suffix to
4157 * the variable names array.
4160 append_variable_names(char ***varnames, int *nvars,
4161 int *maxvars, const char *varname,
4162 const char *prefix, const char *suffix)
4164 if (*nvars >= *maxvars)
4167 *varnames = (char **) pg_realloc(*varnames,
4168 ((*maxvars) + 1) * sizeof(char *));
4171 (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
4176 * This function supports completion with the name of a psql variable.
4177 * The variable names can be prefixed and suffixed with additional text
4178 * to support quoting usages. If need_value is true, only variables
4179 * that are currently set are included; otherwise, special variables
4180 * (those that have hooks) are included even if currently unset.
4183 complete_from_variables(const char *text, const char *prefix, const char *suffix,
4191 struct _variable *ptr;
4193 varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
4195 for (ptr = pset.vars->next; ptr; ptr = ptr->next)
4197 if (need_value && !(ptr->value))
4199 append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
4203 varnames[nvars] = NULL;
4204 COMPLETE_WITH_LIST_CS((const char *const *) varnames);
4206 for (i = 0; i < nvars; i++)
4215 * This function wraps rl_filename_completion_function() to strip quotes from
4216 * the input before searching for matches and to quote any matches for which
4217 * the consuming command will require it.
4220 complete_from_files(const char *text, int state)
4222 static const char *unquoted_text;
4223 char *unquoted_match;
4228 /* Initialization: stash the unquoted input. */
4229 unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
4230 false, true, pset.encoding);
4231 /* expect a NULL return for the empty string only */
4234 Assert(*text == '\0');
4235 unquoted_text = text;
4239 unquoted_match = filename_completion_function(unquoted_text, state);
4243 * Caller sets completion_charp to a zero- or one-character string
4244 * containing the escape character. This is necessary since \copy has
4245 * no escape character, but every other backslash command recognizes
4246 * "\" as an escape character. Since we have only two callers, don't
4247 * bother providing a macro to simplify this.
4249 ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
4250 '\'', *completion_charp, pset.encoding);
4252 free(unquoted_match);
4254 ret = unquoted_match;
4261 /* HELPER FUNCTIONS */
4265 * Make a pg_strdup copy of s and convert the case according to
4266 * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
4269 pg_strdup_keyword_case(const char *s, const char *ref)
4273 unsigned char first = ref[0];
4277 if (pset.comp_case == PSQL_COMP_CASE_LOWER ||
4278 ((pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER ||
4279 pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
4280 (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
4282 for (p = ret; *p; p++)
4283 *p = pg_tolower((unsigned char) *p);
4287 for (p = ret; *p; p++)
4288 *p = pg_toupper((unsigned char) *p);
4296 * escape_string - Escape argument for use as string literal.
4298 * The returned value has to be freed.
4301 escape_string(const char *text)
4306 text_length = strlen(text);
4308 result = pg_malloc(text_length * 2 + 1);
4309 PQescapeStringConn(pset.db, result, text, text_length, NULL);
4316 * Execute a query and report any errors. This should be the preferred way of
4317 * talking to the database in this file.
4320 exec_query(const char *query)
4324 if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
4327 result = PQexec(pset.db, query);
4329 if (PQresultStatus(result) != PGRES_TUPLES_OK)
4332 psql_error("tab completion query failed: %s\nQuery was:\n%s\n",
4333 PQerrorMessage(pset.db), query);
4344 * Parse all the word(s) before point.
4346 * Returns a malloc'd array of character pointers that point into the malloc'd
4347 * data array returned to *buffer; caller must free() both of these when done.
4348 * *nwords receives the number of words found, ie, the valid length of the
4351 * Words are returned right to left, that is, previous_words[0] gets the last
4352 * word before point, previous_words[1] the next-to-last, etc.
4355 get_previous_words(int point, char **buffer, int *nwords)
4357 char **previous_words;
4360 int words_found = 0;
4364 * If we have anything in tab_completion_query_buf, paste it together with
4365 * rl_line_buffer to construct the full query. Otherwise we can just use
4366 * rl_line_buffer as the input string.
4368 if (tab_completion_query_buf && tab_completion_query_buf->len > 0)
4370 i = tab_completion_query_buf->len;
4371 buf = pg_malloc(point + i + 2);
4372 memcpy(buf, tab_completion_query_buf->data, i);
4374 memcpy(buf + i, rl_line_buffer, point);
4377 /* Readjust point to reference appropriate offset in buf */
4381 buf = rl_line_buffer;
4384 * Allocate an array of string pointers and a buffer to hold the strings
4385 * themselves. The worst case is that the line contains only
4386 * non-whitespace WORD_BREAKS characters, making each one a separate word.
4387 * This is usually much more space than we need, but it's cheaper than
4388 * doing a separate malloc() for each word.
4390 previous_words = (char **) pg_malloc(point * sizeof(char *));
4391 *buffer = outptr = (char *) pg_malloc(point * 2);
4394 * First we look for a non-word char before the current point. (This is
4395 * probably useless, if readline is on the same page as we are about what
4396 * is a word, but if so it's cheap.)
4398 for (i = point - 1; i >= 0; i--)
4400 if (strchr(WORD_BREAKS, buf[i]))
4406 * Now parse words, working backwards, until we hit start of line. The
4407 * backwards scan has some interesting but intentional properties
4408 * concerning parenthesis handling.
4414 bool inquotes = false;
4415 int parentheses = 0;
4417 /* now find the first non-space which then constitutes the end */
4419 for (i = point; i >= 0; i--)
4421 if (!isspace((unsigned char) buf[i]))
4427 /* if no end found, we're done */
4432 * Otherwise we now look for the start. The start is either the last
4433 * character before any word-break character going backwards from the
4434 * end, or it's simply character 0. We also handle open quotes and
4437 for (start = end; start > 0; start--)
4439 if (buf[start] == '"')
4440 inquotes = !inquotes;
4443 if (buf[start] == ')')
4445 else if (buf[start] == '(')
4447 if (--parentheses <= 0)
4450 else if (parentheses == 0 &&
4451 strchr(WORD_BREAKS, buf[start - 1]))
4456 /* Return the word located at start to end inclusive */
4457 previous_words[words_found++] = outptr;
4458 i = end - start + 1;
4459 memcpy(outptr, &buf[start], i);
4463 /* Continue searching */
4467 /* Release parsing input workspace, if we made one above */
4468 if (buf != rl_line_buffer)
4471 *nwords = words_found;
4472 return previous_words;
4476 * Look up the type for the GUC variable with the passed name.
4478 * Returns NULL if the variable is unknown. Otherwise the returned string,
4479 * containing the type, has to be freed.
4482 get_guctype(const char *varname)
4484 PQExpBufferData query_buffer;
4487 char *guctype = NULL;
4489 e_varname = escape_string(varname);
4491 initPQExpBuffer(&query_buffer);
4492 appendPQExpBuffer(&query_buffer,
4493 "SELECT vartype FROM pg_catalog.pg_settings "
4494 "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4497 result = exec_query(query_buffer.data);
4498 termPQExpBuffer(&query_buffer);
4501 if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
4502 guctype = pg_strdup(PQgetvalue(result, 0, 0));
4512 * Surround a string with single quotes. This works for both SQL and
4513 * psql internal. Currently disabled because it is reported not to
4514 * cooperate with certain versions of readline.
4517 quote_file_name(char *text, int match_type, char *quote_pointer)
4522 (void) quote_pointer; /* not used */
4524 length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
4525 s = pg_malloc(length);
4527 strcpy(s + 1, text);
4528 if (match_type == SINGLE_MATCH)
4529 s[length - 2] = '\'';
4530 s[length - 1] = '\0';
4535 dequote_file_name(char *text, char quote_char)
4541 return pg_strdup(text);
4543 length = strlen(text);
4544 s = pg_malloc(length - 2 + 1);
4545 strlcpy(s, text +1, length - 2 + 1);
4549 #endif /* NOT_USED */
4551 #endif /* USE_READLINE */