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