2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2018, 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_domains = {
348 .catname = "pg_catalog.pg_type t",
349 .selcondition = "t.typtype = 'd'",
350 .viscondition = "pg_catalog.pg_type_is_visible(t.oid)",
351 .namespace = "t.typnamespace",
352 .result = "pg_catalog.quote_ident(t.typname)",
355 /* Note: this intentionally accepts aggregates as well as plain functions */
356 static const SchemaQuery Query_for_list_of_functions[] = {
358 .min_server_version = 110000,
359 .catname = "pg_catalog.pg_proc p",
360 .selcondition = "p.prokind != 'p'",
361 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
362 .namespace = "p.pronamespace",
363 .result = "pg_catalog.quote_ident(p.proname)",
366 .catname = "pg_catalog.pg_proc p",
367 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
368 .namespace = "p.pronamespace",
369 .result = "pg_catalog.quote_ident(p.proname)",
373 static const SchemaQuery Query_for_list_of_procedures[] = {
375 .min_server_version = 110000,
376 .catname = "pg_catalog.pg_proc p",
377 .selcondition = "p.prokind = 'p'",
378 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
379 .namespace = "p.pronamespace",
380 .result = "pg_catalog.quote_ident(p.proname)",
383 /* not supported in older versions */
388 static const SchemaQuery Query_for_list_of_routines = {
389 .catname = "pg_catalog.pg_proc p",
390 .viscondition = "pg_catalog.pg_function_is_visible(p.oid)",
391 .namespace = "p.pronamespace",
392 .result = "pg_catalog.quote_ident(p.proname)",
395 static const SchemaQuery Query_for_list_of_sequences = {
396 .catname = "pg_catalog.pg_class c",
397 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_SEQUENCE) ")",
398 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
399 .namespace = "c.relnamespace",
400 .result = "pg_catalog.quote_ident(c.relname)",
403 static const SchemaQuery Query_for_list_of_foreign_tables = {
404 .catname = "pg_catalog.pg_class c",
405 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_FOREIGN_TABLE) ")",
406 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
407 .namespace = "c.relnamespace",
408 .result = "pg_catalog.quote_ident(c.relname)",
411 static const SchemaQuery Query_for_list_of_tables = {
412 .catname = "pg_catalog.pg_class c",
414 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
415 CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
416 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
417 .namespace = "c.relnamespace",
418 .result = "pg_catalog.quote_ident(c.relname)",
421 static const SchemaQuery Query_for_list_of_partitioned_tables = {
422 .catname = "pg_catalog.pg_class c",
423 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
424 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
425 .namespace = "c.relnamespace",
426 .result = "pg_catalog.quote_ident(c.relname)",
429 static const SchemaQuery Query_for_list_of_views = {
430 .catname = "pg_catalog.pg_class c",
431 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_VIEW) ")",
432 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
433 .namespace = "c.relnamespace",
434 .result = "pg_catalog.quote_ident(c.relname)",
437 static const SchemaQuery Query_for_list_of_matviews = {
438 .catname = "pg_catalog.pg_class c",
439 .selcondition = "c.relkind IN (" CppAsString2(RELKIND_MATVIEW) ")",
440 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
441 .namespace = "c.relnamespace",
442 .result = "pg_catalog.quote_ident(c.relname)",
445 static const SchemaQuery Query_for_list_of_indexes = {
446 .catname = "pg_catalog.pg_class c",
448 "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", "
449 CppAsString2(RELKIND_PARTITIONED_INDEX) ")",
450 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
451 .namespace = "c.relnamespace",
452 .result = "pg_catalog.quote_ident(c.relname)",
456 static const SchemaQuery Query_for_list_of_relations = {
457 .catname = "pg_catalog.pg_class c",
458 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
459 .namespace = "c.relnamespace",
460 .result = "pg_catalog.quote_ident(c.relname)",
463 /* Relations supporting INSERT, UPDATE or DELETE */
464 static const SchemaQuery Query_for_list_of_updatables = {
465 .catname = "pg_catalog.pg_class c",
467 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
468 CppAsString2(RELKIND_FOREIGN_TABLE) ", "
469 CppAsString2(RELKIND_VIEW) ", "
470 CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
471 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
472 .namespace = "c.relnamespace",
473 .result = "pg_catalog.quote_ident(c.relname)",
476 /* Relations supporting SELECT */
477 static const SchemaQuery Query_for_list_of_selectables = {
478 .catname = "pg_catalog.pg_class c",
480 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
481 CppAsString2(RELKIND_SEQUENCE) ", "
482 CppAsString2(RELKIND_VIEW) ", "
483 CppAsString2(RELKIND_MATVIEW) ", "
484 CppAsString2(RELKIND_FOREIGN_TABLE) ", "
485 CppAsString2(RELKIND_PARTITIONED_TABLE) ")",
486 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
487 .namespace = "c.relnamespace",
488 .result = "pg_catalog.quote_ident(c.relname)",
491 /* Relations supporting GRANT are currently same as those supporting SELECT */
492 #define Query_for_list_of_grantables Query_for_list_of_selectables
494 /* Relations supporting ANALYZE */
495 static const SchemaQuery Query_for_list_of_analyzables = {
496 .catname = "pg_catalog.pg_class c",
498 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
499 CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
500 CppAsString2(RELKIND_MATVIEW) ", "
501 CppAsString2(RELKIND_FOREIGN_TABLE) ")",
502 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
503 .namespace = "c.relnamespace",
504 .result = "pg_catalog.quote_ident(c.relname)",
507 /* Relations supporting index creation */
508 static const SchemaQuery Query_for_list_of_indexables = {
509 .catname = "pg_catalog.pg_class c",
511 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
512 CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
513 CppAsString2(RELKIND_MATVIEW) ")",
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 VACUUM */
520 static const SchemaQuery Query_for_list_of_vacuumables = {
521 .catname = "pg_catalog.pg_class c",
523 "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
524 CppAsString2(RELKIND_MATVIEW) ")",
525 .viscondition = "pg_catalog.pg_table_is_visible(c.oid)",
526 .namespace = "c.relnamespace",
527 .result = "pg_catalog.quote_ident(c.relname)",
530 /* Relations supporting CLUSTER are currently same as those supporting VACUUM */
531 #define Query_for_list_of_clusterables Query_for_list_of_vacuumables
533 static const SchemaQuery Query_for_list_of_constraints_with_schema = {
534 .catname = "pg_catalog.pg_constraint c",
535 .selcondition = "c.conrelid <> 0",
536 .viscondition = "true", /* there is no pg_constraint_is_visible */
537 .namespace = "c.connamespace",
538 .result = "pg_catalog.quote_ident(c.conname)",
541 static const SchemaQuery Query_for_list_of_statistics = {
542 .catname = "pg_catalog.pg_statistic_ext s",
543 .viscondition = "pg_catalog.pg_statistics_obj_is_visible(s.oid)",
544 .namespace = "s.stxnamespace",
545 .result = "pg_catalog.quote_ident(s.stxname)",
550 * Queries to get lists of names of various kinds of things, possibly
551 * restricted to names matching a partially entered name. In these queries,
552 * the first %s will be replaced by the text entered so far (suitably escaped
553 * to become a SQL literal string). %d will be replaced by the length of the
554 * string (in unescaped form). A second and third %s, if present, will be
555 * replaced by a suitably-escaped version of the string provided in
556 * completion_info_charp. A fourth and fifth %s are similarly replaced by
557 * completion_info_charp2.
559 * Beware that the allowed sequences of %s and %d are determined by
560 * _complete_from_query().
563 #define Query_for_list_of_attributes \
564 "SELECT pg_catalog.quote_ident(attname) "\
565 " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\
566 " WHERE c.oid = a.attrelid "\
567 " AND a.attnum > 0 "\
568 " AND NOT a.attisdropped "\
569 " AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\
570 " AND (pg_catalog.quote_ident(relname)='%s' "\
571 " OR '\"' || relname || '\"'='%s') "\
572 " AND pg_catalog.pg_table_is_visible(c.oid)"
574 #define Query_for_list_of_attributes_with_schema \
575 "SELECT pg_catalog.quote_ident(attname) "\
576 " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c, pg_catalog.pg_namespace n "\
577 " WHERE c.oid = a.attrelid "\
578 " AND n.oid = c.relnamespace "\
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.quote_ident(nspname)='%s' "\
585 " OR '\"' || nspname || '\"' ='%s') "
587 #define Query_for_list_of_enum_values \
588 "SELECT pg_catalog.quote_literal(enumlabel) "\
589 " FROM pg_catalog.pg_enum e, pg_catalog.pg_type t "\
590 " WHERE t.oid = e.enumtypid "\
591 " AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
592 " AND (pg_catalog.quote_ident(typname)='%s' "\
593 " OR '\"' || typname || '\"'='%s') "\
594 " AND pg_catalog.pg_type_is_visible(t.oid)"
596 #define Query_for_list_of_enum_values_with_schema \
597 "SELECT pg_catalog.quote_literal(enumlabel) "\
598 " FROM pg_catalog.pg_enum e, pg_catalog.pg_type t, pg_catalog.pg_namespace n "\
599 " WHERE t.oid = e.enumtypid "\
600 " AND n.oid = t.typnamespace "\
601 " AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
602 " AND (pg_catalog.quote_ident(typname)='%s' "\
603 " OR '\"' || typname || '\"'='%s') "\
604 " AND (pg_catalog.quote_ident(nspname)='%s' "\
605 " OR '\"' || nspname || '\"' ='%s') "
607 #define Query_for_list_of_template_databases \
608 "SELECT pg_catalog.quote_ident(d.datname) "\
609 " FROM pg_catalog.pg_database d "\
610 " WHERE substring(pg_catalog.quote_ident(d.datname),1,%d)='%s' "\
611 " AND (d.datistemplate OR pg_catalog.pg_has_role(d.datdba, 'USAGE'))"
613 #define Query_for_list_of_databases \
614 "SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\
615 " WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'"
617 #define Query_for_list_of_tablespaces \
618 "SELECT pg_catalog.quote_ident(spcname) FROM pg_catalog.pg_tablespace "\
619 " WHERE substring(pg_catalog.quote_ident(spcname),1,%d)='%s'"
621 #define Query_for_list_of_encodings \
622 " SELECT DISTINCT pg_catalog.pg_encoding_to_char(conforencoding) "\
623 " FROM pg_catalog.pg_conversion "\
624 " WHERE substring(pg_catalog.pg_encoding_to_char(conforencoding),1,%d)=UPPER('%s')"
626 #define Query_for_list_of_languages \
627 "SELECT pg_catalog.quote_ident(lanname) "\
628 " FROM pg_catalog.pg_language "\
629 " WHERE lanname != 'internal' "\
630 " AND substring(pg_catalog.quote_ident(lanname),1,%d)='%s'"
632 #define Query_for_list_of_schemas \
633 "SELECT pg_catalog.quote_ident(nspname) FROM pg_catalog.pg_namespace "\
634 " WHERE substring(pg_catalog.quote_ident(nspname),1,%d)='%s'"
636 #define Query_for_list_of_alter_system_set_vars \
638 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
639 " WHERE context != 'internal' "\
640 " UNION ALL SELECT 'all') ss "\
641 " WHERE substring(name,1,%d)='%s'"
643 #define Query_for_list_of_set_vars \
645 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
646 " WHERE context IN ('user', 'superuser') "\
647 " UNION ALL SELECT 'constraints' "\
648 " UNION ALL SELECT 'transaction' "\
649 " UNION ALL SELECT 'session' "\
650 " UNION ALL SELECT 'role' "\
651 " UNION ALL SELECT 'tablespace' "\
652 " UNION ALL SELECT 'all') ss "\
653 " WHERE substring(name,1,%d)='%s'"
655 #define Query_for_list_of_show_vars \
657 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
658 " UNION ALL SELECT 'session authorization' "\
659 " UNION ALL SELECT 'all') ss "\
660 " WHERE substring(name,1,%d)='%s'"
662 #define Query_for_list_of_roles \
663 " SELECT pg_catalog.quote_ident(rolname) "\
664 " FROM pg_catalog.pg_roles "\
665 " WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"
667 #define Query_for_list_of_grant_roles \
668 " SELECT pg_catalog.quote_ident(rolname) "\
669 " FROM pg_catalog.pg_roles "\
670 " WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\
671 " UNION ALL SELECT 'PUBLIC'"\
672 " UNION ALL SELECT 'CURRENT_USER'"\
673 " UNION ALL SELECT 'SESSION_USER'"
675 /* the silly-looking length condition is just to eat up the current word */
676 #define Query_for_table_owning_index \
677 "SELECT pg_catalog.quote_ident(c1.relname) "\
678 " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
679 " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
680 " and (%d = pg_catalog.length('%s'))"\
681 " and pg_catalog.quote_ident(c2.relname)='%s'"\
682 " and pg_catalog.pg_table_is_visible(c2.oid)"
684 /* the silly-looking length condition is just to eat up the current word */
685 #define Query_for_index_of_table \
686 "SELECT pg_catalog.quote_ident(c2.relname) "\
687 " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
688 " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
689 " and (%d = pg_catalog.length('%s'))"\
690 " and pg_catalog.quote_ident(c1.relname)='%s'"\
691 " and pg_catalog.pg_table_is_visible(c2.oid)"
693 /* the silly-looking length condition is just to eat up the current word */
694 #define Query_for_constraint_of_table \
695 "SELECT pg_catalog.quote_ident(conname) "\
696 " FROM pg_catalog.pg_class c1, pg_catalog.pg_constraint con "\
697 " WHERE c1.oid=conrelid and (%d = pg_catalog.length('%s'))"\
698 " and pg_catalog.quote_ident(c1.relname)='%s'"\
699 " and pg_catalog.pg_table_is_visible(c1.oid)"
701 #define Query_for_all_table_constraints \
702 "SELECT pg_catalog.quote_ident(conname) "\
703 " FROM pg_catalog.pg_constraint c "\
704 " WHERE c.conrelid <> 0 "
706 /* the silly-looking length condition is just to eat up the current word */
707 #define Query_for_constraint_of_type \
708 "SELECT pg_catalog.quote_ident(conname) "\
709 " FROM pg_catalog.pg_type t, pg_catalog.pg_constraint con "\
710 " WHERE t.oid=contypid and (%d = pg_catalog.length('%s'))"\
711 " and pg_catalog.quote_ident(t.typname)='%s'"\
712 " and pg_catalog.pg_type_is_visible(t.oid)"
714 /* the silly-looking length condition is just to eat up the current word */
715 #define Query_for_list_of_tables_for_constraint \
716 "SELECT pg_catalog.quote_ident(relname) "\
717 " FROM pg_catalog.pg_class"\
718 " WHERE (%d = pg_catalog.length('%s'))"\
720 " (SELECT conrelid FROM pg_catalog.pg_constraint "\
721 " WHERE pg_catalog.quote_ident(conname)='%s')"
723 /* the silly-looking length condition is just to eat up the current word */
724 #define Query_for_rule_of_table \
725 "SELECT pg_catalog.quote_ident(rulename) "\
726 " FROM pg_catalog.pg_class c1, pg_catalog.pg_rewrite "\
727 " WHERE c1.oid=ev_class and (%d = pg_catalog.length('%s'))"\
728 " and pg_catalog.quote_ident(c1.relname)='%s'"\
729 " and pg_catalog.pg_table_is_visible(c1.oid)"
731 /* the silly-looking length condition is just to eat up the current word */
732 #define Query_for_list_of_tables_for_rule \
733 "SELECT pg_catalog.quote_ident(relname) "\
734 " FROM pg_catalog.pg_class"\
735 " WHERE (%d = pg_catalog.length('%s'))"\
737 " (SELECT ev_class FROM pg_catalog.pg_rewrite "\
738 " WHERE pg_catalog.quote_ident(rulename)='%s')"
740 /* the silly-looking length condition is just to eat up the current word */
741 #define Query_for_trigger_of_table \
742 "SELECT pg_catalog.quote_ident(tgname) "\
743 " FROM pg_catalog.pg_class c1, pg_catalog.pg_trigger "\
744 " WHERE c1.oid=tgrelid and (%d = pg_catalog.length('%s'))"\
745 " and pg_catalog.quote_ident(c1.relname)='%s'"\
746 " and pg_catalog.pg_table_is_visible(c1.oid)"\
747 " and not tgisinternal"
749 /* the silly-looking length condition is just to eat up the current word */
750 #define Query_for_list_of_tables_for_trigger \
751 "SELECT pg_catalog.quote_ident(relname) "\
752 " FROM pg_catalog.pg_class"\
753 " WHERE (%d = pg_catalog.length('%s'))"\
755 " (SELECT tgrelid FROM pg_catalog.pg_trigger "\
756 " WHERE pg_catalog.quote_ident(tgname)='%s')"
758 #define Query_for_list_of_ts_configurations \
759 "SELECT pg_catalog.quote_ident(cfgname) FROM pg_catalog.pg_ts_config "\
760 " WHERE substring(pg_catalog.quote_ident(cfgname),1,%d)='%s'"
762 #define Query_for_list_of_ts_dictionaries \
763 "SELECT pg_catalog.quote_ident(dictname) FROM pg_catalog.pg_ts_dict "\
764 " WHERE substring(pg_catalog.quote_ident(dictname),1,%d)='%s'"
766 #define Query_for_list_of_ts_parsers \
767 "SELECT pg_catalog.quote_ident(prsname) FROM pg_catalog.pg_ts_parser "\
768 " WHERE substring(pg_catalog.quote_ident(prsname),1,%d)='%s'"
770 #define Query_for_list_of_ts_templates \
771 "SELECT pg_catalog.quote_ident(tmplname) FROM pg_catalog.pg_ts_template "\
772 " WHERE substring(pg_catalog.quote_ident(tmplname),1,%d)='%s'"
774 #define Query_for_list_of_fdws \
775 " SELECT pg_catalog.quote_ident(fdwname) "\
776 " FROM pg_catalog.pg_foreign_data_wrapper "\
777 " WHERE substring(pg_catalog.quote_ident(fdwname),1,%d)='%s'"
779 #define Query_for_list_of_servers \
780 " SELECT pg_catalog.quote_ident(srvname) "\
781 " FROM pg_catalog.pg_foreign_server "\
782 " WHERE substring(pg_catalog.quote_ident(srvname),1,%d)='%s'"
784 #define Query_for_list_of_user_mappings \
785 " SELECT pg_catalog.quote_ident(usename) "\
786 " FROM pg_catalog.pg_user_mappings "\
787 " WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'"
789 #define Query_for_list_of_access_methods \
790 " SELECT pg_catalog.quote_ident(amname) "\
791 " FROM pg_catalog.pg_am "\
792 " WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'"
794 /* the silly-looking length condition is just to eat up the current word */
795 #define Query_for_list_of_arguments \
796 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
797 " FROM pg_catalog.pg_proc "\
798 " WHERE (%d = pg_catalog.length('%s'))"\
799 " AND (pg_catalog.quote_ident(proname)='%s'"\
800 " OR '\"' || proname || '\"'='%s') "\
801 " AND (pg_catalog.pg_function_is_visible(pg_proc.oid))"
803 /* the silly-looking length condition is just to eat up the current word */
804 #define Query_for_list_of_arguments_with_schema \
805 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
806 " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "\
807 " WHERE (%d = pg_catalog.length('%s'))"\
808 " AND n.oid = p.pronamespace "\
809 " AND (pg_catalog.quote_ident(proname)='%s' "\
810 " OR '\"' || proname || '\"' ='%s') "\
811 " AND (pg_catalog.quote_ident(nspname)='%s' "\
812 " OR '\"' || nspname || '\"' ='%s') "
814 #define Query_for_list_of_extensions \
815 " SELECT pg_catalog.quote_ident(extname) "\
816 " FROM pg_catalog.pg_extension "\
817 " WHERE substring(pg_catalog.quote_ident(extname),1,%d)='%s'"
819 #define Query_for_list_of_available_extensions \
820 " SELECT pg_catalog.quote_ident(name) "\
821 " FROM pg_catalog.pg_available_extensions "\
822 " WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s' AND installed_version IS NULL"
824 /* the silly-looking length condition is just to eat up the current word */
825 #define Query_for_list_of_available_extension_versions \
826 " SELECT pg_catalog.quote_ident(version) "\
827 " FROM pg_catalog.pg_available_extension_versions "\
828 " WHERE (%d = pg_catalog.length('%s'))"\
829 " AND pg_catalog.quote_ident(name)='%s'"
831 /* the silly-looking length condition is just to eat up the current word */
832 #define Query_for_list_of_available_extension_versions_with_TO \
833 " SELECT 'TO ' || pg_catalog.quote_ident(version) "\
834 " FROM pg_catalog.pg_available_extension_versions "\
835 " WHERE (%d = pg_catalog.length('%s'))"\
836 " AND pg_catalog.quote_ident(name)='%s'"
838 #define Query_for_list_of_prepared_statements \
839 " SELECT pg_catalog.quote_ident(name) "\
840 " FROM pg_catalog.pg_prepared_statements "\
841 " WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s'"
843 #define Query_for_list_of_event_triggers \
844 " SELECT pg_catalog.quote_ident(evtname) "\
845 " FROM pg_catalog.pg_event_trigger "\
846 " WHERE substring(pg_catalog.quote_ident(evtname),1,%d)='%s'"
848 #define Query_for_list_of_tablesample_methods \
849 " SELECT pg_catalog.quote_ident(proname) "\
850 " FROM pg_catalog.pg_proc "\
851 " WHERE prorettype = 'pg_catalog.tsm_handler'::pg_catalog.regtype AND "\
852 " proargtypes[0] = 'pg_catalog.internal'::pg_catalog.regtype AND "\
853 " substring(pg_catalog.quote_ident(proname),1,%d)='%s'"
855 #define Query_for_list_of_policies \
856 " SELECT pg_catalog.quote_ident(polname) "\
857 " FROM pg_catalog.pg_policy "\
858 " WHERE substring(pg_catalog.quote_ident(polname),1,%d)='%s'"
860 #define Query_for_list_of_tables_for_policy \
861 "SELECT pg_catalog.quote_ident(relname) "\
862 " FROM pg_catalog.pg_class"\
863 " WHERE (%d = pg_catalog.length('%s'))"\
865 " (SELECT polrelid FROM pg_catalog.pg_policy "\
866 " WHERE pg_catalog.quote_ident(polname)='%s')"
868 #define Query_for_enum \
869 " SELECT name FROM ( "\
870 " SELECT pg_catalog.quote_ident(pg_catalog.unnest(enumvals)) AS name "\
871 " FROM pg_catalog.pg_settings "\
872 " WHERE pg_catalog.lower(name)=pg_catalog.lower('%s') "\
874 " SELECT 'DEFAULT' ) ss "\
875 " WHERE pg_catalog.substring(name,1,%%d)='%%s'"
877 /* the silly-looking length condition is just to eat up the current word */
878 #define Query_for_partition_of_table \
879 "SELECT pg_catalog.quote_ident(c2.relname) "\
880 " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_inherits i"\
881 " WHERE c1.oid=i.inhparent and i.inhrelid=c2.oid"\
882 " and (%d = pg_catalog.length('%s'))"\
883 " and pg_catalog.quote_ident(c1.relname)='%s'"\
884 " and pg_catalog.pg_table_is_visible(c2.oid)"\
885 " and c2.relispartition = 'true'"
888 * These object types were introduced later than our support cutoff of
889 * server version 7.4. We use the VersionedQuery infrastructure so that
890 * we don't send certain-to-fail queries to older servers.
893 static const VersionedQuery Query_for_list_of_publications[] = {
895 " SELECT pg_catalog.quote_ident(pubname) "
896 " FROM pg_catalog.pg_publication "
897 " WHERE substring(pg_catalog.quote_ident(pubname),1,%d)='%s'"
902 static const VersionedQuery Query_for_list_of_subscriptions[] = {
904 " SELECT pg_catalog.quote_ident(s.subname) "
905 " FROM pg_catalog.pg_subscription s, pg_catalog.pg_database d "
906 " WHERE substring(pg_catalog.quote_ident(s.subname),1,%d)='%s' "
907 " AND d.datname = pg_catalog.current_database() "
908 " AND s.subdbid = d.oid"
914 * This is a list of all "things" in Pgsql, which can show up after CREATE or
915 * DROP; and there is also a query to get a list of them.
921 const char *query; /* simple query, or NULL */
922 const VersionedQuery *vquery; /* versioned query, or NULL */
923 const SchemaQuery *squery; /* schema query, or NULL */
924 const bits32 flags; /* visibility flags, see below */
927 #define THING_NO_CREATE (1 << 0) /* should not show up after CREATE */
928 #define THING_NO_DROP (1 << 1) /* should not show up after DROP */
929 #define THING_NO_ALTER (1 << 2) /* should not show up after ALTER */
930 #define THING_NO_SHOW (THING_NO_CREATE | THING_NO_DROP | THING_NO_ALTER)
932 static const pgsql_thing_t words_after_create[] = {
933 {"ACCESS METHOD", NULL, NULL, NULL, THING_NO_ALTER},
934 {"AGGREGATE", NULL, NULL, Query_for_list_of_aggregates},
935 {"CAST", NULL, NULL, NULL}, /* Casts have complex structures for names, so
937 {"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'"},
940 * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
941 * to be used only by pg_dump.
943 {"CONFIGURATION", Query_for_list_of_ts_configurations, NULL, NULL, THING_NO_SHOW},
944 {"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"},
945 {"DATABASE", Query_for_list_of_databases},
946 {"DEFAULT PRIVILEGES", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
947 {"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, NULL, THING_NO_SHOW},
948 {"DOMAIN", NULL, NULL, &Query_for_list_of_domains},
949 {"EVENT TRIGGER", NULL, NULL, NULL},
950 {"EXTENSION", Query_for_list_of_extensions},
951 {"FOREIGN DATA WRAPPER", NULL, NULL, NULL},
952 {"FOREIGN TABLE", NULL, NULL, NULL},
953 {"FUNCTION", NULL, NULL, Query_for_list_of_functions},
954 {"GROUP", Query_for_list_of_roles},
955 {"INDEX", NULL, NULL, &Query_for_list_of_indexes},
956 {"LANGUAGE", Query_for_list_of_languages},
957 {"LARGE OBJECT", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
958 {"MATERIALIZED VIEW", NULL, NULL, &Query_for_list_of_matviews},
959 {"OPERATOR", NULL, NULL, NULL}, /* Querying for this is probably not such
961 {"OWNED", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_ALTER}, /* for DROP OWNED BY ... */
962 {"PARSER", Query_for_list_of_ts_parsers, NULL, NULL, THING_NO_SHOW},
963 {"POLICY", NULL, NULL, NULL},
964 {"PROCEDURE", NULL, NULL, Query_for_list_of_procedures},
965 {"PUBLICATION", NULL, Query_for_list_of_publications},
966 {"ROLE", Query_for_list_of_roles},
967 {"ROUTINE", NULL, NULL, &Query_for_list_of_routines, THING_NO_CREATE},
968 {"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
969 {"SCHEMA", Query_for_list_of_schemas},
970 {"SEQUENCE", NULL, NULL, &Query_for_list_of_sequences},
971 {"SERVER", Query_for_list_of_servers},
972 {"STATISTICS", NULL, NULL, &Query_for_list_of_statistics},
973 {"SUBSCRIPTION", NULL, Query_for_list_of_subscriptions},
974 {"SYSTEM", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP},
975 {"TABLE", NULL, NULL, &Query_for_list_of_tables},
976 {"TABLESPACE", Query_for_list_of_tablespaces},
977 {"TEMP", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMP TABLE
979 {"TEMPLATE", Query_for_list_of_ts_templates, NULL, NULL, THING_NO_SHOW},
980 {"TEMPORARY", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE TEMPORARY
982 {"TEXT SEARCH", NULL, NULL, NULL},
983 {"TRANSFORM", NULL, NULL, NULL},
984 {"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"},
985 {"TYPE", NULL, NULL, &Query_for_list_of_datatypes},
986 {"UNIQUE", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNIQUE
988 {"UNLOGGED", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, /* for CREATE UNLOGGED
990 {"USER", Query_for_list_of_roles " UNION SELECT 'MAPPING FOR'"},
991 {"USER MAPPING FOR", NULL, NULL, NULL},
992 {"VIEW", NULL, NULL, &Query_for_list_of_views},
993 {NULL} /* end of list */
997 /* Forward declaration of functions */
998 static char **psql_completion(const char *text, int start, int end);
999 static char *create_command_generator(const char *text, int state);
1000 static char *drop_command_generator(const char *text, int state);
1001 static char *alter_command_generator(const char *text, int state);
1002 static char *complete_from_query(const char *text, int state);
1003 static char *complete_from_versioned_query(const char *text, int state);
1004 static char *complete_from_schema_query(const char *text, int state);
1005 static char *complete_from_versioned_schema_query(const char *text, int state);
1006 static char *_complete_from_query(const char *simple_query,
1007 const SchemaQuery *schema_query,
1008 const char *text, int state);
1009 static char *complete_from_list(const char *text, int state);
1010 static char *complete_from_const(const char *text, int state);
1011 static void append_variable_names(char ***varnames, int *nvars,
1012 int *maxvars, const char *varname,
1013 const char *prefix, const char *suffix);
1014 static char **complete_from_variables(const char *text,
1015 const char *prefix, const char *suffix, bool need_value);
1016 static char *complete_from_files(const char *text, int state);
1018 static char *pg_strdup_keyword_case(const char *s, const char *ref);
1019 static char *escape_string(const char *text);
1020 static PGresult *exec_query(const char *query);
1022 static char **get_previous_words(int point, char **buffer, int *nwords);
1024 static char *get_guctype(const char *varname);
1027 static char *quote_file_name(char *text, int match_type, char *quote_pointer);
1028 static char *dequote_file_name(char *text, char quote_char);
1033 * Initialize the readline library for our purposes.
1036 initialize_readline(void)
1038 rl_readline_name = (char *) pset.progname;
1039 rl_attempted_completion_function = psql_completion;
1041 rl_basic_word_break_characters = WORD_BREAKS;
1043 completion_max_records = 1000;
1046 * There is a variable rl_completion_query_items for this but apparently
1047 * it's not defined everywhere.
1052 * Check if 'word' matches any of the '|'-separated strings in 'pattern',
1053 * using case-insensitive or case-sensitive comparisons.
1055 * If pattern is NULL, it's a wild card that matches any word.
1056 * If pattern begins with '!', the result is negated, ie we check that 'word'
1057 * does *not* match any alternative appearing in the rest of 'pattern'.
1058 * Any alternative can contain '*' which is a wild card, i.e., it can match
1059 * any substring; however, we allow at most one '*' per alternative.
1061 * For readability, callers should use the macros MatchAny and MatchAnyExcept
1062 * to invoke those two special cases for 'pattern'. (But '|' and '*' must
1063 * just be written directly in patterns.)
1065 #define MatchAny NULL
1066 #define MatchAnyExcept(pattern) ("!" pattern)
1069 word_matches(const char *pattern,
1071 bool case_sensitive)
1075 #define cimatch(s1, s2, n) \
1076 (case_sensitive ? strncmp(s1, s2, n) == 0 : pg_strncasecmp(s1, s2, n) == 0)
1078 /* NULL pattern matches anything. */
1079 if (pattern == NULL)
1082 /* Handle negated patterns from the MatchAnyExcept macro. */
1083 if (*pattern == '!')
1084 return !word_matches(pattern + 1, word, case_sensitive);
1086 /* Else consider each alternative in the pattern. */
1087 wordlen = strlen(word);
1090 const char *star = NULL;
1093 /* Find end of current alternative, and locate any wild card. */
1095 while (*c != '\0' && *c != '|')
1101 /* Was there a wild card? */
1104 /* Yes, wildcard match? */
1105 size_t beforelen = star - pattern,
1106 afterlen = c - star - 1;
1108 if (wordlen >= (beforelen + afterlen) &&
1109 cimatch(word, pattern, beforelen) &&
1110 cimatch(word + wordlen - afterlen, star + 1, afterlen))
1115 /* No, plain match? */
1116 if (wordlen == (c - pattern) &&
1117 cimatch(word, pattern, wordlen))
1120 /* Out of alternatives? */
1123 /* Nope, try next alternative. */
1131 * Implementation of TailMatches and TailMatchesCS macros: do the last N words
1132 * in previous_words match the variadic arguments?
1134 * The array indexing might look backwards, but remember that
1135 * previous_words[0] contains the *last* word on the line, not the first.
1138 TailMatchesImpl(bool case_sensitive,
1139 int previous_words_count, char **previous_words,
1144 if (previous_words_count < narg)
1147 va_start(args, narg);
1149 for (int argno = 0; argno < narg; argno++)
1151 const char *arg = va_arg(args, const char *);
1153 if (!word_matches(arg, previous_words[narg - argno - 1],
1167 * Implementation of Matches and MatchesCS macros: do all of the words
1168 * in previous_words match the variadic arguments?
1171 MatchesImpl(bool case_sensitive,
1172 int previous_words_count, char **previous_words,
1177 if (previous_words_count != narg)
1180 va_start(args, narg);
1182 for (int argno = 0; argno < narg; argno++)
1184 const char *arg = va_arg(args, const char *);
1186 if (!word_matches(arg, previous_words[narg - argno - 1],
1200 * Implementation of HeadMatches and HeadMatchesCS macros: do the first N
1201 * words in previous_words match the variadic arguments?
1204 HeadMatchesImpl(bool case_sensitive,
1205 int previous_words_count, char **previous_words,
1210 if (previous_words_count < narg)
1213 va_start(args, narg);
1215 for (int argno = 0; argno < narg; argno++)
1217 const char *arg = va_arg(args, const char *);
1219 if (!word_matches(arg, previous_words[previous_words_count - argno - 1],
1233 * Check if the final character of 's' is 'c'.
1236 ends_with(const char *s, char c)
1238 size_t length = strlen(s);
1240 return (length > 0 && s[length - 1] == c);
1244 * The completion function.
1246 * According to readline spec this gets passed the text entered so far and its
1247 * start and end positions in the readline buffer. The return value is some
1248 * partially obscure list format that can be generated by readline's
1249 * completion_matches() function, so we don't have to worry about it.
1252 psql_completion(const char *text, int start, int end)
1254 /* This is the variable we'll return. */
1255 char **matches = NULL;
1257 /* Workspace for parsed words. */
1260 /* This array will contain pointers to parsed words. */
1261 char **previous_words;
1263 /* The number of words found on the input line. */
1264 int previous_words_count;
1267 * For compactness, we use these macros to reference previous_words[].
1268 * Caution: do not access a previous_words[] entry without having checked
1269 * previous_words_count to be sure it's valid. In most cases below, that
1270 * check is implicit in a TailMatches() or similar macro, but in some
1271 * places we have to check it explicitly.
1273 #define prev_wd (previous_words[0])
1274 #define prev2_wd (previous_words[1])
1275 #define prev3_wd (previous_words[2])
1276 #define prev4_wd (previous_words[3])
1277 #define prev5_wd (previous_words[4])
1278 #define prev6_wd (previous_words[5])
1279 #define prev7_wd (previous_words[6])
1280 #define prev8_wd (previous_words[7])
1281 #define prev9_wd (previous_words[8])
1283 /* Match the last N words before point, case-insensitively. */
1284 #define TailMatches(...) \
1285 TailMatchesImpl(false, previous_words_count, previous_words, \
1286 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1288 /* Match the last N words before point, case-sensitively. */
1289 #define TailMatchesCS(...) \
1290 TailMatchesImpl(true, previous_words_count, previous_words, \
1291 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1293 /* Match N words representing all of the line, case-insensitively. */
1294 #define Matches(...) \
1295 MatchesImpl(false, previous_words_count, previous_words, \
1296 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1298 /* Match N words representing all of the line, case-sensitively. */
1299 #define MatchesCS(...) \
1300 MatchesImpl(true, previous_words_count, previous_words, \
1301 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1303 /* Match the first N words on the line, case-insensitively. */
1304 #define HeadMatches(...) \
1305 HeadMatchesImpl(false, previous_words_count, previous_words, \
1306 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1308 /* Match the first N words on the line, case-sensitively. */
1309 #define HeadMatchesCS(...) \
1310 HeadMatchesImpl(true, previous_words_count, previous_words, \
1311 VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
1313 /* Known command-starting keywords. */
1314 static const char *const sql_commands[] = {
1315 "ABORT", "ALTER", "ANALYZE", "BEGIN", "CALL", "CHECKPOINT", "CLOSE", "CLUSTER",
1316 "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
1317 "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
1318 "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK",
1319 "MOVE", "NOTIFY", "PREPARE",
1320 "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
1321 "RESET", "REVOKE", "ROLLBACK",
1322 "SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
1323 "TABLE", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", "VALUES", "WITH",
1327 /* psql's backslash commands. */
1328 static const char *const backslash_commands[] = {
1330 "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
1331 "\\copyright", "\\crosstabview",
1332 "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
1333 "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
1334 "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
1335 "\\dm", "\\dn", "\\do", "\\dO", "\\dp",
1336 "\\drds", "\\dRs", "\\dRp", "\\ds", "\\dS",
1337 "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
1338 "\\e", "\\echo", "\\ef", "\\elif", "\\else", "\\encoding",
1339 "\\endif", "\\errverbose", "\\ev",
1341 "\\g", "\\gdesc", "\\gexec", "\\gset", "\\gx",
1342 "\\h", "\\help", "\\H",
1343 "\\i", "\\if", "\\ir",
1344 "\\l", "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
1346 "\\p", "\\password", "\\prompt", "\\pset",
1349 "\\s", "\\set", "\\setenv", "\\sf", "\\sv",
1350 "\\t", "\\T", "\\timing",
1359 (void) end; /* "end" is not used */
1361 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1362 rl_completion_append_character = ' ';
1365 /* Clear a few things. */
1366 completion_charp = NULL;
1367 completion_charpp = NULL;
1368 completion_info_charp = NULL;
1369 completion_info_charp2 = NULL;
1372 * Scan the input line to extract the words before our current position.
1373 * According to those we'll make some smart decisions on what the user is
1374 * probably intending to type.
1376 previous_words = get_previous_words(start,
1378 &previous_words_count);
1380 /* If current word is a backslash command, offer completions for that */
1381 if (text[0] == '\\')
1382 COMPLETE_WITH_LIST_CS(backslash_commands);
1384 /* If current word is a variable interpolation, handle that case */
1385 else if (text[0] == ':' && text[1] != ':')
1387 if (text[1] == '\'')
1388 matches = complete_from_variables(text, ":'", "'", true);
1389 else if (text[1] == '"')
1390 matches = complete_from_variables(text, ":\"", "\"", true);
1392 matches = complete_from_variables(text, ":", "", true);
1395 /* If no previous word, suggest one of the basic sql commands */
1396 else if (previous_words_count == 0)
1397 COMPLETE_WITH_LIST(sql_commands);
1400 /* complete with something you can create */
1401 else if (TailMatches("CREATE"))
1402 matches = completion_matches(text, create_command_generator);
1404 /* DROP, but not DROP embedded in other commands */
1405 /* complete with something you can drop */
1406 else if (Matches("DROP"))
1407 matches = completion_matches(text, drop_command_generator);
1412 else if (Matches("ALTER", "TABLE"))
1413 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
1414 "UNION SELECT 'ALL IN TABLESPACE'");
1416 /* ALTER something */
1417 else if (Matches("ALTER"))
1418 matches = completion_matches(text, alter_command_generator);
1419 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */
1420 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny))
1421 COMPLETE_WITH("SET TABLESPACE", "OWNED BY");
1422 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */
1423 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"))
1424 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1425 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */
1426 else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny))
1427 COMPLETE_WITH("SET TABLESPACE");
1428 /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> */
1429 else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
1431 /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE <name> (...) */
1432 else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny))
1434 if (ends_with(prev_wd, ')'))
1435 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1437 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
1439 /* ALTER PUBLICATION <name> */
1440 else if (Matches("ALTER", "PUBLICATION", MatchAny))
1441 COMPLETE_WITH("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET");
1442 /* ALTER PUBLICATION <name> SET */
1443 else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET"))
1444 COMPLETE_WITH("(", "TABLE");
1445 /* ALTER PUBLICATION <name> SET ( */
1446 else if (HeadMatches("ALTER", "PUBLICATION", MatchAny) && TailMatches("SET", "("))
1447 COMPLETE_WITH("publish");
1448 /* ALTER SUBSCRIPTION <name> */
1449 else if (Matches("ALTER", "SUBSCRIPTION", MatchAny))
1450 COMPLETE_WITH("CONNECTION", "ENABLE", "DISABLE", "OWNER TO",
1451 "RENAME TO", "REFRESH PUBLICATION", "SET");
1452 /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION */
1453 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1454 TailMatches("REFRESH", "PUBLICATION"))
1455 COMPLETE_WITH("WITH (");
1456 /* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION WITH ( */
1457 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1458 TailMatches("REFRESH", "PUBLICATION", "WITH", "("))
1459 COMPLETE_WITH("copy_data");
1460 /* ALTER SUBSCRIPTION <name> SET */
1461 else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, "SET"))
1462 COMPLETE_WITH("(", "PUBLICATION");
1463 /* ALTER SUBSCRIPTION <name> SET ( */
1464 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "("))
1465 COMPLETE_WITH("slot_name", "synchronous_commit");
1466 /* ALTER SUBSCRIPTION <name> SET PUBLICATION */
1467 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "PUBLICATION"))
1469 /* complete with nothing here as this refers to remote publications */
1471 /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> */
1472 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1473 TailMatches("SET", "PUBLICATION", MatchAny))
1474 COMPLETE_WITH("WITH (");
1475 /* ALTER SUBSCRIPTION <name> SET PUBLICATION <name> WITH ( */
1476 else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) &&
1477 TailMatches("SET", "PUBLICATION", MatchAny, "WITH", "("))
1478 COMPLETE_WITH("copy_data", "refresh");
1479 /* ALTER SCHEMA <name> */
1480 else if (Matches("ALTER", "SCHEMA", MatchAny))
1481 COMPLETE_WITH("OWNER TO", "RENAME TO");
1483 /* ALTER COLLATION <name> */
1484 else if (Matches("ALTER", "COLLATION", MatchAny))
1485 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1487 /* ALTER CONVERSION <name> */
1488 else if (Matches("ALTER", "CONVERSION", MatchAny))
1489 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1491 /* ALTER DATABASE <name> */
1492 else if (Matches("ALTER", "DATABASE", MatchAny))
1493 COMPLETE_WITH("RESET", "SET", "OWNER TO", "RENAME TO",
1494 "IS_TEMPLATE", "ALLOW_CONNECTIONS",
1495 "CONNECTION LIMIT");
1497 /* ALTER DATABASE <name> SET TABLESPACE */
1498 else if (Matches("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE"))
1499 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1501 /* ALTER EVENT TRIGGER */
1502 else if (Matches("ALTER", "EVENT", "TRIGGER"))
1503 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
1505 /* ALTER EVENT TRIGGER <name> */
1506 else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny))
1507 COMPLETE_WITH("DISABLE", "ENABLE", "OWNER TO", "RENAME TO");
1509 /* ALTER EVENT TRIGGER <name> ENABLE */
1510 else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"))
1511 COMPLETE_WITH("REPLICA", "ALWAYS");
1513 /* ALTER EXTENSION <name> */
1514 else if (Matches("ALTER", "EXTENSION", MatchAny))
1515 COMPLETE_WITH("ADD", "DROP", "UPDATE", "SET SCHEMA");
1517 /* ALTER EXTENSION <name> UPDATE */
1518 else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE"))
1520 completion_info_charp = prev2_wd;
1521 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO);
1524 /* ALTER EXTENSION <name> UPDATE TO */
1525 else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"))
1527 completion_info_charp = prev3_wd;
1528 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
1532 else if (Matches("ALTER", "FOREIGN"))
1533 COMPLETE_WITH("DATA WRAPPER", "TABLE");
1535 /* ALTER FOREIGN DATA WRAPPER <name> */
1536 else if (Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
1537 COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO");
1539 /* ALTER FOREIGN TABLE <name> */
1540 else if (Matches("ALTER", "FOREIGN", "TABLE", MatchAny))
1541 COMPLETE_WITH("ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE",
1542 "INHERIT", "NO INHERIT", "OPTIONS", "OWNER TO",
1543 "RENAME", "SET", "VALIDATE CONSTRAINT");
1546 else if (Matches("ALTER", "INDEX"))
1547 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
1548 "UNION SELECT 'ALL IN TABLESPACE'");
1549 /* ALTER INDEX <name> */
1550 else if (Matches("ALTER", "INDEX", MatchAny))
1551 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET",
1552 "RESET", "ATTACH PARTITION");
1553 else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH"))
1554 COMPLETE_WITH("PARTITION");
1555 else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION"))
1556 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
1557 /* ALTER INDEX <name> ALTER COLUMN <colnum> */
1558 else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny))
1559 COMPLETE_WITH("SET STATISTICS");
1560 /* ALTER INDEX <name> SET */
1561 else if (Matches("ALTER", "INDEX", MatchAny, "SET"))
1562 COMPLETE_WITH("(", "TABLESPACE");
1563 /* ALTER INDEX <name> RESET */
1564 else if (Matches("ALTER", "INDEX", MatchAny, "RESET"))
1566 /* ALTER INDEX <foo> SET|RESET ( */
1567 else if (Matches("ALTER", "INDEX", MatchAny, "RESET", "("))
1568 COMPLETE_WITH("fillfactor", "recheck_on_update",
1569 "vacuum_cleanup_index_scale_factor", /* BTREE */
1570 "fastupdate", "gin_pending_list_limit", /* GIN */
1571 "buffering", /* GiST */
1572 "pages_per_range", "autosummarize" /* BRIN */
1574 else if (Matches("ALTER", "INDEX", MatchAny, "SET", "("))
1575 COMPLETE_WITH("fillfactor =", "recheck_on_update =",
1576 "vacuum_cleanup_index_scale_factor =", /* BTREE */
1577 "fastupdate =", "gin_pending_list_limit =", /* GIN */
1578 "buffering =", /* GiST */
1579 "pages_per_range =", "autosummarize =" /* BRIN */
1582 /* ALTER LANGUAGE <name> */
1583 else if (Matches("ALTER", "LANGUAGE", MatchAny))
1584 COMPLETE_WITH("OWNER_TO", "RENAME TO");
1586 /* ALTER LARGE OBJECT <oid> */
1587 else if (Matches("ALTER", "LARGE", "OBJECT", MatchAny))
1588 COMPLETE_WITH("OWNER TO");
1590 /* ALTER MATERIALIZED VIEW */
1591 else if (Matches("ALTER", "MATERIALIZED", "VIEW"))
1592 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
1593 "UNION SELECT 'ALL IN TABLESPACE'");
1595 /* ALTER USER,ROLE <name> */
1596 else if (Matches("ALTER", "USER|ROLE", MatchAny) &&
1597 !TailMatches("USER", "MAPPING"))
1598 COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1599 "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1600 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1601 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
1602 "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
1603 "VALID UNTIL", "WITH");
1605 /* ALTER USER,ROLE <name> WITH */
1606 else if (Matches("ALTER", "USER|ROLE", MatchAny, "WITH"))
1607 /* Similar to the above, but don't complete "WITH" again. */
1608 COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1609 "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
1610 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1611 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
1612 "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER",
1615 /* ALTER DEFAULT PRIVILEGES */
1616 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES"))
1617 COMPLETE_WITH("FOR ROLE", "IN SCHEMA");
1618 /* ALTER DEFAULT PRIVILEGES FOR */
1619 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
1620 COMPLETE_WITH("ROLE");
1621 /* ALTER DEFAULT PRIVILEGES IN */
1622 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
1623 COMPLETE_WITH("SCHEMA");
1624 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
1625 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1627 COMPLETE_WITH("GRANT", "REVOKE", "IN SCHEMA");
1628 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
1629 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1631 COMPLETE_WITH("GRANT", "REVOKE", "FOR ROLE");
1632 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
1633 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1635 COMPLETE_WITH("ROLE");
1636 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
1637 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
1638 else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1639 MatchAny, "IN", "SCHEMA", MatchAny) ||
1640 Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1641 MatchAny, "FOR", "ROLE|USER", MatchAny))
1642 COMPLETE_WITH("GRANT", "REVOKE");
1643 /* ALTER DOMAIN <name> */
1644 else if (Matches("ALTER", "DOMAIN", MatchAny))
1645 COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME", "SET",
1646 "VALIDATE CONSTRAINT");
1647 /* ALTER DOMAIN <sth> DROP */
1648 else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP"))
1649 COMPLETE_WITH("CONSTRAINT", "DEFAULT", "NOT NULL");
1650 /* ALTER DOMAIN <sth> DROP|RENAME|VALIDATE CONSTRAINT */
1651 else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
1653 completion_info_charp = prev3_wd;
1654 COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
1656 /* ALTER DOMAIN <sth> RENAME */
1657 else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME"))
1658 COMPLETE_WITH("CONSTRAINT", "TO");
1659 /* ALTER DOMAIN <sth> RENAME CONSTRAINT <sth> */
1660 else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny))
1661 COMPLETE_WITH("TO");
1663 /* ALTER DOMAIN <sth> SET */
1664 else if (Matches("ALTER", "DOMAIN", MatchAny, "SET"))
1665 COMPLETE_WITH("DEFAULT", "NOT NULL", "SCHEMA");
1666 /* ALTER SEQUENCE <name> */
1667 else if (Matches("ALTER", "SEQUENCE", MatchAny))
1668 COMPLETE_WITH("INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO",
1669 "CACHE", "CYCLE", "SET SCHEMA", "OWNED BY", "OWNER TO",
1671 /* ALTER SEQUENCE <name> NO */
1672 else if (Matches("ALTER", "SEQUENCE", MatchAny, "NO"))
1673 COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
1674 /* ALTER SERVER <name> */
1675 else if (Matches("ALTER", "SERVER", MatchAny))
1676 COMPLETE_WITH("VERSION", "OPTIONS", "OWNER TO", "RENAME TO");
1677 /* ALTER SERVER <name> VERSION <version> */
1678 else if (Matches("ALTER", "SERVER", MatchAny, "VERSION", MatchAny))
1679 COMPLETE_WITH("OPTIONS");
1680 /* ALTER SYSTEM SET, RESET, RESET ALL */
1681 else if (Matches("ALTER", "SYSTEM"))
1682 COMPLETE_WITH("SET", "RESET");
1683 else if (Matches("ALTER", "SYSTEM", "SET|RESET"))
1684 COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars);
1685 else if (Matches("ALTER", "SYSTEM", "SET", MatchAny))
1686 COMPLETE_WITH("TO");
1687 /* ALTER VIEW <name> */
1688 else if (Matches("ALTER", "VIEW", MatchAny))
1689 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO",
1691 /* ALTER MATERIALIZED VIEW <name> */
1692 else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny))
1693 COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO",
1696 /* ALTER POLICY <name> */
1697 else if (Matches("ALTER", "POLICY"))
1698 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
1699 /* ALTER POLICY <name> ON */
1700 else if (Matches("ALTER", "POLICY", MatchAny))
1701 COMPLETE_WITH("ON");
1702 /* ALTER POLICY <name> ON <table> */
1703 else if (Matches("ALTER", "POLICY", MatchAny, "ON"))
1705 completion_info_charp = prev2_wd;
1706 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
1708 /* ALTER POLICY <name> ON <table> - show options */
1709 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny))
1710 COMPLETE_WITH("RENAME TO", "TO", "USING (", "WITH CHECK (");
1711 /* ALTER POLICY <name> ON <table> TO <role> */
1712 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
1713 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
1714 /* ALTER POLICY <name> ON <table> USING ( */
1715 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
1717 /* ALTER POLICY <name> ON <table> WITH CHECK ( */
1718 else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
1721 /* ALTER RULE <name>, add ON */
1722 else if (Matches("ALTER", "RULE", MatchAny))
1723 COMPLETE_WITH("ON");
1725 /* If we have ALTER RULE <name> ON, then add the correct tablename */
1726 else if (Matches("ALTER", "RULE", MatchAny, "ON"))
1728 completion_info_charp = prev2_wd;
1729 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1732 /* ALTER RULE <name> ON <name> */
1733 else if (Matches("ALTER", "RULE", MatchAny, "ON", MatchAny))
1734 COMPLETE_WITH("RENAME TO");
1736 /* ALTER STATISTICS <name> */
1737 else if (Matches("ALTER", "STATISTICS", MatchAny))
1738 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1740 /* ALTER TRIGGER <name>, add ON */
1741 else if (Matches("ALTER", "TRIGGER", MatchAny))
1742 COMPLETE_WITH("ON");
1744 else if (Matches("ALTER", "TRIGGER", MatchAny, MatchAny))
1746 completion_info_charp = prev2_wd;
1747 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
1751 * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
1753 else if (Matches("ALTER", "TRIGGER", MatchAny, "ON"))
1754 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
1756 /* ALTER TRIGGER <name> ON <name> */
1757 else if (Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
1758 COMPLETE_WITH("RENAME TO");
1761 * If we detect ALTER TABLE <name>, suggest sub commands
1763 else if (Matches("ALTER", "TABLE", MatchAny))
1764 COMPLETE_WITH("ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP",
1765 "ENABLE", "INHERIT", "NO INHERIT", "RENAME", "RESET",
1766 "OWNER TO", "SET", "VALIDATE CONSTRAINT",
1767 "REPLICA IDENTITY", "ATTACH PARTITION",
1768 "DETACH PARTITION");
1769 /* ALTER TABLE xxx ENABLE */
1770 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE"))
1771 COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
1773 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
1774 COMPLETE_WITH("RULE", "TRIGGER");
1775 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
1777 completion_info_charp = prev3_wd;
1778 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1780 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
1782 completion_info_charp = prev4_wd;
1783 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1785 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
1787 completion_info_charp = prev3_wd;
1788 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1790 else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
1792 completion_info_charp = prev4_wd;
1793 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1795 /* ALTER TABLE xxx INHERIT */
1796 else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT"))
1797 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1798 /* ALTER TABLE xxx NO INHERIT */
1799 else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
1800 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1801 /* ALTER TABLE xxx DISABLE */
1802 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE"))
1803 COMPLETE_WITH("ROW LEVEL SECURITY", "RULE", "TRIGGER");
1804 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
1806 completion_info_charp = prev3_wd;
1807 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1809 else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
1811 completion_info_charp = prev3_wd;
1812 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1815 /* ALTER TABLE xxx ALTER */
1816 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER"))
1817 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'");
1819 /* ALTER TABLE xxx RENAME */
1820 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME"))
1821 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'");
1822 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
1823 COMPLETE_WITH_ATTR(prev3_wd, "");
1825 /* ALTER TABLE xxx RENAME yyy */
1826 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
1827 COMPLETE_WITH("TO");
1829 /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
1830 else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
1831 COMPLETE_WITH("TO");
1833 /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
1834 else if (Matches("ALTER", "TABLE", MatchAny, "DROP"))
1835 COMPLETE_WITH("COLUMN", "CONSTRAINT");
1836 /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
1837 else if (Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
1838 COMPLETE_WITH_ATTR(prev3_wd, "");
1841 * If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
1842 * provide list of constraints
1844 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
1846 completion_info_charp = prev3_wd;
1847 COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
1849 /* ALTER TABLE ALTER [COLUMN] <foo> */
1850 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
1851 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
1852 COMPLETE_WITH("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP");
1853 /* ALTER TABLE ALTER [COLUMN] <foo> SET */
1854 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
1855 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
1856 COMPLETE_WITH("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE");
1857 /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
1858 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
1859 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
1860 COMPLETE_WITH("n_distinct", "n_distinct_inherited");
1861 /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
1862 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
1863 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
1864 COMPLETE_WITH("PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
1865 /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
1866 else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
1867 Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
1868 COMPLETE_WITH("DEFAULT", "IDENTITY", "NOT NULL");
1869 else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER"))
1870 COMPLETE_WITH("ON");
1871 else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
1873 completion_info_charp = prev3_wd;
1874 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1876 /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
1877 else if (Matches("ALTER", "TABLE", MatchAny, "SET"))
1878 COMPLETE_WITH("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED",
1882 * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
1885 else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
1886 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1887 /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
1888 else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
1889 COMPLETE_WITH("CLUSTER", "OIDS");
1890 /* ALTER TABLE <foo> RESET */
1891 else if (Matches("ALTER", "TABLE", MatchAny, "RESET"))
1893 /* ALTER TABLE <foo> SET|RESET ( */
1894 else if (Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
1896 static const char *const list_TABLEOPTIONS[] =
1898 "autovacuum_analyze_scale_factor",
1899 "autovacuum_analyze_threshold",
1900 "autovacuum_enabled",
1901 "autovacuum_freeze_max_age",
1902 "autovacuum_freeze_min_age",
1903 "autovacuum_freeze_table_age",
1904 "autovacuum_multixact_freeze_max_age",
1905 "autovacuum_multixact_freeze_min_age",
1906 "autovacuum_multixact_freeze_table_age",
1907 "autovacuum_vacuum_cost_delay",
1908 "autovacuum_vacuum_cost_limit",
1909 "autovacuum_vacuum_scale_factor",
1910 "autovacuum_vacuum_threshold",
1913 "log_autovacuum_min_duration",
1914 "toast_tuple_target",
1915 "toast.autovacuum_enabled",
1916 "toast.autovacuum_freeze_max_age",
1917 "toast.autovacuum_freeze_min_age",
1918 "toast.autovacuum_freeze_table_age",
1919 "toast.autovacuum_multixact_freeze_max_age",
1920 "toast.autovacuum_multixact_freeze_min_age",
1921 "toast.autovacuum_multixact_freeze_table_age",
1922 "toast.autovacuum_vacuum_cost_delay",
1923 "toast.autovacuum_vacuum_cost_limit",
1924 "toast.autovacuum_vacuum_scale_factor",
1925 "toast.autovacuum_vacuum_threshold",
1926 "toast.log_autovacuum_min_duration",
1927 "user_catalog_table",
1931 COMPLETE_WITH_LIST(list_TABLEOPTIONS);
1933 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
1935 completion_info_charp = prev5_wd;
1936 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1938 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
1939 COMPLETE_WITH("INDEX");
1940 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
1941 COMPLETE_WITH("FULL", "NOTHING", "DEFAULT", "USING");
1942 else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA"))
1943 COMPLETE_WITH("IDENTITY");
1946 * If we have ALTER TABLE <foo> ATTACH PARTITION, provide a list of
1949 else if (Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION"))
1950 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1951 /* Limited completion support for partition bound specification */
1952 else if (TailMatches("ATTACH", "PARTITION", MatchAny))
1953 COMPLETE_WITH("FOR VALUES", "DEFAULT");
1954 else if (TailMatches("FOR", "VALUES"))
1955 COMPLETE_WITH("FROM (", "IN (", "WITH (");
1958 * If we have ALTER TABLE <foo> DETACH PARTITION, provide a list of
1959 * partitions of <foo>.
1961 else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION"))
1963 completion_info_charp = prev3_wd;
1964 COMPLETE_WITH_QUERY(Query_for_partition_of_table);
1967 /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
1968 else if (Matches("ALTER", "TABLESPACE", MatchAny))
1969 COMPLETE_WITH("RENAME TO", "OWNER TO", "SET", "RESET");
1970 /* ALTER TABLESPACE <foo> SET|RESET */
1971 else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
1973 /* ALTER TABLESPACE <foo> SET|RESET ( */
1974 else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
1975 COMPLETE_WITH("seq_page_cost", "random_page_cost",
1976 "effective_io_concurrency");
1978 /* ALTER TEXT SEARCH */
1979 else if (Matches("ALTER", "TEXT", "SEARCH"))
1980 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
1981 else if (Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
1982 COMPLETE_WITH("RENAME TO", "SET SCHEMA");
1983 else if (Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
1984 COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
1985 else if (Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
1986 COMPLETE_WITH("ADD MAPPING FOR", "ALTER MAPPING",
1988 "OWNER TO", "RENAME TO", "SET SCHEMA");
1990 /* complete ALTER TYPE <foo> with actions */
1991 else if (Matches("ALTER", "TYPE", MatchAny))
1992 COMPLETE_WITH("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
1994 "OWNER TO", "RENAME", "SET SCHEMA");
1995 /* complete ALTER TYPE <foo> ADD with actions */
1996 else if (Matches("ALTER", "TYPE", MatchAny, "ADD"))
1997 COMPLETE_WITH("ATTRIBUTE", "VALUE");
1998 /* ALTER TYPE <foo> RENAME */
1999 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME"))
2000 COMPLETE_WITH("ATTRIBUTE", "TO", "VALUE");
2001 /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
2002 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
2003 COMPLETE_WITH("TO");
2006 * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
2009 else if (Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
2010 COMPLETE_WITH_ATTR(prev3_wd, "");
2011 /* ALTER TYPE ALTER ATTRIBUTE <foo> */
2012 else if (Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
2013 COMPLETE_WITH("TYPE");
2014 /* complete ALTER GROUP <foo> */
2015 else if (Matches("ALTER", "GROUP", MatchAny))
2016 COMPLETE_WITH("ADD USER", "DROP USER", "RENAME TO");
2017 /* complete ALTER GROUP <foo> ADD|DROP with USER */
2018 else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP"))
2019 COMPLETE_WITH("USER");
2020 /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
2021 else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
2022 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2025 * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
2027 else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
2028 COMPLETE_WITH_ENUM_VALUE(prev3_wd);
2031 * ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
2032 * ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]
2034 * Currently the only allowed option is VERBOSE, so we can be skimpier on
2035 * the option processing than VACUUM has to be.
2037 else if (Matches("ANALYZE"))
2038 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables,
2039 " UNION SELECT 'VERBOSE'");
2040 else if (Matches("ANALYZE", "("))
2041 COMPLETE_WITH("VERBOSE)");
2042 else if (HeadMatches("ANALYZE") && TailMatches("("))
2043 /* "ANALYZE (" should be caught above, so assume we want columns */
2044 COMPLETE_WITH_ATTR(prev2_wd, "");
2045 else if (HeadMatches("ANALYZE"))
2046 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables, NULL);
2049 else if (Matches("BEGIN"))
2050 COMPLETE_WITH("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2052 else if (Matches("END|ABORT"))
2053 COMPLETE_WITH("WORK", "TRANSACTION");
2055 else if (Matches("COMMIT"))
2056 COMPLETE_WITH("WORK", "TRANSACTION", "PREPARED");
2057 /* RELEASE SAVEPOINT */
2058 else if (Matches("RELEASE"))
2059 COMPLETE_WITH("SAVEPOINT");
2061 else if (Matches("ROLLBACK"))
2062 COMPLETE_WITH("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
2064 else if (Matches("CALL"))
2065 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
2066 else if (Matches("CALL", MatchAny))
2069 else if (Matches("CLUSTER"))
2070 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'");
2071 else if (Matches("CLUSTER", "VERBOSE"))
2072 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL);
2073 /* If we have CLUSTER <sth>, then add "USING" */
2074 else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON")))
2075 COMPLETE_WITH("USING");
2076 /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
2077 else if (Matches("CLUSTER", "VERBOSE", MatchAny))
2078 COMPLETE_WITH("USING");
2079 /* If we have CLUSTER <sth> USING, then add the index as well */
2080 else if (Matches("CLUSTER", MatchAny, "USING") ||
2081 Matches("CLUSTER", "VERBOSE", MatchAny, "USING"))
2083 completion_info_charp = prev2_wd;
2084 COMPLETE_WITH_QUERY(Query_for_index_of_table);
2088 else if (Matches("COMMENT"))
2089 COMPLETE_WITH("ON");
2090 else if (Matches("COMMENT", "ON"))
2091 COMPLETE_WITH("ACCESS METHOD", "CAST", "COLLATION", "CONVERSION",
2092 "DATABASE", "EVENT TRIGGER", "EXTENSION",
2093 "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "SERVER",
2094 "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE",
2095 "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION",
2096 "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW",
2097 "COLUMN", "AGGREGATE", "FUNCTION",
2098 "PROCEDURE", "ROUTINE",
2099 "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN",
2100 "LARGE OBJECT", "TABLESPACE", "TEXT SEARCH", "ROLE");
2101 else if (Matches("COMMENT", "ON", "ACCESS", "METHOD"))
2102 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2103 else if (Matches("COMMENT", "ON", "FOREIGN"))
2104 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2105 else if (Matches("COMMENT", "ON", "TEXT", "SEARCH"))
2106 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2107 else if (Matches("COMMENT", "ON", "CONSTRAINT"))
2108 COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2109 else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny))
2110 COMPLETE_WITH("ON");
2111 else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2113 completion_info_charp = prev2_wd;
2114 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint);
2116 else if (Matches("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2117 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2118 else if (Matches("COMMENT", "ON", "EVENT", "TRIGGER"))
2119 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2120 else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2121 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2122 Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2123 COMPLETE_WITH("IS");
2128 * If we have COPY, offer list of tables or "(" (Also cover the analogous
2129 * backslash command).
2131 else if (Matches("COPY|\\copy"))
2132 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2133 " UNION ALL SELECT '('");
2134 /* If we have COPY BINARY, complete with list of tables */
2135 else if (Matches("COPY", "BINARY"))
2136 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2137 /* If we have COPY (, complete it with legal commands */
2138 else if (Matches("COPY|\\copy", "("))
2139 COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH");
2140 /* If we have COPY [BINARY] <sth>, complete it with "TO" or "FROM" */
2141 else if (Matches("COPY|\\copy", MatchAny) ||
2142 Matches("COPY", "BINARY", MatchAny))
2143 COMPLETE_WITH("FROM", "TO");
2144 /* If we have COPY [BINARY] <sth> FROM|TO, complete with filename */
2145 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO") ||
2146 Matches("COPY", "BINARY", MatchAny, "FROM|TO"))
2148 completion_charp = "";
2149 matches = completion_matches(text, complete_from_files);
2152 /* Handle COPY [BINARY] <sth> FROM|TO filename */
2153 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
2154 Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
2155 COMPLETE_WITH("BINARY", "DELIMITER", "NULL", "CSV",
2158 /* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
2159 else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") ||
2160 Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV"))
2161 COMPLETE_WITH("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE",
2164 /* CREATE ACCESS METHOD */
2165 /* Complete "CREATE ACCESS METHOD <name>" */
2166 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny))
2167 COMPLETE_WITH("TYPE");
2168 /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2169 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2170 COMPLETE_WITH("INDEX");
2171 /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2172 else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2173 COMPLETE_WITH("HANDLER");
2175 /* CREATE DATABASE */
2176 else if (Matches("CREATE", "DATABASE", MatchAny))
2177 COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2179 "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2180 "LC_COLLATE", "LC_CTYPE");
2182 else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2183 COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2185 /* CREATE EXTENSION */
2186 /* Complete with available extensions rather than installed ones. */
2187 else if (Matches("CREATE", "EXTENSION"))
2188 COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2189 /* CREATE EXTENSION <name> */
2190 else if (Matches("CREATE", "EXTENSION", MatchAny))
2191 COMPLETE_WITH("WITH SCHEMA", "CASCADE", "VERSION");
2192 /* CREATE EXTENSION <name> VERSION */
2193 else if (Matches("CREATE", "EXTENSION", MatchAny, "VERSION"))
2195 completion_info_charp = prev2_wd;
2196 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2199 /* CREATE FOREIGN */
2200 else if (Matches("CREATE", "FOREIGN"))
2201 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2203 /* CREATE FOREIGN DATA WRAPPER */
2204 else if (Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2205 COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS");
2207 /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2208 /* First off we complete CREATE UNIQUE with "INDEX" */
2209 else if (TailMatches("CREATE", "UNIQUE"))
2210 COMPLETE_WITH("INDEX");
2213 * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
2216 else if (TailMatches("CREATE|UNIQUE", "INDEX"))
2217 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2218 " UNION SELECT 'ON'"
2219 " UNION SELECT 'CONCURRENTLY'");
2222 * Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of relations
2223 * that indexes can be created on
2225 else if (TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON") ||
2226 TailMatches("INDEX|CONCURRENTLY", "ON"))
2227 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL);
2230 * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
2233 else if (TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
2234 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2235 " UNION SELECT 'ON'");
2236 /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
2237 else if (TailMatches("CREATE|UNIQUE", "INDEX", MatchAny) ||
2238 TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
2239 COMPLETE_WITH("ON");
2242 * Complete INDEX <name> ON <table> with a list of table columns (which
2243 * should really be in parens)
2245 else if (TailMatches("INDEX", MatchAny, "ON", MatchAny) ||
2246 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny))
2247 COMPLETE_WITH("(", "USING");
2248 else if (TailMatches("INDEX", MatchAny, "ON", MatchAny, "(") ||
2249 TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
2250 COMPLETE_WITH_ATTR(prev2_wd, "");
2251 /* same if you put in USING */
2252 else if (TailMatches("ON", MatchAny, "USING", MatchAny, "("))
2253 COMPLETE_WITH_ATTR(prev4_wd, "");
2254 /* Complete USING with an index method */
2255 else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
2256 TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") ||
2257 TailMatches("INDEX", "ON", MatchAny, "USING"))
2258 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2259 else if (TailMatches("ON", MatchAny, "USING", MatchAny) &&
2260 !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
2261 !TailMatches("FOR", MatchAny, MatchAny, MatchAny))
2265 /* Complete "CREATE POLICY <name> ON" */
2266 else if (Matches("CREATE", "POLICY", MatchAny))
2267 COMPLETE_WITH("ON");
2268 /* Complete "CREATE POLICY <name> ON <table>" */
2269 else if (Matches("CREATE", "POLICY", MatchAny, "ON"))
2270 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2271 /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
2272 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny))
2273 COMPLETE_WITH("AS", "FOR", "TO", "USING (", "WITH CHECK (");
2274 /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
2275 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
2276 COMPLETE_WITH("PERMISSIVE", "RESTRICTIVE");
2279 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2280 * FOR|TO|USING|WITH CHECK
2282 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
2283 COMPLETE_WITH("FOR", "TO", "USING", "WITH CHECK");
2284 /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2285 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
2286 COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2287 /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
2288 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
2289 COMPLETE_WITH("TO", "WITH CHECK (");
2290 /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
2291 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
2292 COMPLETE_WITH("TO", "USING (");
2293 /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
2294 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
2295 COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
2296 /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
2297 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
2298 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2299 /* Complete "CREATE POLICY <name> ON <table> USING (" */
2300 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
2304 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2305 * ALL|SELECT|INSERT|UPDATE|DELETE
2307 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
2308 COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2311 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2312 * INSERT TO|WITH CHECK"
2314 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
2315 COMPLETE_WITH("TO", "WITH CHECK (");
2318 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2319 * SELECT|DELETE TO|USING"
2321 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
2322 COMPLETE_WITH("TO", "USING (");
2325 * CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR
2326 * ALL|UPDATE TO|USING|WITH CHECK
2328 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
2329 COMPLETE_WITH("TO", "USING (", "WITH CHECK (");
2332 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO
2335 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
2336 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2339 * Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE
2342 else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
2346 /* CREATE PUBLICATION */
2347 else if (Matches("CREATE", "PUBLICATION", MatchAny))
2348 COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "WITH (");
2349 else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR"))
2350 COMPLETE_WITH("TABLE", "ALL TABLES");
2351 /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>, ..." */
2352 else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE"))
2353 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2354 /* Complete "CREATE PUBLICATION <name> [...] WITH" */
2355 else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "("))
2356 COMPLETE_WITH("publish");
2359 /* Complete "CREATE RULE <sth>" with "AS ON" */
2360 else if (Matches("CREATE", "RULE", MatchAny))
2361 COMPLETE_WITH("AS ON");
2362 /* Complete "CREATE RULE <sth> AS" with "ON" */
2363 else if (Matches("CREATE", "RULE", MatchAny, "AS"))
2364 COMPLETE_WITH("ON");
2365 /* Complete "CREATE RULE <sth> AS ON" with SELECT|UPDATE|INSERT|DELETE */
2366 else if (Matches("CREATE", "RULE", MatchAny, "AS", "ON"))
2367 COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE");
2368 /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
2369 else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
2370 COMPLETE_WITH("TO");
2371 /* Complete "AS ON <sth> TO" with a table name */
2372 else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
2373 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2375 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2376 else if (TailMatches("CREATE", "SEQUENCE", MatchAny) ||
2377 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
2378 COMPLETE_WITH("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE",
2379 "CYCLE", "OWNED BY", "START WITH");
2380 else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "NO") ||
2381 TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
2382 COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE");
2384 /* CREATE SERVER <name> */
2385 else if (Matches("CREATE", "SERVER", MatchAny))
2386 COMPLETE_WITH("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
2388 /* CREATE STATISTICS <name> */
2389 else if (Matches("CREATE", "STATISTICS", MatchAny))
2390 COMPLETE_WITH("(", "ON");
2391 else if (Matches("CREATE", "STATISTICS", MatchAny, "("))
2392 COMPLETE_WITH("ndistinct", "dependencies");
2393 else if (Matches("CREATE", "STATISTICS", MatchAny, "(*)"))
2394 COMPLETE_WITH("ON");
2395 else if (HeadMatches("CREATE", "STATISTICS", MatchAny) &&
2396 TailMatches("FROM"))
2397 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2399 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2400 /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
2401 else if (TailMatches("CREATE", "TEMP|TEMPORARY"))
2402 COMPLETE_WITH("SEQUENCE", "TABLE", "VIEW");
2403 /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
2404 else if (TailMatches("CREATE", "UNLOGGED"))
2405 COMPLETE_WITH("TABLE", "MATERIALIZED VIEW");
2406 /* Complete PARTITION BY with RANGE ( or LIST ( or ... */
2407 else if (TailMatches("PARTITION", "BY"))
2408 COMPLETE_WITH("RANGE (", "LIST (", "HASH (");
2409 /* If we have xxx PARTITION OF, provide a list of partitioned tables */
2410 else if (TailMatches("PARTITION", "OF"))
2411 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, "");
2412 /* Limited completion support for partition bound specification */
2413 else if (TailMatches("PARTITION", "OF", MatchAny))
2414 COMPLETE_WITH("FOR VALUES", "DEFAULT");
2416 /* CREATE TABLESPACE */
2417 else if (Matches("CREATE", "TABLESPACE", MatchAny))
2418 COMPLETE_WITH("OWNER", "LOCATION");
2419 /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
2420 else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
2421 COMPLETE_WITH("LOCATION");
2423 /* CREATE TEXT SEARCH */
2424 else if (Matches("CREATE", "TEXT", "SEARCH"))
2425 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2426 else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2429 /* CREATE SUBSCRIPTION */
2430 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny))
2431 COMPLETE_WITH("CONNECTION");
2432 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny))
2433 COMPLETE_WITH("PUBLICATION");
2434 else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",
2435 MatchAny, "PUBLICATION"))
2437 /* complete with nothing here as this refers to remote publications */
2439 else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("PUBLICATION", MatchAny))
2440 COMPLETE_WITH("WITH (");
2441 /* Complete "CREATE SUBSCRIPTION <name> ... WITH ( <opt>" */
2442 else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("WITH", "("))
2443 COMPLETE_WITH("copy_data", "connect", "create_slot", "enabled",
2444 "slot_name", "synchronous_commit");
2446 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
2447 /* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
2448 else if (TailMatches("CREATE", "TRIGGER", MatchAny))
2449 COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF");
2450 /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
2451 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
2452 COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE");
2453 /* complete CREATE TRIGGER <name> INSTEAD OF with an event */
2454 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
2455 COMPLETE_WITH("INSERT", "DELETE", "UPDATE");
2456 /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
2457 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
2458 TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
2459 COMPLETE_WITH("ON", "OR");
2462 * complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of
2463 * tables. EXECUTE FUNCTION is the recommended grammar instead of EXECUTE
2464 * PROCEDURE in version 11 and upwards.
2466 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
2467 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2468 /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */
2469 else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
2470 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
2471 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("ON", MatchAny))
2473 if (pset.sversion >= 110000)
2474 COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2475 "REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
2477 COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2478 "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2480 else if (HeadMatches("CREATE", "TRIGGER") &&
2481 (TailMatches("DEFERRABLE") || TailMatches("INITIALLY", "IMMEDIATE|DEFERRED")))
2483 if (pset.sversion >= 110000)
2484 COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION");
2486 COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2488 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("REFERENCING"))
2489 COMPLETE_WITH("OLD TABLE", "NEW TABLE");
2490 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("OLD|NEW", "TABLE"))
2491 COMPLETE_WITH("AS");
2492 else if (HeadMatches("CREATE", "TRIGGER") &&
2493 (TailMatches("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
2494 TailMatches("REFERENCING", "OLD", "TABLE", MatchAny)))
2496 if (pset.sversion >= 110000)
2497 COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
2499 COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2501 else if (HeadMatches("CREATE", "TRIGGER") &&
2502 (TailMatches("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
2503 TailMatches("REFERENCING", "NEW", "TABLE", MatchAny)))
2505 if (pset.sversion >= 110000)
2506 COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION");
2508 COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2510 else if (HeadMatches("CREATE", "TRIGGER") &&
2511 (TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2512 TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2513 TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
2514 TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
2516 if (pset.sversion >= 110000)
2517 COMPLETE_WITH("FOR", "WHEN (", "EXECUTE FUNCTION");
2519 COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE");
2521 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR"))
2522 COMPLETE_WITH("EACH", "ROW", "STATEMENT");
2523 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR", "EACH"))
2524 COMPLETE_WITH("ROW", "STATEMENT");
2525 else if (HeadMatches("CREATE", "TRIGGER") &&
2526 (TailMatches("FOR", "EACH", "ROW|STATEMENT") ||
2527 TailMatches("FOR", "ROW|STATEMENT")))
2529 if (pset.sversion >= 110000)
2530 COMPLETE_WITH("WHEN (", "EXECUTE FUNCTION");
2532 COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE");
2534 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("WHEN", "(*)"))
2536 if (pset.sversion >= 110000)
2537 COMPLETE_WITH("EXECUTE FUNCTION");
2539 COMPLETE_WITH("EXECUTE PROCEDURE");
2541 /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE|FUNCTION */
2542 else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("EXECUTE"))
2544 if (pset.sversion >= 110000)
2545 COMPLETE_WITH("FUNCTION");
2547 COMPLETE_WITH("PROCEDURE");
2549 else if (HeadMatches("CREATE", "TRIGGER") &&
2550 TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
2551 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2553 /* CREATE ROLE,USER,GROUP <name> */
2554 else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny) &&
2555 !TailMatches("USER", "MAPPING"))
2556 COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
2557 "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
2558 "LOGIN", "NOBYPASSRLS",
2559 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2560 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2561 "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2562 "VALID UNTIL", "WITH");
2564 /* CREATE ROLE,USER,GROUP <name> WITH */
2565 else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
2566 /* Similar to the above, but don't complete "WITH" again. */
2567 COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB",
2568 "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT",
2569 "LOGIN", "NOBYPASSRLS",
2570 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2571 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2572 "REPLICATION", "ROLE", "SUPERUSER", "SYSID",
2575 /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
2576 else if (Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
2577 COMPLETE_WITH("GROUP", "ROLE");
2579 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
2580 /* Complete CREATE VIEW <name> with AS */
2581 else if (TailMatches("CREATE", "VIEW", MatchAny))
2582 COMPLETE_WITH("AS");
2583 /* Complete "CREATE VIEW <sth> AS with "SELECT" */
2584 else if (TailMatches("CREATE", "VIEW", MatchAny, "AS"))
2585 COMPLETE_WITH("SELECT");
2587 /* CREATE MATERIALIZED VIEW */
2588 else if (Matches("CREATE", "MATERIALIZED"))
2589 COMPLETE_WITH("VIEW");
2590 /* Complete CREATE MATERIALIZED VIEW <name> with AS */
2591 else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny))
2592 COMPLETE_WITH("AS");
2593 /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
2594 else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
2595 COMPLETE_WITH("SELECT");
2597 /* CREATE EVENT TRIGGER */
2598 else if (Matches("CREATE", "EVENT"))
2599 COMPLETE_WITH("TRIGGER");
2600 /* Complete CREATE EVENT TRIGGER <name> with ON */
2601 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny))
2602 COMPLETE_WITH("ON");
2603 /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
2604 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
2605 COMPLETE_WITH("ddl_command_start", "ddl_command_end", "sql_drop");
2608 * Complete CREATE EVENT TRIGGER <name> ON <event_type>. EXECUTE FUNCTION
2609 * is the recommended grammar instead of EXECUTE PROCEDURE in version 11
2612 else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON", MatchAny))
2614 if (pset.sversion >= 110000)
2615 COMPLETE_WITH("WHEN TAG IN (", "EXECUTE FUNCTION");
2617 COMPLETE_WITH("WHEN TAG IN (", "EXECUTE PROCEDURE");
2619 else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
2620 TailMatches("WHEN|AND", MatchAny, "IN", "(*)"))
2622 if (pset.sversion >= 110000)
2623 COMPLETE_WITH("EXECUTE FUNCTION");
2625 COMPLETE_WITH("EXECUTE PROCEDURE");
2627 else if (HeadMatches("CREATE", "EVENT", "TRIGGER") &&
2628 TailMatches("EXECUTE", "FUNCTION|PROCEDURE"))
2629 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2632 else if (Matches("DEALLOCATE"))
2633 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2636 else if (Matches("DECLARE", MatchAny))
2637 COMPLETE_WITH("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL",
2639 else if (HeadMatches("DECLARE") && TailMatches("CURSOR"))
2640 COMPLETE_WITH("WITH HOLD", "WITHOUT HOLD", "FOR");
2642 /* DELETE --- can be inside EXPLAIN, RULE, etc */
2643 /* ... despite which, only complete DELETE with FROM at start of line */
2644 else if (Matches("DELETE"))
2645 COMPLETE_WITH("FROM");
2646 /* Complete DELETE FROM with a list of tables */
2647 else if (TailMatches("DELETE", "FROM"))
2648 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2649 /* Complete DELETE FROM <table> */
2650 else if (TailMatches("DELETE", "FROM", MatchAny))
2651 COMPLETE_WITH("USING", "WHERE");
2652 /* XXX: implement tab completion for DELETE ... USING */
2655 else if (Matches("DISCARD"))
2656 COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP");
2659 else if (Matches("DO"))
2660 COMPLETE_WITH("LANGUAGE");
2663 /* Complete DROP object with CASCADE / RESTRICT */
2664 else if (Matches("DROP",
2665 "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW",
2667 Matches("DROP", "ACCESS", "METHOD", MatchAny) ||
2668 (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) &&
2669 ends_with(prev_wd, ')')) ||
2670 Matches("DROP", "EVENT", "TRIGGER", MatchAny) ||
2671 Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
2672 Matches("DROP", "FOREIGN", "TABLE", MatchAny) ||
2673 Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
2674 COMPLETE_WITH("CASCADE", "RESTRICT");
2676 /* help completing some of the variants */
2677 else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny))
2679 else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "("))
2680 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
2681 else if (Matches("DROP", "FOREIGN"))
2682 COMPLETE_WITH("DATA WRAPPER", "TABLE");
2685 else if (Matches("DROP", "INDEX"))
2686 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2687 " UNION SELECT 'CONCURRENTLY'");
2688 else if (Matches("DROP", "INDEX", "CONCURRENTLY"))
2689 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2690 else if (Matches("DROP", "INDEX", MatchAny))
2691 COMPLETE_WITH("CASCADE", "RESTRICT");
2692 else if (Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny))
2693 COMPLETE_WITH("CASCADE", "RESTRICT");
2695 /* DROP MATERIALIZED VIEW */
2696 else if (Matches("DROP", "MATERIALIZED"))
2697 COMPLETE_WITH("VIEW");
2698 else if (Matches("DROP", "MATERIALIZED", "VIEW"))
2699 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2702 else if (Matches("DROP", "OWNED"))
2703 COMPLETE_WITH("BY");
2704 else if (Matches("DROP", "OWNED", "BY"))
2705 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2707 /* DROP TEXT SEARCH */
2708 else if (Matches("DROP", "TEXT", "SEARCH"))
2709 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2712 else if (Matches("DROP", "TRIGGER", MatchAny))
2713 COMPLETE_WITH("ON");
2714 else if (Matches("DROP", "TRIGGER", MatchAny, "ON"))
2716 completion_info_charp = prev2_wd;
2717 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2719 else if (Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
2720 COMPLETE_WITH("CASCADE", "RESTRICT");
2722 /* DROP ACCESS METHOD */
2723 else if (Matches("DROP", "ACCESS"))
2724 COMPLETE_WITH("METHOD");
2725 else if (Matches("DROP", "ACCESS", "METHOD"))
2726 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2728 /* DROP EVENT TRIGGER */
2729 else if (Matches("DROP", "EVENT"))
2730 COMPLETE_WITH("TRIGGER");
2731 else if (Matches("DROP", "EVENT", "TRIGGER"))
2732 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2734 /* DROP POLICY <name> */
2735 else if (Matches("DROP", "POLICY"))
2736 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2737 /* DROP POLICY <name> ON */
2738 else if (Matches("DROP", "POLICY", MatchAny))
2739 COMPLETE_WITH("ON");
2740 /* DROP POLICY <name> ON <table> */
2741 else if (Matches("DROP", "POLICY", MatchAny, "ON"))
2743 completion_info_charp = prev2_wd;
2744 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
2748 else if (Matches("DROP", "RULE", MatchAny))
2749 COMPLETE_WITH("ON");
2750 else if (Matches("DROP", "RULE", MatchAny, "ON"))
2752 completion_info_charp = prev2_wd;
2753 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2755 else if (Matches("DROP", "RULE", MatchAny, "ON", MatchAny))
2756 COMPLETE_WITH("CASCADE", "RESTRICT");
2759 else if (Matches("EXECUTE"))
2760 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2763 * EXPLAIN [ ( option [, ...] ) ] statement
2764 * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
2766 else if (Matches("EXPLAIN"))
2767 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2768 "ANALYZE", "VERBOSE");
2769 else if (HeadMatches("EXPLAIN", "(*") &&
2770 !HeadMatches("EXPLAIN", "(*)"))
2773 * This fires if we're in an unfinished parenthesized option list.
2774 * get_previous_words treats a completed parenthesized option list as
2775 * one word, so the above test is correct.
2777 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
2778 COMPLETE_WITH("ANALYZE", "VERBOSE", "COSTS", "BUFFERS",
2779 "TIMING", "SUMMARY", "FORMAT");
2780 else if (TailMatches("ANALYZE|VERBOSE|COSTS|BUFFERS|TIMING|SUMMARY"))
2781 COMPLETE_WITH("ON", "OFF");
2782 else if (TailMatches("FORMAT"))
2783 COMPLETE_WITH("TEXT", "XML", "JSON", "YAML");
2785 else if (Matches("EXPLAIN", "ANALYZE"))
2786 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2788 else if (Matches("EXPLAIN", "(*)") ||
2789 Matches("EXPLAIN", "VERBOSE") ||
2790 Matches("EXPLAIN", "ANALYZE", "VERBOSE"))
2791 COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE");
2794 /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
2795 else if (Matches("FETCH|MOVE"))
2796 COMPLETE_WITH("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE");
2797 /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
2798 else if (Matches("FETCH|MOVE", MatchAny))
2799 COMPLETE_WITH("ALL", "NEXT", "PRIOR");
2802 * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
2803 * but we may as well tab-complete both: perhaps some users prefer one
2804 * variant or the other.
2806 else if (Matches("FETCH|MOVE", MatchAny, MatchAny))
2807 COMPLETE_WITH("FROM", "IN");
2809 /* FOREIGN DATA WRAPPER */
2810 /* applies in ALTER/DROP FDW and in CREATE SERVER */
2811 else if (TailMatches("FOREIGN", "DATA", "WRAPPER") &&
2812 !TailMatches("CREATE", MatchAny, MatchAny, MatchAny))
2813 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
2814 /* applies in CREATE SERVER */
2815 else if (TailMatches("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
2816 HeadMatches("CREATE", "SERVER"))
2817 COMPLETE_WITH("OPTIONS");
2820 else if (TailMatches("FOREIGN", "TABLE") &&
2821 !TailMatches("CREATE", MatchAny, MatchAny))
2822 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
2824 /* FOREIGN SERVER */
2825 else if (TailMatches("FOREIGN", "SERVER"))
2826 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
2829 * GRANT and REVOKE are allowed inside CREATE SCHEMA and
2830 * ALTER DEFAULT PRIVILEGES, so use TailMatches
2832 /* Complete GRANT/REVOKE with a list of roles and privileges */
2833 else if (TailMatches("GRANT|REVOKE"))
2836 * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable
2837 * privileges (can't grant roles)
2839 if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
2840 COMPLETE_WITH("SELECT", "INSERT", "UPDATE",
2841 "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2842 "EXECUTE", "USAGE", "ALL");
2844 COMPLETE_WITH_QUERY(Query_for_list_of_roles
2845 " UNION SELECT 'SELECT'"
2846 " UNION SELECT 'INSERT'"
2847 " UNION SELECT 'UPDATE'"
2848 " UNION SELECT 'DELETE'"
2849 " UNION SELECT 'TRUNCATE'"
2850 " UNION SELECT 'REFERENCES'"
2851 " UNION SELECT 'TRIGGER'"
2852 " UNION SELECT 'CREATE'"
2853 " UNION SELECT 'CONNECT'"
2854 " UNION SELECT 'TEMPORARY'"
2855 " UNION SELECT 'EXECUTE'"
2856 " UNION SELECT 'USAGE'"
2857 " UNION SELECT 'ALL'");
2861 * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
2864 else if (TailMatches("GRANT|REVOKE", MatchAny))
2866 if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
2867 COMPLETE_WITH("ON");
2868 else if (TailMatches("GRANT", MatchAny))
2869 COMPLETE_WITH("TO");
2871 COMPLETE_WITH("FROM");
2875 * Complete GRANT/REVOKE <sth> ON with a list of appropriate relations.
2877 * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query
2878 * result via UNION; seems to work intuitively.
2880 * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
2881 * here will only work if the privilege list contains exactly one
2884 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON"))
2887 * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of
2888 * objects supported.
2890 if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
2891 COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS");
2893 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables,
2894 " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
2895 " UNION SELECT 'ALL PROCEDURES IN SCHEMA'"
2896 " UNION SELECT 'ALL ROUTINES IN SCHEMA'"
2897 " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
2898 " UNION SELECT 'ALL TABLES IN SCHEMA'"
2899 " UNION SELECT 'DATABASE'"
2900 " UNION SELECT 'DOMAIN'"
2901 " UNION SELECT 'FOREIGN DATA WRAPPER'"
2902 " UNION SELECT 'FOREIGN SERVER'"
2903 " UNION SELECT 'FUNCTION'"
2904 " UNION SELECT 'LANGUAGE'"
2905 " UNION SELECT 'LARGE OBJECT'"
2906 " UNION SELECT 'PROCEDURE'"
2907 " UNION SELECT 'ROUTINE'"
2908 " UNION SELECT 'SCHEMA'"
2909 " UNION SELECT 'SEQUENCE'"
2910 " UNION SELECT 'TABLE'"
2911 " UNION SELECT 'TABLESPACE'"
2912 " UNION SELECT 'TYPE'");
2914 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL"))
2915 COMPLETE_WITH("FUNCTIONS IN SCHEMA",
2916 "PROCEDURES IN SCHEMA",
2917 "ROUTINES IN SCHEMA",
2918 "SEQUENCES IN SCHEMA",
2919 "TABLES IN SCHEMA");
2920 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"))
2921 COMPLETE_WITH("DATA WRAPPER", "SERVER");
2924 * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
2925 * appropriate objects.
2927 * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
2929 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny))
2931 if (TailMatches("DATABASE"))
2932 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2933 else if (TailMatches("DOMAIN"))
2934 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
2935 else if (TailMatches("FUNCTION"))
2936 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2937 else if (TailMatches("LANGUAGE"))
2938 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
2939 else if (TailMatches("PROCEDURE"))
2940 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL);
2941 else if (TailMatches("ROUTINE"))
2942 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
2943 else if (TailMatches("SCHEMA"))
2944 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2945 else if (TailMatches("SEQUENCE"))
2946 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
2947 else if (TailMatches("TABLE"))
2948 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL);
2949 else if (TailMatches("TABLESPACE"))
2950 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
2951 else if (TailMatches("TYPE"))
2952 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
2953 else if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny))
2954 COMPLETE_WITH("TO");
2956 COMPLETE_WITH("FROM");
2960 * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
2961 * CURRENT_USER, or SESSION_USER.
2963 else if ((HeadMatches("GRANT") && TailMatches("TO")) ||
2964 (HeadMatches("REVOKE") && TailMatches("FROM")))
2965 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2966 /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
2967 else if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches("TO|FROM"))
2968 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2969 /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
2970 else if (HeadMatches("GRANT") && TailMatches("ON", MatchAny, MatchAny))
2971 COMPLETE_WITH("TO");
2972 else if (HeadMatches("REVOKE") && TailMatches("ON", MatchAny, MatchAny))
2973 COMPLETE_WITH("FROM");
2975 /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
2976 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
2978 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2979 COMPLETE_WITH("TO");
2981 COMPLETE_WITH("FROM");
2984 /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
2985 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2987 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2988 COMPLETE_WITH("TO");
2990 COMPLETE_WITH("FROM");
2993 /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
2994 else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
2996 if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2997 COMPLETE_WITH("TO");
2999 COMPLETE_WITH("FROM");
3003 else if (TailMatches("FROM", MatchAny, "GROUP"))
3004 COMPLETE_WITH("BY");
3006 /* IMPORT FOREIGN SCHEMA */
3007 else if (Matches("IMPORT"))
3008 COMPLETE_WITH("FOREIGN SCHEMA");
3009 else if (Matches("IMPORT", "FOREIGN"))
3010 COMPLETE_WITH("SCHEMA");
3012 /* INSERT --- can be inside EXPLAIN, RULE, etc */
3013 /* Complete INSERT with "INTO" */
3014 else if (TailMatches("INSERT"))
3015 COMPLETE_WITH("INTO");
3016 /* Complete INSERT INTO with table names */
3017 else if (TailMatches("INSERT", "INTO"))
3018 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3019 /* Complete "INSERT INTO <table> (" with attribute names */
3020 else if (TailMatches("INSERT", "INTO", MatchAny, "("))
3021 COMPLETE_WITH_ATTR(prev2_wd, "");
3024 * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
3025 * "TABLE" or "DEFAULT VALUES" or "OVERRIDING"
3027 else if (TailMatches("INSERT", "INTO", MatchAny))
3028 COMPLETE_WITH("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING");
3031 * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
3032 * "TABLE" or "OVERRIDING"
3034 else if (TailMatches("INSERT", "INTO", MatchAny, MatchAny) &&
3035 ends_with(prev_wd, ')'))
3036 COMPLETE_WITH("SELECT", "TABLE", "VALUES", "OVERRIDING");
3038 /* Complete OVERRIDING */
3039 else if (TailMatches("OVERRIDING"))
3040 COMPLETE_WITH("SYSTEM VALUE", "USER VALUE");
3042 /* Complete after OVERRIDING clause */
3043 else if (TailMatches("OVERRIDING", MatchAny, "VALUE"))
3044 COMPLETE_WITH("SELECT", "TABLE", "VALUES");
3046 /* Insert an open parenthesis after "VALUES" */
3047 else if (TailMatches("VALUES") && !TailMatches("DEFAULT", "VALUES"))
3051 /* Complete LOCK [TABLE] with a list of tables */
3052 else if (Matches("LOCK"))
3053 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
3054 " UNION SELECT 'TABLE'");
3055 else if (Matches("LOCK", "TABLE"))
3056 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
3058 /* For the following, handle the case of a single table only for now */
3060 /* Complete LOCK [TABLE] <table> with "IN" */
3061 else if (Matches("LOCK", MatchAnyExcept("TABLE")) ||
3062 Matches("LOCK", "TABLE", MatchAny))
3063 COMPLETE_WITH("IN");
3065 /* Complete LOCK [TABLE] <table> IN with a lock mode */
3066 else if (Matches("LOCK", MatchAny, "IN") ||
3067 Matches("LOCK", "TABLE", MatchAny, "IN"))
3068 COMPLETE_WITH("ACCESS SHARE MODE",
3069 "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
3070 "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
3071 "SHARE ROW EXCLUSIVE MODE",
3072 "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
3074 /* Complete LOCK [TABLE] <table> IN ACCESS|ROW with rest of lock mode */
3075 else if (Matches("LOCK", MatchAny, "IN", "ACCESS|ROW") ||
3076 Matches("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW"))
3077 COMPLETE_WITH("EXCLUSIVE MODE", "SHARE MODE");
3079 /* Complete LOCK [TABLE] <table> IN SHARE with rest of lock mode */
3080 else if (Matches("LOCK", MatchAny, "IN", "SHARE") ||
3081 Matches("LOCK", "TABLE", MatchAny, "IN", "SHARE"))
3082 COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE",
3083 "UPDATE EXCLUSIVE MODE");
3085 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
3086 else if (TailMatches("NOTIFY"))
3087 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'");
3090 else if (TailMatches("OPTIONS"))
3093 /* OWNER TO - complete with available roles */
3094 else if (TailMatches("OWNER", "TO"))
3095 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3098 else if (TailMatches("FROM", MatchAny, "ORDER"))
3099 COMPLETE_WITH("BY");
3100 else if (TailMatches("FROM", MatchAny, "ORDER", "BY"))
3101 COMPLETE_WITH_ATTR(prev3_wd, "");
3104 else if (Matches("PREPARE", MatchAny, "AS"))
3105 COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE FROM");
3108 * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
3109 * managers, not for manual use in interactive sessions.
3112 /* REASSIGN OWNED BY xxx TO yyy */
3113 else if (Matches("REASSIGN"))
3114 COMPLETE_WITH("OWNED BY");
3115 else if (Matches("REASSIGN", "OWNED"))
3116 COMPLETE_WITH("BY");
3117 else if (Matches("REASSIGN", "OWNED", "BY"))
3118 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3119 else if (Matches("REASSIGN", "OWNED", "BY", MatchAny))
3120 COMPLETE_WITH("TO");
3121 else if (Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
3122 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3124 /* REFRESH MATERIALIZED VIEW */
3125 else if (Matches("REFRESH"))
3126 COMPLETE_WITH("MATERIALIZED VIEW");
3127 else if (Matches("REFRESH", "MATERIALIZED"))
3128 COMPLETE_WITH("VIEW");
3129 else if (Matches("REFRESH", "MATERIALIZED", "VIEW"))
3130 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
3131 " UNION SELECT 'CONCURRENTLY'");
3132 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
3133 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3134 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
3135 COMPLETE_WITH("WITH");
3136 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
3137 COMPLETE_WITH("WITH");
3138 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
3139 COMPLETE_WITH("NO DATA", "DATA");
3140 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
3141 COMPLETE_WITH("NO DATA", "DATA");
3142 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
3143 COMPLETE_WITH("DATA");
3144 else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
3145 COMPLETE_WITH("DATA");
3148 else if (Matches("REINDEX"))
3149 COMPLETE_WITH("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
3150 else if (Matches("REINDEX", "TABLE"))
3151 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL);
3152 else if (Matches("REINDEX", "INDEX"))
3153 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3154 else if (Matches("REINDEX", "SCHEMA"))
3155 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3156 else if (Matches("REINDEX", "SYSTEM|DATABASE"))
3157 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3159 /* SECURITY LABEL */
3160 else if (Matches("SECURITY"))
3161 COMPLETE_WITH("LABEL");
3162 else if (Matches("SECURITY", "LABEL"))
3163 COMPLETE_WITH("ON", "FOR");
3164 else if (Matches("SECURITY", "LABEL", "FOR", MatchAny))
3165 COMPLETE_WITH("ON");
3166 else if (Matches("SECURITY", "LABEL", "ON") ||
3167 Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
3168 COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
3169 "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION",
3170 "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE",
3171 "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA",
3172 "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW");
3173 else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
3174 COMPLETE_WITH("IS");
3179 /* SET, RESET, SHOW */
3180 /* Complete with a variable name */
3181 else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET"))
3182 COMPLETE_WITH_QUERY(Query_for_list_of_set_vars);
3183 else if (Matches("SHOW"))
3184 COMPLETE_WITH_QUERY(Query_for_list_of_show_vars);
3185 /* Complete "SET TRANSACTION" */
3186 else if (Matches("SET", "TRANSACTION"))
3187 COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3188 else if (Matches("BEGIN|START", "TRANSACTION") ||
3189 Matches("BEGIN", "WORK") ||
3191 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
3192 COMPLETE_WITH("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
3193 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
3194 Matches("BEGIN", "NOT") ||
3195 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
3196 COMPLETE_WITH("DEFERRABLE");
3197 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
3198 Matches("BEGIN", "ISOLATION") ||
3199 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
3200 COMPLETE_WITH("LEVEL");
3201 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
3202 Matches("BEGIN", "ISOLATION", "LEVEL") ||
3203 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
3204 COMPLETE_WITH("READ", "REPEATABLE READ", "SERIALIZABLE");
3205 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
3206 Matches("BEGIN", "ISOLATION", "LEVEL", "READ") ||
3207 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
3208 COMPLETE_WITH("UNCOMMITTED", "COMMITTED");
3209 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
3210 Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
3211 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
3212 COMPLETE_WITH("READ");
3213 else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
3214 Matches("BEGIN", "READ") ||
3215 Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
3216 COMPLETE_WITH("ONLY", "WRITE");
3217 /* SET CONSTRAINTS */
3218 else if (Matches("SET", "CONSTRAINTS"))
3219 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'");
3220 /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
3221 else if (Matches("SET", "CONSTRAINTS", MatchAny))
3222 COMPLETE_WITH("DEFERRED", "IMMEDIATE");
3223 /* Complete SET ROLE */
3224 else if (Matches("SET", "ROLE"))
3225 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3226 /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
3227 else if (Matches("SET", "SESSION"))
3228 COMPLETE_WITH("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
3229 /* Complete SET SESSION AUTHORIZATION with username */
3230 else if (Matches("SET", "SESSION", "AUTHORIZATION"))
3231 COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'");
3232 /* Complete RESET SESSION with AUTHORIZATION */
3233 else if (Matches("RESET", "SESSION"))
3234 COMPLETE_WITH("AUTHORIZATION");
3235 /* Complete SET <var> with "TO" */
3236 else if (Matches("SET", MatchAny))
3237 COMPLETE_WITH("TO");
3240 * Complete ALTER DATABASE|FUNCTION||PROCEDURE|ROLE|ROUTINE|USER ... SET
3243 else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") &&
3244 TailMatches("SET", MatchAny))
3245 COMPLETE_WITH("FROM CURRENT", "TO");
3246 /* Suggest possible variable values */
3247 else if (TailMatches("SET", MatchAny, "TO|="))
3249 /* special cased code for individual GUCs */
3250 if (TailMatches("DateStyle", "TO|="))
3251 COMPLETE_WITH("ISO", "SQL", "Postgres", "German",
3252 "YMD", "DMY", "MDY",
3253 "US", "European", "NonEuropean",
3255 else if (TailMatches("search_path", "TO|="))
3256 COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3257 " AND nspname not like 'pg\\_toast%%' "
3258 " AND nspname not like 'pg\\_temp%%' "
3259 " UNION SELECT 'DEFAULT' ");
3262 /* generic, type based, GUC support */
3263 char *guctype = get_guctype(prev2_wd);
3265 if (guctype && strcmp(guctype, "enum") == 0)
3267 char querybuf[1024];
3269 snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd);
3270 COMPLETE_WITH_QUERY(querybuf);
3272 else if (guctype && strcmp(guctype, "bool") == 0)
3273 COMPLETE_WITH("on", "off", "true", "false", "yes", "no",
3274 "1", "0", "DEFAULT");
3276 COMPLETE_WITH("DEFAULT");
3283 /* START TRANSACTION */
3284 else if (Matches("START"))
3285 COMPLETE_WITH("TRANSACTION");
3287 /* TABLE, but not TABLE embedded in other commands */
3288 else if (Matches("TABLE"))
3289 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3292 else if (TailMatches("TABLESAMPLE"))
3293 COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
3294 else if (TailMatches("TABLESAMPLE", MatchAny))
3298 else if (Matches("TRUNCATE"))
3299 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3302 else if (Matches("UNLISTEN"))
3303 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 '*'");
3305 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
3306 /* If prev. word is UPDATE suggest a list of tables */
3307 else if (TailMatches("UPDATE"))
3308 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3309 /* Complete UPDATE <table> with "SET" */
3310 else if (TailMatches("UPDATE", MatchAny))
3311 COMPLETE_WITH("SET");
3312 /* Complete UPDATE <table> SET with list of attributes */
3313 else if (TailMatches("UPDATE", MatchAny, "SET"))
3314 COMPLETE_WITH_ATTR(prev2_wd, "");
3315 /* UPDATE <table> SET <attr> = */
3316 else if (TailMatches("UPDATE", MatchAny, "SET", MatchAny))
3320 else if (Matches("ALTER|CREATE|DROP", "USER", "MAPPING"))
3321 COMPLETE_WITH("FOR");
3322 else if (Matches("CREATE", "USER", "MAPPING", "FOR"))
3323 COMPLETE_WITH_QUERY(Query_for_list_of_roles
3324 " UNION SELECT 'CURRENT_USER'"
3325 " UNION SELECT 'PUBLIC'"
3326 " UNION SELECT 'USER'");
3327 else if (Matches("ALTER|DROP", "USER", "MAPPING", "FOR"))
3328 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3329 else if (Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
3330 COMPLETE_WITH("SERVER");
3331 else if (Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
3332 COMPLETE_WITH("OPTIONS");
3335 * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
3336 * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
3338 else if (Matches("VACUUM"))
3339 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3340 " UNION SELECT 'FULL'"
3341 " UNION SELECT 'FREEZE'"
3342 " UNION SELECT 'ANALYZE'"
3343 " UNION SELECT 'VERBOSE'");
3344 else if (Matches("VACUUM", "FULL"))
3345 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3346 " UNION SELECT 'FREEZE'"
3347 " UNION SELECT 'ANALYZE'"
3348 " UNION SELECT 'VERBOSE'");
3349 else if (Matches("VACUUM", "FREEZE") ||
3350 Matches("VACUUM", "FULL", "FREEZE"))
3351 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3352 " UNION SELECT 'VERBOSE'"
3353 " UNION SELECT 'ANALYZE'");
3354 else if (Matches("VACUUM", "VERBOSE") ||
3355 Matches("VACUUM", "FULL|FREEZE", "VERBOSE") ||
3356 Matches("VACUUM", "FULL", "FREEZE", "VERBOSE"))
3357 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables,
3358 " UNION SELECT 'ANALYZE'");
3359 else if (HeadMatches("VACUUM", "(*") &&
3360 !HeadMatches("VACUUM", "(*)"))
3363 * This fires if we're in an unfinished parenthesized option list.
3364 * get_previous_words treats a completed parenthesized option list as
3365 * one word, so the above test is correct.
3367 if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
3368 COMPLETE_WITH("FULL", "FREEZE", "ANALYZE", "VERBOSE",
3369 "DISABLE_PAGE_SKIPPING");
3371 else if (HeadMatches("VACUUM") && TailMatches("("))
3372 /* "VACUUM (" should be caught above, so assume we want columns */
3373 COMPLETE_WITH_ATTR(prev2_wd, "");
3374 else if (HeadMatches("VACUUM"))
3375 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, NULL);
3377 /* WITH [RECURSIVE] */
3380 * Only match when WITH is the first word, as WITH may appear in many
3383 else if (Matches("WITH"))
3384 COMPLETE_WITH("RECURSIVE");
3387 /* Simple case of the word before the where being the table name */
3388 else if (TailMatches(MatchAny, "WHERE"))
3389 COMPLETE_WITH_ATTR(prev2_wd, "");
3392 /* TODO: also include SRF ? */
3393 else if (TailMatches("FROM") && !Matches("COPY|\\copy", MatchAny, "FROM"))
3394 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3397 else if (TailMatches("JOIN"))
3398 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL);
3400 /* Backslash commands */
3401 /* TODO: \dc \dd \dl */
3402 else if (TailMatchesCS("\\?"))
3403 COMPLETE_WITH_CS("commands", "options", "variables");
3404 else if (TailMatchesCS("\\connect|\\c"))
3406 if (!recognized_connection_string(text))
3407 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3409 else if (TailMatchesCS("\\connect|\\c", MatchAny))
3411 if (!recognized_connection_string(prev_wd))
3412 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3414 else if (TailMatchesCS("\\da*"))
3415 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
3416 else if (TailMatchesCS("\\dA*"))
3417 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3418 else if (TailMatchesCS("\\db*"))
3419 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3420 else if (TailMatchesCS("\\dD*"))
3421 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3422 else if (TailMatchesCS("\\des*"))
3423 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3424 else if (TailMatchesCS("\\deu*"))
3425 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3426 else if (TailMatchesCS("\\dew*"))
3427 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3428 else if (TailMatchesCS("\\df*"))
3429 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3431 else if (TailMatchesCS("\\dFd*"))
3432 COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
3433 else if (TailMatchesCS("\\dFp*"))
3434 COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
3435 else if (TailMatchesCS("\\dFt*"))
3436 COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
3437 /* must be at end of \dF alternatives: */
3438 else if (TailMatchesCS("\\dF*"))
3439 COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
3441 else if (TailMatchesCS("\\di*"))
3442 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3443 else if (TailMatchesCS("\\dL*"))
3444 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3445 else if (TailMatchesCS("\\dn*"))
3446 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3447 else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z"))
3448 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL);
3449 else if (TailMatchesCS("\\ds*"))
3450 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3451 else if (TailMatchesCS("\\dt*"))
3452 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3453 else if (TailMatchesCS("\\dT*"))
3454 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3455 else if (TailMatchesCS("\\du*") || TailMatchesCS("\\dg*"))
3456 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3457 else if (TailMatchesCS("\\dv*"))
3458 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3459 else if (TailMatchesCS("\\dx*"))
3460 COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
3461 else if (TailMatchesCS("\\dm*"))
3462 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3463 else if (TailMatchesCS("\\dE*"))
3464 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
3465 else if (TailMatchesCS("\\dy*"))
3466 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3468 /* must be at end of \d alternatives: */
3469 else if (TailMatchesCS("\\d*"))
3470 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3472 else if (TailMatchesCS("\\ef"))
3473 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3474 else if (TailMatchesCS("\\ev"))
3475 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3477 else if (TailMatchesCS("\\encoding"))
3478 COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
3479 else if (TailMatchesCS("\\h|\\help"))
3480 COMPLETE_WITH_LIST(sql_commands);
3481 else if (TailMatchesCS("\\h|\\help", MatchAny))
3483 if (TailMatches("DROP"))
3484 matches = completion_matches(text, drop_command_generator);
3485 else if (TailMatches("ALTER"))
3486 matches = completion_matches(text, alter_command_generator);
3489 * CREATE is recognized by tail match elsewhere, so doesn't need to be
3493 else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny))
3495 if (TailMatches("CREATE|DROP", "ACCESS"))
3496 COMPLETE_WITH("METHOD");
3497 else if (TailMatches("ALTER", "DEFAULT"))
3498 COMPLETE_WITH("PRIVILEGES");
3499 else if (TailMatches("CREATE|ALTER|DROP", "EVENT"))
3500 COMPLETE_WITH("TRIGGER");
3501 else if (TailMatches("CREATE|ALTER|DROP", "FOREIGN"))
3502 COMPLETE_WITH("DATA WRAPPER", "TABLE");
3503 else if (TailMatches("ALTER", "LARGE"))
3504 COMPLETE_WITH("OBJECT");
3505 else if (TailMatches("CREATE|ALTER|DROP", "MATERIALIZED"))
3506 COMPLETE_WITH("VIEW");
3507 else if (TailMatches("CREATE|ALTER|DROP", "TEXT"))
3508 COMPLETE_WITH("SEARCH");
3509 else if (TailMatches("CREATE|ALTER|DROP", "USER"))
3510 COMPLETE_WITH("MAPPING FOR");
3512 else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny))
3514 if (TailMatches("CREATE|ALTER|DROP", "FOREIGN", "DATA"))
3515 COMPLETE_WITH("WRAPPER");
3516 else if (TailMatches("CREATE|ALTER|DROP", "TEXT", "SEARCH"))
3517 COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
3518 else if (TailMatches("CREATE|ALTER|DROP", "USER", "MAPPING"))
3519 COMPLETE_WITH("FOR");
3521 else if (TailMatchesCS("\\l*") && !TailMatchesCS("\\lo*"))
3522 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3523 else if (TailMatchesCS("\\password"))
3524 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3525 else if (TailMatchesCS("\\pset"))
3526 COMPLETE_WITH_CS("border", "columns", "csv_fieldsep", "expanded",
3527 "fieldsep", "fieldsep_zero", "footer", "format",
3528 "linestyle", "null", "numericlocale",
3529 "pager", "pager_min_lines",
3530 "recordsep", "recordsep_zero",
3531 "tableattr", "title", "tuples_only",
3532 "unicode_border_linestyle",
3533 "unicode_column_linestyle",
3534 "unicode_header_linestyle");
3535 else if (TailMatchesCS("\\pset", MatchAny))
3537 if (TailMatchesCS("format"))
3538 COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex",
3539 "latex-longtable", "troff-ms", "unaligned",
3541 else if (TailMatchesCS("linestyle"))
3542 COMPLETE_WITH_CS("ascii", "old-ascii", "unicode");
3543 else if (TailMatchesCS("pager"))
3544 COMPLETE_WITH_CS("on", "off", "always");
3545 else if (TailMatchesCS("unicode_border_linestyle|"
3546 "unicode_column_linestyle|"
3547 "unicode_header_linestyle"))
3548 COMPLETE_WITH_CS("single", "double");
3550 else if (TailMatchesCS("\\unset"))
3551 matches = complete_from_variables(text, "", "", true);
3552 else if (TailMatchesCS("\\set"))
3553 matches = complete_from_variables(text, "", "", false);
3554 else if (TailMatchesCS("\\set", MatchAny))
3556 if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
3557 "SINGLELINE|SINGLESTEP"))
3558 COMPLETE_WITH_CS("on", "off");
3559 else if (TailMatchesCS("COMP_KEYWORD_CASE"))
3560 COMPLETE_WITH_CS("lower", "upper",
3561 "preserve-lower", "preserve-upper");
3562 else if (TailMatchesCS("ECHO"))
3563 COMPLETE_WITH_CS("errors", "queries", "all", "none");
3564 else if (TailMatchesCS("ECHO_HIDDEN"))
3565 COMPLETE_WITH_CS("noexec", "off", "on");
3566 else if (TailMatchesCS("HISTCONTROL"))
3567 COMPLETE_WITH_CS("ignorespace", "ignoredups",
3568 "ignoreboth", "none");
3569 else if (TailMatchesCS("ON_ERROR_ROLLBACK"))
3570 COMPLETE_WITH_CS("on", "off", "interactive");
3571 else if (TailMatchesCS("SHOW_CONTEXT"))
3572 COMPLETE_WITH_CS("never", "errors", "always");
3573 else if (TailMatchesCS("VERBOSITY"))
3574 COMPLETE_WITH_CS("default", "verbose", "terse");
3576 else if (TailMatchesCS("\\sf*"))
3577 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL);
3578 else if (TailMatchesCS("\\sv*"))
3579 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3580 else if (TailMatchesCS("\\cd|\\e|\\edit|\\g|\\i|\\include|"
3581 "\\ir|\\include_relative|\\o|\\out|"
3582 "\\s|\\w|\\write|\\lo_import"))
3584 completion_charp = "\\";
3585 matches = completion_matches(text, complete_from_files);
3589 * Finally, we look through the list of "things", such as TABLE, INDEX and
3590 * check if that was the previous word. If so, execute the query to get a
3597 for (i = 0; words_after_create[i].name; i++)
3599 if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
3601 if (words_after_create[i].query)
3602 COMPLETE_WITH_QUERY(words_after_create[i].query);
3603 else if (words_after_create[i].vquery)
3604 COMPLETE_WITH_VERSIONED_QUERY(words_after_create[i].vquery);
3605 else if (words_after_create[i].squery)
3606 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(words_after_create[i].squery,
3614 * If we still don't have anything to match we have to fabricate some sort
3615 * of default list. If we were to just return NULL, readline automatically
3616 * attempts filename completion, and that's usually no good.
3618 if (matches == NULL)
3621 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
3622 rl_completion_append_character = '\0';
3627 free(previous_words);
3630 /* Return our Grand List O' Matches */
3636 * GENERATOR FUNCTIONS
3638 * These functions do all the actual work of completing the input. They get
3639 * passed the text so far and the count how many times they have been called
3640 * so far with the same text.
3641 * If you read the above carefully, you'll see that these don't get called
3642 * directly but through the readline interface.
3643 * The return value is expected to be the full completion of the text, going
3644 * through a list each time, or NULL if there are no more matches. The string
3645 * will be free()'d by readline, so you must run it through strdup() or
3646 * something of that sort.
3650 * Common routine for create_command_generator and drop_command_generator.
3651 * Entries that have 'excluded' flags are not returned.
3654 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
3656 static int list_index,
3660 /* If this is the first time for this completion, init some values */
3664 string_length = strlen(text);
3667 /* find something that matches */
3668 while ((name = words_after_create[list_index++].name))
3670 if ((pg_strncasecmp(name, text, string_length) == 0) &&
3671 !(words_after_create[list_index - 1].flags & excluded))
3672 return pg_strdup_keyword_case(name, text);
3674 /* if nothing matches, return NULL */
3679 * This one gives you one from a list of things you can put after CREATE
3683 create_command_generator(const char *text, int state)
3685 return create_or_drop_command_generator(text, state, THING_NO_CREATE);
3689 * This function gives you a list of things you can put after a DROP command.
3692 drop_command_generator(const char *text, int state)
3694 return create_or_drop_command_generator(text, state, THING_NO_DROP);
3698 * This function gives you a list of things you can put after an ALTER command.
3701 alter_command_generator(const char *text, int state)
3703 return create_or_drop_command_generator(text, state, THING_NO_ALTER);
3707 * These functions generate lists using server queries.
3708 * They are all wrappers for _complete_from_query.
3712 complete_from_query(const char *text, int state)
3714 /* query is assumed to work for any server version */
3715 return _complete_from_query(completion_charp, NULL, text, state);
3719 complete_from_versioned_query(const char *text, int state)
3721 const VersionedQuery *vquery = completion_vquery;
3723 /* Find appropriate array element */
3724 while (pset.sversion < vquery->min_server_version)
3726 /* Fail completion if server is too old */
3727 if (vquery->query == NULL)
3730 return _complete_from_query(vquery->query, NULL, text, state);
3734 complete_from_schema_query(const char *text, int state)
3736 /* query is assumed to work for any server version */
3737 return _complete_from_query(completion_charp, completion_squery,
3742 complete_from_versioned_schema_query(const char *text, int state)
3744 const SchemaQuery *squery = completion_squery;
3745 const VersionedQuery *vquery = completion_vquery;
3747 /* Find appropriate array element */
3748 while (pset.sversion < squery->min_server_version)
3750 /* Fail completion if server is too old */
3751 if (squery->catname == NULL)
3754 /* Likewise for the add-on text, if any */
3757 while (pset.sversion < vquery->min_server_version)
3759 if (vquery->query == NULL)
3763 return _complete_from_query(vquery ? vquery->query : NULL,
3764 squery, text, state);
3769 * This creates a list of matching things, according to a query described by
3770 * the initial arguments. The caller has already done any work needed to
3771 * select the appropriate query for the server's version.
3773 * The query can be one of two kinds:
3775 * 1. A simple query which must contain a %d and a %s, which will be replaced
3776 * by the string length of the text and the text itself. The query may also
3777 * have up to four more %s in it; the first two such will be replaced by the
3778 * value of completion_info_charp, the next two by the value of
3779 * completion_info_charp2.
3781 * 2. A schema query used for completion of both schema and relation names.
3782 * These are more complex and must contain in the following order:
3783 * %d %s %d %s %d %s %s %d %s
3784 * where %d is the string length of the text and %s the text itself.
3786 * If both simple_query and schema_query are non-NULL, then we construct
3787 * a schema query and append the (uninterpreted) string simple_query to it.
3789 * It is assumed that strings should be escaped to become SQL literals
3790 * (that is, what is in the query is actually ... '%s' ...)
3792 * See top of file for examples of both kinds of query.
3794 * "text" and "state" are supplied by readline.
3797 _complete_from_query(const char *simple_query,
3798 const SchemaQuery *schema_query,
3799 const char *text, int state)
3801 static int list_index,
3803 static PGresult *result = NULL;
3806 * If this is the first time for this completion, we fetch a list of our
3807 * "things" from the backend.
3811 PQExpBufferData query_buffer;
3814 char *e_info_charp2;
3815 const char *pstr = text;
3816 int char_length = 0;
3819 byte_length = strlen(text);
3822 * Count length as number of characters (not bytes), for passing to
3828 pstr += PQmblen(pstr, pset.encoding);
3831 /* Free any prior result */
3835 /* Set up suitably-escaped copies of textual inputs */
3836 e_text = escape_string(text);
3838 if (completion_info_charp)
3839 e_info_charp = escape_string(completion_info_charp);
3841 e_info_charp = NULL;
3843 if (completion_info_charp2)
3844 e_info_charp2 = escape_string(completion_info_charp2);
3846 e_info_charp2 = NULL;
3848 initPQExpBuffer(&query_buffer);
3852 /* schema_query gives us the pieces to assemble */
3853 const char *qualresult = schema_query->qualresult;
3855 if (qualresult == NULL)
3856 qualresult = schema_query->result;
3858 /* Get unqualified names matching the input-so-far */
3859 appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
3860 schema_query->result,
3861 schema_query->catname);
3862 if (schema_query->selcondition)
3863 appendPQExpBuffer(&query_buffer, "%s AND ",
3864 schema_query->selcondition);
3865 appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
3866 schema_query->result,
3867 char_length, e_text);
3868 appendPQExpBuffer(&query_buffer, " AND %s",
3869 schema_query->viscondition);
3872 * When fetching relation names, suppress system catalogs unless
3873 * the input-so-far begins with "pg_". This is a compromise
3874 * between not offering system catalogs for completion at all, and
3875 * having them swamp the result when the input is just "p".
3877 if (strcmp(schema_query->catname,
3878 "pg_catalog.pg_class c") == 0 &&
3879 strncmp(text, "pg_", 3) !=0)
3881 appendPQExpBufferStr(&query_buffer,
3882 " AND c.relnamespace <> (SELECT oid FROM"
3883 " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
3887 * Add in matching schema names, but only if there is more than
3888 * one potential match among schema names.
3890 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3891 "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
3892 "FROM pg_catalog.pg_namespace n "
3893 "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
3894 char_length, e_text);
3895 appendPQExpBuffer(&query_buffer,
3896 " AND (SELECT pg_catalog.count(*)"
3897 " FROM pg_catalog.pg_namespace"
3898 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3899 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
3900 char_length, e_text);
3903 * Add in matching qualified names, but only if there is exactly
3904 * one schema matching the input-so-far.
3906 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3907 "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
3908 "FROM %s, pg_catalog.pg_namespace n "
3909 "WHERE %s = n.oid AND ",
3911 schema_query->catname,
3912 schema_query->namespace);
3913 if (schema_query->selcondition)
3914 appendPQExpBuffer(&query_buffer, "%s AND ",
3915 schema_query->selcondition);
3916 appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
3918 char_length, e_text);
3921 * This condition exploits the single-matching-schema rule to
3922 * speed up the query
3924 appendPQExpBuffer(&query_buffer,
3925 " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
3926 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
3927 char_length, e_text);
3928 appendPQExpBuffer(&query_buffer,
3929 " AND (SELECT pg_catalog.count(*)"
3930 " FROM pg_catalog.pg_namespace"
3931 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3932 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
3933 char_length, e_text);
3935 /* If an addon query was provided, use it */
3937 appendPQExpBuffer(&query_buffer, "\n%s", simple_query);
3941 Assert(simple_query);
3942 /* simple_query is an sprintf-style format string */
3943 appendPQExpBuffer(&query_buffer, simple_query,
3944 char_length, e_text,
3945 e_info_charp, e_info_charp,
3946 e_info_charp2, e_info_charp2);
3949 /* Limit the number of records in the result */
3950 appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
3951 completion_max_records);
3953 result = exec_query(query_buffer.data);
3955 termPQExpBuffer(&query_buffer);
3960 free(e_info_charp2);
3963 /* Find something that matches */
3964 if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
3968 while (list_index < PQntuples(result) &&
3969 (item = PQgetvalue(result, list_index++, 0)))
3970 if (pg_strncasecmp(text, item, byte_length) == 0)
3971 return pg_strdup(item);
3974 /* If nothing matches, free the db structure and return null */
3982 * This function returns in order one of a fixed, NULL pointer terminated list
3983 * of strings (if matching). This can be used if there are only a fixed number
3984 * SQL words that can appear at certain spot.
3987 complete_from_list(const char *text, int state)
3989 static int string_length,
3992 static bool casesensitive;
3995 /* need to have a list */
3996 Assert(completion_charpp != NULL);
3998 /* Initialization */
4002 string_length = strlen(text);
4003 casesensitive = completion_case_sensitive;
4007 while ((item = completion_charpp[list_index++]))
4009 /* First pass is case sensitive */
4010 if (casesensitive && strncmp(text, item, string_length) == 0)
4013 return pg_strdup(item);
4016 /* Second pass is case insensitive, don't bother counting matches */
4017 if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
4019 if (completion_case_sensitive)
4020 return pg_strdup(item);
4024 * If case insensitive matching was requested initially,
4025 * adjust the case according to setting.
4027 return pg_strdup_keyword_case(item, text);
4032 * No matches found. If we're not case insensitive already, lets switch to
4033 * being case insensitive and try again
4035 if (casesensitive && matches == 0)
4037 casesensitive = false;
4040 return complete_from_list(text, state);
4043 /* If no more matches, return null. */
4049 * This function returns one fixed string the first time even if it doesn't
4050 * match what's there, and nothing the second time. This should be used if
4051 * there is only one possibility that can appear at a certain spot, so
4052 * misspellings will be overwritten. The string to be passed must be in
4056 complete_from_const(const char *text, int state)
4058 Assert(completion_charp != NULL);
4061 if (completion_case_sensitive)
4062 return pg_strdup(completion_charp);
4066 * If case insensitive matching was requested initially, adjust
4067 * the case according to setting.
4069 return pg_strdup_keyword_case(completion_charp, text);
4077 * This function appends the variable name with prefix and suffix to
4078 * the variable names array.
4081 append_variable_names(char ***varnames, int *nvars,
4082 int *maxvars, const char *varname,
4083 const char *prefix, const char *suffix)
4085 if (*nvars >= *maxvars)
4088 *varnames = (char **) pg_realloc(*varnames,
4089 ((*maxvars) + 1) * sizeof(char *));
4092 (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
4097 * This function supports completion with the name of a psql variable.
4098 * The variable names can be prefixed and suffixed with additional text
4099 * to support quoting usages. If need_value is true, only variables
4100 * that are currently set are included; otherwise, special variables
4101 * (those that have hooks) are included even if currently unset.
4104 complete_from_variables(const char *text, const char *prefix, const char *suffix,
4112 struct _variable *ptr;
4114 varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
4116 for (ptr = pset.vars->next; ptr; ptr = ptr->next)
4118 if (need_value && !(ptr->value))
4120 append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
4124 varnames[nvars] = NULL;
4125 COMPLETE_WITH_LIST_CS((const char *const *) varnames);
4127 for (i = 0; i < nvars; i++)
4136 * This function wraps rl_filename_completion_function() to strip quotes from
4137 * the input before searching for matches and to quote any matches for which
4138 * the consuming command will require it.
4141 complete_from_files(const char *text, int state)
4143 static const char *unquoted_text;
4144 char *unquoted_match;
4149 /* Initialization: stash the unquoted input. */
4150 unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
4151 false, true, pset.encoding);
4152 /* expect a NULL return for the empty string only */
4155 Assert(*text == '\0');
4156 unquoted_text = text;
4160 unquoted_match = filename_completion_function(unquoted_text, state);
4164 * Caller sets completion_charp to a zero- or one-character string
4165 * containing the escape character. This is necessary since \copy has
4166 * no escape character, but every other backslash command recognizes
4167 * "\" as an escape character. Since we have only two callers, don't
4168 * bother providing a macro to simplify this.
4170 ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
4171 '\'', *completion_charp, pset.encoding);
4173 free(unquoted_match);
4175 ret = unquoted_match;
4182 /* HELPER FUNCTIONS */
4186 * Make a pg_strdup copy of s and convert the case according to
4187 * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
4190 pg_strdup_keyword_case(const char *s, const char *ref)
4194 unsigned char first = ref[0];
4198 if (pset.comp_case == PSQL_COMP_CASE_LOWER ||
4199 ((pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER ||
4200 pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
4201 (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
4203 for (p = ret; *p; p++)
4204 *p = pg_tolower((unsigned char) *p);
4208 for (p = ret; *p; p++)
4209 *p = pg_toupper((unsigned char) *p);
4217 * escape_string - Escape argument for use as string literal.
4219 * The returned value has to be freed.
4222 escape_string(const char *text)
4227 text_length = strlen(text);
4229 result = pg_malloc(text_length * 2 + 1);
4230 PQescapeStringConn(pset.db, result, text, text_length, NULL);
4237 * Execute a query and report any errors. This should be the preferred way of
4238 * talking to the database in this file.
4241 exec_query(const char *query)
4245 if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
4248 result = PQexec(pset.db, query);
4250 if (PQresultStatus(result) != PGRES_TUPLES_OK)
4253 psql_error("tab completion query failed: %s\nQuery was:\n%s\n",
4254 PQerrorMessage(pset.db), query);
4265 * Parse all the word(s) before point.
4267 * Returns a malloc'd array of character pointers that point into the malloc'd
4268 * data array returned to *buffer; caller must free() both of these when done.
4269 * *nwords receives the number of words found, ie, the valid length of the
4272 * Words are returned right to left, that is, previous_words[0] gets the last
4273 * word before point, previous_words[1] the next-to-last, etc.
4276 get_previous_words(int point, char **buffer, int *nwords)
4278 char **previous_words;
4281 int words_found = 0;
4285 * If we have anything in tab_completion_query_buf, paste it together with
4286 * rl_line_buffer to construct the full query. Otherwise we can just use
4287 * rl_line_buffer as the input string.
4289 if (tab_completion_query_buf && tab_completion_query_buf->len > 0)
4291 i = tab_completion_query_buf->len;
4292 buf = pg_malloc(point + i + 2);
4293 memcpy(buf, tab_completion_query_buf->data, i);
4295 memcpy(buf + i, rl_line_buffer, point);
4298 /* Readjust point to reference appropriate offset in buf */
4302 buf = rl_line_buffer;
4305 * Allocate an array of string pointers and a buffer to hold the strings
4306 * themselves. The worst case is that the line contains only
4307 * non-whitespace WORD_BREAKS characters, making each one a separate word.
4308 * This is usually much more space than we need, but it's cheaper than
4309 * doing a separate malloc() for each word.
4311 previous_words = (char **) pg_malloc(point * sizeof(char *));
4312 *buffer = outptr = (char *) pg_malloc(point * 2);
4315 * First we look for a non-word char before the current point. (This is
4316 * probably useless, if readline is on the same page as we are about what
4317 * is a word, but if so it's cheap.)
4319 for (i = point - 1; i >= 0; i--)
4321 if (strchr(WORD_BREAKS, buf[i]))
4327 * Now parse words, working backwards, until we hit start of line. The
4328 * backwards scan has some interesting but intentional properties
4329 * concerning parenthesis handling.
4335 bool inquotes = false;
4336 int parentheses = 0;
4338 /* now find the first non-space which then constitutes the end */
4340 for (i = point; i >= 0; i--)
4342 if (!isspace((unsigned char) buf[i]))
4348 /* if no end found, we're done */
4353 * Otherwise we now look for the start. The start is either the last
4354 * character before any word-break character going backwards from the
4355 * end, or it's simply character 0. We also handle open quotes and
4358 for (start = end; start > 0; start--)
4360 if (buf[start] == '"')
4361 inquotes = !inquotes;
4364 if (buf[start] == ')')
4366 else if (buf[start] == '(')
4368 if (--parentheses <= 0)
4371 else if (parentheses == 0 &&
4372 strchr(WORD_BREAKS, buf[start - 1]))
4377 /* Return the word located at start to end inclusive */
4378 previous_words[words_found++] = outptr;
4379 i = end - start + 1;
4380 memcpy(outptr, &buf[start], i);
4384 /* Continue searching */
4388 /* Release parsing input workspace, if we made one above */
4389 if (buf != rl_line_buffer)
4392 *nwords = words_found;
4393 return previous_words;
4397 * Look up the type for the GUC variable with the passed name.
4399 * Returns NULL if the variable is unknown. Otherwise the returned string,
4400 * containing the type, has to be freed.
4403 get_guctype(const char *varname)
4405 PQExpBufferData query_buffer;
4408 char *guctype = NULL;
4410 e_varname = escape_string(varname);
4412 initPQExpBuffer(&query_buffer);
4413 appendPQExpBuffer(&query_buffer,
4414 "SELECT vartype FROM pg_catalog.pg_settings "
4415 "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4418 result = exec_query(query_buffer.data);
4419 termPQExpBuffer(&query_buffer);
4422 if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
4423 guctype = pg_strdup(PQgetvalue(result, 0, 0));
4433 * Surround a string with single quotes. This works for both SQL and
4434 * psql internal. Currently disabled because it is reported not to
4435 * cooperate with certain versions of readline.
4438 quote_file_name(char *text, int match_type, char *quote_pointer)
4443 (void) quote_pointer; /* not used */
4445 length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
4446 s = pg_malloc(length);
4448 strcpy(s + 1, text);
4449 if (match_type == SINGLE_MATCH)
4450 s[length - 2] = '\'';
4451 s[length - 1] = '\0';
4456 dequote_file_name(char *text, char quote_char)
4462 return pg_strdup(text);
4464 length = strlen(text);
4465 s = pg_malloc(length - 2 + 1);
4466 strlcpy(s, text +1, length - 2 + 1);
4470 #endif /* NOT_USED */
4472 #endif /* USE_READLINE */