psql_tab_completion_for_unlogged-20110223.patch
application/octet-stream
Filename: psql_tab_completion_for_unlogged-20110223.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: unified
| File | + | − |
|---|---|---|
| src/bin/psql/tab-complete.c | 0 | 0 |
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 70aa3fa..c60ca84 100644
*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
*************** typedef struct
*** 598,607 ****
const char *name;
const char *query; /* simple query, or NULL */
const SchemaQuery *squery; /* schema query, or NULL */
! const bool noshow; /* NULL or true if this word should not show
! * up after CREATE or DROP */
} pgsql_thing_t;
static const pgsql_thing_t words_after_create[] = {
{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
{"CAST", NULL, NULL}, /* Casts have complex structures for names, so
--- 598,610 ----
const char *name;
const char *query; /* simple query, or NULL */
const SchemaQuery *squery; /* schema query, or NULL */
! const bits32 flags; /* visibility flags, see below */
} pgsql_thing_t;
+ #define THING_NO_CREATE (1 << 0) /* should not show up after CREATE */
+ #define THING_NO_DROP (1 << 1) /* should not show up after DROP */
+ #define THING_NO_SHOW (THING_NO_CREATE | THING_NO_DROP)
+
static const pgsql_thing_t words_after_create[] = {
{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
{"CAST", NULL, NULL}, /* Casts have complex structures for names, so
*************** static const pgsql_thing_t words_after_c
*** 612,621 ****
* CREATE CONSTRAINT TRIGGER is not supported here because it is designed
* to be used only by pg_dump.
*/
! {"CONFIGURATION", Query_for_list_of_ts_configurations, NULL, true},
{"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"},
{"DATABASE", Query_for_list_of_databases},
! {"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, true},
{"DOMAIN", NULL, &Query_for_list_of_domains},
{"EXTENSION", Query_for_list_of_extensions},
{"FOREIGN DATA WRAPPER", NULL, NULL},
--- 615,624 ----
* CREATE CONSTRAINT TRIGGER is not supported here because it is designed
* to be used only by pg_dump.
*/
! {"CONFIGURATION", Query_for_list_of_ts_configurations, NULL, THING_NO_SHOW},
{"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"},
{"DATABASE", Query_for_list_of_databases},
! {"DICTIONARY", Query_for_list_of_ts_dictionaries, NULL, THING_NO_SHOW},
{"DOMAIN", NULL, &Query_for_list_of_domains},
{"EXTENSION", Query_for_list_of_extensions},
{"FOREIGN DATA WRAPPER", NULL, NULL},
*************** static const pgsql_thing_t words_after_c
*** 626,632 ****
{"INDEX", NULL, &Query_for_list_of_indexes},
{"OPERATOR", NULL, NULL}, /* Querying for this is probably not such a
* good idea. */
! {"PARSER", Query_for_list_of_ts_parsers, NULL, true},
{"ROLE", Query_for_list_of_roles},
{"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
{"SCHEMA", Query_for_list_of_schemas},
--- 629,636 ----
{"INDEX", NULL, &Query_for_list_of_indexes},
{"OPERATOR", NULL, NULL}, /* Querying for this is probably not such a
* good idea. */
! {"OWNED", NULL, NULL, THING_NO_CREATE}, /* for DROP OWNED BY ... */
! {"PARSER", Query_for_list_of_ts_parsers, NULL, THING_NO_SHOW},
{"ROLE", Query_for_list_of_roles},
{"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"},
{"SCHEMA", Query_for_list_of_schemas},
*************** static const pgsql_thing_t words_after_c
*** 634,649 ****
{"SERVER", Query_for_list_of_servers},
{"TABLE", NULL, &Query_for_list_of_tables},
{"TABLESPACE", Query_for_list_of_tablespaces},
! {"TEMP", NULL, NULL}, /* for CREATE TEMP TABLE ... */
! {"TEMPLATE", Query_for_list_of_ts_templates, NULL, true},
{"TEXT SEARCH", NULL, NULL},
{"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'"},
{"TYPE", NULL, &Query_for_list_of_datatypes},
! {"UNIQUE", NULL, NULL}, /* for CREATE UNIQUE INDEX ... */
{"USER", Query_for_list_of_roles},
{"USER MAPPING FOR", NULL, NULL},
{"VIEW", NULL, &Query_for_list_of_views},
! {NULL, NULL, NULL, false} /* end of list */
};
--- 638,654 ----
{"SERVER", Query_for_list_of_servers},
{"TABLE", NULL, &Query_for_list_of_tables},
{"TABLESPACE", Query_for_list_of_tablespaces},
! {"TEMP", NULL, NULL, THING_NO_DROP}, /* for CREATE TEMP TABLE ... */
! {"TEMPLATE", Query_for_list_of_ts_templates, NULL, THING_NO_SHOW},
{"TEXT SEARCH", NULL, NULL},
{"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'"},
{"TYPE", NULL, &Query_for_list_of_datatypes},
! {"UNIQUE", NULL, NULL, THING_NO_DROP}, /* for CREATE UNIQUE INDEX ... */
! {"UNLOGGED", NULL, NULL, THING_NO_DROP},/* for CREATE UNLOGGED TABLE ... */
{"USER", Query_for_list_of_roles},
{"USER MAPPING FOR", NULL, NULL},
{"VIEW", NULL, &Query_for_list_of_views},
! {NULL} /* end of list */
};
*************** psql_completion(char *text, int start, i
*** 1771,1776 ****
--- 1776,1787 ----
COMPLETE_WITH_LIST(list_TEMP);
}
+ /* Complete "CREATE UNLOGGED" with TABLE */
+ else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
+ pg_strcasecmp(prev_wd, "UNLOGGED") == 0)
+ {
+ COMPLETE_WITH_CONST("TABLE");
+ }
/* CREATE TABLESPACE */
else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
*************** psql_completion(char *text, int start, i
*** 2858,2868 ****
*/
/*
! * This one gives you one from a list of things you can put after CREATE
! * as defined above.
*/
static char *
! create_command_generator(const char *text, int state)
{
static int list_index,
string_length;
--- 2869,2879 ----
*/
/*
! * Common routine for create_command_generator and drop_command_generator.
! * Entries that have 'excluded' flags are not returned.
*/
static char *
! create_or_drop_command_generator(const char *text, int state, bits32 excluded)
{
static int list_index,
string_length;
*************** create_command_generator(const char *tex
*** 2879,2885 ****
while ((name = words_after_create[list_index++].name))
{
if ((pg_strncasecmp(name, text, string_length) == 0) &&
! !words_after_create[list_index - 1].noshow)
return pg_strdup(name);
}
/* if nothing matches, return NULL */
--- 2890,2896 ----
while ((name = words_after_create[list_index++].name))
{
if ((pg_strncasecmp(name, text, string_length) == 0) &&
! !(words_after_create[list_index - 1].flags & excluded))
return pg_strdup(name);
}
/* if nothing matches, return NULL */
*************** create_command_generator(const char *tex
*** 2887,2935 ****
}
/*
* This function gives you a list of things you can put after a DROP command.
- * Very similar to create_command_generator, but has an additional entry for
- * OWNED BY. (We do it this way in order not to duplicate the
- * words_after_create list.)
*/
static char *
drop_command_generator(const char *text, int state)
{
! static int list_index,
! string_length;
! const char *name;
!
! if (state == 0)
! {
! /* If this is the first time for this completion, init some values */
! list_index = 0;
! string_length = strlen(text);
!
! /*
! * DROP can be followed by "OWNED BY", which is not found in the list
! * for CREATE matches, so make it the first state. (We do not make it
! * the last state because it would be more difficult to detect when we
! * have to return NULL instead.)
! *
! * Make sure we advance to the next state.
! */
! list_index++;
! if (pg_strncasecmp("OWNED", text, string_length) == 0)
! return pg_strdup("OWNED");
! }
!
! /*
! * In subsequent attempts, try to complete with the same items we use for
! * CREATE
! */
! while ((name = words_after_create[list_index++ - 1].name))
! {
! if ((pg_strncasecmp(name, text, string_length) == 0) && (!words_after_create[list_index - 2].noshow))
! return pg_strdup(name);
! }
!
! /* if nothing matches, return NULL */
! return NULL;
}
/* The following two functions are wrappers for _complete_from_query */
--- 2898,2919 ----
}
/*
+ * This one gives you one from a list of things you can put after CREATE
+ * as defined above.
+ */
+ static char *
+ create_command_generator(const char *text, int state)
+ {
+ return create_or_drop_command_generator(text, state, THING_NO_CREATE);
+ }
+
+ /*
* This function gives you a list of things you can put after a DROP command.
*/
static char *
drop_command_generator(const char *text, int state)
{
! return create_or_drop_command_generator(text, state, THING_NO_DROP);
}
/* The following two functions are wrappers for _complete_from_query */