2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2017, 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 "pqexpbuffer.h"
47 #include "stringutils.h"
49 #ifdef HAVE_RL_FILENAME_COMPLETION_FUNCTION
50 #define filename_completion_function rl_filename_completion_function
52 /* missing in some header files */
53 extern char *filename_completion_function();
56 #ifdef HAVE_RL_COMPLETION_MATCHES
57 #define completion_matches rl_completion_matches
60 /* word break characters */
61 #define WORD_BREAKS "\t\n@$><=;|&{() "
64 * Since readline doesn't let us pass any state through to the tab completion
65 * callback, we have to use this global variable to let get_previous_words()
66 * get at the previous lines of the current command. Ick.
68 PQExpBuffer tab_completion_query_buf = NULL;
71 * This struct is used to define "schema queries", which are custom-built
72 * to obtain possibly-schema-qualified names of database objects. There is
73 * enough similarity in the structure that we don't want to repeat it each
74 * time. So we put the components of each query into this struct and
75 * assemble them with the common boilerplate in _complete_from_query().
77 typedef struct SchemaQuery
80 * Name of catalog or catalogs to be queried, with alias, eg.
81 * "pg_catalog.pg_class c". Note that "pg_namespace n" will be added.
86 * Selection condition --- only rows meeting this condition are candidates
87 * to display. If catname mentions multiple tables, include the necessary
88 * join condition here. For example, "c.relkind = 'r'". Write NULL (not
89 * an empty string) if not needed.
91 const char *selcondition;
94 * Visibility condition --- which rows are visible without schema
95 * qualification? For example, "pg_catalog.pg_table_is_visible(c.oid)".
97 const char *viscondition;
100 * Namespace --- name of field to join to pg_namespace.oid. For example,
103 const char *namespace;
106 * Result --- the appropriately-quoted name to return, in the case of an
107 * unqualified name. For example, "pg_catalog.quote_ident(c.relname)".
112 * In some cases a different result must be used for qualified names.
113 * Enter that here, or write NULL if result can be used.
115 const char *qualresult;
119 /* Store maximum number of records we want from database queries
120 * (implemented via SELECT ... LIMIT xx).
122 static int completion_max_records;
125 * Communication variables set by COMPLETE_WITH_FOO macros and then used by
126 * the completion callback functions. Ugly but there is no better way.
128 static const char *completion_charp; /* to pass a string */
129 static const char *const * completion_charpp; /* to pass a list of strings */
130 static const char *completion_info_charp; /* to pass a second string */
131 static const char *completion_info_charp2; /* to pass a third string */
132 static const SchemaQuery *completion_squery; /* to pass a SchemaQuery */
133 static bool completion_case_sensitive; /* completion is case sensitive */
136 * A few macros to ease typing. You can use these to complete the given
138 * 1) The results from a query you pass it. (Perhaps one of those below?)
139 * 2) The results from a schema query you pass it.
140 * 3) The items from a null-pointer-terminated list (with or without
141 * case-sensitive comparison; see also COMPLETE_WITH_LISTn, below).
142 * 4) A string constant.
143 * 5) The list of attributes of the given table (possibly schema-qualified).
144 * 6/ The list of arguments to the given function (possibly schema-qualified).
146 #define COMPLETE_WITH_QUERY(query) \
148 completion_charp = query; \
149 matches = completion_matches(text, complete_from_query); \
152 #define COMPLETE_WITH_SCHEMA_QUERY(query, addon) \
154 completion_squery = &(query); \
155 completion_charp = addon; \
156 matches = completion_matches(text, complete_from_schema_query); \
159 #define COMPLETE_WITH_LIST_CS(list) \
161 completion_charpp = list; \
162 completion_case_sensitive = true; \
163 matches = completion_matches(text, complete_from_list); \
166 #define COMPLETE_WITH_LIST(list) \
168 completion_charpp = list; \
169 completion_case_sensitive = false; \
170 matches = completion_matches(text, complete_from_list); \
173 #define COMPLETE_WITH_CONST(string) \
175 completion_charp = string; \
176 completion_case_sensitive = false; \
177 matches = completion_matches(text, complete_from_const); \
180 #define COMPLETE_WITH_ATTR(relation, addon) \
182 char *_completion_schema; \
183 char *_completion_table; \
185 _completion_schema = strtokx(relation, " \t\n\r", ".", "\"", 0, \
186 false, false, pset.encoding); \
187 (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
188 false, false, pset.encoding); \
189 _completion_table = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
190 false, false, pset.encoding); \
191 if (_completion_table == NULL) \
193 completion_charp = Query_for_list_of_attributes addon; \
194 completion_info_charp = relation; \
198 completion_charp = Query_for_list_of_attributes_with_schema addon; \
199 completion_info_charp = _completion_table; \
200 completion_info_charp2 = _completion_schema; \
202 matches = completion_matches(text, complete_from_query); \
205 #define COMPLETE_WITH_ENUM_VALUE(type) \
207 char *_completion_schema; \
208 char *_completion_type; \
210 _completion_schema = strtokx(type, " \t\n\r", ".", "\"", 0, \
211 false, false, pset.encoding); \
212 (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
213 false, false, pset.encoding); \
214 _completion_type = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
215 false, false, pset.encoding); \
216 if (_completion_type == NULL)\
218 completion_charp = Query_for_list_of_enum_values; \
219 completion_info_charp = type; \
223 completion_charp = Query_for_list_of_enum_values_with_schema; \
224 completion_info_charp = _completion_type; \
225 completion_info_charp2 = _completion_schema; \
227 matches = completion_matches(text, complete_from_query); \
230 #define COMPLETE_WITH_FUNCTION_ARG(function) \
232 char *_completion_schema; \
233 char *_completion_function; \
235 _completion_schema = strtokx(function, " \t\n\r", ".", "\"", 0, \
236 false, false, pset.encoding); \
237 (void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
238 false, false, pset.encoding); \
239 _completion_function = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
240 false, false, pset.encoding); \
241 if (_completion_function == NULL) \
243 completion_charp = Query_for_list_of_arguments; \
244 completion_info_charp = function; \
248 completion_charp = Query_for_list_of_arguments_with_schema; \
249 completion_info_charp = _completion_function; \
250 completion_info_charp2 = _completion_schema; \
252 matches = completion_matches(text, complete_from_query); \
256 * These macros simplify use of COMPLETE_WITH_LIST for short, fixed lists.
257 * There is no COMPLETE_WITH_LIST1; use COMPLETE_WITH_CONST for that case.
259 #define COMPLETE_WITH_LIST2(s1, s2) \
261 static const char *const list[] = { s1, s2, NULL }; \
262 COMPLETE_WITH_LIST(list); \
265 #define COMPLETE_WITH_LIST3(s1, s2, s3) \
267 static const char *const list[] = { s1, s2, s3, NULL }; \
268 COMPLETE_WITH_LIST(list); \
271 #define COMPLETE_WITH_LIST4(s1, s2, s3, s4) \
273 static const char *const list[] = { s1, s2, s3, s4, NULL }; \
274 COMPLETE_WITH_LIST(list); \
277 #define COMPLETE_WITH_LIST5(s1, s2, s3, s4, s5) \
279 static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \
280 COMPLETE_WITH_LIST(list); \
283 #define COMPLETE_WITH_LIST6(s1, s2, s3, s4, s5, s6) \
285 static const char *const list[] = { s1, s2, s3, s4, s5, s6, NULL }; \
286 COMPLETE_WITH_LIST(list); \
289 #define COMPLETE_WITH_LIST7(s1, s2, s3, s4, s5, s6, s7) \
291 static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, NULL }; \
292 COMPLETE_WITH_LIST(list); \
295 #define COMPLETE_WITH_LIST8(s1, s2, s3, s4, s5, s6, s7, s8) \
297 static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, NULL }; \
298 COMPLETE_WITH_LIST(list); \
301 #define COMPLETE_WITH_LIST9(s1, s2, s3, s4, s5, s6, s7, s8, s9) \
303 static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, NULL }; \
304 COMPLETE_WITH_LIST(list); \
307 #define COMPLETE_WITH_LIST10(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \
309 static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, NULL }; \
310 COMPLETE_WITH_LIST(list); \
314 * Likewise for COMPLETE_WITH_LIST_CS.
316 #define COMPLETE_WITH_LIST_CS2(s1, s2) \
318 static const char *const list[] = { s1, s2, NULL }; \
319 COMPLETE_WITH_LIST_CS(list); \
322 #define COMPLETE_WITH_LIST_CS3(s1, s2, s3) \
324 static const char *const list[] = { s1, s2, s3, NULL }; \
325 COMPLETE_WITH_LIST_CS(list); \
328 #define COMPLETE_WITH_LIST_CS4(s1, s2, s3, s4) \
330 static const char *const list[] = { s1, s2, s3, s4, NULL }; \
331 COMPLETE_WITH_LIST_CS(list); \
334 #define COMPLETE_WITH_LIST_CS5(s1, s2, s3, s4, s5) \
336 static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \
337 COMPLETE_WITH_LIST_CS(list); \
341 * Assembly instructions for schema queries
344 static const SchemaQuery Query_for_list_of_aggregates = {
346 "pg_catalog.pg_proc p",
350 "pg_catalog.pg_function_is_visible(p.oid)",
354 "pg_catalog.quote_ident(p.proname)",
359 static const SchemaQuery Query_for_list_of_datatypes = {
361 "pg_catalog.pg_type t",
362 /* selcondition --- ignore table rowtypes and array types */
364 " OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) "
365 "AND t.typname !~ '^_'",
367 "pg_catalog.pg_type_is_visible(t.oid)",
371 "pg_catalog.format_type(t.oid, NULL)",
373 "pg_catalog.quote_ident(t.typname)"
376 static const SchemaQuery Query_for_list_of_domains = {
378 "pg_catalog.pg_type t",
382 "pg_catalog.pg_type_is_visible(t.oid)",
386 "pg_catalog.quote_ident(t.typname)",
391 static const SchemaQuery Query_for_list_of_functions = {
393 "pg_catalog.pg_proc p",
397 "pg_catalog.pg_function_is_visible(p.oid)",
401 "pg_catalog.quote_ident(p.proname)",
406 static const SchemaQuery Query_for_list_of_indexes = {
408 "pg_catalog.pg_class c",
410 "c.relkind IN ('i')",
412 "pg_catalog.pg_table_is_visible(c.oid)",
416 "pg_catalog.quote_ident(c.relname)",
421 static const SchemaQuery Query_for_list_of_sequences = {
423 "pg_catalog.pg_class c",
425 "c.relkind IN ('S')",
427 "pg_catalog.pg_table_is_visible(c.oid)",
431 "pg_catalog.quote_ident(c.relname)",
436 static const SchemaQuery Query_for_list_of_foreign_tables = {
438 "pg_catalog.pg_class c",
440 "c.relkind IN ('f')",
442 "pg_catalog.pg_table_is_visible(c.oid)",
446 "pg_catalog.quote_ident(c.relname)",
451 static const SchemaQuery Query_for_list_of_tables = {
453 "pg_catalog.pg_class c",
455 "c.relkind IN ('r', 'P')",
457 "pg_catalog.pg_table_is_visible(c.oid)",
461 "pg_catalog.quote_ident(c.relname)",
466 static const SchemaQuery Query_for_list_of_constraints_with_schema = {
468 "pg_catalog.pg_constraint c",
472 "true", /* there is no pg_constraint_is_visible */
476 "pg_catalog.quote_ident(c.conname)",
481 /* Relations supporting INSERT, UPDATE or DELETE */
482 static const SchemaQuery Query_for_list_of_updatables = {
484 "pg_catalog.pg_class c",
486 "c.relkind IN ('r', 'f', 'v', 'P')",
488 "pg_catalog.pg_table_is_visible(c.oid)",
492 "pg_catalog.quote_ident(c.relname)",
497 static const SchemaQuery Query_for_list_of_relations = {
499 "pg_catalog.pg_class c",
503 "pg_catalog.pg_table_is_visible(c.oid)",
507 "pg_catalog.quote_ident(c.relname)",
512 static const SchemaQuery Query_for_list_of_tsvmf = {
514 "pg_catalog.pg_class c",
516 "c.relkind IN ('r', 'S', 'v', 'm', 'f', 'P')",
518 "pg_catalog.pg_table_is_visible(c.oid)",
522 "pg_catalog.quote_ident(c.relname)",
527 static const SchemaQuery Query_for_list_of_tmf = {
529 "pg_catalog.pg_class c",
531 "c.relkind IN ('r', 'm', 'f')",
533 "pg_catalog.pg_table_is_visible(c.oid)",
537 "pg_catalog.quote_ident(c.relname)",
542 static const SchemaQuery Query_for_list_of_tm = {
544 "pg_catalog.pg_class c",
546 "c.relkind IN ('r', 'm')",
548 "pg_catalog.pg_table_is_visible(c.oid)",
552 "pg_catalog.quote_ident(c.relname)",
557 static const SchemaQuery Query_for_list_of_views = {
559 "pg_catalog.pg_class c",
561 "c.relkind IN ('v')",
563 "pg_catalog.pg_table_is_visible(c.oid)",
567 "pg_catalog.quote_ident(c.relname)",
572 static const SchemaQuery Query_for_list_of_matviews = {
574 "pg_catalog.pg_class c",
576 "c.relkind IN ('m')",
578 "pg_catalog.pg_table_is_visible(c.oid)",
582 "pg_catalog.quote_ident(c.relname)",
589 * Queries to get lists of names of various kinds of things, possibly
590 * restricted to names matching a partially entered name. In these queries,
591 * the first %s will be replaced by the text entered so far (suitably escaped
592 * to become a SQL literal string). %d will be replaced by the length of the
593 * string (in unescaped form). A second and third %s, if present, will be
594 * replaced by a suitably-escaped version of the string provided in
595 * completion_info_charp. A fourth and fifth %s are similarly replaced by
596 * completion_info_charp2.
598 * Beware that the allowed sequences of %s and %d are determined by
599 * _complete_from_query().
602 #define Query_for_list_of_attributes \
603 "SELECT pg_catalog.quote_ident(attname) "\
604 " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\
605 " WHERE c.oid = a.attrelid "\
606 " AND a.attnum > 0 "\
607 " AND NOT a.attisdropped "\
608 " AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\
609 " AND (pg_catalog.quote_ident(relname)='%s' "\
610 " OR '\"' || relname || '\"'='%s') "\
611 " AND pg_catalog.pg_table_is_visible(c.oid)"
613 #define Query_for_list_of_attributes_with_schema \
614 "SELECT pg_catalog.quote_ident(attname) "\
615 " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c, pg_catalog.pg_namespace n "\
616 " WHERE c.oid = a.attrelid "\
617 " AND n.oid = c.relnamespace "\
618 " AND a.attnum > 0 "\
619 " AND NOT a.attisdropped "\
620 " AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\
621 " AND (pg_catalog.quote_ident(relname)='%s' "\
622 " OR '\"' || relname || '\"' ='%s') "\
623 " AND (pg_catalog.quote_ident(nspname)='%s' "\
624 " OR '\"' || nspname || '\"' ='%s') "
626 #define Query_for_list_of_enum_values \
627 "SELECT pg_catalog.quote_literal(enumlabel) "\
628 " FROM pg_catalog.pg_enum e, pg_catalog.pg_type t "\
629 " WHERE t.oid = e.enumtypid "\
630 " AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
631 " AND (pg_catalog.quote_ident(typname)='%s' "\
632 " OR '\"' || typname || '\"'='%s') "\
633 " AND pg_catalog.pg_type_is_visible(t.oid)"
635 #define Query_for_list_of_enum_values_with_schema \
636 "SELECT pg_catalog.quote_literal(enumlabel) "\
637 " FROM pg_catalog.pg_enum e, pg_catalog.pg_type t, pg_catalog.pg_namespace n "\
638 " WHERE t.oid = e.enumtypid "\
639 " AND n.oid = t.typnamespace "\
640 " AND substring(pg_catalog.quote_literal(enumlabel),1,%d)='%s' "\
641 " AND (pg_catalog.quote_ident(typname)='%s' "\
642 " OR '\"' || typname || '\"'='%s') "\
643 " AND (pg_catalog.quote_ident(nspname)='%s' "\
644 " OR '\"' || nspname || '\"' ='%s') "
646 #define Query_for_list_of_template_databases \
647 "SELECT pg_catalog.quote_ident(d.datname) "\
648 " FROM pg_catalog.pg_database d "\
649 " WHERE substring(pg_catalog.quote_ident(d.datname),1,%d)='%s' "\
650 " AND (d.datistemplate OR pg_catalog.pg_has_role(d.datdba, 'USAGE'))"
652 #define Query_for_list_of_databases \
653 "SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\
654 " WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'"
656 #define Query_for_list_of_tablespaces \
657 "SELECT pg_catalog.quote_ident(spcname) FROM pg_catalog.pg_tablespace "\
658 " WHERE substring(pg_catalog.quote_ident(spcname),1,%d)='%s'"
660 #define Query_for_list_of_encodings \
661 " SELECT DISTINCT pg_catalog.pg_encoding_to_char(conforencoding) "\
662 " FROM pg_catalog.pg_conversion "\
663 " WHERE substring(pg_catalog.pg_encoding_to_char(conforencoding),1,%d)=UPPER('%s')"
665 #define Query_for_list_of_languages \
666 "SELECT pg_catalog.quote_ident(lanname) "\
667 " FROM pg_catalog.pg_language "\
668 " WHERE lanname != 'internal' "\
669 " AND substring(pg_catalog.quote_ident(lanname),1,%d)='%s'"
671 #define Query_for_list_of_schemas \
672 "SELECT pg_catalog.quote_ident(nspname) FROM pg_catalog.pg_namespace "\
673 " WHERE substring(pg_catalog.quote_ident(nspname),1,%d)='%s'"
675 #define Query_for_list_of_alter_system_set_vars \
677 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
678 " WHERE context != 'internal' "\
679 " UNION ALL SELECT 'all') ss "\
680 " WHERE substring(name,1,%d)='%s'"
682 #define Query_for_list_of_set_vars \
684 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
685 " WHERE context IN ('user', 'superuser') "\
686 " UNION ALL SELECT 'constraints' "\
687 " UNION ALL SELECT 'transaction' "\
688 " UNION ALL SELECT 'session' "\
689 " UNION ALL SELECT 'role' "\
690 " UNION ALL SELECT 'tablespace' "\
691 " UNION ALL SELECT 'all') ss "\
692 " WHERE substring(name,1,%d)='%s'"
694 #define Query_for_list_of_show_vars \
696 " (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\
697 " UNION ALL SELECT 'session authorization' "\
698 " UNION ALL SELECT 'all') ss "\
699 " WHERE substring(name,1,%d)='%s'"
701 #define Query_for_list_of_roles \
702 " SELECT pg_catalog.quote_ident(rolname) "\
703 " FROM pg_catalog.pg_roles "\
704 " WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"
706 #define Query_for_list_of_grant_roles \
707 " SELECT pg_catalog.quote_ident(rolname) "\
708 " FROM pg_catalog.pg_roles "\
709 " WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\
710 " UNION ALL SELECT 'PUBLIC'"\
711 " UNION ALL SELECT 'CURRENT_USER'"\
712 " UNION ALL SELECT 'SESSION_USER'"
714 /* the silly-looking length condition is just to eat up the current word */
715 #define Query_for_table_owning_index \
716 "SELECT pg_catalog.quote_ident(c1.relname) "\
717 " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
718 " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
719 " and (%d = pg_catalog.length('%s'))"\
720 " and pg_catalog.quote_ident(c2.relname)='%s'"\
721 " and pg_catalog.pg_table_is_visible(c2.oid)"
723 /* the silly-looking length condition is just to eat up the current word */
724 #define Query_for_index_of_table \
725 "SELECT pg_catalog.quote_ident(c2.relname) "\
726 " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
727 " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
728 " and (%d = pg_catalog.length('%s'))"\
729 " and pg_catalog.quote_ident(c1.relname)='%s'"\
730 " and pg_catalog.pg_table_is_visible(c2.oid)"
732 /* the silly-looking length condition is just to eat up the current word */
733 #define Query_for_constraint_of_table \
734 "SELECT pg_catalog.quote_ident(conname) "\
735 " FROM pg_catalog.pg_class c1, pg_catalog.pg_constraint con "\
736 " WHERE c1.oid=conrelid and (%d = pg_catalog.length('%s'))"\
737 " and pg_catalog.quote_ident(c1.relname)='%s'"\
738 " and pg_catalog.pg_table_is_visible(c1.oid)"
740 #define Query_for_all_table_constraints \
741 "SELECT pg_catalog.quote_ident(conname) "\
742 " FROM pg_catalog.pg_constraint c "\
743 " WHERE c.conrelid <> 0 "
745 /* the silly-looking length condition is just to eat up the current word */
746 #define Query_for_constraint_of_type \
747 "SELECT pg_catalog.quote_ident(conname) "\
748 " FROM pg_catalog.pg_type t, pg_catalog.pg_constraint con "\
749 " WHERE t.oid=contypid and (%d = pg_catalog.length('%s'))"\
750 " and pg_catalog.quote_ident(t.typname)='%s'"\
751 " and pg_catalog.pg_type_is_visible(t.oid)"
753 /* the silly-looking length condition is just to eat up the current word */
754 #define Query_for_list_of_tables_for_constraint \
755 "SELECT pg_catalog.quote_ident(relname) "\
756 " FROM pg_catalog.pg_class"\
757 " WHERE (%d = pg_catalog.length('%s'))"\
759 " (SELECT conrelid FROM pg_catalog.pg_constraint "\
760 " WHERE pg_catalog.quote_ident(conname)='%s')"
762 /* the silly-looking length condition is just to eat up the current word */
763 #define Query_for_rule_of_table \
764 "SELECT pg_catalog.quote_ident(rulename) "\
765 " FROM pg_catalog.pg_class c1, pg_catalog.pg_rewrite "\
766 " WHERE c1.oid=ev_class and (%d = pg_catalog.length('%s'))"\
767 " and pg_catalog.quote_ident(c1.relname)='%s'"\
768 " and pg_catalog.pg_table_is_visible(c1.oid)"
770 /* the silly-looking length condition is just to eat up the current word */
771 #define Query_for_list_of_tables_for_rule \
772 "SELECT pg_catalog.quote_ident(relname) "\
773 " FROM pg_catalog.pg_class"\
774 " WHERE (%d = pg_catalog.length('%s'))"\
776 " (SELECT ev_class FROM pg_catalog.pg_rewrite "\
777 " WHERE pg_catalog.quote_ident(rulename)='%s')"
779 /* the silly-looking length condition is just to eat up the current word */
780 #define Query_for_trigger_of_table \
781 "SELECT pg_catalog.quote_ident(tgname) "\
782 " FROM pg_catalog.pg_class c1, pg_catalog.pg_trigger "\
783 " WHERE c1.oid=tgrelid and (%d = pg_catalog.length('%s'))"\
784 " and pg_catalog.quote_ident(c1.relname)='%s'"\
785 " and pg_catalog.pg_table_is_visible(c1.oid)"\
786 " and not tgisinternal"
788 /* the silly-looking length condition is just to eat up the current word */
789 #define Query_for_list_of_tables_for_trigger \
790 "SELECT pg_catalog.quote_ident(relname) "\
791 " FROM pg_catalog.pg_class"\
792 " WHERE (%d = pg_catalog.length('%s'))"\
794 " (SELECT tgrelid FROM pg_catalog.pg_trigger "\
795 " WHERE pg_catalog.quote_ident(tgname)='%s')"
797 #define Query_for_list_of_ts_configurations \
798 "SELECT pg_catalog.quote_ident(cfgname) FROM pg_catalog.pg_ts_config "\
799 " WHERE substring(pg_catalog.quote_ident(cfgname),1,%d)='%s'"
801 #define Query_for_list_of_ts_dictionaries \
802 "SELECT pg_catalog.quote_ident(dictname) FROM pg_catalog.pg_ts_dict "\
803 " WHERE substring(pg_catalog.quote_ident(dictname),1,%d)='%s'"
805 #define Query_for_list_of_ts_parsers \
806 "SELECT pg_catalog.quote_ident(prsname) FROM pg_catalog.pg_ts_parser "\
807 " WHERE substring(pg_catalog.quote_ident(prsname),1,%d)='%s'"
809 #define Query_for_list_of_ts_templates \
810 "SELECT pg_catalog.quote_ident(tmplname) FROM pg_catalog.pg_ts_template "\
811 " WHERE substring(pg_catalog.quote_ident(tmplname),1,%d)='%s'"
813 #define Query_for_list_of_fdws \
814 " SELECT pg_catalog.quote_ident(fdwname) "\
815 " FROM pg_catalog.pg_foreign_data_wrapper "\
816 " WHERE substring(pg_catalog.quote_ident(fdwname),1,%d)='%s'"
818 #define Query_for_list_of_servers \
819 " SELECT pg_catalog.quote_ident(srvname) "\
820 " FROM pg_catalog.pg_foreign_server "\
821 " WHERE substring(pg_catalog.quote_ident(srvname),1,%d)='%s'"
823 #define Query_for_list_of_user_mappings \
824 " SELECT pg_catalog.quote_ident(usename) "\
825 " FROM pg_catalog.pg_user_mappings "\
826 " WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'"
828 #define Query_for_list_of_access_methods \
829 " SELECT pg_catalog.quote_ident(amname) "\
830 " FROM pg_catalog.pg_am "\
831 " WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'"
833 /* the silly-looking length condition is just to eat up the current word */
834 #define Query_for_list_of_arguments \
835 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
836 " FROM pg_catalog.pg_proc "\
837 " WHERE (%d = pg_catalog.length('%s'))"\
838 " AND (pg_catalog.quote_ident(proname)='%s'"\
839 " OR '\"' || proname || '\"'='%s') "\
840 " AND (pg_catalog.pg_function_is_visible(pg_proc.oid))"
842 /* the silly-looking length condition is just to eat up the current word */
843 #define Query_for_list_of_arguments_with_schema \
844 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
845 " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "\
846 " WHERE (%d = pg_catalog.length('%s'))"\
847 " AND n.oid = p.pronamespace "\
848 " AND (pg_catalog.quote_ident(proname)='%s' "\
849 " OR '\"' || proname || '\"' ='%s') "\
850 " AND (pg_catalog.quote_ident(nspname)='%s' "\
851 " OR '\"' || nspname || '\"' ='%s') "
853 #define Query_for_list_of_extensions \
854 " SELECT pg_catalog.quote_ident(extname) "\
855 " FROM pg_catalog.pg_extension "\
856 " WHERE substring(pg_catalog.quote_ident(extname),1,%d)='%s'"
858 #define Query_for_list_of_available_extensions \
859 " SELECT pg_catalog.quote_ident(name) "\
860 " FROM pg_catalog.pg_available_extensions "\
861 " WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s' AND installed_version IS NULL"
863 /* the silly-looking length condition is just to eat up the current word */
864 #define Query_for_list_of_available_extension_versions \
865 " SELECT pg_catalog.quote_ident(version) "\
866 " FROM pg_catalog.pg_available_extension_versions "\
867 " WHERE (%d = pg_catalog.length('%s'))"\
868 " AND pg_catalog.quote_ident(name)='%s'"
870 /* the silly-looking length condition is just to eat up the current word */
871 #define Query_for_list_of_available_extension_versions_with_TO \
872 " SELECT 'TO ' || pg_catalog.quote_ident(version) "\
873 " FROM pg_catalog.pg_available_extension_versions "\
874 " WHERE (%d = pg_catalog.length('%s'))"\
875 " AND pg_catalog.quote_ident(name)='%s'"
877 #define Query_for_list_of_prepared_statements \
878 " SELECT pg_catalog.quote_ident(name) "\
879 " FROM pg_catalog.pg_prepared_statements "\
880 " WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s'"
882 #define Query_for_list_of_event_triggers \
883 " SELECT pg_catalog.quote_ident(evtname) "\
884 " FROM pg_catalog.pg_event_trigger "\
885 " WHERE substring(pg_catalog.quote_ident(evtname),1,%d)='%s'"
887 #define Query_for_list_of_tablesample_methods \
888 " SELECT pg_catalog.quote_ident(proname) "\
889 " FROM pg_catalog.pg_proc "\
890 " WHERE prorettype = 'pg_catalog.tsm_handler'::pg_catalog.regtype AND "\
891 " proargtypes[0] = 'pg_catalog.internal'::pg_catalog.regtype AND "\
892 " substring(pg_catalog.quote_ident(proname),1,%d)='%s'"
894 #define Query_for_list_of_policies \
895 " SELECT pg_catalog.quote_ident(polname) "\
896 " FROM pg_catalog.pg_policy "\
897 " WHERE substring(pg_catalog.quote_ident(polname),1,%d)='%s'"
899 #define Query_for_list_of_tables_for_policy \
900 "SELECT pg_catalog.quote_ident(relname) "\
901 " FROM pg_catalog.pg_class"\
902 " WHERE (%d = pg_catalog.length('%s'))"\
904 " (SELECT polrelid FROM pg_catalog.pg_policy "\
905 " WHERE pg_catalog.quote_ident(polname)='%s')"
907 #define Query_for_enum \
908 " SELECT name FROM ( "\
909 " SELECT pg_catalog.quote_ident(pg_catalog.unnest(enumvals)) AS name "\
910 " FROM pg_catalog.pg_settings "\
911 " WHERE pg_catalog.lower(name)=pg_catalog.lower('%s') "\
913 " SELECT 'DEFAULT' ) ss "\
914 " WHERE pg_catalog.substring(name,1,%%d)='%%s'"
917 * This is a list of all "things" in Pgsql, which can show up after CREATE or
918 * DROP; and there is also a query to get a list of them.
924 const char *query; /* simple query, or NULL */
925 const SchemaQuery *squery; /* schema query, or NULL */
926 const bits32 flags; /* visibility flags, see below */
929 #define THING_NO_CREATE (1 << 0) /* should not show up after CREATE */
930 #define THING_NO_DROP (1 << 1) /* should not show up after DROP */
931 #define THING_NO_SHOW (THING_NO_CREATE | THING_NO_DROP)
933 static const pgsql_thing_t words_after_create[] = {
934 {"ACCESS METHOD", NULL, NULL},
935 {"AGGREGATE", NULL, &Query_for_list_of_aggregates},
936 {"CAST", NULL, NULL}, /* Casts have complex structures for names, so
938 {"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'"},
941 * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
942 * to be used only by pg_dump.
944 {"CONFIGURATION", Query_for_list_of_ts_configurations, NULL, THING_NO_SHOW},
945 {"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"},
946 {"DATABASE", Query_for_list_of_databases},
947 {"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, THING_NO_SHOW},
948 {"DOMAIN", NULL, &Query_for_list_of_domains},
949 {"EVENT TRIGGER", NULL, NULL},
950 {"EXTENSION", Query_for_list_of_extensions},
951 {"FOREIGN DATA WRAPPER", NULL, NULL},
952 {"FOREIGN TABLE", NULL, NULL},
953 {"FUNCTION", NULL, &Query_for_list_of_functions},
954 {"GROUP", Query_for_list_of_roles},
955 {"LANGUAGE", Query_for_list_of_languages},
956 {"INDEX", NULL, &Query_for_list_of_indexes},
957 {"MATERIALIZED VIEW", NULL, &Query_for_list_of_matviews},
958 {"OPERATOR", NULL, NULL}, /* Querying for this is probably not such a
960 {"OWNED", NULL, NULL, THING_NO_CREATE}, /* for DROP OWNED BY ... */
961 {"PARSER", Query_for_list_of_ts_parsers, NULL, THING_NO_SHOW},
962 {"POLICY", NULL, NULL},
963 {"PUBLICATION", NULL, NULL},
964 {"ROLE", Query_for_list_of_roles},
965 {"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
966 {"SCHEMA", Query_for_list_of_schemas},
967 {"SEQUENCE", NULL, &Query_for_list_of_sequences},
968 {"SERVER", Query_for_list_of_servers},
969 {"SUBSCRIPTION", NULL, NULL},
970 {"TABLE", NULL, &Query_for_list_of_tables},
971 {"TABLESPACE", Query_for_list_of_tablespaces},
972 {"TEMP", NULL, NULL, THING_NO_DROP}, /* for CREATE TEMP TABLE ... */
973 {"TEMPLATE", Query_for_list_of_ts_templates, NULL, THING_NO_SHOW},
974 {"TEXT SEARCH", NULL, NULL},
975 {"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"},
976 {"TYPE", NULL, &Query_for_list_of_datatypes},
977 {"UNIQUE", NULL, NULL, THING_NO_DROP}, /* for CREATE UNIQUE INDEX ... */
978 {"UNLOGGED", NULL, NULL, THING_NO_DROP}, /* for CREATE UNLOGGED TABLE
980 {"USER", Query_for_list_of_roles},
981 {"USER MAPPING FOR", NULL, NULL},
982 {"VIEW", NULL, &Query_for_list_of_views},
983 {NULL} /* end of list */
987 /* Forward declaration of functions */
988 static char **psql_completion(const char *text, int start, int end);
989 static char *create_command_generator(const char *text, int state);
990 static char *drop_command_generator(const char *text, int state);
991 static char *complete_from_query(const char *text, int state);
992 static char *complete_from_schema_query(const char *text, int state);
993 static char *_complete_from_query(int is_schema_query,
994 const char *text, int state);
995 static char *complete_from_list(const char *text, int state);
996 static char *complete_from_const(const char *text, int state);
997 static void append_variable_names(char ***varnames, int *nvars,
998 int *maxvars, const char *varname,
999 const char *prefix, const char *suffix);
1000 static char **complete_from_variables(const char *text,
1001 const char *prefix, const char *suffix, bool need_value);
1002 static char *complete_from_files(const char *text, int state);
1004 static char *pg_strdup_keyword_case(const char *s, const char *ref);
1005 static char *escape_string(const char *text);
1006 static PGresult *exec_query(const char *query);
1008 static char **get_previous_words(int point, char **buffer, int *nwords);
1010 static char *get_guctype(const char *varname);
1013 static char *quote_file_name(char *text, int match_type, char *quote_pointer);
1014 static char *dequote_file_name(char *text, char quote_char);
1019 * Initialize the readline library for our purposes.
1022 initialize_readline(void)
1024 rl_readline_name = (char *) pset.progname;
1025 rl_attempted_completion_function = psql_completion;
1027 rl_basic_word_break_characters = WORD_BREAKS;
1029 completion_max_records = 1000;
1032 * There is a variable rl_completion_query_items for this but apparently
1033 * it's not defined everywhere.
1038 * Check if 'word' matches any of the '|'-separated strings in 'pattern',
1039 * using case-insensitive or case-sensitive comparisons.
1041 * If pattern is NULL, it's a wild card that matches any word.
1042 * If pattern begins with '!', the result is negated, ie we check that 'word'
1043 * does *not* match any alternative appearing in the rest of 'pattern'.
1044 * Any alternative can end with '*' which is a wild card, i.e., it means
1045 * match any word that matches the characters so far. (We do not currently
1046 * support '*' elsewhere than the end of an alternative.)
1048 * For readability, callers should use the macros MatchAny and MatchAnyExcept
1049 * to invoke those two special cases for 'pattern'. (But '|' and '*' must
1050 * just be written directly in patterns.)
1052 #define MatchAny NULL
1053 #define MatchAnyExcept(pattern) ("!" pattern)
1056 word_matches_internal(const char *pattern,
1058 bool case_sensitive)
1063 /* NULL pattern matches anything. */
1064 if (pattern == NULL)
1067 /* Handle negated patterns from the MatchAnyExcept macro. */
1068 if (*pattern == '!')
1069 return !word_matches_internal(pattern + 1, word, case_sensitive);
1071 /* Else consider each alternative in the pattern. */
1072 wordlen = strlen(word);
1077 /* Find end of current alternative. */
1079 while (*c != '\0' && *c != '|')
1081 /* Was there a wild card? (Assumes first alternative is not empty) */
1084 /* Yes, wildcard match? */
1085 patternlen = c - pattern - 1;
1086 if (wordlen >= patternlen &&
1088 strncmp(word, pattern, patternlen) == 0 :
1089 pg_strncasecmp(word, pattern, patternlen) == 0))
1094 /* No, plain match? */
1095 patternlen = c - pattern;
1096 if (wordlen == patternlen &&
1098 strncmp(word, pattern, wordlen) == 0 :
1099 pg_strncasecmp(word, pattern, wordlen) == 0))
1102 /* Out of alternatives? */
1105 /* Nope, try next alternative. */
1113 * There are enough matching calls below that it seems worth having these two
1114 * interface routines rather than including a third parameter in every call.
1116 * word_matches --- match case-insensitively.
1119 word_matches(const char *pattern, const char *word)
1121 return word_matches_internal(pattern, word, false);
1125 * word_matches_cs --- match case-sensitively.
1128 word_matches_cs(const char *pattern, const char *word)
1130 return word_matches_internal(pattern, word, true);
1134 * Check if the final character of 's' is 'c'.
1137 ends_with(const char *s, char c)
1139 size_t length = strlen(s);
1141 return (length > 0 && s[length - 1] == c);
1145 * The completion function.
1147 * According to readline spec this gets passed the text entered so far and its
1148 * start and end positions in the readline buffer. The return value is some
1149 * partially obscure list format that can be generated by readline's
1150 * completion_matches() function, so we don't have to worry about it.
1153 psql_completion(const char *text, int start, int end)
1155 /* This is the variable we'll return. */
1156 char **matches = NULL;
1158 /* Workspace for parsed words. */
1161 /* This array will contain pointers to parsed words. */
1162 char **previous_words;
1164 /* The number of words found on the input line. */
1165 int previous_words_count;
1168 * For compactness, we use these macros to reference previous_words[].
1169 * Caution: do not access a previous_words[] entry without having checked
1170 * previous_words_count to be sure it's valid. In most cases below, that
1171 * check is implicit in a TailMatches() or similar macro, but in some
1172 * places we have to check it explicitly.
1174 #define prev_wd (previous_words[0])
1175 #define prev2_wd (previous_words[1])
1176 #define prev3_wd (previous_words[2])
1177 #define prev4_wd (previous_words[3])
1178 #define prev5_wd (previous_words[4])
1179 #define prev6_wd (previous_words[5])
1180 #define prev7_wd (previous_words[6])
1181 #define prev8_wd (previous_words[7])
1182 #define prev9_wd (previous_words[8])
1184 /* Macros for matching the last N words before point, case-insensitively. */
1185 #define TailMatches1(p1) \
1186 (previous_words_count >= 1 && \
1187 word_matches(p1, prev_wd))
1189 #define TailMatches2(p2, p1) \
1190 (previous_words_count >= 2 && \
1191 word_matches(p1, prev_wd) && \
1192 word_matches(p2, prev2_wd))
1194 #define TailMatches3(p3, p2, p1) \
1195 (previous_words_count >= 3 && \
1196 word_matches(p1, prev_wd) && \
1197 word_matches(p2, prev2_wd) && \
1198 word_matches(p3, prev3_wd))
1200 #define TailMatches4(p4, p3, p2, p1) \
1201 (previous_words_count >= 4 && \
1202 word_matches(p1, prev_wd) && \
1203 word_matches(p2, prev2_wd) && \
1204 word_matches(p3, prev3_wd) && \
1205 word_matches(p4, prev4_wd))
1207 #define TailMatches5(p5, p4, p3, p2, p1) \
1208 (previous_words_count >= 5 && \
1209 word_matches(p1, prev_wd) && \
1210 word_matches(p2, prev2_wd) && \
1211 word_matches(p3, prev3_wd) && \
1212 word_matches(p4, prev4_wd) && \
1213 word_matches(p5, prev5_wd))
1215 #define TailMatches6(p6, p5, p4, p3, p2, p1) \
1216 (previous_words_count >= 6 && \
1217 word_matches(p1, prev_wd) && \
1218 word_matches(p2, prev2_wd) && \
1219 word_matches(p3, prev3_wd) && \
1220 word_matches(p4, prev4_wd) && \
1221 word_matches(p5, prev5_wd) && \
1222 word_matches(p6, prev6_wd))
1224 #define TailMatches7(p7, p6, p5, p4, p3, p2, p1) \
1225 (previous_words_count >= 7 && \
1226 word_matches(p1, prev_wd) && \
1227 word_matches(p2, prev2_wd) && \
1228 word_matches(p3, prev3_wd) && \
1229 word_matches(p4, prev4_wd) && \
1230 word_matches(p5, prev5_wd) && \
1231 word_matches(p6, prev6_wd) && \
1232 word_matches(p7, prev7_wd))
1234 #define TailMatches8(p8, p7, p6, p5, p4, p3, p2, p1) \
1235 (previous_words_count >= 8 && \
1236 word_matches(p1, prev_wd) && \
1237 word_matches(p2, prev2_wd) && \
1238 word_matches(p3, prev3_wd) && \
1239 word_matches(p4, prev4_wd) && \
1240 word_matches(p5, prev5_wd) && \
1241 word_matches(p6, prev6_wd) && \
1242 word_matches(p7, prev7_wd) && \
1243 word_matches(p8, prev8_wd))
1245 #define TailMatches9(p9, p8, p7, p6, p5, p4, p3, p2, p1) \
1246 (previous_words_count >= 9 && \
1247 word_matches(p1, prev_wd) && \
1248 word_matches(p2, prev2_wd) && \
1249 word_matches(p3, prev3_wd) && \
1250 word_matches(p4, prev4_wd) && \
1251 word_matches(p5, prev5_wd) && \
1252 word_matches(p6, prev6_wd) && \
1253 word_matches(p7, prev7_wd) && \
1254 word_matches(p8, prev8_wd) && \
1255 word_matches(p9, prev9_wd))
1257 /* Macros for matching the last N words before point, case-sensitively. */
1258 #define TailMatchesCS1(p1) \
1259 (previous_words_count >= 1 && \
1260 word_matches_cs(p1, prev_wd))
1261 #define TailMatchesCS2(p2, p1) \
1262 (previous_words_count >= 2 && \
1263 word_matches_cs(p1, prev_wd) && \
1264 word_matches_cs(p2, prev2_wd))
1267 * Macros for matching N words beginning at the start of the line,
1268 * case-insensitively.
1270 #define Matches1(p1) \
1271 (previous_words_count == 1 && \
1273 #define Matches2(p1, p2) \
1274 (previous_words_count == 2 && \
1275 TailMatches2(p1, p2))
1276 #define Matches3(p1, p2, p3) \
1277 (previous_words_count == 3 && \
1278 TailMatches3(p1, p2, p3))
1279 #define Matches4(p1, p2, p3, p4) \
1280 (previous_words_count == 4 && \
1281 TailMatches4(p1, p2, p3, p4))
1282 #define Matches5(p1, p2, p3, p4, p5) \
1283 (previous_words_count == 5 && \
1284 TailMatches5(p1, p2, p3, p4, p5))
1285 #define Matches6(p1, p2, p3, p4, p5, p6) \
1286 (previous_words_count == 6 && \
1287 TailMatches6(p1, p2, p3, p4, p5, p6))
1288 #define Matches7(p1, p2, p3, p4, p5, p6, p7) \
1289 (previous_words_count == 7 && \
1290 TailMatches7(p1, p2, p3, p4, p5, p6, p7))
1291 #define Matches8(p1, p2, p3, p4, p5, p6, p7, p8) \
1292 (previous_words_count == 8 && \
1293 TailMatches8(p1, p2, p3, p4, p5, p6, p7, p8))
1294 #define Matches9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \
1295 (previous_words_count == 9 && \
1296 TailMatches9(p1, p2, p3, p4, p5, p6, p7, p8, p9))
1299 * Macros for matching N words at the start of the line, regardless of
1300 * what is after them, case-insensitively.
1302 #define HeadMatches1(p1) \
1303 (previous_words_count >= 1 && \
1304 word_matches(p1, previous_words[previous_words_count - 1]))
1306 #define HeadMatches2(p1, p2) \
1307 (previous_words_count >= 2 && \
1308 word_matches(p1, previous_words[previous_words_count - 1]) && \
1309 word_matches(p2, previous_words[previous_words_count - 2]))
1311 #define HeadMatches3(p1, p2, p3) \
1312 (previous_words_count >= 3 && \
1313 word_matches(p1, previous_words[previous_words_count - 1]) && \
1314 word_matches(p2, previous_words[previous_words_count - 2]) && \
1315 word_matches(p3, previous_words[previous_words_count - 3]))
1317 /* Known command-starting keywords. */
1318 static const char *const sql_commands[] = {
1319 "ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER",
1320 "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
1321 "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN",
1322 "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK",
1323 "MOVE", "NOTIFY", "PREPARE",
1324 "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE",
1325 "RESET", "REVOKE", "ROLLBACK",
1326 "SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START",
1327 "TABLE", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", "VALUES", "WITH",
1331 /* psql's backslash commands. */
1332 static const char *const backslash_commands[] = {
1333 "\\a", "\\connect", "\\conninfo", "\\C", "\\cd", "\\copy",
1334 "\\copyright", "\\crosstabview",
1335 "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD",
1336 "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df",
1337 "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
1338 "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\drds", "\\ds", "\\dS",
1339 "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
1340 "\\e", "\\echo", "\\ef", "\\encoding", "\\errverbose", "\\ev",
1341 "\\f", "\\g", "\\gexec", "\\gset", "\\h", "\\help", "\\H", "\\i", "\\ir", "\\l",
1342 "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
1343 "\\o", "\\p", "\\password", "\\prompt", "\\pset", "\\q", "\\qecho", "\\r",
1344 "\\s", "\\set", "\\setenv", "\\sf", "\\sv", "\\t", "\\T",
1345 "\\timing", "\\unset", "\\x", "\\w", "\\watch", "\\z", "\\!", NULL
1348 (void) end; /* "end" is not used */
1350 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1351 rl_completion_append_character = ' ';
1354 /* Clear a few things. */
1355 completion_charp = NULL;
1356 completion_charpp = NULL;
1357 completion_info_charp = NULL;
1358 completion_info_charp2 = NULL;
1361 * Scan the input line to extract the words before our current position.
1362 * According to those we'll make some smart decisions on what the user is
1363 * probably intending to type.
1365 previous_words = get_previous_words(start,
1367 &previous_words_count);
1369 /* If current word is a backslash command, offer completions for that */
1370 if (text[0] == '\\')
1371 COMPLETE_WITH_LIST_CS(backslash_commands);
1373 /* If current word is a variable interpolation, handle that case */
1374 else if (text[0] == ':' && text[1] != ':')
1376 if (text[1] == '\'')
1377 matches = complete_from_variables(text, ":'", "'", true);
1378 else if (text[1] == '"')
1379 matches = complete_from_variables(text, ":\"", "\"", true);
1381 matches = complete_from_variables(text, ":", "", true);
1384 /* If no previous word, suggest one of the basic sql commands */
1385 else if (previous_words_count == 0)
1386 COMPLETE_WITH_LIST(sql_commands);
1389 /* complete with something you can create */
1390 else if (TailMatches1("CREATE"))
1391 matches = completion_matches(text, create_command_generator);
1393 /* DROP, but not DROP embedded in other commands */
1394 /* complete with something you can drop */
1395 else if (Matches1("DROP"))
1396 matches = completion_matches(text, drop_command_generator);
1401 else if (Matches2("ALTER", "TABLE"))
1402 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
1403 "UNION SELECT 'ALL IN TABLESPACE'");
1405 /* ALTER something */
1406 else if (Matches1("ALTER"))
1408 static const char *const list_ALTER[] =
1409 {"AGGREGATE", "COLLATION", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN",
1410 "EVENT TRIGGER", "EXTENSION", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "FUNCTION",
1411 "GROUP", "INDEX", "LANGUAGE", "LARGE OBJECT", "MATERIALIZED VIEW", "OPERATOR",
1412 "POLICY", "PUBLICATION", "ROLE", "RULE", "SCHEMA", "SERVER", "SEQUENCE",
1413 "SUBSCRIPTION", "SYSTEM", "TABLE", "TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE",
1414 "USER", "USER MAPPING FOR", "VIEW", NULL};
1416 COMPLETE_WITH_LIST(list_ALTER);
1418 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */
1419 else if (TailMatches4("ALL", "IN", "TABLESPACE", MatchAny))
1420 COMPLETE_WITH_LIST2("SET TABLESPACE", "OWNED BY");
1421 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */
1422 else if (TailMatches6("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY"))
1423 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1424 /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */
1425 else if (TailMatches7("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny))
1426 COMPLETE_WITH_CONST("SET TABLESPACE");
1427 /* ALTER AGGREGATE,FUNCTION <name> */
1428 else if (Matches3("ALTER", "AGGREGATE|FUNCTION", MatchAny))
1429 COMPLETE_WITH_CONST("(");
1430 /* ALTER AGGREGATE,FUNCTION <name> (...) */
1431 else if (Matches4("ALTER", "AGGREGATE|FUNCTION", MatchAny, MatchAny))
1433 if (ends_with(prev_wd, ')'))
1434 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1436 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
1438 /* ALTER PUBLICATION <name> ...*/
1439 else if (Matches3("ALTER","PUBLICATION",MatchAny))
1441 COMPLETE_WITH_LIST5("WITH", "ADD TABLE", "SET TABLE", "DROP TABLE", "OWNER TO");
1443 /* ALTER PUBLICATION <name> .. WITH ( ... */
1444 else if (HeadMatches3("ALTER", "PUBLICATION",MatchAny) && TailMatches2("WITH", "("))
1446 COMPLETE_WITH_LIST6("PUBLISH INSERT", "NOPUBLISH INSERT", "PUBLISH UPDATE",
1447 "NOPUBLISH UPDATE", "PUBLISH DELETE", "NOPUBLISH DELETE");
1449 /* ALTER SUBSCRIPTION <name> ... */
1450 else if (Matches3("ALTER","SUBSCRIPTION",MatchAny))
1452 COMPLETE_WITH_LIST6("WITH", "CONNECTION", "SET PUBLICATION", "ENABLE", "DISABLE", "OWNER TO");
1454 else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("WITH", "("))
1456 COMPLETE_WITH_CONST("SLOT NAME");
1458 /* ALTER SCHEMA <name> */
1459 else if (Matches3("ALTER", "SCHEMA", MatchAny))
1460 COMPLETE_WITH_LIST2("OWNER TO", "RENAME TO");
1462 /* ALTER COLLATION <name> */
1463 else if (Matches3("ALTER", "COLLATION", MatchAny))
1464 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1466 /* ALTER CONVERSION <name> */
1467 else if (Matches3("ALTER", "CONVERSION", MatchAny))
1468 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1470 /* ALTER DATABASE <name> */
1471 else if (Matches3("ALTER", "DATABASE", MatchAny))
1472 COMPLETE_WITH_LIST7("RESET", "SET", "OWNER TO", "RENAME TO",
1473 "IS_TEMPLATE", "ALLOW_CONNECTIONS",
1474 "CONNECTION LIMIT");
1476 /* ALTER EVENT TRIGGER */
1477 else if (Matches3("ALTER", "EVENT", "TRIGGER"))
1478 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
1480 /* ALTER EVENT TRIGGER <name> */
1481 else if (Matches4("ALTER", "EVENT", "TRIGGER", MatchAny))
1482 COMPLETE_WITH_LIST4("DISABLE", "ENABLE", "OWNER TO", "RENAME TO");
1484 /* ALTER EVENT TRIGGER <name> ENABLE */
1485 else if (Matches5("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE"))
1486 COMPLETE_WITH_LIST2("REPLICA", "ALWAYS");
1488 /* ALTER EXTENSION <name> */
1489 else if (Matches3("ALTER", "EXTENSION", MatchAny))
1490 COMPLETE_WITH_LIST4("ADD", "DROP", "UPDATE", "SET SCHEMA");
1492 /* ALTER EXTENSION <name> UPDATE */
1493 else if (Matches4("ALTER", "EXTENSION", MatchAny, "UPDATE"))
1495 completion_info_charp = prev2_wd;
1496 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO);
1499 /* ALTER EXTENSION <name> UPDATE TO */
1500 else if (Matches5("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO"))
1502 completion_info_charp = prev3_wd;
1503 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
1507 else if (Matches2("ALTER", "FOREIGN"))
1508 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
1510 /* ALTER FOREIGN DATA WRAPPER <name> */
1511 else if (Matches5("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
1512 COMPLETE_WITH_LIST5("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO");
1514 /* ALTER FOREIGN TABLE <name> */
1515 else if (Matches4("ALTER", "FOREIGN", "TABLE", MatchAny))
1517 static const char *const list_ALTER_FOREIGN_TABLE[] =
1518 {"ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE", "INHERIT",
1519 "NO INHERIT", "OPTIONS", "OWNER TO", "RENAME", "SET",
1520 "VALIDATE CONSTRAINT", NULL};
1522 COMPLETE_WITH_LIST(list_ALTER_FOREIGN_TABLE);
1526 else if (Matches2("ALTER", "INDEX"))
1527 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
1528 "UNION SELECT 'ALL IN TABLESPACE'");
1529 /* ALTER INDEX <name> */
1530 else if (Matches3("ALTER", "INDEX", MatchAny))
1531 COMPLETE_WITH_LIST4("OWNER TO", "RENAME TO", "SET", "RESET");
1532 /* ALTER INDEX <name> SET */
1533 else if (Matches4("ALTER", "INDEX", MatchAny, "SET"))
1534 COMPLETE_WITH_LIST2("(", "TABLESPACE");
1535 /* ALTER INDEX <name> RESET */
1536 else if (Matches4("ALTER", "INDEX", MatchAny, "RESET"))
1537 COMPLETE_WITH_CONST("(");
1538 /* ALTER INDEX <foo> SET|RESET ( */
1539 else if (Matches5("ALTER", "INDEX", MatchAny, "RESET", "("))
1540 COMPLETE_WITH_LIST3("fillfactor", "fastupdate",
1541 "gin_pending_list_limit");
1542 else if (Matches5("ALTER", "INDEX", MatchAny, "SET", "("))
1543 COMPLETE_WITH_LIST3("fillfactor =", "fastupdate =",
1544 "gin_pending_list_limit =");
1546 /* ALTER LANGUAGE <name> */
1547 else if (Matches3("ALTER", "LANGUAGE", MatchAny))
1548 COMPLETE_WITH_LIST2("OWNER_TO", "RENAME TO");
1550 /* ALTER LARGE OBJECT <oid> */
1551 else if (Matches4("ALTER", "LARGE", "OBJECT", MatchAny))
1552 COMPLETE_WITH_CONST("OWNER TO");
1554 /* ALTER MATERIALIZED VIEW */
1555 else if (Matches3("ALTER", "MATERIALIZED", "VIEW"))
1556 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
1557 "UNION SELECT 'ALL IN TABLESPACE'");
1559 /* ALTER USER,ROLE <name> */
1560 else if (Matches3("ALTER", "USER|ROLE", MatchAny) &&
1561 !TailMatches2("USER", "MAPPING"))
1563 static const char *const list_ALTERUSER[] =
1564 {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1565 "ENCRYPTED", "INHERIT", "LOGIN", "NOBYPASSRLS",
1566 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1567 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
1568 "REPLICATION", "RESET", "SET", "SUPERUSER", "UNENCRYPTED",
1569 "VALID UNTIL", "WITH", NULL};
1571 COMPLETE_WITH_LIST(list_ALTERUSER);
1574 /* ALTER USER,ROLE <name> WITH */
1575 else if (Matches4("ALTER", "USER|ROLE", MatchAny, "WITH"))
1577 /* Similar to the above, but don't complete "WITH" again. */
1578 static const char *const list_ALTERUSER_WITH[] =
1579 {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
1580 "ENCRYPTED", "INHERIT", "LOGIN", "NOBYPASSRLS",
1581 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
1582 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
1583 "REPLICATION", "RESET", "SET", "SUPERUSER", "UNENCRYPTED",
1584 "VALID UNTIL", NULL};
1586 COMPLETE_WITH_LIST(list_ALTERUSER_WITH);
1589 /* complete ALTER USER,ROLE <name> ENCRYPTED,UNENCRYPTED with PASSWORD */
1590 else if (Matches4("ALTER", "USER|ROLE", MatchAny, "ENCRYPTED|UNENCRYPTED"))
1591 COMPLETE_WITH_CONST("PASSWORD");
1592 /* ALTER DEFAULT PRIVILEGES */
1593 else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES"))
1594 COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA");
1595 /* ALTER DEFAULT PRIVILEGES FOR */
1596 else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR"))
1597 COMPLETE_WITH_CONST("ROLE");
1598 /* ALTER DEFAULT PRIVILEGES IN */
1599 else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN"))
1600 COMPLETE_WITH_CONST("SCHEMA");
1601 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */
1602 else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1604 COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA");
1605 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */
1606 else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1608 COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE");
1609 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */
1610 else if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1612 COMPLETE_WITH_CONST("ROLE");
1613 /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */
1614 /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */
1615 else if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER",
1616 MatchAny, "IN", "SCHEMA", MatchAny) ||
1617 Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA",
1618 MatchAny, "FOR", "ROLE|USER", MatchAny))
1619 COMPLETE_WITH_LIST2("GRANT", "REVOKE");
1620 /* ALTER DOMAIN <name> */
1621 else if (Matches3("ALTER", "DOMAIN", MatchAny))
1622 COMPLETE_WITH_LIST6("ADD", "DROP", "OWNER TO", "RENAME", "SET",
1623 "VALIDATE CONSTRAINT");
1624 /* ALTER DOMAIN <sth> DROP */
1625 else if (Matches4("ALTER", "DOMAIN", MatchAny, "DROP"))
1626 COMPLETE_WITH_LIST3("CONSTRAINT", "DEFAULT", "NOT NULL");
1627 /* ALTER DOMAIN <sth> DROP|RENAME|VALIDATE CONSTRAINT */
1628 else if (Matches5("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
1630 completion_info_charp = prev3_wd;
1631 COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
1633 /* ALTER DOMAIN <sth> RENAME */
1634 else if (Matches4("ALTER", "DOMAIN", MatchAny, "RENAME"))
1635 COMPLETE_WITH_LIST2("CONSTRAINT", "TO");
1636 /* ALTER DOMAIN <sth> RENAME CONSTRAINT <sth> */
1637 else if (Matches6("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny))
1638 COMPLETE_WITH_CONST("TO");
1640 /* ALTER DOMAIN <sth> SET */
1641 else if (Matches4("ALTER", "DOMAIN", MatchAny, "SET"))
1642 COMPLETE_WITH_LIST3("DEFAULT", "NOT NULL", "SCHEMA");
1643 /* ALTER SEQUENCE <name> */
1644 else if (Matches3("ALTER", "SEQUENCE", MatchAny))
1646 static const char *const list_ALTERSEQUENCE[] =
1647 {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE",
1648 "SET SCHEMA", "OWNED BY", "OWNER TO", "RENAME TO", NULL};
1650 COMPLETE_WITH_LIST(list_ALTERSEQUENCE);
1652 /* ALTER SEQUENCE <name> NO */
1653 else if (Matches4("ALTER", "SEQUENCE", MatchAny, "NO"))
1654 COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE");
1655 /* ALTER SERVER <name> */
1656 else if (Matches3("ALTER", "SERVER", MatchAny))
1657 COMPLETE_WITH_LIST4("VERSION", "OPTIONS", "OWNER TO", "RENAME TO");
1658 /* ALTER SERVER <name> VERSION <version> */
1659 else if (Matches5("ALTER", "SERVER", MatchAny, "VERSION", MatchAny))
1660 COMPLETE_WITH_CONST("OPTIONS");
1661 /* ALTER SYSTEM SET, RESET, RESET ALL */
1662 else if (Matches2("ALTER", "SYSTEM"))
1663 COMPLETE_WITH_LIST2("SET", "RESET");
1664 else if (Matches3("ALTER", "SYSTEM", "SET|RESET"))
1665 COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars);
1666 else if (Matches4("ALTER", "SYSTEM", "SET", MatchAny))
1667 COMPLETE_WITH_CONST("TO");
1668 /* ALTER VIEW <name> */
1669 else if (Matches3("ALTER", "VIEW", MatchAny))
1670 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1672 /* ALTER MATERIALIZED VIEW <name> */
1673 else if (Matches4("ALTER", "MATERIALIZED", "VIEW", MatchAny))
1674 COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
1677 /* ALTER POLICY <name> */
1678 else if (Matches2("ALTER", "POLICY"))
1679 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
1680 /* ALTER POLICY <name> ON */
1681 else if (Matches3("ALTER", "POLICY", MatchAny))
1682 COMPLETE_WITH_CONST("ON");
1683 /* ALTER POLICY <name> ON <table> */
1684 else if (Matches4("ALTER", "POLICY", MatchAny, "ON"))
1686 completion_info_charp = prev2_wd;
1687 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
1689 /* ALTER POLICY <name> ON <table> - show options */
1690 else if (Matches5("ALTER", "POLICY", MatchAny, "ON", MatchAny))
1691 COMPLETE_WITH_LIST4("RENAME TO", "TO", "USING (", "WITH CHECK (");
1692 /* ALTER POLICY <name> ON <table> TO <role> */
1693 else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO"))
1694 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
1695 /* ALTER POLICY <name> ON <table> USING ( */
1696 else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING"))
1697 COMPLETE_WITH_CONST("(");
1698 /* ALTER POLICY <name> ON <table> WITH CHECK ( */
1699 else if (Matches7("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK"))
1700 COMPLETE_WITH_CONST("(");
1702 /* ALTER RULE <name>, add ON */
1703 else if (Matches3("ALTER", "RULE", MatchAny))
1704 COMPLETE_WITH_CONST("ON");
1706 /* If we have ALTER RULE <name> ON, then add the correct tablename */
1707 else if (Matches4("ALTER", "RULE", MatchAny, "ON"))
1709 completion_info_charp = prev2_wd;
1710 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1713 /* ALTER RULE <name> ON <name> */
1714 else if (Matches5("ALTER", "RULE", MatchAny, "ON", MatchAny))
1715 COMPLETE_WITH_CONST("RENAME TO");
1717 /* ALTER TRIGGER <name>, add ON */
1718 else if (Matches3("ALTER", "TRIGGER", MatchAny))
1719 COMPLETE_WITH_CONST("ON");
1721 else if (Matches4("ALTER", "TRIGGER", MatchAny, MatchAny))
1723 completion_info_charp = prev2_wd;
1724 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
1728 * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
1730 else if (Matches4("ALTER", "TRIGGER", MatchAny, "ON"))
1731 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
1733 /* ALTER TRIGGER <name> ON <name> */
1734 else if (Matches5("ALTER", "TRIGGER", MatchAny, "ON", MatchAny))
1735 COMPLETE_WITH_CONST("RENAME TO");
1738 * If we detect ALTER TABLE <name>, suggest sub commands
1740 else if (Matches3("ALTER", "TABLE", MatchAny))
1742 static const char *const list_ALTER2[] =
1743 {"ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", "ENABLE", "INHERIT",
1744 "NO INHERIT", "RENAME", "RESET", "OWNER TO", "SET",
1745 "VALIDATE CONSTRAINT", "REPLICA IDENTITY", NULL};
1747 COMPLETE_WITH_LIST(list_ALTER2);
1749 /* ALTER TABLE xxx ENABLE */
1750 else if (Matches4("ALTER", "TABLE", MatchAny, "ENABLE"))
1751 COMPLETE_WITH_LIST5("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE",
1753 else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS"))
1754 COMPLETE_WITH_LIST2("RULE", "TRIGGER");
1755 else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "RULE"))
1757 completion_info_charp = prev3_wd;
1758 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1760 else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE"))
1762 completion_info_charp = prev4_wd;
1763 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1765 else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER"))
1767 completion_info_charp = prev3_wd;
1768 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1770 else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER"))
1772 completion_info_charp = prev4_wd;
1773 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1775 /* ALTER TABLE xxx INHERIT */
1776 else if (Matches4("ALTER", "TABLE", MatchAny, "INHERIT"))
1777 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1778 /* ALTER TABLE xxx NO INHERIT */
1779 else if (Matches5("ALTER", "TABLE", MatchAny, "NO", "INHERIT"))
1780 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
1781 /* ALTER TABLE xxx DISABLE */
1782 else if (Matches4("ALTER", "TABLE", MatchAny, "DISABLE"))
1783 COMPLETE_WITH_LIST3("ROW LEVEL SECURITY", "RULE", "TRIGGER");
1784 else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "RULE"))
1786 completion_info_charp = prev3_wd;
1787 COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1789 else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER"))
1791 completion_info_charp = prev3_wd;
1792 COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1795 /* ALTER TABLE xxx ALTER */
1796 else if (Matches4("ALTER", "TABLE", MatchAny, "ALTER"))
1797 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'");
1799 /* ALTER TABLE xxx RENAME */
1800 else if (Matches4("ALTER", "TABLE", MatchAny, "RENAME"))
1801 COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'");
1802 else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN"))
1803 COMPLETE_WITH_ATTR(prev3_wd, "");
1805 /* ALTER TABLE xxx RENAME yyy */
1806 else if (Matches5("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO")))
1807 COMPLETE_WITH_CONST("TO");
1809 /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */
1810 else if (Matches6("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO")))
1811 COMPLETE_WITH_CONST("TO");
1813 /* If we have ALTER TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
1814 else if (Matches4("ALTER", "TABLE", MatchAny, "DROP"))
1815 COMPLETE_WITH_LIST2("COLUMN", "CONSTRAINT");
1816 /* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
1817 else if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
1818 COMPLETE_WITH_ATTR(prev3_wd, "");
1821 * If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
1822 * provide list of constraints
1824 else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
1826 completion_info_charp = prev3_wd;
1827 COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
1829 /* ALTER TABLE ALTER [COLUMN] <foo> */
1830 else if (Matches6("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) ||
1831 Matches5("ALTER", "TABLE", MatchAny, "ALTER", MatchAny))
1832 COMPLETE_WITH_LIST4("TYPE", "SET", "RESET", "DROP");
1833 /* ALTER TABLE ALTER [COLUMN] <foo> SET */
1834 else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") ||
1835 Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET"))
1836 COMPLETE_WITH_LIST5("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE");
1837 /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
1838 else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") ||
1839 Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "("))
1840 COMPLETE_WITH_LIST2("n_distinct", "n_distinct_inherited");
1841 /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
1842 else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") ||
1843 Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE"))
1844 COMPLETE_WITH_LIST4("PLAIN", "EXTERNAL", "EXTENDED", "MAIN");
1845 /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
1846 else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") ||
1847 Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP"))
1848 COMPLETE_WITH_LIST2("DEFAULT", "NOT NULL");
1849 else if (Matches4("ALTER", "TABLE", MatchAny, "CLUSTER"))
1850 COMPLETE_WITH_CONST("ON");
1851 else if (Matches5("ALTER", "TABLE", MatchAny, "CLUSTER", "ON"))
1853 completion_info_charp = prev3_wd;
1854 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1856 /* If we have ALTER TABLE <sth> SET, provide list of attributes and '(' */
1857 else if (Matches4("ALTER", "TABLE", MatchAny, "SET"))
1858 COMPLETE_WITH_LIST7("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED",
1862 * If we have ALTER TABLE <sth> SET TABLESPACE provide a list of
1865 else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
1866 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
1867 /* If we have ALTER TABLE <sth> SET WITH provide OIDS */
1868 else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITH"))
1869 COMPLETE_WITH_CONST("OIDS");
1870 /* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
1871 else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
1872 COMPLETE_WITH_LIST2("CLUSTER", "OIDS");
1873 /* ALTER TABLE <foo> RESET */
1874 else if (Matches4("ALTER", "TABLE", MatchAny, "RESET"))
1875 COMPLETE_WITH_CONST("(");
1876 /* ALTER TABLE <foo> SET|RESET ( */
1877 else if (Matches5("ALTER", "TABLE", MatchAny, "SET|RESET", "("))
1879 static const char *const list_TABLEOPTIONS[] =
1881 "autovacuum_analyze_scale_factor",
1882 "autovacuum_analyze_threshold",
1883 "autovacuum_enabled",
1884 "autovacuum_freeze_max_age",
1885 "autovacuum_freeze_min_age",
1886 "autovacuum_freeze_table_age",
1887 "autovacuum_multixact_freeze_max_age",
1888 "autovacuum_multixact_freeze_min_age",
1889 "autovacuum_multixact_freeze_table_age",
1890 "autovacuum_vacuum_cost_delay",
1891 "autovacuum_vacuum_cost_limit",
1892 "autovacuum_vacuum_scale_factor",
1893 "autovacuum_vacuum_threshold",
1896 "log_autovacuum_min_duration",
1897 "toast.autovacuum_enabled",
1898 "toast.autovacuum_freeze_max_age",
1899 "toast.autovacuum_freeze_min_age",
1900 "toast.autovacuum_freeze_table_age",
1901 "toast.autovacuum_multixact_freeze_max_age",
1902 "toast.autovacuum_multixact_freeze_min_age",
1903 "toast.autovacuum_multixact_freeze_table_age",
1904 "toast.autovacuum_vacuum_cost_delay",
1905 "toast.autovacuum_vacuum_cost_limit",
1906 "toast.autovacuum_vacuum_scale_factor",
1907 "toast.autovacuum_vacuum_threshold",
1908 "toast.log_autovacuum_min_duration",
1909 "user_catalog_table",
1913 COMPLETE_WITH_LIST(list_TABLEOPTIONS);
1915 else if (Matches7("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX"))
1917 completion_info_charp = prev5_wd;
1918 COMPLETE_WITH_QUERY(Query_for_index_of_table);
1920 else if (Matches6("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING"))
1921 COMPLETE_WITH_CONST("INDEX");
1922 else if (Matches5("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY"))
1923 COMPLETE_WITH_LIST4("FULL", "NOTHING", "DEFAULT", "USING");
1924 else if (Matches4("ALTER", "TABLE", MatchAny, "REPLICA"))
1925 COMPLETE_WITH_CONST("IDENTITY");
1927 /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
1928 else if (Matches3("ALTER", "TABLESPACE", MatchAny))
1929 COMPLETE_WITH_LIST4("RENAME TO", "OWNER TO", "SET", "RESET");
1930 /* ALTER TABLESPACE <foo> SET|RESET */
1931 else if (Matches4("ALTER", "TABLESPACE", MatchAny, "SET|RESET"))
1932 COMPLETE_WITH_CONST("(");
1933 /* ALTER TABLESPACE <foo> SET|RESET ( */
1934 else if (Matches5("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "("))
1935 COMPLETE_WITH_LIST3("seq_page_cost", "random_page_cost",
1936 "effective_io_concurrency");
1938 /* ALTER TEXT SEARCH */
1939 else if (Matches3("ALTER", "TEXT", "SEARCH"))
1940 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
1941 else if (Matches5("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny))
1942 COMPLETE_WITH_LIST2("RENAME TO", "SET SCHEMA");
1943 else if (Matches5("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny))
1944 COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA");
1945 else if (Matches5("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
1946 COMPLETE_WITH_LIST6("ADD MAPPING FOR", "ALTER MAPPING",
1948 "OWNER TO", "RENAME TO", "SET SCHEMA");
1950 /* complete ALTER TYPE <foo> with actions */
1951 else if (Matches3("ALTER", "TYPE", MatchAny))
1952 COMPLETE_WITH_LIST7("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE",
1954 "OWNER TO", "RENAME", "SET SCHEMA");
1955 /* complete ALTER TYPE <foo> ADD with actions */
1956 else if (Matches4("ALTER", "TYPE", MatchAny, "ADD"))
1957 COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE");
1958 /* ALTER TYPE <foo> RENAME */
1959 else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME"))
1960 COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE");
1961 /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */
1962 else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny))
1963 COMPLETE_WITH_CONST("TO");
1965 * If we have ALTER TYPE <sth> ALTER/DROP/RENAME ATTRIBUTE, provide list
1968 else if (Matches5("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
1969 COMPLETE_WITH_ATTR(prev3_wd, "");
1970 /* ALTER TYPE ALTER ATTRIBUTE <foo> */
1971 else if (Matches6("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
1972 COMPLETE_WITH_CONST("TYPE");
1973 /* complete ALTER GROUP <foo> */
1974 else if (Matches3("ALTER", "GROUP", MatchAny))
1975 COMPLETE_WITH_LIST3("ADD USER", "DROP USER", "RENAME TO");
1976 /* complete ALTER GROUP <foo> ADD|DROP with USER */
1977 else if (Matches4("ALTER", "GROUP", MatchAny, "ADD|DROP"))
1978 COMPLETE_WITH_CONST("USER");
1979 /* complete ALTER GROUP <foo> ADD|DROP USER with a user name */
1980 else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER"))
1981 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1984 * If we have ALTER TYPE <sth> RENAME VALUE, provide list of enum values
1986 else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE"))
1987 COMPLETE_WITH_ENUM_VALUE(prev3_wd);
1990 else if (Matches1("BEGIN"))
1991 COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
1993 else if (Matches1("END|ABORT"))
1994 COMPLETE_WITH_LIST2("WORK", "TRANSACTION");
1996 else if (Matches1("COMMIT"))
1997 COMPLETE_WITH_LIST3("WORK", "TRANSACTION", "PREPARED");
1998 /* RELEASE SAVEPOINT */
1999 else if (Matches1("RELEASE"))
2000 COMPLETE_WITH_CONST("SAVEPOINT");
2002 else if (Matches1("ROLLBACK"))
2003 COMPLETE_WITH_LIST4("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED");
2005 else if (Matches1("CLUSTER"))
2006 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, "UNION SELECT 'VERBOSE'");
2007 else if (Matches2("CLUSTER", "VERBOSE"))
2008 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2009 /* If we have CLUSTER <sth>, then add "USING" */
2010 else if (Matches2("CLUSTER", MatchAnyExcept("VERBOSE|ON")))
2011 COMPLETE_WITH_CONST("USING");
2012 /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
2013 else if (Matches3("CLUSTER", "VERBOSE", MatchAny))
2014 COMPLETE_WITH_CONST("USING");
2015 /* If we have CLUSTER <sth> USING, then add the index as well */
2016 else if (Matches3("CLUSTER", MatchAny, "USING") ||
2017 Matches4("CLUSTER", "VERBOSE", MatchAny, "USING"))
2019 completion_info_charp = prev2_wd;
2020 COMPLETE_WITH_QUERY(Query_for_index_of_table);
2024 else if (Matches1("COMMENT"))
2025 COMPLETE_WITH_CONST("ON");
2026 else if (Matches2("COMMENT", "ON"))
2028 static const char *const list_COMMENT[] =
2029 {"ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", "DATABASE",
2030 "EVENT TRIGGER", "EXTENSION",
2031 "FOREIGN DATA WRAPPER", "FOREIGN TABLE",
2032 "SERVER", "INDEX", "LANGUAGE", "POLICY", "RULE", "SCHEMA", "SEQUENCE",
2033 "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
2034 "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
2035 "TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
2037 COMPLETE_WITH_LIST(list_COMMENT);
2039 else if (Matches4("COMMENT", "ON", "ACCESS", "METHOD"))
2040 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2041 else if (Matches3("COMMENT", "ON", "FOREIGN"))
2042 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2043 else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH"))
2044 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2045 else if (Matches3("COMMENT", "ON", "CONSTRAINT"))
2046 COMPLETE_WITH_QUERY(Query_for_all_table_constraints);
2047 else if (Matches4("COMMENT", "ON", "CONSTRAINT", MatchAny))
2048 COMPLETE_WITH_CONST("ON");
2049 else if (Matches5("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON"))
2051 completion_info_charp = prev2_wd;
2052 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint);
2054 else if (Matches4("COMMENT", "ON", "MATERIALIZED", "VIEW"))
2055 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2056 else if (Matches4("COMMENT", "ON", "EVENT", "TRIGGER"))
2057 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2058 else if (Matches4("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) ||
2059 Matches5("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) ||
2060 Matches6("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS")))
2061 COMPLETE_WITH_CONST("IS");
2066 * If we have COPY, offer list of tables or "(" (Also cover the analogous
2067 * backslash command).
2069 else if (Matches1("COPY|\\copy"))
2070 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2071 " UNION ALL SELECT '('");
2072 /* If we have COPY BINARY, complete with list of tables */
2073 else if (Matches2("COPY", "BINARY"))
2074 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2075 /* If we have COPY (, complete it with legal commands */
2076 else if (Matches2("COPY|\\copy", "("))
2077 COMPLETE_WITH_LIST7("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH");
2078 /* If we have COPY [BINARY] <sth>, complete it with "TO" or "FROM" */
2079 else if (Matches2("COPY|\\copy", MatchAny) ||
2080 Matches3("COPY", "BINARY", MatchAny))
2081 COMPLETE_WITH_LIST2("FROM", "TO");
2082 /* If we have COPY [BINARY] <sth> FROM|TO, complete with filename */
2083 else if (Matches3("COPY|\\copy", MatchAny, "FROM|TO") ||
2084 Matches4("COPY", "BINARY", MatchAny, "FROM|TO"))
2086 completion_charp = "";
2087 matches = completion_matches(text, complete_from_files);
2090 /* Handle COPY [BINARY] <sth> FROM|TO filename */
2091 else if (Matches4("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
2092 Matches5("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
2093 COMPLETE_WITH_LIST6("BINARY", "OIDS", "DELIMITER", "NULL", "CSV",
2096 /* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
2097 else if (Matches5("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") ||
2098 Matches6("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV"))
2099 COMPLETE_WITH_LIST5("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE",
2102 /* CREATE ACCESS METHOD */
2103 /* Complete "CREATE ACCESS METHOD <name>" */
2104 else if (Matches4("CREATE", "ACCESS", "METHOD", MatchAny))
2105 COMPLETE_WITH_CONST("TYPE");
2106 /* Complete "CREATE ACCESS METHOD <name> TYPE" */
2107 else if (Matches5("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
2108 COMPLETE_WITH_CONST("INDEX");
2109 /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
2110 else if (Matches6("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
2111 COMPLETE_WITH_CONST("HANDLER");
2113 /* CREATE DATABASE */
2114 else if (Matches3("CREATE", "DATABASE", MatchAny))
2115 COMPLETE_WITH_LIST9("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE",
2117 "ALLOW_CONNECTIONS", "CONNECTION LIMIT",
2118 "LC_COLLATE", "LC_CTYPE");
2120 else if (Matches4("CREATE", "DATABASE", MatchAny, "TEMPLATE"))
2121 COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
2123 /* CREATE EXTENSION */
2124 /* Complete with available extensions rather than installed ones. */
2125 else if (Matches2("CREATE", "EXTENSION"))
2126 COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
2127 /* CREATE EXTENSION <name> */
2128 else if (Matches3("CREATE", "EXTENSION", MatchAny))
2129 COMPLETE_WITH_LIST3("WITH SCHEMA", "CASCADE", "VERSION");
2130 /* CREATE EXTENSION <name> VERSION */
2131 else if (Matches4("CREATE", "EXTENSION", MatchAny, "VERSION"))
2133 completion_info_charp = prev2_wd;
2134 COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions);
2137 /* CREATE FOREIGN */
2138 else if (Matches2("CREATE", "FOREIGN"))
2139 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2141 /* CREATE FOREIGN DATA WRAPPER */
2142 else if (Matches5("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2143 COMPLETE_WITH_LIST3("HANDLER", "VALIDATOR", "OPTIONS");
2145 /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */
2146 /* First off we complete CREATE UNIQUE with "INDEX" */
2147 else if (TailMatches2("CREATE", "UNIQUE"))
2148 COMPLETE_WITH_CONST("INDEX");
2151 * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and
2154 else if (TailMatches2("CREATE|UNIQUE", "INDEX"))
2155 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2156 " UNION SELECT 'ON'"
2157 " UNION SELECT 'CONCURRENTLY'");
2158 /* Complete ... INDEX|CONCURRENTLY [<name>] ON with a list of tables */
2159 else if (TailMatches3("INDEX|CONCURRENTLY", MatchAny, "ON") ||
2160 TailMatches2("INDEX|CONCURRENTLY", "ON"))
2161 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2164 * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing
2167 else if (TailMatches3("CREATE|UNIQUE", "INDEX", "CONCURRENTLY"))
2168 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2169 " UNION SELECT 'ON'");
2170 /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] <sth> with "ON" */
2171 else if (TailMatches3("CREATE|UNIQUE", "INDEX", MatchAny) ||
2172 TailMatches4("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny))
2173 COMPLETE_WITH_CONST("ON");
2176 * Complete INDEX <name> ON <table> with a list of table columns (which
2177 * should really be in parens)
2179 else if (TailMatches4("INDEX", MatchAny, "ON", MatchAny) ||
2180 TailMatches3("INDEX|CONCURRENTLY", "ON", MatchAny))
2181 COMPLETE_WITH_LIST2("(", "USING");
2182 else if (TailMatches5("INDEX", MatchAny, "ON", MatchAny, "(") ||
2183 TailMatches4("INDEX|CONCURRENTLY", "ON", MatchAny, "("))
2184 COMPLETE_WITH_ATTR(prev2_wd, "");
2185 /* same if you put in USING */
2186 else if (TailMatches5("ON", MatchAny, "USING", MatchAny, "("))
2187 COMPLETE_WITH_ATTR(prev4_wd, "");
2188 /* Complete USING with an index method */
2189 else if (TailMatches6("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
2190 TailMatches5("INDEX", MatchAny, "ON", MatchAny, "USING") ||
2191 TailMatches4("INDEX", "ON", MatchAny, "USING"))
2192 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2193 else if (TailMatches4("ON", MatchAny, "USING", MatchAny) &&
2194 !TailMatches6("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
2195 !TailMatches4("FOR", MatchAny, MatchAny, MatchAny))
2196 COMPLETE_WITH_CONST("(");
2199 /* Complete "CREATE POLICY <name> ON" */
2200 else if (Matches3("CREATE", "POLICY", MatchAny))
2201 COMPLETE_WITH_CONST("ON");
2202 /* Complete "CREATE POLICY <name> ON <table>" */
2203 else if (Matches4("CREATE", "POLICY", MatchAny, "ON"))
2204 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2205 /* Complete "CREATE POLICY <name> ON <table> AS|FOR|TO|USING|WITH CHECK" */
2206 else if (Matches5("CREATE", "POLICY", MatchAny, "ON", MatchAny))
2207 COMPLETE_WITH_LIST5("AS", "FOR", "TO", "USING (", "WITH CHECK (");
2208 /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE */
2209 else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS"))
2210 COMPLETE_WITH_LIST2("PERMISSIVE", "RESTRICTIVE");
2211 /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR|TO|USING|WITH CHECK */
2212 else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny))
2213 COMPLETE_WITH_LIST4("FOR", "TO", "USING", "WITH CHECK");
2214 /* CREATE POLICY <name> ON <table> FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2215 else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR"))
2216 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2217 /* Complete "CREATE POLICY <name> ON <table> FOR INSERT TO|WITH CHECK" */
2218 else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT"))
2219 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2220 /* Complete "CREATE POLICY <name> ON <table> FOR SELECT|DELETE TO|USING" */
2221 else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE"))
2222 COMPLETE_WITH_LIST2("TO", "USING (");
2223 /* CREATE POLICY <name> ON <table> FOR ALL|UPDATE TO|USING|WITH CHECK */
2224 else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE"))
2225 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2226 /* Complete "CREATE POLICY <name> ON <table> TO <role>" */
2227 else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO"))
2228 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2229 /* Complete "CREATE POLICY <name> ON <table> USING (" */
2230 else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING"))
2231 COMPLETE_WITH_CONST("(");
2232 /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR ALL|SELECT|INSERT|UPDATE|DELETE */
2233 else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR"))
2234 COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE");
2235 /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR INSERT TO|WITH CHECK" */
2236 else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT"))
2237 COMPLETE_WITH_LIST2("TO", "WITH CHECK (");
2238 /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR SELECT|DELETE TO|USING" */
2239 else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE"))
2240 COMPLETE_WITH_LIST2("TO", "USING (");
2241 /* CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE FOR ALL|UPDATE TO|USING|WITH CHECK */
2242 else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE"))
2243 COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK (");
2244 /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE TO <role>" */
2245 else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO"))
2246 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2247 /* Complete "CREATE POLICY <name> ON <table> AS PERMISSIVE|RESTRICTIVE USING (" */
2248 else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING"))
2249 COMPLETE_WITH_CONST("(");
2252 /* CREATE PUBLICATION */
2253 else if (Matches3("CREATE", "PUBLICATION", MatchAny))
2254 COMPLETE_WITH_LIST3("FOR TABLE", "FOR ALL TABLES", "WITH (");
2255 else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR"))
2256 COMPLETE_WITH_LIST2("TABLE", "ALL TABLES");
2257 /* Complete "CREATE PUBLICATION <name> FOR TABLE <table>" */
2258 else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR TABLE"))
2259 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2260 /* Complete "CREATE PUBLICATION <name> [...] WITH" */
2261 else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "("))
2262 COMPLETE_WITH_LIST2("PUBLISH", "NOPUBLISH");
2263 else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches3("WITH", "(", MatchAny))
2264 COMPLETE_WITH_LIST3("INSERT", "UPDATE", "DELETE");
2267 /* Complete "CREATE RULE <sth>" with "AS ON" */
2268 else if (Matches3("CREATE", "RULE", MatchAny))
2269 COMPLETE_WITH_CONST("AS ON");
2270 /* Complete "CREATE RULE <sth> AS" with "ON" */
2271 else if (Matches4("CREATE", "RULE", MatchAny, "AS"))
2272 COMPLETE_WITH_CONST("ON");
2273 /* Complete "CREATE RULE <sth> AS ON" with SELECT|UPDATE|INSERT|DELETE */
2274 else if (Matches5("CREATE", "RULE", MatchAny, "AS", "ON"))
2275 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE");
2276 /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */
2277 else if (TailMatches3("AS", "ON", "SELECT|UPDATE|INSERT|DELETE"))
2278 COMPLETE_WITH_CONST("TO");
2279 /* Complete "AS ON <sth> TO" with a table name */
2280 else if (TailMatches4("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO"))
2281 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2283 /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2284 else if (TailMatches3("CREATE", "SEQUENCE", MatchAny) ||
2285 TailMatches4("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny))
2286 COMPLETE_WITH_LIST8("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE",
2287 "CYCLE", "OWNED BY", "START WITH");
2288 else if (TailMatches4("CREATE", "SEQUENCE", MatchAny, "NO") ||
2289 TailMatches5("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO"))
2290 COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE");
2292 /* CREATE SERVER <name> */
2293 else if (Matches3("CREATE", "SERVER", MatchAny))
2294 COMPLETE_WITH_LIST3("TYPE", "VERSION", "FOREIGN DATA WRAPPER");
2296 /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
2297 /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */
2298 else if (TailMatches2("CREATE", "TEMP|TEMPORARY"))
2299 COMPLETE_WITH_LIST3("SEQUENCE", "TABLE", "VIEW");
2300 /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
2301 else if (TailMatches2("CREATE", "UNLOGGED"))
2302 COMPLETE_WITH_LIST2("TABLE", "MATERIALIZED VIEW");
2304 /* CREATE TABLESPACE */
2305 else if (Matches3("CREATE", "TABLESPACE", MatchAny))
2306 COMPLETE_WITH_LIST2("OWNER", "LOCATION");
2307 /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */
2308 else if (Matches5("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny))
2309 COMPLETE_WITH_CONST("LOCATION");
2311 /* CREATE TEXT SEARCH */
2312 else if (Matches3("CREATE", "TEXT", "SEARCH"))
2313 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2314 else if (Matches5("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny))
2315 COMPLETE_WITH_CONST("(");
2317 /* CREATE SUBSCRIPTION */
2318 else if (Matches3("CREATE", "SUBSCRIPTION", MatchAny))
2319 COMPLETE_WITH_CONST("CONNECTION");
2320 else if (Matches5("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION",MatchAny))
2321 COMPLETE_WITH_CONST("PUBLICATION");
2322 /* Complete "CREATE SUBSCRIPTION <name> ... WITH ( <opt>" */
2323 else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("WITH", "("))
2324 COMPLETE_WITH_LIST5("ENABLED", "DISABLED", "CREATE SLOT",
2325 "NOCREATE SLOT", "SLOT NAME");
2327 /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
2328 /* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
2329 else if (TailMatches3("CREATE", "TRIGGER", MatchAny))
2330 COMPLETE_WITH_LIST3("BEFORE", "AFTER", "INSTEAD OF");
2331 /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
2332 else if (TailMatches4("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER"))
2333 COMPLETE_WITH_LIST4("INSERT", "DELETE", "UPDATE", "TRUNCATE");
2334 /* complete CREATE TRIGGER <name> INSTEAD OF with an event */
2335 else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF"))
2336 COMPLETE_WITH_LIST3("INSERT", "DELETE", "UPDATE");
2337 /* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
2338 else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) ||
2339 TailMatches6("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny))
2340 COMPLETE_WITH_LIST2("ON", "OR");
2343 * complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of
2346 else if (TailMatches6("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON"))
2347 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
2348 /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */
2349 else if (TailMatches7("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON"))
2350 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
2351 else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("ON", MatchAny))
2352 COMPLETE_WITH_LIST7("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY",
2353 "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2354 else if (HeadMatches2("CREATE", "TRIGGER") &&
2355 (TailMatches1("DEFERRABLE") || TailMatches2("INITIALLY", "IMMEDIATE|DEFERRED")))
2356 COMPLETE_WITH_LIST4("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2357 else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("REFERENCING"))
2358 COMPLETE_WITH_LIST2("OLD TABLE", "NEW TABLE");
2359 else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("OLD|NEW", "TABLE"))
2360 COMPLETE_WITH_CONST("AS");
2361 else if (HeadMatches2("CREATE", "TRIGGER") &&
2362 (TailMatches5("REFERENCING", "OLD", "TABLE", "AS", MatchAny) ||
2363 TailMatches4("REFERENCING", "OLD", "TABLE", MatchAny)))
2364 COMPLETE_WITH_LIST4("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2365 else if (HeadMatches2("CREATE", "TRIGGER") &&
2366 (TailMatches5("REFERENCING", "NEW", "TABLE", "AS", MatchAny) ||
2367 TailMatches4("REFERENCING", "NEW", "TABLE", MatchAny)))
2368 COMPLETE_WITH_LIST4("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE");
2369 else if (HeadMatches2("CREATE", "TRIGGER") &&
2370 (TailMatches9("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2371 TailMatches8("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) ||
2372 TailMatches8("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) ||
2373 TailMatches7("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny)))
2374 COMPLETE_WITH_LIST3("FOR", "WHEN (", "EXECUTE PROCEDURE");
2375 else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("FOR"))
2376 COMPLETE_WITH_LIST3("EACH", "ROW", "STATEMENT");
2377 else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("FOR", "EACH"))
2378 COMPLETE_WITH_LIST2("ROW", "STATEMENT");
2379 else if (HeadMatches2("CREATE", "TRIGGER") &&
2380 (TailMatches3("FOR", "EACH", "ROW|STATEMENT") ||
2381 TailMatches2("FOR", "ROW|STATEMENT")))
2382 COMPLETE_WITH_LIST2("WHEN (", "EXECUTE PROCEDURE");
2383 /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE */
2384 else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("EXECUTE"))
2385 COMPLETE_WITH_CONST("PROCEDURE");
2386 else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("EXECUTE", "PROCEDURE"))
2387 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2389 /* CREATE ROLE,USER,GROUP <name> */
2390 else if (Matches3("CREATE", "ROLE|GROUP|USER", MatchAny) &&
2391 !TailMatches2("USER", "MAPPING"))
2393 static const char *const list_CREATEROLE[] =
2394 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2395 "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2396 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2397 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2398 "REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
2399 "VALID UNTIL", "WITH", NULL};
2401 COMPLETE_WITH_LIST(list_CREATEROLE);
2404 /* CREATE ROLE,USER,GROUP <name> WITH */
2405 else if (Matches4("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH"))
2407 /* Similar to the above, but don't complete "WITH" again. */
2408 static const char *const list_CREATEROLE_WITH[] =
2409 {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
2410 "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
2411 "NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
2412 "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
2413 "REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
2414 "VALID UNTIL", NULL};
2416 COMPLETE_WITH_LIST(list_CREATEROLE_WITH);
2420 * complete CREATE ROLE,USER,GROUP <name> ENCRYPTED,UNENCRYPTED with
2423 else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "ENCRYPTED|UNENCRYPTED"))
2424 COMPLETE_WITH_CONST("PASSWORD");
2425 /* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
2426 else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
2427 COMPLETE_WITH_LIST2("GROUP", "ROLE");
2429 /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
2430 /* Complete CREATE VIEW <name> with AS */
2431 else if (TailMatches3("CREATE", "VIEW", MatchAny))
2432 COMPLETE_WITH_CONST("AS");
2433 /* Complete "CREATE VIEW <sth> AS with "SELECT" */
2434 else if (TailMatches4("CREATE", "VIEW", MatchAny, "AS"))
2435 COMPLETE_WITH_CONST("SELECT");
2437 /* CREATE MATERIALIZED VIEW */
2438 else if (Matches2("CREATE", "MATERIALIZED"))
2439 COMPLETE_WITH_CONST("VIEW");
2440 /* Complete CREATE MATERIALIZED VIEW <name> with AS */
2441 else if (Matches4("CREATE", "MATERIALIZED", "VIEW", MatchAny))
2442 COMPLETE_WITH_CONST("AS");
2443 /* Complete "CREATE MATERIALIZED VIEW <sth> AS with "SELECT" */
2444 else if (Matches5("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS"))
2445 COMPLETE_WITH_CONST("SELECT");
2447 /* CREATE EVENT TRIGGER */
2448 else if (Matches2("CREATE", "EVENT"))
2449 COMPLETE_WITH_CONST("TRIGGER");
2450 /* Complete CREATE EVENT TRIGGER <name> with ON */
2451 else if (Matches4("CREATE", "EVENT", "TRIGGER", MatchAny))
2452 COMPLETE_WITH_CONST("ON");
2453 /* Complete CREATE EVENT TRIGGER <name> ON with event_type */
2454 else if (Matches5("CREATE", "EVENT", "TRIGGER", MatchAny, "ON"))
2455 COMPLETE_WITH_LIST3("ddl_command_start", "ddl_command_end", "sql_drop");
2458 else if (Matches2("DECLARE", MatchAny))
2459 COMPLETE_WITH_LIST5("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL",
2461 else if (HeadMatches1("DECLARE") && TailMatches1("CURSOR"))
2462 COMPLETE_WITH_LIST3("WITH HOLD", "WITHOUT HOLD", "FOR");
2464 /* DELETE --- can be inside EXPLAIN, RULE, etc */
2465 /* ... despite which, only complete DELETE with FROM at start of line */
2466 else if (Matches1("DELETE"))
2467 COMPLETE_WITH_CONST("FROM");
2468 /* Complete DELETE FROM with a list of tables */
2469 else if (TailMatches2("DELETE", "FROM"))
2470 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2471 /* Complete DELETE FROM <table> */
2472 else if (TailMatches3("DELETE", "FROM", MatchAny))
2473 COMPLETE_WITH_LIST2("USING", "WHERE");
2474 /* XXX: implement tab completion for DELETE ... USING */
2477 else if (Matches1("DISCARD"))
2478 COMPLETE_WITH_LIST4("ALL", "PLANS", "SEQUENCES", "TEMP");
2481 else if (Matches1("DO"))
2482 COMPLETE_WITH_CONST("LANGUAGE");
2485 /* Complete DROP object with CASCADE / RESTRICT */
2486 else if (Matches3("DROP",
2487 "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|TABLE|TYPE|VIEW",
2489 Matches4("DROP", "ACCESS", "METHOD", MatchAny) ||
2490 (Matches4("DROP", "AGGREGATE|FUNCTION", MatchAny, MatchAny) &&
2491 ends_with(prev_wd, ')')) ||
2492 Matches4("DROP", "EVENT", "TRIGGER", MatchAny) ||
2493 Matches5("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) ||
2494 Matches4("DROP", "FOREIGN", "TABLE", MatchAny) ||
2495 Matches5("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny))
2496 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2498 /* help completing some of the variants */
2499 else if (Matches3("DROP", "AGGREGATE|FUNCTION", MatchAny))
2500 COMPLETE_WITH_CONST("(");
2501 else if (Matches4("DROP", "AGGREGATE|FUNCTION", MatchAny, "("))
2502 COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
2503 else if (Matches2("DROP", "FOREIGN"))
2504 COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE");
2507 else if (Matches2("DROP", "INDEX"))
2508 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
2509 " UNION SELECT 'CONCURRENTLY'");
2510 else if (Matches3("DROP", "INDEX", "CONCURRENTLY"))
2511 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2512 else if (Matches3("DROP", "INDEX", MatchAny))
2513 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2514 else if (Matches4("DROP", "INDEX", "CONCURRENTLY", MatchAny))
2515 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2517 /* DROP MATERIALIZED VIEW */
2518 else if (Matches2("DROP", "MATERIALIZED"))
2519 COMPLETE_WITH_CONST("VIEW");
2520 else if (Matches3("DROP", "MATERIALIZED", "VIEW"))
2521 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2524 else if (Matches2("DROP", "OWNED"))
2525 COMPLETE_WITH_CONST("BY");
2526 else if (Matches3("DROP", "OWNED", "BY"))
2527 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2529 else if (Matches3("DROP", "TEXT", "SEARCH"))
2530 COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE");
2533 else if (Matches3("DROP", "TRIGGER", MatchAny))
2534 COMPLETE_WITH_CONST("ON");
2535 else if (Matches4("DROP", "TRIGGER", MatchAny, "ON"))
2537 completion_info_charp = prev2_wd;
2538 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2540 else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny))
2541 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2543 /* DROP ACCESS METHOD */
2544 else if (Matches2("DROP", "ACCESS"))
2545 COMPLETE_WITH_CONST("METHOD");
2546 else if (Matches3("DROP", "ACCESS", "METHOD"))
2547 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
2549 /* DROP EVENT TRIGGER */
2550 else if (Matches2("DROP", "EVENT"))
2551 COMPLETE_WITH_CONST("TRIGGER");
2552 else if (Matches3("DROP", "EVENT", "TRIGGER"))
2553 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
2555 /* DROP POLICY <name> */
2556 else if (Matches2("DROP", "POLICY"))
2557 COMPLETE_WITH_QUERY(Query_for_list_of_policies);
2558 /* DROP POLICY <name> ON */
2559 else if (Matches3("DROP", "POLICY", MatchAny))
2560 COMPLETE_WITH_CONST("ON");
2561 /* DROP POLICY <name> ON <table> */
2562 else if (Matches4("DROP", "POLICY", MatchAny, "ON"))
2564 completion_info_charp = prev2_wd;
2565 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy);
2569 else if (Matches3("DROP", "RULE", MatchAny))
2570 COMPLETE_WITH_CONST("ON");
2571 else if (Matches4("DROP", "RULE", MatchAny, "ON"))
2573 completion_info_charp = prev2_wd;
2574 COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2576 else if (Matches5("DROP", "RULE", MatchAny, "ON", MatchAny))
2577 COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
2580 else if (Matches1("EXECUTE"))
2581 COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
2586 * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands
2588 else if (Matches1("EXPLAIN"))
2589 COMPLETE_WITH_LIST7("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2590 "ANALYZE", "VERBOSE");
2591 else if (Matches2("EXPLAIN", "ANALYZE"))
2592 COMPLETE_WITH_LIST6("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE",
2594 else if (Matches2("EXPLAIN", "VERBOSE") ||
2595 Matches3("EXPLAIN", "ANALYZE", "VERBOSE"))
2596 COMPLETE_WITH_LIST5("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE");
2599 /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
2600 else if (Matches1("FETCH|MOVE"))
2601 COMPLETE_WITH_LIST4("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE");
2602 /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
2603 else if (Matches2("FETCH|MOVE", MatchAny))
2604 COMPLETE_WITH_LIST3("ALL", "NEXT", "PRIOR");
2607 * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
2608 * but we may as well tab-complete both: perhaps some users prefer one
2609 * variant or the other.
2611 else if (Matches3("FETCH|MOVE", MatchAny, MatchAny))
2612 COMPLETE_WITH_LIST2("FROM", "IN");
2614 /* FOREIGN DATA WRAPPER */
2615 /* applies in ALTER/DROP FDW and in CREATE SERVER */
2616 else if (TailMatches3("FOREIGN", "DATA", "WRAPPER") &&
2617 !TailMatches4("CREATE", MatchAny, MatchAny, MatchAny))
2618 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
2619 /* applies in CREATE SERVER */
2620 else if (TailMatches4("FOREIGN", "DATA", "WRAPPER", MatchAny) &&
2621 HeadMatches2("CREATE", "SERVER"))
2622 COMPLETE_WITH_CONST("OPTIONS");
2625 else if (TailMatches2("FOREIGN", "TABLE") &&
2626 !TailMatches3("CREATE", MatchAny, MatchAny))
2627 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
2629 /* FOREIGN SERVER */
2630 else if (TailMatches2("FOREIGN", "SERVER"))
2631 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
2634 * GRANT and REVOKE are allowed inside CREATE SCHEMA and
2635 * ALTER DEFAULT PRIVILEGES, so use TailMatches
2637 /* Complete GRANT/REVOKE with a list of roles and privileges */
2638 else if (TailMatches1("GRANT|REVOKE"))
2640 * With ALTER DEFAULT PRIVILEGES, restrict completion
2641 * to grantable privileges (can't grant roles)
2643 if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2644 COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE",
2645 "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
2646 "EXECUTE", "USAGE", "ALL");
2648 COMPLETE_WITH_QUERY(Query_for_list_of_roles
2649 " UNION SELECT 'SELECT'"
2650 " UNION SELECT 'INSERT'"
2651 " UNION SELECT 'UPDATE'"
2652 " UNION SELECT 'DELETE'"
2653 " UNION SELECT 'TRUNCATE'"
2654 " UNION SELECT 'REFERENCES'"
2655 " UNION SELECT 'TRIGGER'"
2656 " UNION SELECT 'CREATE'"
2657 " UNION SELECT 'CONNECT'"
2658 " UNION SELECT 'TEMPORARY'"
2659 " UNION SELECT 'EXECUTE'"
2660 " UNION SELECT 'USAGE'"
2661 " UNION SELECT 'ALL'");
2664 * Complete GRANT/REVOKE <privilege> with "ON", GRANT/REVOKE <role> with
2667 else if (TailMatches2("GRANT|REVOKE", MatchAny))
2669 if (TailMatches1("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
2670 COMPLETE_WITH_CONST("ON");
2671 else if (TailMatches2("GRANT", MatchAny))
2672 COMPLETE_WITH_CONST("TO");
2674 COMPLETE_WITH_CONST("FROM");
2678 * Complete GRANT/REVOKE <sth> ON with a list of tables, views, and
2681 * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query
2682 * result via UNION; seems to work intuitively.
2684 * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
2685 * here will only work if the privilege list contains exactly one
2688 else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON"))
2690 * With ALTER DEFAULT PRIVILEGES, restrict completion
2691 * to the kinds of objects supported.
2693 if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
2694 COMPLETE_WITH_LIST4("TABLES", "SEQUENCES", "FUNCTIONS", "TYPES");
2696 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf,
2697 " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"
2698 " UNION SELECT 'ALL SEQUENCES IN SCHEMA'"
2699 " UNION SELECT 'ALL TABLES IN SCHEMA'"
2700 " UNION SELECT 'DATABASE'"
2701 " UNION SELECT 'DOMAIN'"
2702 " UNION SELECT 'FOREIGN DATA WRAPPER'"
2703 " UNION SELECT 'FOREIGN SERVER'"
2704 " UNION SELECT 'FUNCTION'"
2705 " UNION SELECT 'LANGUAGE'"
2706 " UNION SELECT 'LARGE OBJECT'"
2707 " UNION SELECT 'SCHEMA'"
2708 " UNION SELECT 'SEQUENCE'"
2709 " UNION SELECT 'TABLE'"
2710 " UNION SELECT 'TABLESPACE'"
2711 " UNION SELECT 'TYPE'");
2713 else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "ALL"))
2714 COMPLETE_WITH_LIST3("FUNCTIONS IN SCHEMA", "SEQUENCES IN SCHEMA",
2715 "TABLES IN SCHEMA");
2717 else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "FOREIGN"))
2718 COMPLETE_WITH_LIST2("DATA WRAPPER", "SERVER");
2721 * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of
2722 * appropriate objects.
2724 * Complete "GRANT/REVOKE * ON *" with "TO/FROM".
2726 else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", MatchAny))
2728 if (TailMatches1("DATABASE"))
2729 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2730 else if (TailMatches1("DOMAIN"))
2731 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
2732 else if (TailMatches1("FUNCTION"))
2733 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
2734 else if (TailMatches1("LANGUAGE"))
2735 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
2736 else if (TailMatches1("SCHEMA"))
2737 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2738 else if (TailMatches1("SEQUENCE"))
2739 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
2740 else if (TailMatches1("TABLE"))
2741 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
2742 else if (TailMatches1("TABLESPACE"))
2743 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
2744 else if (TailMatches1("TYPE"))
2745 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
2746 else if (TailMatches4("GRANT", MatchAny, MatchAny, MatchAny))
2747 COMPLETE_WITH_CONST("TO");
2749 COMPLETE_WITH_CONST("FROM");
2753 * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC,
2754 * CURRENT_USER, or SESSION_USER.
2756 else if ((HeadMatches1("GRANT") && TailMatches1("TO")) ||
2757 (HeadMatches1("REVOKE") && TailMatches1("FROM")))
2758 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2759 /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */
2760 else if (HeadMatches3("ALTER","DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM"))
2761 COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
2762 /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */
2763 else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny))
2764 COMPLETE_WITH_CONST("TO");
2765 else if (HeadMatches1("REVOKE") && TailMatches3("ON", MatchAny, MatchAny))
2766 COMPLETE_WITH_CONST("FROM");
2768 /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */
2769 else if (TailMatches8("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny))
2771 if (TailMatches8("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2772 COMPLETE_WITH_CONST("TO");
2774 COMPLETE_WITH_CONST("FROM");
2777 /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */
2778 else if (TailMatches7("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny))
2780 if (TailMatches7("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2781 COMPLETE_WITH_CONST("TO");
2783 COMPLETE_WITH_CONST("FROM");
2786 /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */
2787 else if (TailMatches6("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny))
2789 if (TailMatches6("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny))
2790 COMPLETE_WITH_CONST("TO");
2792 COMPLETE_WITH_CONST("FROM");
2796 else if (TailMatches3("FROM", MatchAny, "GROUP"))
2797 COMPLETE_WITH_CONST("BY");
2799 /* IMPORT FOREIGN SCHEMA */
2800 else if (Matches1("IMPORT"))
2801 COMPLETE_WITH_CONST("FOREIGN SCHEMA");
2802 else if (Matches2("IMPORT", "FOREIGN"))
2803 COMPLETE_WITH_CONST("SCHEMA");
2805 /* INSERT --- can be inside EXPLAIN, RULE, etc */
2806 /* Complete INSERT with "INTO" */
2807 else if (TailMatches1("INSERT"))
2808 COMPLETE_WITH_CONST("INTO");
2809 /* Complete INSERT INTO with table names */
2810 else if (TailMatches2("INSERT", "INTO"))
2811 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
2812 /* Complete "INSERT INTO <table> (" with attribute names */
2813 else if (TailMatches4("INSERT", "INTO", MatchAny, "("))
2814 COMPLETE_WITH_ATTR(prev2_wd, "");
2817 * Complete INSERT INTO <table> with "(" or "VALUES" or "SELECT" or
2818 * "TABLE" or "DEFAULT VALUES"
2820 else if (TailMatches3("INSERT", "INTO", MatchAny))
2821 COMPLETE_WITH_LIST5("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES");
2824 * Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" or
2827 else if (TailMatches4("INSERT", "INTO", MatchAny, MatchAny) &&
2828 ends_with(prev_wd, ')'))
2829 COMPLETE_WITH_LIST3("SELECT", "TABLE", "VALUES");
2831 /* Insert an open parenthesis after "VALUES" */
2832 else if (TailMatches1("VALUES") && !TailMatches2("DEFAULT", "VALUES"))
2833 COMPLETE_WITH_CONST("(");
2836 /* Complete LOCK [TABLE] with a list of tables */
2837 else if (Matches1("LOCK"))
2838 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
2839 " UNION SELECT 'TABLE'");
2840 else if (Matches2("LOCK", "TABLE"))
2841 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
2843 /* For the following, handle the case of a single table only for now */
2845 /* Complete LOCK [TABLE] <table> with "IN" */
2846 else if (Matches2("LOCK", MatchAnyExcept("TABLE")) ||
2847 Matches3("LOCK", "TABLE", MatchAny))
2848 COMPLETE_WITH_CONST("IN");
2850 /* Complete LOCK [TABLE] <table> IN with a lock mode */
2851 else if (Matches3("LOCK", MatchAny, "IN") ||
2852 Matches4("LOCK", "TABLE", MatchAny, "IN"))
2853 COMPLETE_WITH_LIST8("ACCESS SHARE MODE",
2854 "ROW SHARE MODE", "ROW EXCLUSIVE MODE",
2855 "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE",
2856 "SHARE ROW EXCLUSIVE MODE",
2857 "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE");
2859 /* Complete LOCK [TABLE] <table> IN ACCESS|ROW with rest of lock mode */
2860 else if (Matches4("LOCK", MatchAny, "IN", "ACCESS|ROW") ||
2861 Matches5("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW"))
2862 COMPLETE_WITH_LIST2("EXCLUSIVE MODE", "SHARE MODE");
2864 /* Complete LOCK [TABLE] <table> IN SHARE with rest of lock mode */
2865 else if (Matches4("LOCK", MatchAny, "IN", "SHARE") ||
2866 Matches5("LOCK", "TABLE", MatchAny, "IN", "SHARE"))
2867 COMPLETE_WITH_LIST3("MODE", "ROW EXCLUSIVE MODE",
2868 "UPDATE EXCLUSIVE MODE");
2870 /* NOTIFY --- can be inside EXPLAIN, RULE, etc */
2871 else if (TailMatches1("NOTIFY"))
2872 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'");
2875 else if (TailMatches1("OPTIONS"))
2876 COMPLETE_WITH_CONST("(");
2878 /* OWNER TO - complete with available roles */
2879 else if (TailMatches2("OWNER", "TO"))
2880 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2883 else if (TailMatches3("FROM", MatchAny, "ORDER"))
2884 COMPLETE_WITH_CONST("BY");
2885 else if (TailMatches4("FROM", MatchAny, "ORDER", "BY"))
2886 COMPLETE_WITH_ATTR(prev3_wd, "");
2889 else if (Matches3("PREPARE", MatchAny, "AS"))
2890 COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE FROM");
2893 * PREPARE TRANSACTION is missing on purpose. It's intended for transaction
2894 * managers, not for manual use in interactive sessions.
2897 /* REASSIGN OWNED BY xxx TO yyy */
2898 else if (Matches1("REASSIGN"))
2899 COMPLETE_WITH_CONST("OWNED BY");
2900 else if (Matches2("REASSIGN", "OWNED"))
2901 COMPLETE_WITH_CONST("BY");
2902 else if (Matches3("REASSIGN", "OWNED", "BY"))
2903 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2904 else if (Matches4("REASSIGN", "OWNED", "BY", MatchAny))
2905 COMPLETE_WITH_CONST("TO");
2906 else if (Matches5("REASSIGN", "OWNED", "BY", MatchAny, "TO"))
2907 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
2909 /* REFRESH MATERIALIZED VIEW */
2910 else if (Matches1("REFRESH"))
2911 COMPLETE_WITH_CONST("MATERIALIZED VIEW");
2912 else if (Matches2("REFRESH", "MATERIALIZED"))
2913 COMPLETE_WITH_CONST("VIEW");
2914 else if (Matches3("REFRESH", "MATERIALIZED", "VIEW"))
2915 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
2916 " UNION SELECT 'CONCURRENTLY'");
2917 else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY"))
2918 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
2919 else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", MatchAny))
2920 COMPLETE_WITH_CONST("WITH");
2921 else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny))
2922 COMPLETE_WITH_CONST("WITH");
2923 else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH"))
2924 COMPLETE_WITH_LIST2("NO DATA", "DATA");
2925 else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH"))
2926 COMPLETE_WITH_LIST2("NO DATA", "DATA");
2927 else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO"))
2928 COMPLETE_WITH_CONST("DATA");
2929 else if (Matches7("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO"))
2930 COMPLETE_WITH_CONST("DATA");
2933 else if (Matches1("REINDEX"))
2934 COMPLETE_WITH_LIST5("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE");
2935 else if (Matches2("REINDEX", "TABLE"))
2936 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
2937 else if (Matches2("REINDEX", "INDEX"))
2938 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
2939 else if (Matches2("REINDEX", "SCHEMA"))
2940 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
2941 else if (Matches2("REINDEX", "SYSTEM|DATABASE"))
2942 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
2944 /* SECURITY LABEL */
2945 else if (Matches1("SECURITY"))
2946 COMPLETE_WITH_CONST("LABEL");
2947 else if (Matches2("SECURITY", "LABEL"))
2948 COMPLETE_WITH_LIST2("ON", "FOR");
2949 else if (Matches4("SECURITY", "LABEL", "FOR", MatchAny))
2950 COMPLETE_WITH_CONST("ON");
2951 else if (Matches3("SECURITY", "LABEL", "ON") ||
2952 Matches5("SECURITY", "LABEL", "FOR", MatchAny, "ON"))
2954 static const char *const list_SECURITY_LABEL[] =
2955 {"TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN",
2956 "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", "LARGE OBJECT",
2957 "MATERIALIZED VIEW", "LANGUAGE", "ROLE", "SCHEMA",
2958 "SEQUENCE", "TABLESPACE", "TYPE", "VIEW", NULL};
2960 COMPLETE_WITH_LIST(list_SECURITY_LABEL);
2962 else if (Matches5("SECURITY", "LABEL", "ON", MatchAny, MatchAny))
2963 COMPLETE_WITH_CONST("IS");
2968 /* SET, RESET, SHOW */
2969 /* Complete with a variable name */
2970 else if (TailMatches1("SET|RESET") && !TailMatches3("UPDATE", MatchAny, "SET"))
2971 COMPLETE_WITH_QUERY(Query_for_list_of_set_vars);
2972 else if (Matches1("SHOW"))
2973 COMPLETE_WITH_QUERY(Query_for_list_of_show_vars);
2974 /* Complete "SET TRANSACTION" */
2975 else if (Matches2("SET", "TRANSACTION"))
2976 COMPLETE_WITH_LIST5("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2977 else if (Matches2("BEGIN|START", "TRANSACTION") ||
2978 Matches2("BEGIN", "WORK") ||
2979 Matches1("BEGIN") ||
2980 Matches5("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION"))
2981 COMPLETE_WITH_LIST4("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
2982 else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") ||
2983 Matches2("BEGIN", "NOT") ||
2984 Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT"))
2985 COMPLETE_WITH_CONST("DEFERRABLE");
2986 else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") ||
2987 Matches2("BEGIN", "ISOLATION") ||
2988 Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION"))
2989 COMPLETE_WITH_CONST("LEVEL");
2990 else if (Matches4("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") ||
2991 Matches3("BEGIN", "ISOLATION", "LEVEL") ||
2992 Matches7("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL"))
2993 COMPLETE_WITH_LIST3("READ", "REPEATABLE READ", "SERIALIZABLE");
2994 else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") ||
2995 Matches4("BEGIN", "ISOLATION", "LEVEL", "READ") ||
2996 Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ"))
2997 COMPLETE_WITH_LIST2("UNCOMMITTED", "COMMITTED");
2998 else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") ||
2999 Matches4("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") ||
3000 Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE"))
3001 COMPLETE_WITH_CONST("READ");
3002 else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "READ") ||
3003 Matches2("BEGIN", "READ") ||
3004 Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ"))
3005 COMPLETE_WITH_LIST2("ONLY", "WRITE");
3006 /* SET CONSTRAINTS */
3007 else if (Matches2("SET", "CONSTRAINTS"))
3008 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'");
3009 /* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
3010 else if (Matches3("SET", "CONSTRAINTS", MatchAny))
3011 COMPLETE_WITH_LIST2("DEFERRED", "IMMEDIATE");
3012 /* Complete SET ROLE */
3013 else if (Matches2("SET", "ROLE"))
3014 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3015 /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
3016 else if (Matches2("SET", "SESSION"))
3017 COMPLETE_WITH_LIST2("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION");
3018 /* Complete SET SESSION AUTHORIZATION with username */
3019 else if (Matches3("SET", "SESSION", "AUTHORIZATION"))
3020 COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'");
3021 /* Complete RESET SESSION with AUTHORIZATION */
3022 else if (Matches2("RESET", "SESSION"))
3023 COMPLETE_WITH_CONST("AUTHORIZATION");
3024 /* Complete SET <var> with "TO" */
3025 else if (Matches2("SET", MatchAny))
3026 COMPLETE_WITH_CONST("TO");
3027 /* Complete ALTER DATABASE|FUNCTION|ROLE|USER ... SET <name> */
3028 else if (HeadMatches2("ALTER", "DATABASE|FUNCTION|ROLE|USER") &&
3029 TailMatches2("SET", MatchAny))
3030 COMPLETE_WITH_LIST2("FROM CURRENT", "TO");
3031 /* Suggest possible variable values */
3032 else if (TailMatches3("SET", MatchAny, "TO|="))
3034 /* special cased code for individual GUCs */
3035 if (TailMatches2("DateStyle", "TO|="))
3037 static const char *const my_list[] =
3038 {"ISO", "SQL", "Postgres", "German",
3039 "YMD", "DMY", "MDY",
3040 "US", "European", "NonEuropean",
3043 COMPLETE_WITH_LIST(my_list);
3045 else if (TailMatches2("search_path", "TO|="))
3046 COMPLETE_WITH_QUERY(Query_for_list_of_schemas
3047 " AND nspname not like 'pg\\_toast%%' "
3048 " AND nspname not like 'pg\\_temp%%' "
3049 " UNION SELECT 'DEFAULT' ");
3052 /* generic, type based, GUC support */
3053 char *guctype = get_guctype(prev2_wd);
3055 if (guctype && strcmp(guctype, "enum") == 0)
3057 char querybuf[1024];
3059 snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd);
3060 COMPLETE_WITH_QUERY(querybuf);
3062 else if (guctype && strcmp(guctype, "bool") == 0)
3063 COMPLETE_WITH_LIST9("on", "off", "true", "false", "yes", "no",
3064 "1", "0", "DEFAULT");
3066 COMPLETE_WITH_CONST("DEFAULT");
3073 /* START TRANSACTION */
3074 else if (Matches1("START"))
3075 COMPLETE_WITH_CONST("TRANSACTION");
3077 /* TABLE, but not TABLE embedded in other commands */
3078 else if (Matches1("TABLE"))
3079 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3082 else if (TailMatches1("TABLESAMPLE"))
3083 COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods);
3084 else if (TailMatches2("TABLESAMPLE", MatchAny))
3085 COMPLETE_WITH_CONST("(");
3088 else if (Matches1("TRUNCATE"))
3089 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3092 else if (Matches1("UNLISTEN"))
3093 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 '*'");
3095 /* UPDATE --- can be inside EXPLAIN, RULE, etc */
3096 /* If prev. word is UPDATE suggest a list of tables */
3097 else if (TailMatches1("UPDATE"))
3098 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL);
3099 /* Complete UPDATE <table> with "SET" */
3100 else if (TailMatches2("UPDATE", MatchAny))
3101 COMPLETE_WITH_CONST("SET");
3102 /* Complete UPDATE <table> SET with list of attributes */
3103 else if (TailMatches3("UPDATE", MatchAny, "SET"))
3104 COMPLETE_WITH_ATTR(prev2_wd, "");
3105 /* UPDATE <table> SET <attr> = */
3106 else if (TailMatches4("UPDATE", MatchAny, "SET", MatchAny))
3107 COMPLETE_WITH_CONST("=");
3110 else if (Matches3("ALTER|CREATE|DROP", "USER", "MAPPING"))
3111 COMPLETE_WITH_CONST("FOR");
3112 else if (Matches4("CREATE", "USER", "MAPPING", "FOR"))
3113 COMPLETE_WITH_QUERY(Query_for_list_of_roles
3114 " UNION SELECT 'CURRENT_USER'"
3115 " UNION SELECT 'PUBLIC'"
3116 " UNION SELECT 'USER'");
3117 else if (Matches4("ALTER|DROP", "USER", "MAPPING", "FOR"))
3118 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3119 else if (Matches5("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny))
3120 COMPLETE_WITH_CONST("SERVER");
3121 else if (Matches7("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny))
3122 COMPLETE_WITH_CONST("OPTIONS");
3125 * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ]
3126 * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]
3128 else if (Matches1("VACUUM"))
3129 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3130 " UNION SELECT 'FULL'"
3131 " UNION SELECT 'FREEZE'"
3132 " UNION SELECT 'ANALYZE'"
3133 " UNION SELECT 'VERBOSE'");
3134 else if (Matches2("VACUUM", "FULL|FREEZE"))
3135 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3136 " UNION SELECT 'ANALYZE'"
3137 " UNION SELECT 'VERBOSE'");
3138 else if (Matches3("VACUUM", "FULL|FREEZE", "ANALYZE"))
3139 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3140 " UNION SELECT 'VERBOSE'");
3141 else if (Matches3("VACUUM", "FULL|FREEZE", "VERBOSE"))
3142 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3143 " UNION SELECT 'ANALYZE'");
3144 else if (Matches2("VACUUM", "VERBOSE"))
3145 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3146 " UNION SELECT 'ANALYZE'");
3147 else if (Matches2("VACUUM", "ANALYZE"))
3148 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
3149 " UNION SELECT 'VERBOSE'");
3150 else if (HeadMatches1("VACUUM"))
3151 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
3153 /* WITH [RECURSIVE] */
3156 * Only match when WITH is the first word, as WITH may appear in many
3159 else if (Matches1("WITH"))
3160 COMPLETE_WITH_CONST("RECURSIVE");
3163 /* Complete with list of tables */
3164 else if (Matches1("ANALYZE"))
3165 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tmf, NULL);
3168 /* Simple case of the word before the where being the table name */
3169 else if (TailMatches2(MatchAny, "WHERE"))
3170 COMPLETE_WITH_ATTR(prev2_wd, "");
3173 /* TODO: also include SRF ? */
3174 else if (TailMatches1("FROM") && !Matches3("COPY|\\copy", MatchAny, "FROM"))
3175 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3178 else if (TailMatches1("JOIN"))
3179 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3181 /* Backslash commands */
3182 /* TODO: \dc \dd \dl */
3183 else if (TailMatchesCS1("\\?"))
3184 COMPLETE_WITH_LIST_CS3("commands", "options", "variables");
3185 else if (TailMatchesCS1("\\connect|\\c"))
3187 if (!recognized_connection_string(text))
3188 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3190 else if (TailMatchesCS2("\\connect|\\c", MatchAny))
3192 if (!recognized_connection_string(prev_wd))
3193 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3195 else if (TailMatchesCS1("\\da*"))
3196 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL);
3197 else if (TailMatchesCS1("\\dA*"))
3198 COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
3199 else if (TailMatchesCS1("\\db*"))
3200 COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
3201 else if (TailMatchesCS1("\\dD*"))
3202 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
3203 else if (TailMatchesCS1("\\des*"))
3204 COMPLETE_WITH_QUERY(Query_for_list_of_servers);
3205 else if (TailMatchesCS1("\\deu*"))
3206 COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings);
3207 else if (TailMatchesCS1("\\dew*"))
3208 COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
3209 else if (TailMatchesCS1("\\df*"))
3210 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3212 else if (TailMatchesCS1("\\dFd*"))
3213 COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
3214 else if (TailMatchesCS1("\\dFp*"))
3215 COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
3216 else if (TailMatchesCS1("\\dFt*"))
3217 COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
3218 /* must be at end of \dF alternatives: */
3219 else if (TailMatchesCS1("\\dF*"))
3220 COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
3222 else if (TailMatchesCS1("\\di*"))
3223 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
3224 else if (TailMatchesCS1("\\dL*"))
3225 COMPLETE_WITH_QUERY(Query_for_list_of_languages);
3226 else if (TailMatchesCS1("\\dn*"))
3227 COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
3228 else if (TailMatchesCS1("\\dp") || TailMatchesCS1("\\z"))
3229 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL);
3230 else if (TailMatchesCS1("\\ds*"))
3231 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL);
3232 else if (TailMatchesCS1("\\dt*"))
3233 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
3234 else if (TailMatchesCS1("\\dT*"))
3235 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL);
3236 else if (TailMatchesCS1("\\du*") || TailMatchesCS1("\\dg*"))
3237 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3238 else if (TailMatchesCS1("\\dv*"))
3239 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3240 else if (TailMatchesCS1("\\dx*"))
3241 COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
3242 else if (TailMatchesCS1("\\dm*"))
3243 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
3244 else if (TailMatchesCS1("\\dE*"))
3245 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL);
3246 else if (TailMatchesCS1("\\dy*"))
3247 COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
3249 /* must be at end of \d alternatives: */
3250 else if (TailMatchesCS1("\\d*"))
3251 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL);
3253 else if (TailMatchesCS1("\\ef"))
3254 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3255 else if (TailMatchesCS1("\\ev"))
3256 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3258 else if (TailMatchesCS1("\\encoding"))
3259 COMPLETE_WITH_QUERY(Query_for_list_of_encodings);
3260 else if (TailMatchesCS1("\\h") || TailMatchesCS1("\\help"))
3261 COMPLETE_WITH_LIST(sql_commands);
3262 else if (TailMatchesCS1("\\l*") && !TailMatchesCS1("\\lo*"))
3263 COMPLETE_WITH_QUERY(Query_for_list_of_databases);
3264 else if (TailMatchesCS1("\\password"))
3265 COMPLETE_WITH_QUERY(Query_for_list_of_roles);
3266 else if (TailMatchesCS1("\\pset"))
3268 static const char *const my_list[] =
3269 {"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
3270 "footer", "format", "linestyle", "null", "numericlocale",
3271 "pager", "pager_min_lines", "recordsep", "recordsep_zero",
3272 "tableattr", "title", "tuples_only", "unicode_border_linestyle",
3273 "unicode_column_linestyle", "unicode_header_linestyle", NULL};
3275 COMPLETE_WITH_LIST_CS(my_list);
3277 else if (TailMatchesCS2("\\pset", MatchAny))
3279 if (TailMatchesCS1("format"))
3281 static const char *const my_list[] =
3282 {"unaligned", "aligned", "wrapped", "html", "asciidoc",
3283 "latex", "latex-longtable", "troff-ms", NULL};
3285 COMPLETE_WITH_LIST_CS(my_list);
3287 else if (TailMatchesCS1("linestyle"))
3288 COMPLETE_WITH_LIST_CS3("ascii", "old-ascii", "unicode");
3289 else if (TailMatchesCS1("unicode_border_linestyle|"
3290 "unicode_column_linestyle|"
3291 "unicode_header_linestyle"))
3292 COMPLETE_WITH_LIST_CS2("single", "double");
3294 else if (TailMatchesCS1("\\unset"))
3296 matches = complete_from_variables(text, "", "", true);
3298 else if (TailMatchesCS1("\\set"))
3300 matches = complete_from_variables(text, "", "", false);
3302 else if (TailMatchesCS2("\\set", MatchAny))
3304 if (TailMatchesCS1("AUTOCOMMIT|ON_ERROR_STOP|QUIET|"
3305 "SINGLELINE|SINGLESTEP"))
3306 COMPLETE_WITH_LIST_CS2("on", "off");
3307 else if (TailMatchesCS1("COMP_KEYWORD_CASE"))
3308 COMPLETE_WITH_LIST_CS4("lower", "upper",
3309 "preserve-lower", "preserve-upper");
3310 else if (TailMatchesCS1("ECHO"))
3311 COMPLETE_WITH_LIST_CS4("errors", "queries", "all", "none");
3312 else if (TailMatchesCS1("ECHO_HIDDEN"))
3313 COMPLETE_WITH_LIST_CS3("noexec", "off", "on");
3314 else if (TailMatchesCS1("HISTCONTROL"))
3315 COMPLETE_WITH_LIST_CS4("ignorespace", "ignoredups",
3316 "ignoreboth", "none");
3317 else if (TailMatchesCS1("ON_ERROR_ROLLBACK"))
3318 COMPLETE_WITH_LIST_CS3("on", "off", "interactive");
3319 else if (TailMatchesCS1("SHOW_CONTEXT"))
3320 COMPLETE_WITH_LIST_CS3("never", "errors", "always");
3321 else if (TailMatchesCS1("VERBOSITY"))
3322 COMPLETE_WITH_LIST_CS3("default", "verbose", "terse");
3324 else if (TailMatchesCS1("\\sf*"))
3325 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
3326 else if (TailMatchesCS1("\\sv*"))
3327 COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
3328 else if (TailMatchesCS1("\\cd|\\e|\\edit|\\g|\\i|\\include|"
3329 "\\ir|\\include_relative|\\o|\\out|"
3330 "\\s|\\w|\\write|\\lo_import"))
3332 completion_charp = "\\";
3333 matches = completion_matches(text, complete_from_files);
3337 * Finally, we look through the list of "things", such as TABLE, INDEX and
3338 * check if that was the previous word. If so, execute the query to get a
3345 for (i = 0; words_after_create[i].name; i++)
3347 if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
3349 if (words_after_create[i].query)
3350 COMPLETE_WITH_QUERY(words_after_create[i].query);
3351 else if (words_after_create[i].squery)
3352 COMPLETE_WITH_SCHEMA_QUERY(*words_after_create[i].squery,
3360 * If we still don't have anything to match we have to fabricate some sort
3361 * of default list. If we were to just return NULL, readline automatically
3362 * attempts filename completion, and that's usually no good.
3364 if (matches == NULL)
3366 COMPLETE_WITH_CONST("");
3367 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
3368 rl_completion_append_character = '\0';
3373 free(previous_words);
3376 /* Return our Grand List O' Matches */
3382 * GENERATOR FUNCTIONS
3384 * These functions do all the actual work of completing the input. They get
3385 * passed the text so far and the count how many times they have been called
3386 * so far with the same text.
3387 * If you read the above carefully, you'll see that these don't get called
3388 * directly but through the readline interface.
3389 * The return value is expected to be the full completion of the text, going
3390 * through a list each time, or NULL if there are no more matches. The string
3391 * will be free()'d by readline, so you must run it through strdup() or
3392 * something of that sort.
3396 * Common routine for create_command_generator and drop_command_generator.
3397 * Entries that have 'excluded' flags are not returned.
3400 create_or_drop_command_generator(const char *text, int state, bits32 excluded)
3402 static int list_index,
3406 /* If this is the first time for this completion, init some values */
3410 string_length = strlen(text);
3413 /* find something that matches */
3414 while ((name = words_after_create[list_index++].name))
3416 if ((pg_strncasecmp(name, text, string_length) == 0) &&
3417 !(words_after_create[list_index - 1].flags & excluded))
3418 return pg_strdup_keyword_case(name, text);
3420 /* if nothing matches, return NULL */
3425 * This one gives you one from a list of things you can put after CREATE
3429 create_command_generator(const char *text, int state)
3431 return create_or_drop_command_generator(text, state, THING_NO_CREATE);
3435 * This function gives you a list of things you can put after a DROP command.
3438 drop_command_generator(const char *text, int state)
3440 return create_or_drop_command_generator(text, state, THING_NO_DROP);
3443 /* The following two functions are wrappers for _complete_from_query */
3446 complete_from_query(const char *text, int state)
3448 return _complete_from_query(0, text, state);
3452 complete_from_schema_query(const char *text, int state)
3454 return _complete_from_query(1, text, state);
3459 * This creates a list of matching things, according to a query pointed to
3460 * by completion_charp.
3461 * The query can be one of two kinds:
3463 * 1. A simple query which must contain a %d and a %s, which will be replaced
3464 * by the string length of the text and the text itself. The query may also
3465 * have up to four more %s in it; the first two such will be replaced by the
3466 * value of completion_info_charp, the next two by the value of
3467 * completion_info_charp2.
3469 * 2. A schema query used for completion of both schema and relation names.
3470 * These are more complex and must contain in the following order:
3471 * %d %s %d %s %d %s %s %d %s
3472 * where %d is the string length of the text and %s the text itself.
3474 * It is assumed that strings should be escaped to become SQL literals
3475 * (that is, what is in the query is actually ... '%s' ...)
3477 * See top of file for examples of both kinds of query.
3480 _complete_from_query(int is_schema_query, const char *text, int state)
3482 static int list_index,
3484 static PGresult *result = NULL;
3487 * If this is the first time for this completion, we fetch a list of our
3488 * "things" from the backend.
3492 PQExpBufferData query_buffer;
3495 char *e_info_charp2;
3496 const char *pstr = text;
3497 int char_length = 0;
3500 byte_length = strlen(text);
3503 * Count length as number of characters (not bytes), for passing to
3509 pstr += PQmblen(pstr, pset.encoding);
3512 /* Free any prior result */
3516 /* Set up suitably-escaped copies of textual inputs */
3517 e_text = escape_string(text);
3519 if (completion_info_charp)
3520 e_info_charp = escape_string(completion_info_charp);
3522 e_info_charp = NULL;
3524 if (completion_info_charp2)
3525 e_info_charp2 = escape_string(completion_info_charp2);
3527 e_info_charp2 = NULL;
3529 initPQExpBuffer(&query_buffer);
3531 if (is_schema_query)
3533 /* completion_squery gives us the pieces to assemble */
3534 const char *qualresult = completion_squery->qualresult;
3536 if (qualresult == NULL)
3537 qualresult = completion_squery->result;
3539 /* Get unqualified names matching the input-so-far */
3540 appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
3541 completion_squery->result,
3542 completion_squery->catname);
3543 if (completion_squery->selcondition)
3544 appendPQExpBuffer(&query_buffer, "%s AND ",
3545 completion_squery->selcondition);
3546 appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
3547 completion_squery->result,
3548 char_length, e_text);
3549 appendPQExpBuffer(&query_buffer, " AND %s",
3550 completion_squery->viscondition);
3553 * When fetching relation names, suppress system catalogs unless
3554 * the input-so-far begins with "pg_". This is a compromise
3555 * between not offering system catalogs for completion at all, and
3556 * having them swamp the result when the input is just "p".
3558 if (strcmp(completion_squery->catname,
3559 "pg_catalog.pg_class c") == 0 &&
3560 strncmp(text, "pg_", 3) !=0)
3562 appendPQExpBufferStr(&query_buffer,
3563 " AND c.relnamespace <> (SELECT oid FROM"
3564 " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
3568 * Add in matching schema names, but only if there is more than
3569 * one potential match among schema names.
3571 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3572 "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
3573 "FROM pg_catalog.pg_namespace n "
3574 "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
3575 char_length, e_text);
3576 appendPQExpBuffer(&query_buffer,
3577 " AND (SELECT pg_catalog.count(*)"
3578 " FROM pg_catalog.pg_namespace"
3579 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3580 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
3581 char_length, e_text);
3584 * Add in matching qualified names, but only if there is exactly
3585 * one schema matching the input-so-far.
3587 appendPQExpBuffer(&query_buffer, "\nUNION\n"
3588 "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
3589 "FROM %s, pg_catalog.pg_namespace n "
3590 "WHERE %s = n.oid AND ",
3592 completion_squery->catname,
3593 completion_squery->namespace);
3594 if (completion_squery->selcondition)
3595 appendPQExpBuffer(&query_buffer, "%s AND ",
3596 completion_squery->selcondition);
3597 appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
3599 char_length, e_text);
3602 * This condition exploits the single-matching-schema rule to
3603 * speed up the query
3605 appendPQExpBuffer(&query_buffer,
3606 " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
3607 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
3608 char_length, e_text);
3609 appendPQExpBuffer(&query_buffer,
3610 " AND (SELECT pg_catalog.count(*)"
3611 " FROM pg_catalog.pg_namespace"
3612 " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
3613 " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
3614 char_length, e_text);
3616 /* If an addon query was provided, use it */
3617 if (completion_charp)
3618 appendPQExpBuffer(&query_buffer, "\n%s", completion_charp);
3622 /* completion_charp is an sprintf-style format string */
3623 appendPQExpBuffer(&query_buffer, completion_charp,
3624 char_length, e_text,
3625 e_info_charp, e_info_charp,
3626 e_info_charp2, e_info_charp2);
3629 /* Limit the number of records in the result */
3630 appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
3631 completion_max_records);
3633 result = exec_query(query_buffer.data);
3635 termPQExpBuffer(&query_buffer);
3640 free(e_info_charp2);
3643 /* Find something that matches */
3644 if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
3648 while (list_index < PQntuples(result) &&
3649 (item = PQgetvalue(result, list_index++, 0)))
3650 if (pg_strncasecmp(text, item, byte_length) == 0)
3651 return pg_strdup(item);
3654 /* If nothing matches, free the db structure and return null */
3662 * This function returns in order one of a fixed, NULL pointer terminated list
3663 * of strings (if matching). This can be used if there are only a fixed number
3664 * SQL words that can appear at certain spot.
3667 complete_from_list(const char *text, int state)
3669 static int string_length,
3672 static bool casesensitive;
3675 /* need to have a list */
3676 Assert(completion_charpp != NULL);
3678 /* Initialization */
3682 string_length = strlen(text);
3683 casesensitive = completion_case_sensitive;
3687 while ((item = completion_charpp[list_index++]))
3689 /* First pass is case sensitive */
3690 if (casesensitive && strncmp(text, item, string_length) == 0)
3693 return pg_strdup(item);
3696 /* Second pass is case insensitive, don't bother counting matches */
3697 if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
3699 if (completion_case_sensitive)
3700 return pg_strdup(item);
3704 * If case insensitive matching was requested initially,
3705 * adjust the case according to setting.
3707 return pg_strdup_keyword_case(item, text);
3712 * No matches found. If we're not case insensitive already, lets switch to
3713 * being case insensitive and try again
3715 if (casesensitive && matches == 0)
3717 casesensitive = false;
3720 return complete_from_list(text, state);
3723 /* If no more matches, return null. */
3729 * This function returns one fixed string the first time even if it doesn't
3730 * match what's there, and nothing the second time. This should be used if
3731 * there is only one possibility that can appear at a certain spot, so
3732 * misspellings will be overwritten. The string to be passed must be in
3736 complete_from_const(const char *text, int state)
3738 Assert(completion_charp != NULL);
3741 if (completion_case_sensitive)
3742 return pg_strdup(completion_charp);
3746 * If case insensitive matching was requested initially, adjust
3747 * the case according to setting.
3749 return pg_strdup_keyword_case(completion_charp, text);
3757 * This function appends the variable name with prefix and suffix to
3758 * the variable names array.
3761 append_variable_names(char ***varnames, int *nvars,
3762 int *maxvars, const char *varname,
3763 const char *prefix, const char *suffix)
3765 if (*nvars >= *maxvars)
3768 *varnames = (char **) pg_realloc(*varnames,
3769 ((*maxvars) + 1) * sizeof(char *));
3772 (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
3777 * This function supports completion with the name of a psql variable.
3778 * The variable names can be prefixed and suffixed with additional text
3779 * to support quoting usages. If need_value is true, only variables
3780 * that are currently set are included; otherwise, special variables
3781 * (those that have hooks) are included even if currently unset.
3784 complete_from_variables(const char *text, const char *prefix, const char *suffix,
3792 struct _variable *ptr;
3794 varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
3796 for (ptr = pset.vars->next; ptr; ptr = ptr->next)
3798 if (need_value && !(ptr->value))
3800 append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
3804 varnames[nvars] = NULL;
3805 COMPLETE_WITH_LIST_CS((const char *const *) varnames);
3807 for (i = 0; i < nvars; i++)
3816 * This function wraps rl_filename_completion_function() to strip quotes from
3817 * the input before searching for matches and to quote any matches for which
3818 * the consuming command will require it.
3821 complete_from_files(const char *text, int state)
3823 static const char *unquoted_text;
3824 char *unquoted_match;
3829 /* Initialization: stash the unquoted input. */
3830 unquoted_text = strtokx(text, "", NULL, "'", *completion_charp,
3831 false, true, pset.encoding);
3832 /* expect a NULL return for the empty string only */
3835 Assert(*text == '\0');
3836 unquoted_text = text;
3840 unquoted_match = filename_completion_function(unquoted_text, state);
3844 * Caller sets completion_charp to a zero- or one-character string
3845 * containing the escape character. This is necessary since \copy has
3846 * no escape character, but every other backslash command recognizes
3847 * "\" as an escape character. Since we have only two callers, don't
3848 * bother providing a macro to simplify this.
3850 ret = quote_if_needed(unquoted_match, " \t\r\n\"`",
3851 '\'', *completion_charp, pset.encoding);
3853 free(unquoted_match);
3855 ret = unquoted_match;
3862 /* HELPER FUNCTIONS */
3866 * Make a pg_strdup copy of s and convert the case according to
3867 * COMP_KEYWORD_CASE setting, using ref as the text that was already entered.
3870 pg_strdup_keyword_case(const char *s, const char *ref)
3874 unsigned char first = ref[0];
3878 if (pset.comp_case == PSQL_COMP_CASE_LOWER ||
3879 ((pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER ||
3880 pset.comp_case == PSQL_COMP_CASE_PRESERVE_UPPER) && islower(first)) ||
3881 (pset.comp_case == PSQL_COMP_CASE_PRESERVE_LOWER && !isalpha(first)))
3883 for (p = ret; *p; p++)
3884 *p = pg_tolower((unsigned char) *p);
3888 for (p = ret; *p; p++)
3889 *p = pg_toupper((unsigned char) *p);
3897 * escape_string - Escape argument for use as string literal.
3899 * The returned value has to be freed.
3902 escape_string(const char *text)
3907 text_length = strlen(text);
3909 result = pg_malloc(text_length * 2 + 1);
3910 PQescapeStringConn(pset.db, result, text, text_length, NULL);
3917 * Execute a query and report any errors. This should be the preferred way of
3918 * talking to the database in this file.
3921 exec_query(const char *query)
3925 if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
3928 result = PQexec(pset.db, query);
3930 if (PQresultStatus(result) != PGRES_TUPLES_OK)
3933 psql_error("tab completion query failed: %s\nQuery was:\n%s\n",
3934 PQerrorMessage(pset.db), query);
3945 * Parse all the word(s) before point.
3947 * Returns a malloc'd array of character pointers that point into the malloc'd
3948 * data array returned to *buffer; caller must free() both of these when done.
3949 * *nwords receives the number of words found, ie, the valid length of the
3952 * Words are returned right to left, that is, previous_words[0] gets the last
3953 * word before point, previous_words[1] the next-to-last, etc.
3956 get_previous_words(int point, char **buffer, int *nwords)
3958 char **previous_words;
3961 int words_found = 0;
3965 * If we have anything in tab_completion_query_buf, paste it together with
3966 * rl_line_buffer to construct the full query. Otherwise we can just use
3967 * rl_line_buffer as the input string.
3969 if (tab_completion_query_buf && tab_completion_query_buf->len > 0)
3971 i = tab_completion_query_buf->len;
3972 buf = pg_malloc(point + i + 2);
3973 memcpy(buf, tab_completion_query_buf->data, i);
3975 memcpy(buf + i, rl_line_buffer, point);
3978 /* Readjust point to reference appropriate offset in buf */
3982 buf = rl_line_buffer;
3985 * Allocate an array of string pointers and a buffer to hold the strings
3986 * themselves. The worst case is that the line contains only
3987 * non-whitespace WORD_BREAKS characters, making each one a separate word.
3988 * This is usually much more space than we need, but it's cheaper than
3989 * doing a separate malloc() for each word.
3991 previous_words = (char **) pg_malloc(point * sizeof(char *));
3992 *buffer = outptr = (char *) pg_malloc(point * 2);
3995 * First we look for a non-word char before the current point. (This is
3996 * probably useless, if readline is on the same page as we are about what
3997 * is a word, but if so it's cheap.)
3999 for (i = point - 1; i >= 0; i--)
4001 if (strchr(WORD_BREAKS, buf[i]))
4007 * Now parse words, working backwards, until we hit start of line. The
4008 * backwards scan has some interesting but intentional properties
4009 * concerning parenthesis handling.
4015 bool inquotes = false;
4016 int parentheses = 0;
4018 /* now find the first non-space which then constitutes the end */
4020 for (i = point; i >= 0; i--)
4022 if (!isspace((unsigned char) buf[i]))
4028 /* if no end found, we're done */
4033 * Otherwise we now look for the start. The start is either the last
4034 * character before any word-break character going backwards from the
4035 * end, or it's simply character 0. We also handle open quotes and
4038 for (start = end; start > 0; start--)
4040 if (buf[start] == '"')
4041 inquotes = !inquotes;
4044 if (buf[start] == ')')
4046 else if (buf[start] == '(')
4048 if (--parentheses <= 0)
4051 else if (parentheses == 0 &&
4052 strchr(WORD_BREAKS, buf[start - 1]))
4057 /* Return the word located at start to end inclusive */
4058 previous_words[words_found++] = outptr;
4059 i = end - start + 1;
4060 memcpy(outptr, &buf[start], i);
4064 /* Continue searching */
4068 /* Release parsing input workspace, if we made one above */
4069 if (buf != rl_line_buffer)
4072 *nwords = words_found;
4073 return previous_words;
4077 * Look up the type for the GUC variable with the passed name.
4079 * Returns NULL if the variable is unknown. Otherwise the returned string,
4080 * containing the type, has to be freed.
4083 get_guctype(const char *varname)
4085 PQExpBufferData query_buffer;
4088 char *guctype = NULL;
4090 e_varname = escape_string(varname);
4092 initPQExpBuffer(&query_buffer);
4093 appendPQExpBuffer(&query_buffer,
4094 "SELECT vartype FROM pg_catalog.pg_settings "
4095 "WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4098 result = exec_query(query_buffer.data);
4099 termPQExpBuffer(&query_buffer);
4102 if (PQresultStatus(result) == PGRES_TUPLES_OK && PQntuples(result) > 0)
4103 guctype = pg_strdup(PQgetvalue(result, 0, 0));
4113 * Surround a string with single quotes. This works for both SQL and
4114 * psql internal. Currently disabled because it is reported not to
4115 * cooperate with certain versions of readline.
4118 quote_file_name(char *text, int match_type, char *quote_pointer)
4123 (void) quote_pointer; /* not used */
4125 length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
4126 s = pg_malloc(length);
4128 strcpy(s + 1, text);
4129 if (match_type == SINGLE_MATCH)
4130 s[length - 2] = '\'';
4131 s[length - 1] = '\0';
4136 dequote_file_name(char *text, char quote_char)
4142 return pg_strdup(text);
4144 length = strlen(text);
4145 s = pg_malloc(length - 2 + 1);
4146 strlcpy(s, text +1, length - 2 + 1);
4150 #endif /* NOT_USED */
4152 #endif /* USE_READLINE */