Full support for all schema and table name combinations when getting a list of attributes. All of the following will now work:
select * from information_schema.columns where <tab> select * from foo where <tab> select * from "user" where <tab> select * from "foo" where <tab> select * from "Uppercase".lower where <tab> select * from "gtsm.com"."foo.Bar" where <tab> select * from "GTSM.com".foo where <tab> Also applies to other places that get lists of columns: insert into, alter table, create index, etc. -- Greg Sabino Mullane [EMAIL PROTECTED] PGP Key: 0x14964AC8 200710211212 http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
Index: tab-complete.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v retrieving revision 1.167 diff -r1.167 tab-complete.c 55a56 > #include "stringutils.h" 127,130c128,132 < static const char *completion_charp; /* to pass a string */ < static const char *const * completion_charpp; /* to pass a list of strings */ < static const char *completion_info_charp; /* to pass a second string */ < static const SchemaQuery *completion_squery; /* to pass a SchemaQuery */ --- > static const char *completion_charp; /* to pass a string */ > static const char *const * completion_charpp; /* to pass a list of strings */ > static const char *completion_info_charp; /* to pass a second string */ > static const char *completion_info_charp2; /* to pass a third string */ > static const SchemaQuery *completion_squery; /* to pass a SchemaQuery */ 148,149c150,164 < #define COMPLETE_WITH_ATTR(table, addon) \ < do {completion_charp = Query_for_list_of_attributes addon; completion_info_charp = table; matches = completion_matches(text, complete_from_query); } while(0) --- > #define COMPLETE_WITH_ATTR(relation, addon) \ > do { \ > completion_schema = strtokx(relation, " \t\n\r", ".", "\"", 0, false, false, pset.encoding); \ > strtokx(NULL, " \t\n\r", ".", "\"", 0, false, false, pset.encoding); \ > completion_table = strtokx(NULL, " \t\n\r", ".", "\"", 0, false, false, pset.encoding); \ > if (NULL == completion_table) { \ > completion_charp = Query_for_list_of_attributes addon; \ > completion_info_charp = relation; \ > } \ > else { \ > completion_charp = Query_for_list_of_attributes_with_schema addon; \ > completion_info_charp = completion_table; \ > completion_info_charp2 = completion_schema; \ > } \ > matches = completion_matches(text, complete_from_relation_query); } while(0) 315c330 < * completion_info_charp. --- > * completion_info_charp. A third %s is replaced by completion_info_charp2. 328c343,344 < " AND pg_catalog.quote_ident(relname)='%s' "\ --- > " AND (pg_catalog.quote_ident(relname)='%s' "\ > " OR '\"' || pg_catalog.quote_ident(relname) || '\"'='%s') "\ 330a347,359 > #define Query_for_list_of_attributes_with_schema \ > "SELECT pg_catalog.quote_ident(attname) "\ > " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c, pg_catalog.pg_namespace n "\ > " WHERE c.oid = a.attrelid "\ > " AND n.oid = c.relnamespace "\ > " AND a.attnum > 0 "\ > " AND NOT a.attisdropped "\ > " AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\ > " AND (pg_catalog.quote_ident(relname)='%s' "\ > " OR '\"' || pg_catalog.quote_ident(relname) || '\"' ='%s') "\ > " AND (pg_catalog.quote_ident(nspname)='%s' "\ > " OR '\"' || pg_catalog.quote_ident(nspname) || '\"' ='%s') " > 499a529 > static char *complete_from_relation_query(const char *text, int state); 552a583,585 > /* We may want to separate a word into a table and schema */ > char *completion_schema, *completion_table; > 585a619,621 > completion_info_charp2 = NULL; > completion_schema = NULL; > completion_table = NULL; 588c624 < * Scan the input line before our current position for the last four --- > * Scan the input line before our current position for the last five 2202c2238 < /* The following two functions are wrappers for _complete_from_query */ --- > /* The following three functions are wrappers for _complete_from_query */ 2215a2252,2256 > static char * > complete_from_relation_query(const char *text, int state) > { > return _complete_from_query(2, text, state); > } 2219c2260 < The query can be one of two kinds: --- > The query can be one of three kinds: 2224a2266,2269 > - A simple query as above, but with two or four additional %s in it, > which are replaced by completion_info_charp (first two), and > by completion_info_charp2 for the second two if needed. > or: 2251a2297 > char *e_info_charp2; 2275a2322,2333 > if (completion_info_charp2) > { > size_t charp_len; > > charp_len = strlen(completion_info_charp2); > e_info_charp2 = pg_malloc(charp_len * 2 + 1); > PQescapeString(e_info_charp2, completion_info_charp2, > charp_len); > } > else > e_info_charp2 = NULL; > 2278c2336 < if (is_schema_query) --- > if (1 == is_schema_query) 2366a2425,2430 > else if (2 == is_schema_query) > { > /* Last two args are doubled up to catch quoted tables and schemas */ > appendPQExpBuffer(&query_buffer, completion_charp, > string_length, e_text, e_info_charp, e_info_charp, e_info_charp2, e_info_charp2); > } 2383a2448,2449 > if (e_info_charp2) > free(e_info_charp2);
---------------------------(end of broadcast)--------------------------- TIP 3: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faq