Re: tab complete changes

From: Bruce Momjian <bruce(at)momjian(dot)us>
To: Stefan Kaltenbrunner <stefan(at)kaltenbrunner(dot)cc>
Cc: Patches <pgsql-patches(at)postgresql(dot)org>
Subject: Re: tab complete changes
Date: 2007-09-14 04:25:35
Message-ID: 200709140425.l8E4PZk02156@momjian.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches


Patch applied. Thanks.

---------------------------------------------------------------------------

Stefan Kaltenbrunner wrote:
> the attached patch makes teh following changes to the psql tab-complete
> support
>
> * adds a few missing words to some commands (like adding GIN as a valid
> index type or OWNED BY for ALTER SEQUENCE,...)
>
> * support for ALTER TABLE foo ENABLE/DISABLE REPLICA TRIGGER/RULE
>
> * autocomplete CREATE DATABASE foo TEMPLATE (mostly done to prevent
> conflicts with the TEMPLATE keyword for text search)
>
> * support for ALTER/CREATE/DROP TEXT SEARCH as well as COMMENT ON TEXT
> SEARCH and the corresponding psql backslash commands.
> This proved a little more difficult than expected due to the fact that
> words_after_create[] is used for two purposes - one is to provide a list
> of words that follow immediatly after CREATE (or DROP) and the other
> purpose is to use it for autocompleting anywhere in the statement if the
> word in that struct is found with a query.
> Since TEXT SEARCH CONFIGURATION|DICTIONARY|TEMPLATE|PARSER results in 3
> words instead of one (as all the other words in that list are) I added a
> flag to the struct to tell create_command_generator() to skip that entry
> for autocompleting immediatly after CREATE which feels like a dirty
> hack (but that holds true for a lot of code in tab-complete.c).
>
>
> Stefan

> Index: src/bin/psql/tab-complete.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v
> retrieving revision 1.166
> diff -c -r1.166 tab-complete.c
> *** src/bin/psql/tab-complete.c 3 Jul 2007 01:30:37 -0000 1.166
> --- src/bin/psql/tab-complete.c 25 Aug 2007 11:17:23 -0000
> ***************
> *** 328,333 ****
> --- 328,337 ----
> " AND pg_catalog.quote_ident(relname)='%s' "\
> " AND pg_catalog.pg_table_is_visible(c.oid)"
>
> + #define Query_for_list_of_template_databases \
> + "SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\
> + " WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s' and datistemplate IS TRUE"
> +
> #define Query_for_list_of_databases \
> "SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\
> " WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'"
> ***************
> *** 419,424 ****
> --- 423,444 ----
> " (SELECT tgrelid FROM pg_catalog.pg_trigger "\
> " WHERE pg_catalog.quote_ident(tgname)='%s')"
>
> + #define Query_for_list_of_ts_configurations \
> + "SELECT pg_catalog.quote_ident(cfgname) FROM pg_catalog.pg_ts_config "\
> + " WHERE substring(pg_catalog.quote_ident(cfgname),1,%d)='%s'"
> +
> + #define Query_for_list_of_ts_dictionaries \
> + "SELECT pg_catalog.quote_ident(dictname) FROM pg_catalog.pg_ts_dict "\
> + " WHERE substring(pg_catalog.quote_ident(dictname),1,%d)='%s'"
> +
> + #define Query_for_list_of_ts_parsers \
> + "SELECT pg_catalog.quote_ident(prsname) FROM pg_catalog.pg_ts_parser "\
> + " WHERE substring(pg_catalog.quote_ident(prsname),1,%d)='%s'"
> +
> + #define Query_for_list_of_ts_templates \
> + "SELECT pg_catalog.quote_ident(tmplname) FROM pg_catalog.pg_ts_template "\
> + " WHERE substring(pg_catalog.quote_ident(tmplname),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.
> ***************
> *** 429,434 ****
> --- 449,455 ----
> 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[] = {
> ***************
> *** 440,447 ****
> --- 461,470 ----
> * 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},
> {"FUNCTION", NULL, &Query_for_list_of_functions},
> {"GROUP", Query_for_list_of_roles},
> ***************
> *** 449,454 ****
> --- 472,478 ----
> {"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},
> ***************
> *** 456,467 ****
> {"TABLE", NULL, &Query_for_list_of_tables},
> {"TABLESPACE", Query_for_list_of_tablespaces},
> {"TEMP", NULL, NULL}, /* for CREATE TEMP TABLE ... */
> {"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},
> {"VIEW", NULL, &Query_for_list_of_views},
> ! {NULL, NULL, NULL} /* end of list */
> };
>
>
> --- 480,493 ----
> {"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},
> {"VIEW", NULL, &Query_for_list_of_views},
> ! {NULL, NULL, NULL, false} /* end of list */
> };
>
>
> ***************
> *** 531,544 ****
> "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "PREPARE",
> "REASSIGN", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK",
> "SAVEPOINT", "SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN",
> ! "UPDATE", "VACUUM", NULL
> };
>
> static const char *const backslash_commands[] = {
> "\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright",
> "\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\dD", "\\df",
> ! "\\dg", "\\di", "\\dl", "\\dn", "\\do", "\\dp", "\\ds", "\\dS",
> ! "\\dt", "\\dT", "\\dv", "\\du",
> "\\e", "\\echo", "\\encoding",
> "\\f", "\\g", "\\h", "\\help", "\\H", "\\i", "\\l",
> "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
> --- 557,570 ----
> "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "PREPARE",
> "REASSIGN", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK",
> "SAVEPOINT", "SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN",
> ! "UPDATE", "VACUUM", "VALUES", NULL
> };
>
> static const char *const backslash_commands[] = {
> "\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright",
> "\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\dD", "\\df",
> ! "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl",
> ! "\\dn", "\\do", "\\dp", "\\ds", "\\dS", "\\dt", "\\dT", "\\dv", "\\du",
> "\\e", "\\echo", "\\encoding",
> "\\f", "\\g", "\\h", "\\help", "\\H", "\\i", "\\l",
> "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
> ***************
> *** 602,608 ****
> static const char *const list_ALTER[] =
> {"AGGREGATE", "CONVERSION", "DATABASE", "DOMAIN", "FUNCTION",
> "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "ROLE", "SCHEMA", "SEQUENCE", "TABLE",
> ! "TABLESPACE", "TRIGGER", "TYPE", "USER", "VIEW", NULL};
>
> COMPLETE_WITH_LIST(list_ALTER);
> }
> --- 628,634 ----
> static const char *const list_ALTER[] =
> {"AGGREGATE", "CONVERSION", "DATABASE", "DOMAIN", "FUNCTION",
> "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "ROLE", "SCHEMA", "SEQUENCE", "TABLE",
> ! "TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE", "USER", "VIEW", NULL};
>
> COMPLETE_WITH_LIST(list_ALTER);
> }
> ***************
> *** 643,649 ****
> pg_strcasecmp(prev2_wd, "INDEX") == 0)
> {
> static const char *const list_ALTERINDEX[] =
> ! {"SET TABLESPACE", "OWNER TO", "RENAME TO", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERINDEX);
> }
> --- 669,675 ----
> pg_strcasecmp(prev2_wd, "INDEX") == 0)
> {
> static const char *const list_ALTERINDEX[] =
> ! {"SET TABLESPACE", "OWNER TO", "RENAME TO", "SET", "RESET", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERINDEX);
> }
> ***************
> *** 714,720 ****
> {
> static const char *const list_ALTERSEQUENCE[] =
> {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE",
> ! "SET SCHEMA", "RENAME TO", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERSEQUENCE);
> }
> --- 740,746 ----
> {
> static const char *const list_ALTERSEQUENCE[] =
> {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE",
> ! "SET SCHEMA", "OWNED BY", "RENAME TO", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERSEQUENCE);
> }
> ***************
> *** 769,779 ****
> pg_strcasecmp(prev2_wd, "TABLE") == 0)
> {
> static const char *const list_ALTER2[] =
> ! {"ADD", "ALTER", "CLUSTER ON", "DROP", "RENAME", "OWNER TO",
> ! "SET", NULL};
>
> COMPLETE_WITH_LIST(list_ALTER2);
> }
> /* If we have TABLE <sth> ALTER|RENAME, provide list of columns */
> else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
> (pg_strcasecmp(prev_wd, "ALTER") == 0 ||
> --- 795,832 ----
> pg_strcasecmp(prev2_wd, "TABLE") == 0)
> {
> static const char *const list_ALTER2[] =
> ! {"ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", "ENABLE", "INHERIT",
> ! "NO INHERIT", "RENAME", "RESET", "OWNER TO", "SET", NULL};
>
> COMPLETE_WITH_LIST(list_ALTER2);
> }
> + /* ALTER TABLE xxx ENABLE */
> + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
> + pg_strcasecmp(prev_wd, "ENABLE") == 0)
> + {
> + static const char *const list_ALTERENABLE[] =
> + {"ALWAYS","REPLICA","RULE", "TRIGGER", NULL};
> + COMPLETE_WITH_LIST(list_ALTERENABLE);
> + }
> + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
> + pg_strcasecmp(prev2_wd, "ENABLE") == 0 &&
> + (pg_strcasecmp(prev_wd, "REPLICA") == 0 ||
> + pg_strcasecmp(prev_wd, "ALWAYS") == 0))
> + {
> + static const char *const list_ALTERENABLE2[] =
> + {"RULE", "TRIGGER", NULL};
> + COMPLETE_WITH_LIST(list_ALTERENABLE2);
> + }
> + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
> + pg_strcasecmp(prev_wd, "DISABLE") == 0)
> + {
> + static const char *const list_ALTERDISABLE[] =
> + {"RULE", "TRIGGER", NULL};
> + COMPLETE_WITH_LIST(list_ALTERDISABLE);
> + }
> +
> /* If we have TABLE <sth> ALTER|RENAME, provide list of columns */
> else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
> (pg_strcasecmp(prev_wd, "ALTER") == 0 ||
> ***************
> *** 871,876 ****
> --- 924,968 ----
>
> COMPLETE_WITH_LIST(list_ALTERTSPC);
> }
> + /* ALTER TEXT SEARCH */
> + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev2_wd, "TEXT") == 0 &&
> + pg_strcasecmp(prev_wd, "SEARCH") == 0)
> + {
> + static const char *const list_ALTERTEXTSEARCH[] =
> + {"CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE", NULL};
> +
> + COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH);
> + }
> + else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
> + pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
> + (pg_strcasecmp(prev2_wd, "TEMPLATE") == 0 ||
> + pg_strcasecmp(prev2_wd, "PARSER") == 0))
> + COMPLETE_WITH_CONST("RENAME TO");
> +
> + else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
> + pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
> + pg_strcasecmp(prev2_wd, "DICTIONARY") == 0)
> + {
> + static const char *const list_ALTERTEXTSEARCH2[] =
> + {"OWNER TO", "RENAME TO", NULL};
> +
> + COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH2);
> + }
> +
> + else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
> + pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
> + pg_strcasecmp(prev2_wd, "CONFIGURATION") == 0)
> + {
> + static const char *const list_ALTERTEXTSEARCH3[] =
> + {"ADD MAPPING FOR", "ALTER MAPPING", "DROP MAPPING FOR", "OWNER TO", "RENAME TO", NULL};
> +
> + COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH3);
> + }
> +
> /* complete ALTER TYPE <foo> with OWNER TO, SET SCHEMA */
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> pg_strcasecmp(prev2_wd, "TYPE") == 0)
> ***************
> *** 947,953 ****
> }
>
> /*
> ! * If we have CLUSTER <sth> ORDER BY, then add the index as well.
> */
> else if (pg_strcasecmp(prev3_wd, "CLUSTER") == 0 &&
> pg_strcasecmp(prev_wd, "USING") == 0)
> --- 1039,1045 ----
> }
>
> /*
> ! * If we have CLUSTER <sth> USING, then add the index as well.
> */
> else if (pg_strcasecmp(prev3_wd, "CLUSTER") == 0 &&
> pg_strcasecmp(prev_wd, "USING") == 0)
> ***************
> *** 966,977 ****
> {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA",
> "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
> "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
> ! "TABLESPACE", "ROLE", NULL};
>
> COMPLETE_WITH_LIST(list_COMMENT);
> }
> else if (pg_strcasecmp(prev4_wd, "COMMENT") == 0 &&
> ! pg_strcasecmp(prev3_wd, "ON") == 0)
> COMPLETE_WITH_CONST("IS");
>
> /* COPY */
> --- 1058,1082 ----
> {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA",
> "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
> "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
> ! "TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
>
> COMPLETE_WITH_LIST(list_COMMENT);
> }
> else if (pg_strcasecmp(prev4_wd, "COMMENT") == 0 &&
> ! pg_strcasecmp(prev3_wd, "ON") == 0 &&
> ! pg_strcasecmp(prev2_wd, "TEXT") == 0 &&
> ! pg_strcasecmp(prev_wd, "SEARCH") == 0)
> ! {
> ! static const char *const list_TRANS2[] =
> ! {"CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE", NULL};
> !
> ! COMPLETE_WITH_LIST(list_TRANS2);
> ! }
> ! else if ((pg_strcasecmp(prev4_wd, "COMMENT") == 0 &&
> ! pg_strcasecmp(prev3_wd, "ON") == 0) ||
> ! (pg_strcasecmp(prev5_wd, "ON") == 0 &&
> ! pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
> ! pg_strcasecmp(prev3_wd, "SEARCH") == 0))
> COMPLETE_WITH_CONST("IS");
>
> /* COPY */
> ***************
> *** 1038,1043 ****
> --- 1143,1153 ----
> COMPLETE_WITH_LIST(list_DATABASE);
> }
>
> + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 &&
> + pg_strcasecmp(prev3_wd, "DATABASE") == 0 &&
> + pg_strcasecmp(prev_wd, "TEMPLATE") == 0)
> + COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);
> +
> /* CREATE INDEX */
> /* First off we complete CREATE UNIQUE with "INDEX" */
> else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
> ***************
> *** 1077,1083 ****
> else if (pg_strcasecmp(prev_wd, "USING") == 0)
> {
> static const char *const index_mth[] =
> ! {"BTREE", "HASH", "GIST", NULL};
>
> COMPLETE_WITH_LIST(index_mth);
> }
> --- 1187,1193 ----
> else if (pg_strcasecmp(prev_wd, "USING") == 0)
> {
> static const char *const index_mth[] =
> ! {"BTREE", "HASH", "GIN", "GIST", NULL};
>
> COMPLETE_WITH_LIST(index_mth);
> }
> ***************
> *** 1143,1148 ****
> --- 1253,1273 ----
> COMPLETE_WITH_CONST("LOCATION");
> }
>
> + /* CREATE TEXT SEARCH */
> + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
> + pg_strcasecmp(prev2_wd, "TEXT") == 0 &&
> + pg_strcasecmp(prev_wd, "SEARCH") == 0)
> + {
> + static const char *const list_CREATETEXTSEARCH[] =
> + {"CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE", NULL};
> +
> + COMPLETE_WITH_LIST(list_CREATETEXTSEARCH);
> + }
> + else if (pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
> + pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
> + pg_strcasecmp(prev2_wd, "CONFIGURATION") == 0)
> + COMPLETE_WITH_CONST("(");
> +
> /* CREATE TRIGGER */
> /* complete CREATE TRIGGER <name> with BEFORE,AFTER */
> else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
> ***************
> *** 1287,1293 ****
> pg_strcasecmp(prev2_wd, "VIEW") == 0)) ||
> (pg_strcasecmp(prev4_wd, "DROP") == 0 &&
> pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 &&
> ! prev_wd[strlen(prev_wd) - 1] == ')'))
> {
> if ((pg_strcasecmp(prev3_wd, "DROP") == 0) && (pg_strcasecmp(prev2_wd, "FUNCTION") == 0))
> {
> --- 1412,1426 ----
> pg_strcasecmp(prev2_wd, "VIEW") == 0)) ||
> (pg_strcasecmp(prev4_wd, "DROP") == 0 &&
> pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 &&
> ! prev_wd[strlen(prev_wd) - 1] == ')') ||
> ! (pg_strcasecmp(prev5_wd, "DROP") == 0 &&
> ! pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
> ! pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
> ! (pg_strcasecmp(prev2_wd, "CONFIGURATION") == 0 ||
> ! pg_strcasecmp(prev2_wd, "DICTIONARY") == 0 ||
> ! pg_strcasecmp(prev2_wd, "PARSER") == 0 ||
> ! pg_strcasecmp(prev2_wd, "TEMPLATE") == 0))
> ! )
> {
> if ((pg_strcasecmp(prev3_wd, "DROP") == 0) && (pg_strcasecmp(prev2_wd, "FUNCTION") == 0))
> {
> ***************
> *** 1332,1340 ****
> pg_strcasecmp(prev2_wd, "OWNED") == 0 &&
> pg_strcasecmp(prev_wd, "BY") == 0)
> COMPLETE_WITH_QUERY(Query_for_list_of_roles);
>
>
> !
> /* EXPLAIN */
>
> /*
> --- 1465,1481 ----
> pg_strcasecmp(prev2_wd, "OWNED") == 0 &&
> pg_strcasecmp(prev_wd, "BY") == 0)
> COMPLETE_WITH_QUERY(Query_for_list_of_roles);
> + else if (pg_strcasecmp(prev3_wd, "DROP") == 0 &&
> + pg_strcasecmp(prev2_wd, "TEXT") == 0 &&
> + pg_strcasecmp(prev_wd, "SEARCH") == 0)
> + {
>
> + static const char *const list_ALTERTEXTSEARCH[] =
> + {"CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE", NULL};
>
> ! COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH);
> ! }
> !
> /* EXPLAIN */
>
> /*
> ***************
> *** 1873,1878 ****
> --- 2014,2027 ----
> COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL);
> else if (strcmp(prev_wd, "\\df") == 0 || strcmp(prev_wd, "\\df+") == 0)
> COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
> + else if (strcmp(prev_wd, "\\dF") == 0 || strcmp(prev_wd, "\\dF+") == 0)
> + COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations);
> + else if (strcmp(prev_wd, "\\dFd") == 0 || strcmp(prev_wd, "\\dFd+") == 0)
> + COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries);
> + else if (strcmp(prev_wd, "\\dFp") == 0 || strcmp(prev_wd, "\\dFp+") == 0)
> + COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers);
> + else if (strcmp(prev_wd, "\\dFt") == 0 || strcmp(prev_wd, "\\dFt+") == 0)
> + COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates);
> else if (strcmp(prev_wd, "\\di") == 0 || strcmp(prev_wd, "\\di+") == 0)
> COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
> else if (strcmp(prev_wd, "\\dn") == 0)
> ***************
> *** 1985,1992 ****
> static char *
> create_command_generator(const char *text, int state)
> {
> ! static int list_index,
> ! string_length;
> const char *name;
>
> /* If this is the first time for this completion, init some values */
> --- 2134,2140 ----
> static char *
> create_command_generator(const char *text, int state)
> {
> ! static int list_index, string_length;
> const char *name;
>
> /* If this is the first time for this completion, init some values */
> ***************
> *** 1998,2006 ****
>
> /* find something that matches */
> while ((name = words_after_create[list_index++].name))
> ! if (pg_strncasecmp(name, text, string_length) == 0)
> ! return pg_strdup(name);
> !
> /* if nothing matches, return NULL */
> return NULL;
> }
> --- 2146,2155 ----
>
> /* find something that matches */
> 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 */
> return NULL;
> }
> ***************
> *** 2014,2021 ****
> static char *
> drop_command_generator(const char *text, int state)
> {
> ! static int list_index,
> ! string_length;
> const char *name;
>
> if (state == 0)
> --- 2163,2169 ----
> static char *
> drop_command_generator(const char *text, int state)
> {
> ! static int list_index, string_length;
> const char *name;
>
> if (state == 0)
> ***************
> *** 2043,2049 ****
> */
> while ((name = words_after_create[list_index++ - 1].name))
> {
> ! if (pg_strncasecmp(name, text, string_length) == 0)
> return pg_strdup(name);
> }
>
> --- 2191,2197 ----
> */
> 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);
> }
>

>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: In versions below 8.0, the planner will ignore your desire to
> choose an index scan if your joining column's datatypes do not
> match

--
Bruce Momjian <bruce(at)momjian(dot)us> http://momjian.us
EnterpriseDB http://www.enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

In response to

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2007-09-14 04:28:53 Re: XLogCacheByte is unused
Previous Message Bruce Momjian 2007-09-14 03:54:55 Re: [HACKERS] PGparam extension version 0.4