($INBOX_DIR/description missing)
help / color / mirror / Atom feedFrom: Kyotaro Horiguchi <[email protected]>
Subject: [PATCH 5/6] Add suggestion for IF (NOT) EXISTS for some syntaxes
Date: Thu, 15 Sep 2016 20:49:45 +0900
Add suggestion for IF EXISTS or IF NOT EXISTS for some arbitrary
syntaxes, ALTER TABLE/ALTER FOREIGN TABLE/ALTER INDEX/
ALTER MATERIALIZED VIEW/ALTER DOMAIN DROP CONSTRAINT/ALTER SEQUENCE/
ALTER VIEW/ALTER POLICY/ALTER TABLE DROP COLUMN/
ALTER TABLE DROP CONSTRAINT/CREATE INDEX/CREATE SEQUENCE/
CREATE TABLE/CREATE VIEW/DROP INDEX/DROP (MATERIALIZED) VIEW/
DROP USER MAPPING
---
src/bin/psql/tab-complete.c | 178 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 168 insertions(+), 10 deletions(-)
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index ec5a700..cbac5d3 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1094,7 +1094,9 @@ psql_completion_internal(const char *text, char **previous_words,
/* ALTER TABLE */
if (Matches2("ALTER", "TABLE"))
COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_tables,
- ADDLIST1("ALL IN TABLESPACE"));
+ ADDLIST2("ALL IN TABLESPACE", "IF EXISTS"));
+ if (HeadMatches4("ALTER", "TABLE", "IF", "EXISTS"))
+ COLLAPSE(3, 2);
/* ALTER something */
if (Matches1("ALTER"))
@@ -1197,6 +1199,14 @@ psql_completion_internal(const char *text, char **previous_words,
if (Matches5("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny))
COMPLETE_WITH_LIST5("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO");
+ /* ALTER FOREIGN TABLE */
+ if (Matches3("ALTER", "FOREIGN", "TABLE"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_foreign_tables,
+ ADDLIST1("IF EXISTS"));
+ /* Remove optional words for further completion */
+ if (HeadMatches5("ALTER", "FOREIGN", "TABLE", "IF", "EXISTS"))
+ COLLAPSE(4, 2);
+
/* ALTER FOREIGN TABLE <name> */
if (Matches4("ALTER", "FOREIGN", "TABLE", MatchAny))
{
@@ -1211,7 +1221,11 @@ psql_completion_internal(const char *text, char **previous_words,
/* ALTER INDEX */
if (Matches2("ALTER", "INDEX"))
COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_indexes,
- ADDLIST1("ALL IN TABLESPACE"));
+ ADDLIST2("ALL IN TABLESPACE", "IF EXISTS"));
+ /* Remove optional words for further completion */
+ if (HeadMatches4("ALTER", "INDEX", "IF", "EXISTS"))
+ COLLAPSE(3, 2);
+
/* ALTER INDEX <name> */
if (Matches3("ALTER", "INDEX", MatchAny))
COMPLETE_WITH_LIST4("OWNER TO", "RENAME TO", "SET", "RESET");
@@ -1240,7 +1254,10 @@ psql_completion_internal(const char *text, char **previous_words,
/* ALTER MATERIALIZED VIEW */
if (Matches3("ALTER", "MATERIALIZED", "VIEW"))
COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_matviews,
- ADDLIST1("ALL IN TABLESPACE"));
+ ADDLIST2("ALL IN TABLESPACE", "IF EXISTS"));
+ /* Remove optional words for further completion */
+ if (HeadMatches5("ALTER", "MATERIALIZED", "VIEW", "IF", "EXISTS"))
+ COLLAPSE(4, 2);
/* ALTER USER,ROLE <name> */
if (Matches3("ALTER", "USER|ROLE", MatchAny) &&
@@ -1296,6 +1313,19 @@ psql_completion_internal(const char *text, char **previous_words,
if (Matches5("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT"))
{
completion_info_charp = prev3_wd;
+ if (word_matches("DROP", prev2_wd))
+ COMPLETE_WITH_QUERY_KW(Query_for_constraint_of_type,
+ ADDLIST1("IF EXISTS"));
+ else
+ COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
+ }
+ /* Remove optional words for further completion */
+ if (HeadMatches7("ALTER", "DOMAIN", MatchAny, "DROP", "CONSTRAINT", "IF", "EXISTS"))
+ COLLAPSE(6, 2);
+ /* Complete constraint name again without IF EXISTS */
+ if (Matches5("ALTER", "DOMAIN", MatchAny, "DROP", "CONSTRAINT"))
+ {
+ completion_info_charp = prev3_wd;
COMPLETE_WITH_QUERY(Query_for_constraint_of_type);
}
/* ALTER DOMAIN <sth> RENAME */
@@ -1308,6 +1338,16 @@ psql_completion_internal(const char *text, char **previous_words,
/* ALTER DOMAIN <sth> SET */
if (Matches4("ALTER", "DOMAIN", MatchAny, "SET"))
COMPLETE_WITH_LIST3("DEFAULT", "NOT NULL", "SCHEMA");
+ /* ALTER SEQUENCE */
+ if (Matches2("ALTER", "SEQUENCE"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_sequences,
+ ADDLIST1("IF EXISTS"));
+ /* Remove optional words for further completion */
+ if (HeadMatches4("ALTER", "SEQUENCE", "IF", "EXISTS"))
+ COLLAPSE(3, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches2("ALTER", "SEQUENCE"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences);
/* ALTER SEQUENCE <name> */
if (Matches3("ALTER", "SEQUENCE", MatchAny))
{
@@ -1333,6 +1373,16 @@ psql_completion_internal(const char *text, char **previous_words,
if (Matches3("ALTER", "SYSTEM", "SET|RESET"))
COMPLETE_WITH_QUERY_KW(Query_for_list_of_alter_system_set_vars,
ADDLIST1("ALL"));
+ /* ALTER VIEW */
+ if (Matches2("ALTER", "VIEW"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_views,
+ ADDLIST1("IF EXISTS"));
+ /* Remove optional words for further completion */
+ if (HeadMatches4("ALTER", "VIEW", "IF", "EXISTS"))
+ COLLAPSE(3, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches2("ALTER", "VIEW"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
/* ALTER VIEW <name> */
if (Matches3("ALTER", "VIEW", MatchAny))
COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO",
@@ -1344,6 +1394,12 @@ psql_completion_internal(const char *text, char **previous_words,
/* ALTER POLICY <name> */
if (Matches2("ALTER", "POLICY"))
+ COMPLETE_WITH_QUERY_KW(Query_for_list_of_policies, ADDLIST1("IF EXISTS"));
+ /* Remove optional words for further completion */
+ if (Matches4("ALTER", "POLICY", "IF", "EXISTS"))
+ COLLAPSE(3, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches2("ALTER", "POLICY"))
COMPLETE_WITH_QUERY(Query_for_list_of_policies);
/* ALTER POLICY <name> ON */
if (Matches3("ALTER", "POLICY", MatchAny))
@@ -1483,8 +1539,13 @@ psql_completion_internal(const char *text, char **previous_words,
COMPLETE_WITH_LIST2("COLUMN", "CONSTRAINT");
/* If we have ALTER TABLE <sth> DROP COLUMN, provide list of columns */
if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
+ COMPLETE_WITH_ATTR_KW(prev3_wd, ADDLIST1("IF EXISTS"));
+ /* Remove optional words for further completion */
+ if (HeadMatches7("ALTER", "TABLE", MatchAny, "DROP", "COLUMN", "IF", "EXISTS"))
+ COLLAPSE(6, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN"))
COMPLETE_WITH_ATTR(prev3_wd);
-
/*
* If we have ALTER TABLE <sth> ALTER|DROP|RENAME|VALIDATE CONSTRAINT,
* provide list of constraints
@@ -1492,6 +1553,19 @@ psql_completion_internal(const char *text, char **previous_words,
if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT"))
{
completion_info_charp = prev3_wd;
+ if (word_matches("DROP", prev2_wd))
+ COMPLETE_WITH_QUERY_KW(Query_for_constraint_of_table,
+ ADDLIST1("IF EXISTS"));
+ else
+ COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
+ }
+ /* Remove IF EXISTS for further completion */
+ if (HeadMatches7("ALTER", "TABLE", MatchAny, "DROP", "CONSTRAINT", "IF", "EXISTS"))
+ COLLAPSE(6, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "CONSTRAINT"))
+ {
+ completion_info_charp = prev3_wd;
COMPLETE_WITH_QUERY(Query_for_constraint_of_table);
}
/* Remove COLUMN just after ALTER */
@@ -1633,7 +1707,18 @@ psql_completion_internal(const char *text, char **previous_words,
* of attributes
*/
if (Matches5("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE"))
- COMPLETE_WITH_ATTR(prev3_wd);
+ {
+ if (word_matches("DROP", prev2_wd))
+ COMPLETE_WITH_ATTR_KW(prev3_wd, ADDLIST1("IF EXISTS"));
+ else
+ COMPLETE_WITH_ATTR(prev3_wd);
+ }
+ /* Remove IF EXISTS for further completion */
+ if (HeadMatches7("ALTER", "TYPE", MatchAny, "DROP", "ATTRIBUTE", "IF", "EXISTS"))
+ COLLAPSE(6, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches5("ALTER", "TYPE", MatchAny, "DROP", "ATTRIBUTE"))
+ COMPLETE_WITH_ATTR(prev3_wd);
/* ALTER TYPE ALTER ATTRIBUTE <foo> */
if (Matches6("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny))
COMPLETE_WITH_CONST("TYPE");
@@ -1787,6 +1872,13 @@ psql_completion_internal(const char *text, char **previous_words,
/* CREATE EXTENSION */
/* Complete with available extensions rather than installed ones. */
if (Matches2("CREATE", "EXTENSION"))
+ COMPLETE_WITH_QUERY_KW(Query_for_list_of_available_extensions,
+ ADDLIST1("IF NOT EXISTS"));
+ /* Remove IF NOT EXISTS for further completion*/
+ if (HeadMatches5("CREATE", "EXTENSION", "IF", "NOT", "EXISTS"))
+ COLLAPSE(3, 3);
+ /* Complete again without IF NOT EXISTS */
+ if (Matches2("CREATE", "EXTENSION"))
COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions);
/* CREATE EXTENSION <name> */
if (Matches3("CREATE", "EXTENSION", MatchAny))
@@ -1817,14 +1909,20 @@ psql_completion_internal(const char *text, char **previous_words,
/* Complete with index names as category suggestion and possible keywords */
if (Matches2("CREATE", "INDEX"))
COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_indexes,
- ADDLIST2("ON", "CONCURRENTLY"));
+ ADDLIST3("ON", "CONCURRENTLY", "IF NOT EXISTS"));
/* Remove CONCURRENTLY for further completion */
if (HeadMatches3("CREATE", "INDEX", "CONCURRENTLY"))
COLLAPSE(3, 1);
/* Complete with existing index names as word category suggestion */
if (Matches2("CREATE", "INDEX"))
COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_indexes,
- ADDLIST1("ON"));
+ ADDLIST2("ON", "IF NOT EXISTS"));
+ /* Remove IF NOT EXISTS for further completion */
+ if (HeadMatches5("CREATE", "INDEX", "IF", "NOT", "EXISTS"))
+ COLLAPSE(3, 3);
+ /* Complete again without IF NOT EXISTS */
+ if (Matches2("CREATE", "INDEX"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
/* Suggest ON just after index name */
if (Matches3("CREATE", "INDEX", MatchAnyExcept("ON")))
COMPLETE_WITH_CONST("ON");
@@ -1917,6 +2015,13 @@ psql_completion_internal(const char *text, char **previous_words,
/* CREATE SEQUENCE */
if (Matches2("CREATE", "SEQUENCE"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_sequences,
+ ADDLIST1("IF NOT EXISTS"));
+ /* Remove IF NOT EXISTS for further completion */
+ if (HeadMatches5("CREATE", "SEQUENCE", "IF", "NOT", "EXISTS"))
+ COLLAPSE(3, 3);
+ /* Complete again without IF NOT EXISTS */
+ if (Matches2("CREATE", "SEQUENCE"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences);
if (Matches3("CREATE", "SEQUENCE", MatchAny))
COMPLETE_WITH_LIST8("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO",
@@ -1942,6 +2047,13 @@ psql_completion_internal(const char *text, char **previous_words,
COLLAPSE(2, 1);
/* Complete CREATE TABLE with existing table names */
if (Matches2("CREATE", "TABLE"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_tables,
+ ADDLIST1("IF NOT EXISTS"));
+ /* Remove IF NOT EXIST for further completion */
+ if (HeadMatches5("CREATE", "TABLE", "IF", "NOT", "EXISTS"))
+ COLLAPSE(3, 3);
+ /* Complete again without IF NOT EXISTS */
+ if (Matches2("CREATE", "TABLE"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables);
/* CREATE TABLESPACE */
@@ -2134,6 +2246,16 @@ psql_completion_internal(const char *text, char **previous_words,
COMPLETE_WITH_LIST2("GROUP", "ROLE");
/* CREATE VIEW */
+ /* Complete CREATE VIEW with name */
+ if (Matches2("CREATE", "VIEW"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_views,
+ ADDLIST1("IF NOT EXISTS"));
+ /* Remove IF NOT EXISTS for further completion */
+ if (HeadMatches5("CREATE", "VIEW", "IF", "NOT", "EXISTS"))
+ COLLAPSE(3, 3);
+ /* Complete again without IF NOT EXISTS */
+ if (Matches2("CREATE", "VIEW"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
/* Complete CREATE VIEW <name> with AS */
if (Matches3("CREATE", "VIEW", MatchAny))
COMPLETE_WITH_CONST("AS");
@@ -2213,18 +2335,43 @@ psql_completion_internal(const char *text, char **previous_words,
/* DROP INDEX */
if (Matches2("DROP", "INDEX"))
COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_indexes,
- ADDLIST1("CONCURRENTLY"));
+ ADDLIST2("CONCURRENTLY", "IF EXISTS"));
+ if (Matches3("DROP", "INDEX", "CONCURRENTLY"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_indexes,
+ ADDLIST1("IF EXISTS"));
if (HeadMatches3("DROP", "INDEX", "CONCURRENTLY"))
COLLAPSE(3, 1);
+ /* Remove IF EXISTS for further completion */
+ if (HeadMatches4("DROP", "INDEX", "IF", "EXISTS"))
+ COLLAPSE(3, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches2("DROP", "INDEX"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes);
if (Matches3("DROP", "INDEX", MatchAny))
COMPLETE_WITH_LIST2("CASCADE", "RESTRICT");
+ /* DROP VIEW */
+ if (Matches2("DROP", "VIEW"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_views,
+ ADDLIST1("IF EXISTS"));
+ /* Remove IF EXISTS for further completion */
+ if (HeadMatches4("DROP", "VIEW", "IF", "EXISTS"))
+ COLLAPSE(3, 2);
+ /* Complet again without IF EXISTS */
+ if (Matches2("DROP", "VIEW"))
+ COMPLETE_THING(-1);
+
/* DROP MATERIALIZED VIEW */
if (Matches2("DROP", "MATERIALIZED"))
COMPLETE_WITH_CONST("VIEW");
- /* DROP VIEW is suggested as a general thing */
-
+ if (Matches3("DROP", "MATERIALIZED", "VIEW"))
+ COMPLETE_WITH_SCHEMA_QUERY_KW(Query_for_list_of_matviews,
+ ADDLIST1("IF EXISTS"));
+ /* Remove IF EXISTS for further completion */
+ if (HeadMatches5("DROP", "MATERIALIZED", "VIEW", "IF", "EXISTS"))
+ COLLAPSE(4, 2);
+ /* Complet again without IF EXISTS */
if (Matches3("DROP", "MATERIALIZED", "VIEW"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews);
@@ -2791,6 +2938,17 @@ psql_completion_internal(const char *text, char **previous_words,
/* USER MAPPING */
if (Matches3("ALTER|CREATE|DROP", "USER", "MAPPING"))
+ {
+ if (word_matches("DROP", prev3_wd))
+ COMPLETE_WITH_LIST2("FOR", "IF EXISTS FOR");
+ else
+ COMPLETE_WITH_CONST("FOR");
+ }
+ /* Remove IF EXISTS for further completion */
+ if (HeadMatches5("DROP", "USER", "MAPPING", "IF", "EXISTS"))
+ COLLAPSE(4, 2);
+ /* Complete again without IF EXISTS */
+ if (Matches3("DROP", "USER", "MAPPING"))
COMPLETE_WITH_CONST("FOR");
if (Matches4("CREATE", "USER", "MAPPING", "FOR"))
COMPLETE_WITH_QUERY_KW(Query_for_list_of_roles,
--
2.9.2
----Next_Part(Tue_Nov_15_20_26_42_2016_708)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="0006-Add-README-for-tab-completion.patch"
view thread (3+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH 5/6] Add suggestion for IF (NOT) EXISTS for some syntaxes
In-Reply-To: <no-message-id-66725@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox