psql-tab-completion_20100216.patch
application/octet-stream
Filename: psql-tab-completion_20100216.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/bin/psql/tab-complete.c | 250 | 99 |
diff -cprN head/src/bin/psql/tab-complete.c work/src/bin/psql/tab-complete.c
*** head/src/bin/psql/tab-complete.c 2010-02-15 11:56:18.651089000 +0900
--- work/src/bin/psql/tab-complete.c 2010-02-16 14:23:09.274053000 +0900
*************** static const SchemaQuery Query_for_list_
*** 500,505 ****
--- 500,510 ----
" FROM pg_catalog.pg_user_mappings "\
" WHERE substring(pg_catalog.quote_ident(usename),1,%d)='%s'"
+ #define Query_for_list_of_access_methods \
+ " SELECT pg_catalog.quote_ident(amname) "\
+ " FROM pg_catalog.pg_am "\
+ " WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'"
+
/*
* This is a list of all "things" in Pgsql, which can show up after CREATE or
* DROP; and there is also a query to get a list of them.
*************** static PGresult *exec_query(const char *
*** 571,578 ****
static char *previous_word(int point, int skip);
- static int find_open_parenthesis(int end);
-
#if 0
static char *quote_file_name(char *text, int match_type, char *quote_pointer);
static char *dequote_file_name(char *text, char quote_char);
--- 576,581 ----
*************** psql_completion(char *text, int start, i
*** 638,645 ****
"\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", NULL
};
- (void) end; /* not used */
-
#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
rl_completion_append_character = ' ';
#endif
--- 641,646 ----
*************** psql_completion(char *text, int start, i
*** 749,754 ****
--- 750,782 ----
COMPLETE_WITH_LIST(list_ALTERINDEX);
}
+ /* ALTER INDEX <name> SET */
+ else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev3_wd, "INDEX") == 0 &&
+ pg_strcasecmp(prev_wd, "SET") == 0)
+ {
+ static const char *const list_ALTERINDEXSET[] =
+ {"(", "TABLESPACE", NULL};
+
+ COMPLETE_WITH_LIST(list_ALTERINDEXSET);
+ }
+ /* ALTER INDEX <name> RESET */
+ else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev3_wd, "INDEX") == 0 &&
+ pg_strcasecmp(prev_wd, "RESET") == 0)
+ COMPLETE_WITH_CONST("(");
+ /* ALTER INDEX <foo> SET|RESET ( */
+ else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev4_wd, "INDEX") == 0 &&
+ (pg_strcasecmp(prev2_wd, "SET") == 0 ||
+ pg_strcasecmp(prev2_wd, "RESET") == 0) &&
+ pg_strcasecmp(prev_wd, "(") == 0)
+ {
+ static const char *const list_INDEXOPTIONS[] =
+ {"fillfactor", "fastupdate", NULL};
+
+ COMPLETE_WITH_LIST(list_INDEXOPTIONS);
+ }
/* ALTER LANGUAGE <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
*************** psql_completion(char *text, int start, i
*** 977,986 ****
pg_strcasecmp(prev2_wd, "ALTER") == 0))
{
static const char *const list_COLUMNALTER[] =
! {"TYPE", "SET", "DROP", NULL};
COMPLETE_WITH_LIST(list_COLUMNALTER);
}
else if (((pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
pg_strcasecmp(prev3_wd, "COLUMN") == 0) ||
(pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
--- 1005,1015 ----
pg_strcasecmp(prev2_wd, "ALTER") == 0))
{
static const char *const list_COLUMNALTER[] =
! {"TYPE", "SET", "RESET", "DROP", NULL};
COMPLETE_WITH_LIST(list_COLUMNALTER);
}
+ /* ALTER TABLE ALTER [COLUMN] <foo> SET */
else if (((pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
pg_strcasecmp(prev3_wd, "COLUMN") == 0) ||
(pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
*************** psql_completion(char *text, int start, i
*** 988,997 ****
pg_strcasecmp(prev_wd, "SET") == 0)
{
static const char *const list_COLUMNSET[] =
! {"DEFAULT", "NOT NULL", "STATISTICS", "STORAGE", NULL};
COMPLETE_WITH_LIST(list_COLUMNSET);
}
else if (((pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
pg_strcasecmp(prev3_wd, "COLUMN") == 0) ||
(pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
--- 1017,1051 ----
pg_strcasecmp(prev_wd, "SET") == 0)
{
static const char *const list_COLUMNSET[] =
! {"(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE", NULL};
COMPLETE_WITH_LIST(list_COLUMNSET);
}
+ /* ALTER TABLE ALTER [COLUMN] <foo> SET ( */
+ else if (((pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev4_wd, "COLUMN") == 0) ||
+ pg_strcasecmp(prev4_wd, "ALTER") == 0) &&
+ pg_strcasecmp(prev2_wd, "SET") == 0 &&
+ pg_strcasecmp(prev_wd, "(") == 0)
+ {
+ static const char *const list_COLUMNOPTIONS[] =
+ {"n_distinct", "n_distinct_inherited", NULL};
+
+ COMPLETE_WITH_LIST(list_COLUMNOPTIONS);
+ }
+ /* ALTER TABLE ALTER [COLUMN] <foo> SET STORAGE */
+ else if (((pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev4_wd, "COLUMN") == 0) ||
+ pg_strcasecmp(prev4_wd, "ALTER") == 0) &&
+ pg_strcasecmp(prev2_wd, "SET") == 0 &&
+ pg_strcasecmp(prev_wd, "STORAGE") == 0)
+ {
+ static const char *const list_COLUMNSTORAGE[] =
+ {"PLAIN", "EXTERNAL", "EXTENDED", "MAIN", NULL};
+
+ COMPLETE_WITH_LIST(list_COLUMNSTORAGE);
+ }
+ /* ALTER TABLE ALTER [COLUMN] <foo> DROP */
else if (((pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
pg_strcasecmp(prev3_wd, "COLUMN") == 0) ||
(pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
*************** psql_completion(char *text, int start, i
*** 1018,1024 ****
pg_strcasecmp(prev_wd, "SET") == 0)
{
static const char *const list_TABLESET[] =
! {"WITHOUT", "TABLESPACE", "SCHEMA", NULL};
COMPLETE_WITH_LIST(list_TABLESET);
}
--- 1072,1078 ----
pg_strcasecmp(prev_wd, "SET") == 0)
{
static const char *const list_TABLESET[] =
! {"(", "WITHOUT", "TABLESPACE", "SCHEMA", NULL};
COMPLETE_WITH_LIST(list_TABLESET);
}
*************** psql_completion(char *text, int start, i
*** 1037,1051 ****
COMPLETE_WITH_LIST(list_TABLESET2);
}
! /* we have ALTER TABLESPACE, so suggest RENAME TO, OWNER TO */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "TABLESPACE") == 0)
{
static const char *const list_ALTERTSPC[] =
! {"RENAME TO", "OWNER TO", NULL};
COMPLETE_WITH_LIST(list_ALTERTSPC);
}
/* ALTER TEXT SEARCH */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "TEXT") == 0 &&
--- 1091,1163 ----
COMPLETE_WITH_LIST(list_TABLESET2);
}
! /* ALTER TABLE <foo> RESET */
! else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
! pg_strcasecmp(prev_wd, "RESET") == 0)
! COMPLETE_WITH_CONST("(");
! /* ALTER TABLE <foo> SET|RESET ( */
! else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
! (pg_strcasecmp(prev2_wd, "SET") == 0 ||
! pg_strcasecmp(prev2_wd, "RESET") == 0) &&
! pg_strcasecmp(prev_wd, "(") == 0)
! {
! static const char *const list_TABLEOPTIONS[] =
! {
! "autovacuum_analyze_scale_factor",
! "autovacuum_analyze_threshold",
! "autovacuum_enabled",
! "autovacuum_freeze_max_age",
! "autovacuum_freeze_min_age",
! "autovacuum_freeze_table_age",
! "autovacuum_vacuum_cost_delay",
! "autovacuum_vacuum_cost_limit",
! "autovacuum_vacuum_scale_factor",
! "autovacuum_vacuum_threshold",
! "fillfactor",
! "toast.autovacuum_analyze_scale_factor",
! "toast.autovacuum_analyze_threshold",
! "toast.autovacuum_enabled",
! "toast.autovacuum_freeze_max_age",
! "toast.autovacuum_freeze_min_age",
! "toast.autovacuum_freeze_table_age",
! "toast.autovacuum_vacuum_cost_delay",
! "toast.autovacuum_vacuum_cost_limit",
! "toast.autovacuum_vacuum_scale_factor",
! "toast.autovacuum_vacuum_threshold",
! NULL
! };
!
! COMPLETE_WITH_LIST(list_TABLEOPTIONS);
! }
!
! /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "TABLESPACE") == 0)
{
static const char *const list_ALTERTSPC[] =
! {"RENAME TO", "OWNER TO", "SET", "RESET", NULL};
COMPLETE_WITH_LIST(list_ALTERTSPC);
}
+ /* ALTER TABLESPACE <foo> SET|RESET */
+ else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev3_wd, "TABLESPACE") == 0 &&
+ (pg_strcasecmp(prev_wd, "SET") == 0 ||
+ pg_strcasecmp(prev_wd, "RESET") == 0))
+ COMPLETE_WITH_CONST("(");
+ /* ALTER TABLESPACE <foo> SET|RESET ( */
+ else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev4_wd, "TABLESPACE") == 0 &&
+ (pg_strcasecmp(prev2_wd, "SET") == 0 ||
+ pg_strcasecmp(prev2_wd, "RESET") == 0) &&
+ pg_strcasecmp(prev_wd, "(") == 0)
+ {
+ static const char *const list_TABLESPACEOPTIONS[] =
+ {"seq_page_cost", "random_page_cost", NULL};
+
+ COMPLETE_WITH_LIST(list_TABLESPACEOPTIONS);
+ }
+
/* ALTER TEXT SEARCH */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "TEXT") == 0 &&
*************** psql_completion(char *text, int start, i
*** 1282,1325 ****
else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
pg_strcasecmp(prev_wd, "UNIQUE") == 0)
COMPLETE_WITH_CONST("INDEX");
! /* If we have CREATE|UNIQUE INDEX <sth>, then add "ON" */
! else if (pg_strcasecmp(prev2_wd, "INDEX") == 0 &&
! (pg_strcasecmp(prev3_wd, "CREATE") == 0 ||
! pg_strcasecmp(prev3_wd, "UNIQUE") == 0))
! COMPLETE_WITH_CONST("ON");
! /* Complete ... INDEX <name> ON with a list of tables */
! else if (pg_strcasecmp(prev3_wd, "INDEX") == 0 &&
pg_strcasecmp(prev_wd, "ON") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
/*
* Complete INDEX <name> ON <table> with a list of table columns (which
* should really be in parens)
*/
! else if (pg_strcasecmp(prev4_wd, "INDEX") == 0 &&
pg_strcasecmp(prev2_wd, "ON") == 0)
{
! if (find_open_parenthesis(end))
! COMPLETE_WITH_ATTR(prev_wd, "");
! else
! COMPLETE_WITH_CONST("(");
}
! else if (pg_strcasecmp(prev5_wd, "INDEX") == 0 &&
pg_strcasecmp(prev3_wd, "ON") == 0 &&
pg_strcasecmp(prev_wd, "(") == 0)
COMPLETE_WITH_ATTR(prev2_wd, "");
/* same if you put in USING */
! else if (pg_strcasecmp(prev4_wd, "ON") == 0 &&
! pg_strcasecmp(prev2_wd, "USING") == 0)
! COMPLETE_WITH_ATTR(prev3_wd, "");
/* Complete USING with an index method */
else if (pg_strcasecmp(prev_wd, "USING") == 0)
! {
! static const char *const index_mth[] =
! {"BTREE", "HASH", "GIN", "GIST", NULL};
!
! COMPLETE_WITH_LIST(index_mth);
! }
/* CREATE RULE */
/* Complete "CREATE RULE <sth>" with "AS" */
--- 1394,1459 ----
else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
pg_strcasecmp(prev_wd, "UNIQUE") == 0)
COMPLETE_WITH_CONST("INDEX");
! /* If we have CREATE|UNIQUE INDEX, then add "ON" and existing indexes */
! else if (pg_strcasecmp(prev_wd, "INDEX") == 0 &&
! (pg_strcasecmp(prev2_wd, "CREATE") == 0 ||
! pg_strcasecmp(prev2_wd, "UNIQUE") == 0))
! COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
! " UNION SELECT 'ON'"
! " UNION SELECT 'CONCURRENTLY'");
! /* Complete ... INDEX [<name>] ON with a list of tables */
! else if ((pg_strcasecmp(prev3_wd, "INDEX") == 0 ||
! pg_strcasecmp(prev2_wd, "INDEX") == 0 ||
! pg_strcasecmp(prev2_wd, "CONCURRENTLY") == 0) &&
pg_strcasecmp(prev_wd, "ON") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
+ /* If we have CREATE|UNIQUE INDEX <sth> CONCURRENTLY, then add "ON" */
+ else if ((pg_strcasecmp(prev3_wd, "INDEX") == 0 ||
+ pg_strcasecmp(prev2_wd, "INDEX") == 0) &&
+ pg_strcasecmp(prev_wd, "CONCURRENTLY") == 0)
+ COMPLETE_WITH_CONST("ON");
+ /* If we have CREATE|UNIQUE INDEX <sth>, then add "ON" or "CONCURRENTLY" */
+ else if ((pg_strcasecmp(prev3_wd, "CREATE") == 0 ||
+ pg_strcasecmp(prev3_wd, "UNIQUE") == 0) &&
+ pg_strcasecmp(prev2_wd, "INDEX") == 0)
+ {
+ static const char *const list_CREATE_INDEX[] =
+ {"CONCURRENTLY", "ON", NULL};
+
+ COMPLETE_WITH_LIST(list_CREATE_INDEX);
+ }
/*
* Complete INDEX <name> ON <table> with a list of table columns (which
* should really be in parens)
*/
! else if ((pg_strcasecmp(prev4_wd, "INDEX") == 0 ||
! pg_strcasecmp(prev3_wd, "INDEX") == 0 ||
! pg_strcasecmp(prev3_wd, "CONCURRENTLY") == 0) &&
pg_strcasecmp(prev2_wd, "ON") == 0)
{
! static const char *const list_CREATE_INDEX2[] =
! {"(", "USING", NULL};
!
! COMPLETE_WITH_LIST(list_CREATE_INDEX2);
}
! else if ((pg_strcasecmp(prev5_wd, "INDEX") == 0 ||
! pg_strcasecmp(prev4_wd, "INDEX") == 0 ||
! pg_strcasecmp(prev4_wd, "CONCURRENTLY") == 0) &&
pg_strcasecmp(prev3_wd, "ON") == 0 &&
pg_strcasecmp(prev_wd, "(") == 0)
COMPLETE_WITH_ATTR(prev2_wd, "");
/* same if you put in USING */
! else if (pg_strcasecmp(prev5_wd, "ON") == 0 &&
! pg_strcasecmp(prev3_wd, "USING") == 0 &&
! pg_strcasecmp(prev_wd, "(") == 0)
! COMPLETE_WITH_ATTR(prev4_wd, "");
/* Complete USING with an index method */
else if (pg_strcasecmp(prev_wd, "USING") == 0)
! COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
! else if (pg_strcasecmp(prev4_wd, "ON") == 0 &&
! pg_strcasecmp(prev2_wd, "USING") == 0)
! COMPLETE_WITH_CONST("(");
/* CREATE RULE */
/* Complete "CREATE RULE <sth>" with "AS" */
*************** psql_completion(char *text, int start, i
*** 1417,1422 ****
--- 1551,1567 ----
COMPLETE_WITH_LIST(list_CREATETRIGGER);
}
+ /* complete CREATE TRIGGER <name> BEFORE,AFTER with an event */
+ else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 &&
+ pg_strcasecmp(prev3_wd, "TRIGGER") == 0 &&
+ (pg_strcasecmp(prev_wd, "BEFORE") == 0 ||
+ pg_strcasecmp(prev_wd, "AFTER") == 0))
+ {
+ static const char *const list_CREATETRIGGER_EVENTS[] =
+ {"INSERT", "DELETE", "UPDATE", "TRUNCATE", NULL};
+
+ COMPLETE_WITH_LIST(list_CREATETRIGGER_EVENTS);
+ }
/* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 &&
pg_strcasecmp(prev4_wd, "TRIGGER") == 0 &&
*************** psql_completion(char *text, int start, i
*** 1428,1433 ****
--- 1573,1587 ----
COMPLETE_WITH_LIST(list_CREATETRIGGER2);
}
+ /* complete CREATE TRIGGER <name> BEFORE,AFTER event ON with a list of tables */
+ else if (pg_strcasecmp(prev5_wd, "TRIGGER") == 0 &&
+ (pg_strcasecmp(prev3_wd, "BEFORE") == 0 ||
+ pg_strcasecmp(prev3_wd, "AFTER") == 0) &&
+ pg_strcasecmp(prev_wd, "ON") == 0)
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
+ /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE */
+ else if (pg_strcasecmp(prev_wd, "EXECUTE") == 0)
+ COMPLETE_WITH_CONST("PROCEDURE");
/* CREATE ROLE,USER,GROUP */
else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
*************** psql_completion(char *text, int start, i
*** 1487,1492 ****
--- 1641,1647 ----
COMPLETE_WITH_LIST(list_DECLARE);
}
+ /* CURSOR */
else if (pg_strcasecmp(prev_wd, "CURSOR") == 0)
{
static const char *const list_DECLARECURSOR[] =
*************** psql_completion(char *text, int start, i
*** 1579,1599 ****
pg_strcasecmp(prev2_wd, "TEMPLATE") == 0))
)
{
! if ((pg_strcasecmp(prev3_wd, "DROP") == 0) && (pg_strcasecmp(prev2_wd, "FUNCTION") == 0))
{
! if (find_open_parenthesis(end))
! {
! static const char func_args_query[] = "select pg_catalog.oidvectortypes(proargtypes)||')' from pg_proc where proname='%s'";
! char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev_wd));
!
! sprintf(tmp_buf, func_args_query, prev_wd);
! COMPLETE_WITH_QUERY(tmp_buf);
! free(tmp_buf);
! }
! else
! {
! COMPLETE_WITH_CONST("(");
! }
}
else
{
--- 1734,1743 ----
pg_strcasecmp(prev2_wd, "TEMPLATE") == 0))
)
{
! if (pg_strcasecmp(prev3_wd, "DROP") == 0 &&
! pg_strcasecmp(prev2_wd, "FUNCTION") == 0)
{
! COMPLETE_WITH_CONST("(");
}
else
{
*************** psql_completion(char *text, int start, i
*** 1712,1723 ****
else if (pg_strcasecmp(prev_wd, "GRANT") == 0 ||
pg_strcasecmp(prev_wd, "REVOKE") == 0)
{
! static const char *const list_privileg[] =
{"SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES",
"TRIGGER", "CREATE", "CONNECT", "TEMPORARY", "EXECUTE", "USAGE",
"ALL", NULL};
! COMPLETE_WITH_LIST(list_privileg);
}
/* Complete GRANT/REVOKE <sth> with "ON" */
else if (pg_strcasecmp(prev2_wd, "GRANT") == 0 ||
--- 1856,1867 ----
else if (pg_strcasecmp(prev_wd, "GRANT") == 0 ||
pg_strcasecmp(prev_wd, "REVOKE") == 0)
{
! static const char *const list_privilege[] =
{"SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES",
"TRIGGER", "CREATE", "CONNECT", "TEMPORARY", "EXECUTE", "USAGE",
"ALL", NULL};
! COMPLETE_WITH_LIST(list_privilege);
}
/* Complete GRANT/REVOKE <sth> with "ON" */
else if (pg_strcasecmp(prev2_wd, "GRANT") == 0 ||
*************** psql_completion(char *text, int start, i
*** 1747,1754 ****
" UNION SELECT 'LARGE OBJECT'"
" UNION SELECT 'SCHEMA'"
" UNION SELECT 'TABLESPACE'");
! /* Complete "GRANT/REVOKE * ON * " with "TO" */
else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 ||
pg_strcasecmp(prev4_wd, "REVOKE") == 0) &&
pg_strcasecmp(prev2_wd, "ON") == 0)
--- 1891,1908 ----
" UNION SELECT 'LARGE OBJECT'"
" UNION SELECT 'SCHEMA'"
" UNION SELECT 'TABLESPACE'");
+ else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 ||
+ pg_strcasecmp(prev4_wd, "REVOKE") == 0) &&
+ pg_strcasecmp(prev2_wd, "ON") == 0 &&
+ pg_strcasecmp(prev_wd, "FOREIGN") == 0)
+ {
+ static const char *const list_privilege_foreign[] =
+ {"DATA WRAPPER", "SERVER", NULL};
+
+ COMPLETE_WITH_LIST(list_privilege_foreign);
+ }
! /* Complete "GRANT/REVOKE * ON * " with "TO/FROM" */
else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 ||
pg_strcasecmp(prev4_wd, "REVOKE") == 0) &&
pg_strcasecmp(prev2_wd, "ON") == 0)
*************** psql_completion(char *text, int start, i
*** 1770,1781 ****
}
/* Complete "GRANT/REVOKE * ON * TO/FROM" with username, GROUP, or PUBLIC */
! else if (pg_strcasecmp(prev3_wd, "ON") == 0 &&
! ((pg_strcasecmp(prev5_wd, "GRANT") == 0 &&
! pg_strcasecmp(prev_wd, "TO") == 0) ||
! (pg_strcasecmp(prev5_wd, "REVOKE") == 0 &&
! pg_strcasecmp(prev_wd, "FROM") == 0)))
! COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
/* GROUP BY */
else if (pg_strcasecmp(prev3_wd, "FROM") == 0 &&
--- 1924,1945 ----
}
/* Complete "GRANT/REVOKE * ON * TO/FROM" with username, GROUP, or PUBLIC */
! else if (pg_strcasecmp(prev5_wd, "GRANT") == 0 &&
! pg_strcasecmp(prev3_wd, "ON") == 0)
! {
! if (pg_strcasecmp(prev_wd, "TO") == 0)
! COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
! else
! COMPLETE_WITH_CONST("TO");
! }
! else if (pg_strcasecmp(prev5_wd, "REVOKE") == 0 &&
! pg_strcasecmp(prev3_wd, "ON") == 0)
! {
! if (pg_strcasecmp(prev_wd, "FROM") == 0)
! COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles);
! else
! COMPLETE_WITH_CONST("FROM");
! }
/* GROUP BY */
else if (pg_strcasecmp(prev3_wd, "FROM") == 0 &&
*************** psql_completion(char *text, int start, i
*** 2056,2061 ****
--- 2220,2226 ----
else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
pg_strcasecmp(prev4_wd, "UPDATE") != 0 &&
pg_strcasecmp(prev_wd, "TABLESPACE") != 0 &&
+ pg_strcasecmp(prev_wd, "(") != 0 &&
pg_strcasecmp(prev4_wd, "DOMAIN") != 0)
COMPLETE_WITH_CONST("TO");
/* Suggest possible variable values */
*************** exec_query(const char *query)
*** 2767,2772 ****
--- 2932,2940 ----
* skip that many words; e.g. skip=1 finds the word before the
* previous one. Return value is NULL or a malloc'ed string.
*/
+ #define issep(c) \
+ (isspace((unsigned char) (c)) || (c) == '(' || (c) == ')')
+
static char *
previous_word(int point, int skip)
{
*************** previous_word(int point, int skip)
*** 2776,2791 ****
inquotes = 0;
char *s;
while (skip-- >= 0)
{
- /* first we look for a space before the current word */
- for (i = point; i >= 0; i--)
- if (rl_line_buffer[i] == ' ')
- break;
-
/* now find the first non-space which then constitutes the end */
! for (; i >= 0; i--)
! if (rl_line_buffer[i] != ' ')
{
end = i;
break;
--- 2944,2960 ----
inquotes = 0;
char *s;
+ /* first we look for a space before the current word */
+ for (i = point - 1; i >= 0; i--)
+ if (issep(rl_line_buffer[i]))
+ break;
+ point = i;
+
while (skip-- >= 0)
{
/* now find the first non-space which then constitutes the end */
! for (i = point; i >= 0; i--)
! if (!isspace((unsigned char) rl_line_buffer[i]))
{
end = i;
break;
*************** previous_word(int point, int skip)
*** 2798,2817 ****
if (end == -1)
return NULL;
! /*
! * Otherwise we now look for the start. The start is either the last
! * character before any space going backwards from the end, or it's
! * simply character 0
! */
! for (start = end; start > 0; start--)
{
! if (rl_line_buffer[start] == '"')
! inquotes = !inquotes;
! if ((rl_line_buffer[start - 1] == ' ') && inquotes == 0)
! break;
}
!
! point = start;
}
/* make a copy */
--- 2967,2994 ----
if (end == -1)
return NULL;
! if (issep(rl_line_buffer[end]))
{
! /* non-alphabet separator is a single-character word */
! start = end;
! point = start - 1;
}
! else
! {
! /*
! * Otherwise we now look for the start. The start is either the
! * last character before any space going backwards from the end,
! * or it's simply character 0
! */
! for (start = end; start > 0; start--)
! {
! if (rl_line_buffer[start] == '"')
! inquotes = !inquotes;
! if (inquotes == 0 && issep(rl_line_buffer[start - 1]))
! break;
! }
! }
! point = start - 1;
}
/* make a copy */
*************** previous_word(int point, int skip)
*** 2821,2852 ****
return s;
}
- /* Find the parenthesis after the last word */
-
-
- static int
- find_open_parenthesis(int end)
- {
- int i = end - 1;
-
- while ((rl_line_buffer[i] != ' ') && (i >= 0))
- {
- if (rl_line_buffer[i] == '(')
- return 1;
- i--;
- }
- while ((rl_line_buffer[i] == ' ') && (i >= 0))
- {
- i--;
- }
- if (rl_line_buffer[i] == '(')
- {
- return 1;
- }
- return 0;
-
- }
-
#if 0
/*
--- 2998,3003 ----