Re: tab complete changes - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: tab complete changes |
Date | |
Msg-id | 200709140425.l8E4PZk02156@momjian.us Whole thread Raw |
In response to | tab complete changes (Stefan Kaltenbrunner <stefan@kaltenbrunner.cc>) |
List | 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@momjian.us> http://momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
pgsql-patches by date: