aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/tab-complete.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql/tab-complete.c')
-rw-r--r--src/bin/psql/tab-complete.c2869
1 files changed, 2343 insertions, 526 deletions
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 3a5fe0ab1f6..27d7469b935 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.137 2005/08/14 18:49:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.138 2005/10/15 02:49:40 momjian Exp $
*/
/*----------------------------------------------------------------------
@@ -83,30 +83,28 @@ typedef struct SchemaQuery
const char *catname;
/*
- * Selection condition --- only rows meeting this condition are
- * candidates to display. If catname mentions multiple tables,
- * include the necessary join condition here. For example, "c.relkind
- * = 'r'". Write NULL (not an empty string) if not needed.
+ * Selection condition --- only rows meeting this condition are candidates
+ * to display. If catname mentions multiple tables, include the necessary
+ * join condition here. For example, "c.relkind = 'r'". Write NULL (not
+ * an empty string) if not needed.
*/
const char *selcondition;
/*
* Visibility condition --- which rows are visible without schema
- * qualification? For example,
- * "pg_catalog.pg_table_is_visible(c.oid)".
+ * qualification? For example, "pg_catalog.pg_table_is_visible(c.oid)".
*/
const char *viscondition;
/*
- * Namespace --- name of field to join to pg_namespace.oid. For
- * example, "c.relnamespace".
+ * Namespace --- name of field to join to pg_namespace.oid. For example,
+ * "c.relnamespace".
*/
const char *namespace;
/*
- * Result --- the appropriately-quoted name to return, in the case of
- * an unqualified name. For example,
- * "pg_catalog.quote_ident(c.relname)".
+ * Result --- the appropriately-quoted name to return, in the case of an
+ * unqualified name. For example, "pg_catalog.quote_ident(c.relname)".
*/
const char *result;
@@ -128,8 +126,7 @@ static int completion_max_records;
* the completion callback functions. Ugly but there is no better way.
*/
static const char *completion_charp; /* to pass a string */
-static const char *const * completion_charpp; /* to pass a list of
- * strings */
+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 */
@@ -433,9 +430,13 @@ typedef struct
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 skip it */
- /* CREATE CONSTRAINT TRIGGER is not supported here because it is designed to be used only by pg_dump. */
+ {"CAST", NULL, NULL}, /* Casts have complex structures for names, so
+ * skip it */
+
+ /*
+ * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
+ * to be used only by pg_dump.
+ */
{"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},
{"DOMAIN", NULL, &Query_for_list_of_domains},
@@ -443,8 +444,8 @@ static const pgsql_thing_t words_after_create[] = {
{"GROUP", Query_for_list_of_roles},
{"LANGUAGE", Query_for_list_of_languages},
{"INDEX", NULL, &Query_for_list_of_indexes},
- {"OPERATOR", NULL, NULL}, /* Querying for this is probably not such
- * a good idea. */
+ {"OPERATOR", NULL, NULL}, /* Querying for this is probably not such a
+ * good idea. */
{"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},
@@ -493,8 +494,8 @@ initialize_readline(void)
completion_max_records = 1000;
/*
- * There is a variable rl_completion_query_items for this but
- * apparently it's not defined everywhere.
+ * There is a variable rl_completion_query_items for this but apparently
+ * it's not defined everywhere.
*/
}
@@ -550,9 +551,8 @@ psql_completion(char *text, int start, int end)
/*
* Scan the input line before our current position for the last four
- * words. According to those we'll make some smart decisions on what
- * the user is probably intending to type. TODO: Use strtokx() to do
- * this.
+ * words. According to those we'll make some smart decisions on what the
+ * user is probably intending to type. TODO: Use strtokx() to do this.
*/
prev_wd = previous_word(start, 0);
prev2_wd = previous_word(start, 1);
@@ -580,8 +580,8 @@ psql_completion(char *text, int start, int end)
/* ALTER */
/*
- * complete with what you can alter (TABLE, GROUP, USER, ...) unless
- * we're in ALTER TABLE sth ALTER
+ * complete with what you can alter (TABLE, GROUP, USER, ...) unless we're
+ * in ALTER TABLE sth ALTER
*/
else if (pg_strcasecmp(prev_wd, "ALTER") == 0 &&
pg_strcasecmp(prev3_wd, "TABLE") != 0)
@@ -595,18 +595,18 @@ psql_completion(char *text, int start, int end)
}
/* ALTER AGGREGATE,FUNCTION <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
- (pg_strcasecmp(prev2_wd, "AGGREGATE") == 0 ||
+ (pg_strcasecmp(prev2_wd, "AGGREGATE") == 0 ||
pg_strcasecmp(prev2_wd, "FUNCTION") == 0))
{
static const char *const list_ALTERAGG[] =
- {"OWNER TO", "RENAME TO","SET SCHEMA", NULL};
+ {"OWNER TO", "RENAME TO", "SET SCHEMA", NULL};
- COMPLETE_WITH_LIST(list_ALTERAGG);
+ COMPLETE_WITH_LIST(list_ALTERAGG);
}
/* ALTER CONVERSION,SCHEMA <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
- (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
+ (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
pg_strcasecmp(prev2_wd, "SCHEMA") == 0))
{
static const char *const list_ALTERGEN[] =
@@ -643,23 +643,23 @@ psql_completion(char *text, int start, int end)
/* ALTER USER,ROLE <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
(pg_strcasecmp(prev2_wd, "USER") == 0 ||
- pg_strcasecmp(prev2_wd, "ROLE") == 0))
+ pg_strcasecmp(prev2_wd, "ROLE") == 0))
{
static const char *const list_ALTERUSER[] =
{"ENCRYPTED", "UNENCRYPTED", "CREATEDB", "NOCREATEDB", "CREATEUSER",
- "NOCREATEUSER","CREATEROLE","NOCREATEROLE","INHERIT","NOINHERIT",
- "LOGIN","NOLOGIN","CONNECTION LIMIT", "VALID UNTIL", "RENAME TO",
- "SUPERUSER","NOSUPERUSER", "SET", "RESET", NULL};
+ "NOCREATEUSER", "CREATEROLE", "NOCREATEROLE", "INHERIT", "NOINHERIT",
+ "LOGIN", "NOLOGIN", "CONNECTION LIMIT", "VALID UNTIL", "RENAME TO",
+ "SUPERUSER", "NOSUPERUSER", "SET", "RESET", NULL};
COMPLETE_WITH_LIST(list_ALTERUSER);
}
/* complete ALTER USER,ROLE <name> ENCRYPTED,UNENCRYPTED with PASSWORD */
else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
- (pg_strcasecmp(prev3_wd, "ROLE") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) &&
- (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0))
+ (pg_strcasecmp(prev3_wd, "ROLE") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) &&
+ (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0))
{
- COMPLETE_WITH_CONST("PASSWORD");
+ COMPLETE_WITH_CONST("PASSWORD");
}
/* ALTER DOMAIN <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
@@ -694,21 +694,21 @@ psql_completion(char *text, int start, int end)
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "SEQUENCE") == 0)
{
- static const char *const list_ALTERSEQUENCE[] =
- {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE",
- "SET SCHEMA", NULL};
+ static const char *const list_ALTERSEQUENCE[] =
+ {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE",
+ "SET SCHEMA", NULL};
- COMPLETE_WITH_LIST(list_ALTERSEQUENCE);
+ COMPLETE_WITH_LIST(list_ALTERSEQUENCE);
}
/* ALTER SEQUENCE <name> NO */
else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
pg_strcasecmp(prev3_wd, "SEQUENCE") == 0 &&
pg_strcasecmp(prev_wd, "NO") == 0)
{
- static const char *const list_ALTERSEQUENCE2[] =
- {"MINVALUE", "MAXVALUE", "CYCLE", NULL};
+ static const char *const list_ALTERSEQUENCE2[] =
+ {"MINVALUE", "MAXVALUE", "CYCLE", NULL};
- COMPLETE_WITH_LIST(list_ALTERSEQUENCE2);
+ COMPLETE_WITH_LIST(list_ALTERSEQUENCE2);
}
/* ALTER TRIGGER <name>, add ON */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
@@ -781,9 +781,9 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev2_wd, "ALTER") == 0))
{
/* DROP ... does not work well yet */
- static const char *const list_COLUMNALTER[] =
+ static const char *const list_COLUMNALTER[] =
{"TYPE", "SET DEFAULT", "DROP DEFAULT", "SET NOT NULL",
- "DROP NOT NULL", "SET STATISTICS", "SET STORAGE", NULL};
+ "DROP NOT NULL", "SET STATISTICS", "SET STORAGE", NULL};
COMPLETE_WITH_LIST(list_COLUMNALTER);
}
@@ -802,7 +802,7 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev_wd, "SET") == 0)
{
static const char *const list_TABLESET[] =
- {"WITHOUT", "TABLESPACE","SCHEMA", NULL};
+ {"WITHOUT", "TABLESPACE", "SCHEMA", NULL};
COMPLETE_WITH_LIST(list_TABLESET);
}
@@ -836,6 +836,7 @@ psql_completion(char *text, int start, int end)
{
static const char *const list_ALTERTYPE[] =
{"OWNER TO", "SET SCHEMA", NULL};
+
COMPLETE_WITH_LIST(list_ALTERTYPE);
}
/* complete ALTER GROUP <foo> */
@@ -869,9 +870,9 @@ psql_completion(char *text, int start, int end)
{"WORK", "TRANSACTION", NULL};
COMPLETE_WITH_LIST(list_TRANS);
- }
+ }
/* COMMIT */
- else if(pg_strcasecmp(prev_wd, "COMMIT") == 0)
+ else if (pg_strcasecmp(prev_wd, "COMMIT") == 0)
{
static const char *const list_COMMIT[] =
{"WORK", "TRANSACTION", "PREPARED", NULL};
@@ -904,8 +905,7 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_CONST("ON");
/*
- * If we have CLUSTER <sth> ON, then add the correct tablename as
- * well.
+ * If we have CLUSTER <sth> ON, then add the correct tablename as well.
*/
else if (pg_strcasecmp(prev3_wd, "CLUSTER") == 0 &&
pg_strcasecmp(prev_wd, "ON") == 0)
@@ -923,7 +923,7 @@ psql_completion(char *text, int start, int end)
static const char *const list_COMMENT[] =
{"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA",
"SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
- "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN","LARGE OBJECT", NULL};
+ "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", NULL};
COMPLETE_WITH_LIST(list_COMMENT);
}
@@ -946,12 +946,12 @@ psql_completion(char *text, int start, int end)
else if (pg_strcasecmp(prev2_wd, "COPY") == 0 ||
pg_strcasecmp(prev2_wd, "\\copy") == 0 ||
pg_strcasecmp(prev2_wd, "BINARY") == 0)
- {
- static const char *const list_FROMTO[] =
- {"FROM", "TO", NULL};
+ {
+ static const char *const list_FROMTO[] =
+ {"FROM", "TO", NULL};
- COMPLETE_WITH_LIST(list_FROMTO);
- }
+ COMPLETE_WITH_LIST(list_FROMTO);
+ }
/* If we have COPY|BINARY <sth> FROM|TO, complete with filename */
else if ((pg_strcasecmp(prev3_wd, "COPY") == 0 ||
pg_strcasecmp(prev3_wd, "\\copy") == 0 ||
@@ -966,22 +966,22 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev4_wd, "BINARY") == 0) &&
(pg_strcasecmp(prev2_wd, "FROM") == 0 ||
pg_strcasecmp(prev2_wd, "TO") == 0))
- {
- static const char *const list_COPY[] =
- {"BINARY", "OIDS", "DELIMITER", "NULL", "CSV", NULL};
+ {
+ static const char *const list_COPY[] =
+ {"BINARY", "OIDS", "DELIMITER", "NULL", "CSV", NULL};
- COMPLETE_WITH_LIST(list_COPY);
- }
+ COMPLETE_WITH_LIST(list_COPY);
+ }
/* Handle COPY|BINARY <sth> FROM|TO filename CSV */
- else if (pg_strcasecmp(prev_wd, "CSV") == 0 &&
+ else if (pg_strcasecmp(prev_wd, "CSV") == 0 &&
(pg_strcasecmp(prev3_wd, "FROM") == 0 ||
pg_strcasecmp(prev3_wd, "TO") == 0))
{
- static const char *const list_CSV[] =
- {"HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", NULL};
+ static const char *const list_CSV[] =
+ {"HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", NULL};
- COMPLETE_WITH_LIST(list_CSV);
+ COMPLETE_WITH_LIST(list_CSV);
}
/* CREATE DATABASE */
@@ -990,7 +990,7 @@ psql_completion(char *text, int start, int end)
{
static const char *const list_DATABASE[] =
{"OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", "CONNECTION LIMIT",
- NULL};
+ NULL};
COMPLETE_WITH_LIST(list_DATABASE);
}
@@ -1011,8 +1011,8 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
/*
- * Complete INDEX <name> ON <table> with a list of table columns
- * (which should really be in parens)
+ * Complete INDEX <name> ON <table> with a list of table columns (which
+ * should really be in parens)
*/
else if (pg_strcasecmp(prev4_wd, "INDEX") == 0 &&
pg_strcasecmp(prev2_wd, "ON") == 0)
@@ -1088,20 +1088,22 @@ psql_completion(char *text, int start, int end)
/* CREATE TRIGGER */
/* complete CREATE TRIGGER <name> with BEFORE,AFTER */
else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
- pg_strcasecmp(prev2_wd, "TRIGGER") == 0)
+ pg_strcasecmp(prev2_wd, "TRIGGER") == 0)
{
static const char *const list_CREATETRIGGER[] =
- {"BEFORE", "AFTER", NULL};
- COMPLETE_WITH_LIST(list_CREATETRIGGER);
+ {"BEFORE", "AFTER", NULL};
+
+ COMPLETE_WITH_LIST(list_CREATETRIGGER);
}
/* complete CREATE TRIGGER <name> BEFORE,AFTER sth with OR,ON */
else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 &&
- pg_strcasecmp(prev4_wd, "TRIGGER") == 0 &&
- (pg_strcasecmp(prev2_wd, "BEFORE") == 0 ||
- pg_strcasecmp(prev2_wd, "AFTER") == 0))
+ pg_strcasecmp(prev4_wd, "TRIGGER") == 0 &&
+ (pg_strcasecmp(prev2_wd, "BEFORE") == 0 ||
+ pg_strcasecmp(prev2_wd, "AFTER") == 0))
{
static const char *const list_CREATETRIGGER2[] =
- {"ON","OR",NULL};
+ {"ON", "OR", NULL};
+
COMPLETE_WITH_LIST(list_CREATETRIGGER2);
}
@@ -1111,29 +1113,35 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev2_wd, "GROUP") == 0 || pg_strcasecmp(prev2_wd, "USER") == 0))
{
static const char *const list_CREATEROLE[] =
- {"ADMIN","CONNECTION LIMIT","CREATEDB","CREATEROLE","CREATEUSER",
- "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOINHERIT", "NOLOGIN", "NOCREATEDB",
- "NOCREATEROLE", "NOCREATEUSER", "NOSUPERUSER", "ROLE", "SUPERUSER", "SYSID",
- "UNENCRYPTED",NULL};
- COMPLETE_WITH_LIST(list_CREATEROLE);
+ {"ADMIN", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", "CREATEUSER",
+ "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOINHERIT", "NOLOGIN", "NOCREATEDB",
+ "NOCREATEROLE", "NOCREATEUSER", "NOSUPERUSER", "ROLE", "SUPERUSER", "SYSID",
+ "UNENCRYPTED", NULL};
+
+ COMPLETE_WITH_LIST(list_CREATEROLE);
}
- /* complete CREATE ROLE,USER,GROUP <name> ENCRYPTED,UNENCRYPTED with PASSWORD */
+
+ /*
+ * complete CREATE ROLE,USER,GROUP <name> ENCRYPTED,UNENCRYPTED with
+ * PASSWORD
+ */
else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 &&
- (pg_strcasecmp(prev3_wd, "ROLE") == 0 ||
- pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) &&
- (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0))
+ (pg_strcasecmp(prev3_wd, "ROLE") == 0 ||
+ pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) &&
+ (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0))
{
- COMPLETE_WITH_CONST("PASSWORD");
+ COMPLETE_WITH_CONST("PASSWORD");
}
/* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 &&
- (pg_strcasecmp(prev3_wd, "ROLE") == 0 ||
- pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) &&
- pg_strcasecmp(prev_wd, "IN") == 0)
+ (pg_strcasecmp(prev3_wd, "ROLE") == 0 ||
+ pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) &&
+ pg_strcasecmp(prev_wd, "IN") == 0)
{
static const char *const list_CREATEROLE3[] =
- {"GROUP","ROLE",NULL};
- COMPLETE_WITH_LIST(list_CREATEROLE3);
+ {"GROUP", "ROLE", NULL};
+
+ COMPLETE_WITH_LIST(list_CREATEROLE3);
}
/* CREATE VIEW */
@@ -1150,20 +1158,23 @@ psql_completion(char *text, int start, int end)
/* DECLARE */
else if (pg_strcasecmp(prev2_wd, "DECLARE") == 0)
{
- static const char *const list_DECLARE[] =
- {"BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", "CURSOR", NULL};
- COMPLETE_WITH_LIST(list_DECLARE);
+ static const char *const list_DECLARE[] =
+ {"BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", "CURSOR", NULL};
+
+ COMPLETE_WITH_LIST(list_DECLARE);
}
else if (pg_strcasecmp(prev_wd, "CURSOR") == 0)
{
- static const char *const list_DECLARECURSOR[] =
- {"WITH HOLD", "WITHOUT HOLD", "FOR", NULL};
- COMPLETE_WITH_LIST(list_DECLARECURSOR);
+ static const char *const list_DECLARECURSOR[] =
+ {"WITH HOLD", "WITHOUT HOLD", "FOR", NULL};
+
+ COMPLETE_WITH_LIST(list_DECLARECURSOR);
}
/* DELETE */
+
/*
* Complete DELETE with FROM (only if the word before that is not "ON"
* (cf. rules) or "BEFORE" or "AFTER" (cf. triggers) or GRANT)
@@ -1211,27 +1222,31 @@ psql_completion(char *text, int start, int end)
pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 &&
prev_wd[strlen(prev_wd) - 1] == ')'))
{
- static const char *const list_DROPCR[] =
- {"CASCADE", "RESTRICT", NULL};
- COMPLETE_WITH_LIST(list_DROPCR);
+ static const char *const list_DROPCR[] =
+ {"CASCADE", "RESTRICT", NULL};
+
+ COMPLETE_WITH_LIST(list_DROPCR);
}
/* EXPLAIN */
+
/*
* Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands
*/
else if (pg_strcasecmp(prev_wd, "EXPLAIN") == 0)
{
- static const char *const list_EXPLAIN[] =
- {"SELECT","INSERT","DELETE","UPDATE","DECLARE","ANALYZE","VERBOSE",NULL};
- COMPLETE_WITH_LIST(list_EXPLAIN);
+ static const char *const list_EXPLAIN[] =
+ {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", "ANALYZE", "VERBOSE", NULL};
+
+ COMPLETE_WITH_LIST(list_EXPLAIN);
}
else if (pg_strcasecmp(prev2_wd, "EXPLAIN") == 0 &&
- pg_strcasecmp(prev_wd, "ANALYZE") == 0)
+ pg_strcasecmp(prev_wd, "ANALYZE") == 0)
{
- static const char *const list_EXPLAIN[] =
- {"SELECT","INSERT","DELETE","UPDATE","DECLARE","VERBOSE",NULL};
- COMPLETE_WITH_LIST(list_EXPLAIN);
+ static const char *const list_EXPLAIN[] =
+ {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", "VERBOSE", NULL};
+
+ COMPLETE_WITH_LIST(list_EXPLAIN);
}
else if (pg_strcasecmp(prev_wd, "VERBOSE") == 0 &&
pg_strcasecmp(prev3_wd, "VACUUM") != 0 &&
@@ -1239,9 +1254,10 @@ psql_completion(char *text, int start, int end)
(pg_strcasecmp(prev2_wd, "ANALYZE") == 0 ||
pg_strcasecmp(prev2_wd, "EXPLAIN") == 0))
{
- static const char *const list_EXPLAIN[] =
- {"SELECT","INSERT","DELETE","UPDATE","DECLARE",NULL};
- COMPLETE_WITH_LIST(list_EXPLAIN);
+ static const char *const list_EXPLAIN[] =
+ {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", NULL};
+
+ COMPLETE_WITH_LIST(list_EXPLAIN);
}
/* FETCH && MOVE */
@@ -1265,9 +1281,9 @@ psql_completion(char *text, int start, int end)
}
/*
- * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are
- * equivalent, but we may as well tab-complete both: perhaps some
- * users prefer one variant or the other.
+ * Complete FETCH <sth1> <sth2> with "FROM" or "IN". These are equivalent,
+ * but we may as well tab-complete both: perhaps some users prefer one
+ * variant or the other.
*/
else if (pg_strcasecmp(prev3_wd, "FETCH") == 0 ||
pg_strcasecmp(prev3_wd, "MOVE") == 0)
@@ -1295,15 +1311,15 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_CONST("ON");
/*
- * Complete GRANT/REVOKE <sth> ON with a list of tables, views,
- * sequences, and indexes
+ * Complete GRANT/REVOKE <sth> ON with a list of tables, views, sequences,
+ * and indexes
*
- * keywords DATABASE, FUNCTION, LANGUAGE, SCHEMA added to query result
- * via UNION; seems to work intuitively
+ * keywords DATABASE, FUNCTION, LANGUAGE, SCHEMA added to query result via
+ * UNION; seems to work intuitively
*
- * Note: GRANT/REVOKE can get quite complex; tab-completion as
- * implemented here will only work if the privilege list contains
- * exactly one privilege
+ * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented
+ * here will only work if the privilege list contains exactly one
+ * privilege
*/
else if ((pg_strcasecmp(prev3_wd, "GRANT") == 0 ||
pg_strcasecmp(prev3_wd, "REVOKE") == 0) &&
@@ -1564,7 +1580,7 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(constraint_list);
}
/* Complete SET ROLE */
- else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
+ else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
pg_strcasecmp(prev_wd, "ROLE") == 0)
COMPLETE_WITH_QUERY(Query_for_list_of_roles);
/* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
@@ -1589,14 +1605,14 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_CONST("TO");
/* Suggest possible variable values */
else if (pg_strcasecmp(prev3_wd, "SET") == 0 &&
- (pg_strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0))
+ (pg_strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0))
{
if (pg_strcasecmp(prev2_wd, "DateStyle") == 0)
{
static const char *const my_list[] =
{"ISO", "SQL", "Postgres", "German",
- "YMD", "DMY", "MDY",
- "US", "European", "NonEuropean",
+ "YMD", "DMY", "MDY",
+ "US", "European", "NonEuropean",
"DEFAULT", NULL};
COMPLETE_WITH_LIST(my_list);
@@ -1638,16 +1654,16 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_CONST("SET");
/*
- * If the previous word is SET (and it wasn't caught above as the
- * _first_ word) the word before it was (hopefully) a table name and
- * we'll now make a list of attributes.
+ * If the previous word is SET (and it wasn't caught above as the _first_
+ * word) the word before it was (hopefully) a table name and we'll now
+ * make a list of attributes.
*/
else if (pg_strcasecmp(prev_wd, "SET") == 0)
COMPLETE_WITH_ATTR(prev2_wd);
/* UPDATE xx SET yy = */
else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
- pg_strcasecmp(prev4_wd, "UPDATE") == 0)
+ pg_strcasecmp(prev4_wd, "UPDATE") == 0)
COMPLETE_WITH_CONST("=");
/*
@@ -1756,21 +1772,144 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(my_list);
}
else if (strcmp(prev_wd, "\\cd") == 0 ||
- strcmp(prev_wd, "\\e") == 0 || strcmp(prev_wd, "\\edit") == 0 ||
+ strcmp(prev_wd, "\\e") == 0 || strcmp(prev_wd, "\\edit") == 0 ||
strcmp(prev_wd, "\\g") == 0 ||
- strcmp(prev_wd, "\\i") == 0 || strcmp(prev_wd, "\\include") == 0 ||
- strcmp(prev_wd, "\\o") == 0 || strcmp(prev_wd, "\\out") == 0 ||
+ strcmp(prev_wd, "\\i") == 0 || strcmp(prev_wd, "\\include") == 0 ||
+ strcmp(prev_wd, "\\o") == 0 || strcmp(prev_wd, "\\out") == 0 ||
strcmp(prev_wd, "\\s") == 0 ||
- strcmp(prev_wd, "\\w") == 0 || strcmp(prev_wd, "\\write") == 0
+ strcmp(prev_wd, "\\w") == 0 || strcmp(prev_wd, "\\write") == 0
)
matches = completion_matches(text, filename_completion_function);
- /*
- * Finally, we look through the list of "things", such as TABLE, INDEX
- * and check if that was the previous word. If so, execute the query
- * to get a list of them.
- */
+ /*
+ *
+ * Fi
+ * n
+ * a
+ * l
+ * l
+ * y
+ * ,
+ *
+ * we
+ *
+ * lo
+ * o
+ * k
+ *
+ * th
+ * r
+ * o
+ * u
+ * g
+ * h
+ *
+ * th
+ * e
+ *
+ * li
+ * s
+ * t
+ *
+ * of
+ *
+ * "t
+ * h
+ * i
+ * n
+ * g
+ * s
+ * "
+ * ,
+ *
+ * su
+ * c
+ * h
+ *
+ * as
+ *
+ * TA
+ * B
+ * L
+ * E
+ * ,
+ *
+ * IN
+ * D
+ * E
+ * X
+ *
+ * an
+ * d
+ *
+ * ch
+ * e
+ * c
+ * k
+ *
+ * if
+ *
+ * th
+ * a
+ * t
+ *
+ * wa
+ * s
+ *
+ * th
+ * e
+ *
+ * pr
+ * e
+ * v
+ * i
+ * o
+ * u
+ * s
+ *
+ * wo
+ * r
+ * d
+ * .
+ *
+ * If
+ *
+ * so
+ * ,
+ *
+ * ex
+ * e
+ * c
+ * u
+ * t
+ * e
+ *
+ * th
+ * e
+ *
+ * qu
+ * e
+ * r
+ * y
+ *
+ * to
+ *
+ * ge
+ * t
+ *
+ * a
+ * li
+ * s
+ * t
+ *
+ * of
+ *
+ * th
+ * e
+ * m
+ * .
+ * */
else
{
int i;
@@ -1789,30 +1928,236 @@ psql_completion(char *text, int start, int end)
}
}
- /*
- * If we still don't have anything to match we have to fabricate some
- * sort of default list. If we were to just return NULL, readline
- * automatically attempts filename completion, and that's usually no
- * good.
- */
- if (matches == NULL)
- {
- COMPLETE_WITH_CONST("");
+ /*
+ *
+ * If
+ *
+ * we
+ *
+ * st
+ * i
+ * l
+ * l
+ *
+ * do
+ * n
+ * '
+ * t
+ *
+ * ha
+ * v
+ * e
+ *
+ * an
+ * y
+ * t
+ * h
+ * i
+ * n
+ * g
+ *
+ * to
+ *
+ * ma
+ * t
+ * c
+ * h
+ *
+ * we
+ *
+ * ha
+ * v
+ * e
+ *
+ * to
+ *
+ * fa
+ * b
+ * r
+ * i
+ * c
+ * a
+ * t
+ * e
+ *
+ * so
+ * m
+ * e
+ *
+ * so
+ * r
+ * t
+ *
+ * of
+ *
+ * de
+ * f
+ * a
+ * u
+ * l
+ * t
+ *
+ * li
+ * s
+ * t
+ * .
+ *
+ * If
+ *
+ * we
+ *
+ * we
+ * r
+ * e
+ *
+ * to
+ *
+ * ju
+ * s
+ * t
+ *
+ * re
+ * t
+ * u
+ * r
+ * n
+ *
+ * NU
+ * L
+ * L
+ * ,
+ *
+ * re
+ * a
+ * d
+ * l
+ * i
+ * n
+ * e
+ *
+ * au
+ * t
+ * o
+ * m
+ * a
+ * t
+ * i
+ * c
+ * a
+ * l
+ * l
+ * y
+ *
+ * at
+ * t
+ * e
+ * m
+ * p
+ * t
+ * s
+ *
+ * fi
+ * l
+ * e
+ * n
+ * a
+ * m
+ * e
+ *
+ * co
+ * m
+ * p
+ * l
+ * e
+ * t
+ * i
+ * o
+ * n
+ * ,
+ *
+ * an
+ * d
+ *
+ * th
+ * a
+ * t
+ * '
+ * s
+ *
+ * us
+ * u
+ * a
+ * l
+ * l
+ * y
+ *
+ * no
+ *
+ * go
+ * o
+ * d
+ * .
+ * */
+ if (matches == NULL)
+ {
+ COMPLETE_WITH_CONST("");
#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
- rl_completion_append_character = '\0';
+ rl_completion_append_character = '\0';
#endif
- }
-
- /* free storage */
- free(prev_wd);
- free(prev2_wd);
- free(prev3_wd);
- free(prev4_wd);
- free(prev5_wd);
-
- /* Return our Grand List O' Matches */
- return matches;
-}
+ }
+
+ /*
+ * f
+ * r
+ * e
+ * e
+ *
+ * st
+ * o
+ * r
+ * a
+ * g
+ * e
+ *
+ */
+ free(prev_wd);
+ free(prev2_wd);
+ free(prev3_wd);
+ free(prev4_wd);
+ free(prev5_wd);
+
+ /*
+ * R
+ * e
+ * t
+ * u
+ * r
+ * n
+ *
+ * ou
+ * r
+ *
+ * Gr
+ * a
+ * n
+ * d
+ *
+ * Li
+ * s
+ * t
+ *
+ * O'
+ *
+ * Ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ *
+ */
+ return matches;
+ }
@@ -1832,43 +2177,152 @@ psql_completion(char *text, int start, int end)
/* This one gives you one from a list of things you can put after CREATE or DROP
as defined above.
*/
-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 */
- if (state == 0)
- {
- list_index = 0;
- string_length = strlen(text);
- }
-
- /* 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;
-}
+ static char *
+ create_command_generator(const char *text, int state)
+ {
+ static int list_index,
+ string_length;
+ const char *name;
+
+ /*
+ * I
+ * f
+ *
+ * th
+ * i
+ * s
+ *
+ * is
+ *
+ * th
+ * e
+ *
+ * fi
+ * r
+ * s
+ * t
+ *
+ * ti
+ * m
+ * e
+ *
+ * fo
+ * r
+ *
+ * th
+ * i
+ * s
+ *
+ * co
+ * m
+ * p
+ * l
+ * e
+ * t
+ * i
+ * o
+ * n
+ * ,
+ *
+ * in
+ * i
+ * t
+ *
+ * so
+ * m
+ * e
+ *
+ * va
+ * l
+ * u
+ * e
+ * s
+ *
+ */
+ if (state == 0)
+ {
+ list_index = 0;
+ string_length = strlen(text);
+ }
+
+ /*
+ * f
+ * i
+ * n
+ * d
+ *
+ * so
+ * m
+ * e
+ * t
+ * h
+ * i
+ * n
+ * g
+ *
+ * th
+ * a
+ * t
+ *
+ * ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ *
+ */
+ while ((name = words_after_create[list_index++].name))
+ if (pg_strncasecmp(name, text, string_length) == 0)
+ return pg_strdup(name);
+
+ /*
+ * i
+ * f
+ *
+ * no
+ * t
+ * h
+ * i
+ * n
+ * g
+ *
+ * ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ * ,
+ *
+ * re
+ * t
+ * u
+ * r
+ * n
+ *
+ * NU
+ * L
+ * L
+ *
+ */
+ return NULL;
+ }
/* The following two functions are wrappers for _complete_from_query */
-static char *
-complete_from_query(const char *text, int state)
-{
- return _complete_from_query(0, text, state);
-}
+ static char *
+ complete_from_query(const char *text, int state)
+ {
+ return _complete_from_query(0, text, state);
+ }
-static char *
-complete_from_schema_query(const char *text, int state)
-{
- return _complete_from_query(1, text, state);
-}
+ static char *
+ complete_from_schema_query(const char *text, int state)
+ {
+ return _complete_from_query(1, text, state);
+ }
/* This creates a list of matching things, according to a query pointed to
@@ -1890,229 +2344,1308 @@ complete_from_schema_query(const char *text, int state)
See top of file for examples of both kinds of query.
*/
-static char *
-_complete_from_query(int is_schema_query, const char *text, int state)
-{
- static int list_index,
- string_length;
- static PGresult *result = NULL;
-
- /*
- * If this is the first time for this completion, we fetch a list of
- * our "things" from the backend.
- */
- if (state == 0)
- {
- PQExpBufferData query_buffer;
- char *e_text;
- char *e_info_charp;
-
- list_index = 0;
- string_length = strlen(text);
-
- /* Free any prior result */
- PQclear(result);
- result = NULL;
-
- /* Set up suitably-escaped copies of textual inputs */
- e_text = pg_malloc(string_length * 2 + 1);
- PQescapeString(e_text, text, string_length);
-
- if (completion_info_charp)
- {
- size_t charp_len;
-
- charp_len = strlen(completion_info_charp);
- e_info_charp = pg_malloc(charp_len * 2 + 1);
- PQescapeString(e_info_charp, completion_info_charp,
- charp_len);
- }
- else
- e_info_charp = NULL;
-
- initPQExpBuffer(&query_buffer);
-
- if (is_schema_query)
- {
- /* completion_squery gives us the pieces to assemble */
- const char *qualresult = completion_squery->qualresult;
-
- if (qualresult == NULL)
- qualresult = completion_squery->result;
-
- /* Get unqualified names matching the input-so-far */
- appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
- completion_squery->result,
- completion_squery->catname);
- if (completion_squery->selcondition)
- appendPQExpBuffer(&query_buffer, "%s AND ",
- completion_squery->selcondition);
- appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
- completion_squery->result,
- string_length, e_text);
- appendPQExpBuffer(&query_buffer, " AND %s",
- completion_squery->viscondition);
-
- /*
- * When fetching relation names, suppress system catalogs
- * unless the input-so-far begins with "pg_". This is a
- * compromise between not offering system catalogs for
- * completion at all, and having them swamp the result when
- * the input is just "p".
- */
- if (strcmp(completion_squery->catname,
- "pg_catalog.pg_class c") == 0 &&
- strncmp(text, "pg_", 3) !=0)
- {
- appendPQExpBuffer(&query_buffer,
- " AND c.relnamespace <> (SELECT oid FROM"
- " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
- }
-
- /*
- * Add in matching schema names, but only if there is more
- * than one potential match among schema names.
- */
- appendPQExpBuffer(&query_buffer, "\nUNION\n"
- "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
- "FROM pg_catalog.pg_namespace n "
- "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
- string_length, e_text);
- appendPQExpBuffer(&query_buffer,
- " AND (SELECT pg_catalog.count(*)"
- " FROM pg_catalog.pg_namespace"
- " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
- " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
- string_length, e_text);
-
- /*
- * Add in matching qualified names, but only if there is
- * exactly one schema matching the input-so-far.
- */
- appendPQExpBuffer(&query_buffer, "\nUNION\n"
- "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
- "FROM %s, pg_catalog.pg_namespace n "
- "WHERE %s = n.oid AND ",
- qualresult,
- completion_squery->catname,
- completion_squery->namespace);
- if (completion_squery->selcondition)
- appendPQExpBuffer(&query_buffer, "%s AND ",
- completion_squery->selcondition);
- appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
- qualresult,
- string_length, e_text);
-
- /*
- * This condition exploits the single-matching-schema rule to
- * speed up the query
- */
- appendPQExpBuffer(&query_buffer,
- " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
- " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
- string_length, e_text);
- appendPQExpBuffer(&query_buffer,
- " AND (SELECT pg_catalog.count(*)"
- " FROM pg_catalog.pg_namespace"
- " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
- " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
- string_length, e_text);
-
- /* If an addon query was provided, use it */
- if (completion_charp)
- appendPQExpBuffer(&query_buffer, "\n%s", completion_charp);
- }
- else
- {
- /* completion_charp is an sprintf-style format string */
- appendPQExpBuffer(&query_buffer, completion_charp,
- string_length, e_text, e_info_charp);
- }
-
- /* Limit the number of records in the result */
- appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
- completion_max_records);
-
- result = exec_query(query_buffer.data);
-
- termPQExpBuffer(&query_buffer);
- free(e_text);
- if (e_info_charp)
- free(e_info_charp);
- }
-
- /* Find something that matches */
- if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
- {
- const char *item;
-
- while (list_index < PQntuples(result) &&
- (item = PQgetvalue(result, list_index++, 0)))
- if (pg_strncasecmp(text, item, string_length) == 0)
- return pg_strdup(item);
- }
-
- /* If nothing matches, free the db structure and return null */
- PQclear(result);
- result = NULL;
- return NULL;
-}
+ static char *
+ _complete_from_query(int is_schema_query, const char *text, int state)
+ {
+ static int list_index,
+ string_length;
+ static PGresult *result = NULL;
+
+ /*
+ *
+ * If
+ *
+ * th
+ * i
+ * s
+ *
+ * is
+ *
+ * th
+ * e
+ *
+ * fi
+ * r
+ * s
+ * t
+ *
+ * ti
+ * m
+ * e
+ *
+ * fo
+ * r
+ *
+ * th
+ * i
+ * s
+ *
+ * co
+ * m
+ * p
+ * l
+ * e
+ * t
+ * i
+ * o
+ * n
+ * ,
+ *
+ * we
+ *
+ * fe
+ * t
+ * c
+ * h
+ *
+ * a
+ * li
+ * s
+ * t
+ *
+ * of
+ *
+ * ou
+ * r
+ *
+ * "t
+ * h
+ * i
+ * n
+ * g
+ * s
+ * "
+ *
+ * fr
+ * o
+ * m
+ *
+ * th
+ * e
+ *
+ * ba
+ * c
+ * k
+ * e
+ * n
+ * d
+ * .
+ * */
+ if (state == 0)
+ {
+ PQExpBufferData query_buffer;
+ char *e_text;
+ char *e_info_charp;
+
+ list_index = 0;
+ string_length = strlen(text);
+
+ /*
+ * F
+ * r
+ * e
+ * e
+ *
+ * an
+ * y
+ *
+ * pr
+ * i
+ * o
+ * r
+ *
+ * re
+ * s
+ * u
+ * l
+ * t
+ *
+ */
+ PQclear(result);
+ result = NULL;
+
+ /*
+ * S
+ * e
+ * t
+ *
+ * up
+ *
+ * su
+ * i
+ * t
+ * a
+ * b
+ * l
+ * y
+ * -
+ * e
+ * s
+ * c
+ * a
+ * p
+ * e
+ * d
+ *
+ * co
+ * p
+ * i
+ * e
+ * s
+ *
+ * of
+ *
+ * te
+ * x
+ * t
+ * u
+ * a
+ * l
+ *
+ * in
+ * p
+ * u
+ * t
+ * s
+ *
+ */
+ e_text = pg_malloc(string_length * 2 + 1);
+ PQescapeString(e_text, text, string_length);
+
+ if (completion_info_charp)
+ {
+ size_t charp_len;
+
+ charp_len = strlen(completion_info_charp);
+ e_info_charp = pg_malloc(charp_len * 2 + 1);
+ PQescapeString(e_info_charp, completion_info_charp,
+ charp_len);
+ }
+ else
+ e_info_charp = NULL;
+
+ initPQExpBuffer(&query_buffer);
+
+ if (is_schema_query)
+ {
+ /*
+ * c
+ * o
+ * m
+ * p
+ * l
+ * e
+ * t
+ * i
+ * o
+ * n
+ * _
+ * s
+ * q
+ * u
+ * e
+ * r
+ * y
+ *
+ * gi
+ * v
+ * e
+ * s
+ *
+ * us
+ *
+ * th
+ * e
+ *
+ * pi
+ * e
+ * c
+ * e
+ * s
+ *
+ * to
+ *
+ * as
+ * s
+ * e
+ * m
+ * b
+ * l
+ * e
+ *
+ */
+ const char *qualresult = completion_squery->qualresult;
+
+ if (qualresult == NULL)
+ qualresult = completion_squery->result;
+
+ /*
+ * G
+ * e
+ * t
+ *
+ * un
+ * q
+ * u
+ * a
+ * l
+ * i
+ * f
+ * i
+ * e
+ * d
+ *
+ * na
+ * m
+ * e
+ * s
+ *
+ * ma
+ * t
+ * c
+ * h
+ * i
+ * n
+ * g
+ *
+ * th
+ * e
+ *
+ * in
+ * p
+ * u
+ * t
+ * -
+ * s
+ * o
+ * -
+ * f
+ * a
+ * r
+ *
+ */
+ appendPQExpBuffer(&query_buffer, "SELECT %s FROM %s WHERE ",
+ completion_squery->result,
+ completion_squery->catname);
+ if (completion_squery->selcondition)
+ appendPQExpBuffer(&query_buffer, "%s AND ",
+ completion_squery->selcondition);
+ appendPQExpBuffer(&query_buffer, "substring(%s,1,%d)='%s'",
+ completion_squery->result,
+ string_length, e_text);
+ appendPQExpBuffer(&query_buffer, " AND %s",
+ completion_squery->viscondition);
+
+ /*
+ *
+ * Wh
+ * e
+ * n
+ *
+ * fe
+ * t
+ * c
+ * h
+ * i
+ * n
+ * g
+ *
+ * re
+ * l
+ * a
+ * t
+ * i
+ * o
+ * n
+ *
+ * na
+ * m
+ * e
+ * s
+ * ,
+ *
+ * su
+ * p
+ * p
+ * r
+ * e
+ * s
+ * s
+ *
+ * sy
+ * s
+ * t
+ * e
+ * m
+ *
+ * ca
+ * t
+ * a
+ * l
+ * o
+ * g
+ * s
+ *
+ * un
+ * l
+ * e
+ * s
+ * s
+ *
+ * th
+ * e
+ *
+ * in
+ * p
+ * u
+ * t
+ * -
+ * s
+ * o
+ * -
+ * f
+ * a
+ * r
+ *
+ * be
+ * g
+ * i
+ * n
+ * s
+ *
+ * wi
+ * t
+ * h
+ *
+ * "p
+ * g
+ * _
+ * "
+ * .
+ *
+ * Th
+ * i
+ * s
+ *
+ * is
+ *
+ * a
+ * co
+ * m
+ * p
+ * r
+ * o
+ * m
+ * i
+ * s
+ * e
+ *
+ * be
+ * t
+ * w
+ * e
+ * e
+ * n
+ *
+ * no
+ * t
+ *
+ * of
+ * f
+ * e
+ * r
+ * i
+ * n
+ * g
+ *
+ * sy
+ * s
+ * t
+ * e
+ * m
+ *
+ * ca
+ * t
+ * a
+ * l
+ * o
+ * g
+ * s
+ *
+ * fo
+ * r
+ *
+ * co
+ * m
+ * p
+ * l
+ * e
+ * t
+ * i
+ * o
+ * n
+ *
+ * at
+ *
+ * al
+ * l
+ * ,
+ *
+ * an
+ * d
+ *
+ * ha
+ * v
+ * i
+ * n
+ * g
+ *
+ * th
+ * e
+ * m
+ *
+ * sw
+ * a
+ * m
+ * p
+ *
+ * th
+ * e
+ *
+ * re
+ * s
+ * u
+ * l
+ * t
+ *
+ * wh
+ * e
+ * n
+ *
+ * th
+ * e
+ *
+ * in
+ * p
+ * u
+ * t
+ *
+ * is
+ *
+ * ju
+ * s
+ * t
+ *
+ * "p
+ * "
+ * .
+ * */
+ if (strcmp(completion_squery->catname,
+ "pg_catalog.pg_class c") == 0 &&
+ strncmp(text, "pg_", 3) !=0)
+ {
+ appendPQExpBuffer(&query_buffer,
+ " AND c.relnamespace <> (SELECT oid FROM"
+ " pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')");
+ }
+
+ /*
+ *
+ * Ad
+ * d
+ *
+ * in
+ *
+ * ma
+ * t
+ * c
+ * h
+ * i
+ * n
+ * g
+ *
+ * sc
+ * h
+ * e
+ * m
+ * a
+ *
+ * na
+ * m
+ * e
+ * s
+ * ,
+ *
+ * bu
+ * t
+ *
+ * on
+ * l
+ * y
+ *
+ * if
+ *
+ * th
+ * e
+ * r
+ * e
+ *
+ * is
+ *
+ * mo
+ * r
+ * e
+ *
+ * th
+ * a
+ * n
+ *
+ * on
+ * e
+ *
+ * po
+ * t
+ * e
+ * n
+ * t
+ * i
+ * a
+ * l
+ *
+ * ma
+ * t
+ * c
+ * h
+ *
+ * am
+ * o
+ * n
+ * g
+ *
+ * sc
+ * h
+ * e
+ * m
+ * a
+ *
+ * na
+ * m
+ * e
+ * s
+ * .
+ * */
+ appendPQExpBuffer(&query_buffer, "\nUNION\n"
+ "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
+ "FROM pg_catalog.pg_namespace n "
+ "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
+ string_length, e_text);
+ appendPQExpBuffer(&query_buffer,
+ " AND (SELECT pg_catalog.count(*)"
+ " FROM pg_catalog.pg_namespace"
+ " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
+ " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
+ string_length, e_text);
+
+ /*
+ *
+ * Ad
+ * d
+ *
+ * in
+ *
+ * ma
+ * t
+ * c
+ * h
+ * i
+ * n
+ * g
+ *
+ * qu
+ * a
+ * l
+ * i
+ * f
+ * i
+ * e
+ * d
+ *
+ * na
+ * m
+ * e
+ * s
+ * ,
+ *
+ * bu
+ * t
+ *
+ * on
+ * l
+ * y
+ *
+ * if
+ *
+ * th
+ * e
+ * r
+ * e
+ *
+ * is
+ *
+ * ex
+ * a
+ * c
+ * t
+ * l
+ * y
+ *
+ * on
+ * e
+ *
+ * sc
+ * h
+ * e
+ * m
+ * a
+ *
+ * ma
+ * t
+ * c
+ * h
+ * i
+ * n
+ * g
+ *
+ * th
+ * e
+ *
+ * in
+ * p
+ * u
+ * t
+ * -
+ * s
+ * o
+ * -
+ * f
+ * a
+ * r
+ * .
+ * */
+ appendPQExpBuffer(&query_buffer, "\nUNION\n"
+ "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
+ "FROM %s, pg_catalog.pg_namespace n "
+ "WHERE %s = n.oid AND ",
+ qualresult,
+ completion_squery->catname,
+ completion_squery->namespace);
+ if (completion_squery->selcondition)
+ appendPQExpBuffer(&query_buffer, "%s AND ",
+ completion_squery->selcondition);
+ appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
+ qualresult,
+ string_length, e_text);
+
+ /*
+ *
+ * Th
+ * i
+ * s
+ *
+ * co
+ * n
+ * d
+ * i
+ * t
+ * i
+ * o
+ * n
+ *
+ * ex
+ * p
+ * l
+ * o
+ * i
+ * t
+ * s
+ *
+ * th
+ * e
+ *
+ * si
+ * n
+ * g
+ * l
+ * e
+ * -
+ * m
+ * a
+ * t
+ * c
+ * h
+ * i
+ * n
+ * g
+ * -
+ * s
+ * c
+ * h
+ * e
+ * m
+ * a
+ *
+ * ru
+ * l
+ * e
+ *
+ * to
+ *
+ * sp
+ * e
+ * e
+ * d
+ *
+ * up
+ *
+ * th
+ * e
+ *
+ * qu
+ * e
+ * r
+ * y
+ * */
+ appendPQExpBuffer(&query_buffer,
+ " AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
+ " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
+ string_length, e_text);
+ appendPQExpBuffer(&query_buffer,
+ " AND (SELECT pg_catalog.count(*)"
+ " FROM pg_catalog.pg_namespace"
+ " WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
+ " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
+ string_length, e_text);
+
+ /*
+ * I
+ * f
+ *
+ * an
+ *
+ * ad
+ * d
+ * o
+ * n
+ *
+ * qu
+ * e
+ * r
+ * y
+ *
+ * wa
+ * s
+ *
+ * pr
+ * o
+ * v
+ * i
+ * d
+ * e
+ * d
+ * ,
+ *
+ * us
+ * e
+ *
+ * it
+ *
+ */
+ if (completion_charp)
+ appendPQExpBuffer(&query_buffer, "\n%s", completion_charp);
+ }
+ else
+ {
+ /*
+ * c
+ * o
+ * m
+ * p
+ * l
+ * e
+ * t
+ * i
+ * o
+ * n
+ * _
+ * c
+ * h
+ * a
+ * r
+ * p
+ *
+ * is
+ *
+ * an
+ *
+ * sp
+ * r
+ * i
+ * n
+ * t
+ * f
+ * -
+ * s
+ * t
+ * y
+ * l
+ * e
+ *
+ * fo
+ * r
+ * m
+ * a
+ * t
+ *
+ * st
+ * r
+ * i
+ * n
+ * g
+ *
+ */
+ appendPQExpBuffer(&query_buffer, completion_charp,
+ string_length, e_text, e_info_charp);
+ }
+
+ /*
+ * L
+ * i
+ * m
+ * i
+ * t
+ *
+ * th
+ * e
+ *
+ * nu
+ * m
+ * b
+ * e
+ * r
+ *
+ * of
+ *
+ * re
+ * c
+ * o
+ * r
+ * d
+ * s
+ *
+ * in
+ *
+ * th
+ * e
+ *
+ * re
+ * s
+ * u
+ * l
+ * t
+ *
+ */
+ appendPQExpBuffer(&query_buffer, "\nLIMIT %d",
+ completion_max_records);
+
+ result = exec_query(query_buffer.data);
+
+ termPQExpBuffer(&query_buffer);
+ free(e_text);
+ if (e_info_charp)
+ free(e_info_charp);
+ }
+
+ /*
+ * F
+ * i
+ * n
+ * d
+ *
+ * so
+ * m
+ * e
+ * t
+ * h
+ * i
+ * n
+ * g
+ *
+ * th
+ * a
+ * t
+ *
+ * ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ *
+ */
+ if (result && PQresultStatus(result) == PGRES_TUPLES_OK)
+ {
+ const char *item;
+
+ while (list_index < PQntuples(result) &&
+ (item = PQgetvalue(result, list_index++, 0)))
+ if (pg_strncasecmp(text, item, string_length) == 0)
+ return pg_strdup(item);
+ }
+
+ /*
+ * I
+ * f
+ *
+ * no
+ * t
+ * h
+ * i
+ * n
+ * g
+ *
+ * ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ * ,
+ *
+ * fr
+ * e
+ * e
+ *
+ * th
+ * e
+ *
+ * db
+ *
+ * st
+ * r
+ * u
+ * c
+ * t
+ * u
+ * r
+ * e
+ *
+ * an
+ * d
+ *
+ * re
+ * t
+ * u
+ * r
+ * n
+ *
+ * nu
+ * l
+ * l
+ *
+ */
+ PQclear(result);
+ result = NULL;
+ return NULL;
+ }
/* This function returns in order one of a fixed, NULL pointer terminated list
of strings (if matching). This can be used if there are only a fixed number
SQL words that can appear at certain spot.
*/
-static char *
-complete_from_list(const char *text, int state)
-{
- static int string_length,
- list_index,
- matches;
- static bool casesensitive;
- const char *item;
-
- /* need to have a list */
- psql_assert(completion_charpp);
-
- /* Initialization */
- if (state == 0)
- {
- list_index = 0;
- string_length = strlen(text);
- casesensitive = true;
- matches = 0;
- }
-
- while ((item = completion_charpp[list_index++]))
- {
- /* First pass is case sensitive */
- if (casesensitive && strncmp(text, item, string_length) == 0)
- {
- matches++;
- return pg_strdup(item);
- }
-
- /* Second pass is case insensitive, don't bother counting matches */
- if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
- return pg_strdup(item);
- }
-
- /*
- * No matches found. If we're not case insensitive already, lets
- * switch to being case insensitive and try again
- */
- if (casesensitive && matches == 0)
- {
- casesensitive = false;
- list_index = 0;
- state++;
- return (complete_from_list(text, state));
- }
-
- /* If no more matches, return null. */
- return NULL;
-}
+ static char *
+ complete_from_list(const char *text, int state)
+ {
+ static int string_length,
+ list_index,
+ matches;
+ static bool casesensitive;
+ const char *item;
+
+ /*
+ * n
+ * e
+ * e
+ * d
+ *
+ * to
+ *
+ * ha
+ * v
+ * e
+ *
+ * a
+ * li
+ * s
+ * t
+ *
+ */
+ psql_assert(completion_charpp);
+
+ /*
+ * I
+ * n
+ * i
+ * t
+ * i
+ * a
+ * l
+ * i
+ * z
+ * a
+ * t
+ * i
+ * o
+ * n
+ *
+ */
+ if (state == 0)
+ {
+ list_index = 0;
+ string_length = strlen(text);
+ casesensitive = true;
+ matches = 0;
+ }
+
+ while ((item = completion_charpp[list_index++]))
+ {
+ /*
+ * F
+ * i
+ * r
+ * s
+ * t
+ *
+ * pa
+ * s
+ * s
+ *
+ * is
+ *
+ * ca
+ * s
+ * e
+ *
+ * se
+ * n
+ * s
+ * i
+ * t
+ * i
+ * v
+ * e
+ *
+ */
+ if (casesensitive && strncmp(text, item, string_length) == 0)
+ {
+ matches++;
+ return pg_strdup(item);
+ }
+
+ /*
+ * S
+ * e
+ * c
+ * o
+ * n
+ * d
+ *
+ * pa
+ * s
+ * s
+ *
+ * is
+ *
+ * ca
+ * s
+ * e
+ *
+ * in
+ * s
+ * e
+ * n
+ * s
+ * i
+ * t
+ * i
+ * v
+ * e
+ * ,
+ *
+ * do
+ * n
+ * '
+ * t
+ *
+ * bo
+ * t
+ * h
+ * e
+ * r
+ *
+ * co
+ * u
+ * n
+ * t
+ * i
+ * n
+ * g
+ *
+ * ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ *
+ */
+ if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
+ return pg_strdup(item);
+ }
+
+ /*
+ *
+ * No
+ *
+ * ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ *
+ * fo
+ * u
+ * n
+ * d
+ * .
+ *
+ * If
+ *
+ * we
+ * '
+ * r
+ * e
+ *
+ * no
+ * t
+ *
+ * ca
+ * s
+ * e
+ *
+ * in
+ * s
+ * e
+ * n
+ * s
+ * i
+ * t
+ * i
+ * v
+ * e
+ *
+ * al
+ * r
+ * e
+ * a
+ * d
+ * y
+ * ,
+ *
+ * le
+ * t
+ * s
+ *
+ * sw
+ * i
+ * t
+ * c
+ * h
+ *
+ * to
+ *
+ * be
+ * i
+ * n
+ * g
+ *
+ * ca
+ * s
+ * e
+ *
+ * in
+ * s
+ * e
+ * n
+ * s
+ * i
+ * t
+ * i
+ * v
+ * e
+ *
+ * an
+ * d
+ *
+ * tr
+ * y
+ *
+ * ag
+ * a
+ * i
+ * n
+ * */
+ if (casesensitive && matches == 0)
+ {
+ casesensitive = false;
+ list_index = 0;
+ state++;
+ return (complete_from_list(text, state));
+ }
+
+ /*
+ * I
+ * f
+ *
+ * no
+ *
+ * mo
+ * r
+ * e
+ *
+ * ma
+ * t
+ * c
+ * h
+ * e
+ * s
+ * ,
+ *
+ * re
+ * t
+ * u
+ * r
+ * n
+ *
+ * nu
+ * l
+ * l
+ * .
+ *
+ */
+ return NULL;
+ }
/* This function returns one fixed string the first time even if it doesn't
@@ -2121,18 +3654,19 @@ complete_from_list(const char *text, int state)
will be overwritten.
The string to be passed must be in completion_charp.
*/
-static char *
-complete_from_const(const char *text, int state)
-{
- (void) text; /* We don't care about what was entered
- * already. */
+ static char *
+ complete_from_const(const char *text, int state)
+ {
+ (void) text; /* We don't care about
+ * what was entered
+ * already. */
- psql_assert(completion_charp);
- if (state == 0)
- return pg_strdup(completion_charp);
- else
- return NULL;
-}
+ psql_assert(completion_charp);
+ if (state == 0)
+ return pg_strdup(completion_charp);
+ else
+ return NULL;
+ }
@@ -2143,28 +3677,28 @@ complete_from_const(const char *text, int state)
* Execute a query and report any errors. This should be the preferred way of
* talking to the database in this file.
*/
-static PGresult *
-exec_query(const char *query)
-{
- PGresult *result;
+ static PGresult *
+ exec_query(const char *query)
+ {
+ PGresult *result;
- if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
- return NULL;
+ if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK)
+ return NULL;
- result = PQexec(pset.db, query);
+ result = PQexec(pset.db, query);
- if (result != NULL && PQresultStatus(result) != PGRES_TUPLES_OK)
- {
+ if (result != NULL && PQresultStatus(result) != PGRES_TUPLES_OK)
+ {
#if 0
- psql_error("tab completion: %s failed - %s\n",
- query, PQresStatus(PQresultStatus(result)));
+ psql_error("tab completion: %s failed - %s\n",
+ query, PQresStatus(PQresultStatus(result)));
#endif
- PQclear(result);
- result = NULL;
- }
+ PQclear(result);
+ result = NULL;
+ }
- return result;
-}
+ return result;
+ }
@@ -2173,61 +3707,344 @@ exec_query(const char *query)
* skip that many words; e.g. skip=1 finds the word before the
* previous one. Return value is NULL or a malloc'ed string.
*/
-static char *
-previous_word(int point, int skip)
-{
- int i,
- start = 0,
- end = -1,
- inquotes = 0;
- char *s;
-
- while (skip-- >= 0)
- {
- /* first we look for a space before the current word */
- for (i = point; i >= 0; i--)
- if (rl_line_buffer[i] == ' ')
- break;
-
- /* now find the first non-space which then constitutes the end */
- for (; i >= 0; i--)
- if (rl_line_buffer[i] != ' ')
- {
- end = i;
- break;
- }
-
- /*
- * If no end found we return null, because there is no word before
- * the point
- */
- if (end == -1)
- return NULL;
-
- /*
- * Otherwise we now look for the start. The start is either the
- * last character before any space going backwards from the end,
- * or it's simply character 0
- */
- for (start = end; start > 0; start--)
- {
- if (rl_line_buffer[start] == '"')
- inquotes = !inquotes;
- if ((rl_line_buffer[start - 1] == ' ') && inquotes == 0)
- break;
- }
-
- point = start;
- }
-
- /* make a copy */
- s = pg_malloc(end - start + 2);
-
- strncpy(s, &rl_line_buffer[start], end - start + 1);
- s[end - start + 1] = '\0';
-
- return s;
-}
+ static char *
+ previous_word(int point, int skip)
+ {
+ int i,
+ start = 0,
+ end = -1,
+ inquotes = 0;
+ char *s;
+
+ while (skip-- >= 0)
+ {
+ /*
+ * f
+ * i
+ * r
+ * s
+ * t
+ *
+ * we
+ *
+ * lo
+ * o
+ * k
+ *
+ * fo
+ * r
+ *
+ * a
+ * sp
+ * a
+ * c
+ * e
+ *
+ * be
+ * f
+ * o
+ * r
+ * e
+ *
+ * th
+ * e
+ *
+ * cu
+ * r
+ * r
+ * e
+ * n
+ * t
+ *
+ * wo
+ * r
+ * d
+ *
+ */
+ for (i = point; i >= 0; i--)
+ if (rl_line_buffer[i] == ' ')
+ break;
+
+ /*
+ * n
+ * o
+ * w
+ *
+ * fi
+ * n
+ * d
+ *
+ * th
+ * e
+ *
+ * fi
+ * r
+ * s
+ * t
+ *
+ * no
+ * n
+ * -
+ * s
+ * p
+ * a
+ * c
+ * e
+ *
+ * wh
+ * i
+ * c
+ * h
+ *
+ * th
+ * e
+ * n
+ *
+ * co
+ * n
+ * s
+ * t
+ * i
+ * t
+ * u
+ * t
+ * e
+ * s
+ *
+ * th
+ * e
+ *
+ * en
+ * d
+ *
+ */
+ for (; i >= 0; i--)
+ if (rl_line_buffer[i] != ' ')
+ {
+ end = i;
+ break;
+ }
+
+ /*
+ *
+ * If
+ *
+ * no
+ *
+ * en
+ * d
+ *
+ * fo
+ * u
+ * n
+ * d
+ *
+ * we
+ *
+ * re
+ * t
+ * u
+ * r
+ * n
+ *
+ * nu
+ * l
+ * l
+ * ,
+ *
+ * be
+ * c
+ * a
+ * u
+ * s
+ * e
+ *
+ * th
+ * e
+ * r
+ * e
+ *
+ * is
+ *
+ * no
+ *
+ * wo
+ * r
+ * d
+ *
+ * be
+ * f
+ * o
+ * r
+ * e
+ *
+ * th
+ * e
+ *
+ * po
+ * i
+ * n
+ * t
+ * */
+ if (end == -1)
+ return NULL;
+
+ /*
+ *
+ * Ot
+ * h
+ * e
+ * r
+ * w
+ * i
+ * s
+ * e
+ *
+ * we
+ *
+ * no
+ * w
+ *
+ * lo
+ * o
+ * k
+ *
+ * fo
+ * r
+ *
+ * th
+ * e
+ *
+ * st
+ * a
+ * r
+ * t
+ * .
+ *
+ * Th
+ * e
+ *
+ * st
+ * a
+ * r
+ * t
+ *
+ * is
+ *
+ * ei
+ * t
+ * h
+ * e
+ * r
+ *
+ * th
+ * e
+ *
+ * la
+ * s
+ * t
+ *
+ * ch
+ * a
+ * r
+ * a
+ * c
+ * t
+ * e
+ * r
+ *
+ * be
+ * f
+ * o
+ * r
+ * e
+ *
+ * an
+ * y
+ *
+ * sp
+ * a
+ * c
+ * e
+ *
+ * go
+ * i
+ * n
+ * g
+ *
+ * ba
+ * c
+ * k
+ * w
+ * a
+ * r
+ * d
+ * s
+ *
+ * fr
+ * o
+ * m
+ *
+ * th
+ * e
+ *
+ * en
+ * d
+ * ,
+ *
+ * or
+ *
+ * it
+ * '
+ * s
+ *
+ * si
+ * m
+ * p
+ * l
+ * y
+ *
+ * ch
+ * a
+ * r
+ * a
+ * c
+ * t
+ * e
+ * r
+ *
+ * 0
+ */
+ for (start = end; start > 0; start--)
+ {
+ if (rl_line_buffer[start] == '"')
+ inquotes = !inquotes;
+ if ((rl_line_buffer[start - 1] == ' ') && inquotes == 0)
+ break;
+ }
+
+ point = start;
+ }
+
+ /*
+ * m
+ * a
+ * k
+ * e
+ *
+ * a
+ * co
+ * p
+ * y
+ *
+ */
+ s = pg_malloc(end - start + 2);
+
+ strncpy(s, &rl_line_buffer[start], end - start + 1);
+ s[end - start + 1] = '\0';
+
+ return s;
+ }
@@ -2238,42 +4055,42 @@ previous_word(int point, int skip)
* psql internal. Currently disabled because it is reported not to
* cooperate with certain versions of readline.
*/
-static char *
-quote_file_name(char *text, int match_type, char *quote_pointer)
-{
- char *s;
- size_t length;
-
- (void) quote_pointer; /* not used */
-
- length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
- s = pg_malloc(length);
- s[0] = '\'';
- strcpy(s + 1, text);
- if (match_type == SINGLE_MATCH)
- s[length - 2] = '\'';
- s[length - 1] = '\0';
- return s;
-}
-
-
-
-static char *
-dequote_file_name(char *text, char quote_char)
-{
- char *s;
- size_t length;
-
- if (!quote_char)
- return pg_strdup(text);
-
- length = strlen(text);
- s = pg_malloc(length - 2 + 1);
- strncpy(s, text +1, length - 2);
- s[length] = '\0';
-
- return s;
-}
+ static char *
+ quote_file_name(char *text, int match_type, char *quote_pointer)
+ {
+ char *s;
+ size_t length;
+
+ (void) quote_pointer; /* not used */
+
+ length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2);
+ s = pg_malloc(length);
+ s[0] = '\'';
+ strcpy(s + 1, text);
+ if (match_type == SINGLE_MATCH)
+ s[length - 2] = '\'';
+ s[length - 1] = '\0';
+ return s;
+ }
+
+
+
+ static char *
+ dequote_file_name(char *text, char quote_char)
+ {
+ char *s;
+ size_t length;
+
+ if (!quote_char)
+ return pg_strdup(text);
+
+ length = strlen(text);
+ s = pg_malloc(length - 2 + 1);
+ strncpy(s, text +1, length - 2);
+ s[length] = '\0';
+
+ return s;
+ }
#endif /* 0 */
#endif /* USE_READLINE */