diff options
Diffstat (limited to 'src/fe_utils/string_utils.c')
-rw-r--r-- | src/fe_utils/string_utils.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c index 4cf08dbdcaa..f986dbcf39b 100644 --- a/src/fe_utils/string_utils.c +++ b/src/fe_utils/string_utils.c @@ -488,10 +488,10 @@ appendConnStrVal(PQExpBuffer buf, const char *str) bool needquotes; /* - * If the string consists entirely of plain ASCII characters, no need to - * quote it. This is quite conservative, but better safe than sorry. + * If the string is one or more plain ASCII characters, no need to quote + * it. This is quite conservative, but better safe than sorry. */ - needquotes = false; + needquotes = true; for (s = str; *s; s++) { if (!((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || @@ -500,6 +500,7 @@ appendConnStrVal(PQExpBuffer buf, const char *str) needquotes = true; break; } + needquotes = false; } if (needquotes) @@ -522,6 +523,66 @@ appendConnStrVal(PQExpBuffer buf, const char *str) /* + * Append a psql meta-command that connects to the given database with the + * then-current connection's user, host and port. + */ +void +appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname) +{ + const char *s; + bool complex; + + /* + * If the name is plain ASCII characters, emit a trivial "\connect "foo"". + * For other names, even many not technically requiring it, skip to the + * general case. No database has a zero-length name. + */ + complex = false; + for (s = dbname; *s; s++) + { + if (*s == '\n' || *s == '\r') + { + fprintf(stderr, + _("database name contains a newline or carriage return: \"%s\"\n"), + dbname); + exit(EXIT_FAILURE); + } + + if (!((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || + (*s >= '0' && *s <= '9') || *s == '_' || *s == '.')) + { + complex = true; + } + } + + appendPQExpBufferStr(buf, "\\connect "); + if (complex) + { + PQExpBufferData connstr; + + initPQExpBuffer(&connstr); + appendPQExpBuffer(&connstr, "dbname="); + appendConnStrVal(&connstr, dbname); + + appendPQExpBuffer(buf, "-reuse-previous=on "); + + /* + * As long as the name does not contain a newline, SQL identifier + * quoting satisfies the psql meta-command parser. Prefer not to + * involve psql-interpreted single quotes, which behaved differently + * before PostgreSQL 9.2. + */ + appendPQExpBufferStr(buf, fmtId(connstr.data)); + + termPQExpBuffer(&connstr); + } + else + appendPQExpBufferStr(buf, fmtId(dbname)); + appendPQExpBufferChar(buf, '\n'); +} + + +/* * Deconstruct the text representation of a 1-dimensional Postgres array * into individual items. * |