aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/command.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-06-28 00:12:40 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-06-28 00:12:40 +0000
commitf9ebf36970df6e61142dbe7590482cd240fdb66a (patch)
tree9dd310595417c131d80a018540029ec822729424 /src/bin/psql/command.c
parentea20397b79f795441d48eae0ace03caf4c108a3c (diff)
downloadpostgresql-f9ebf36970df6e61142dbe7590482cd240fdb66a.tar.gz
postgresql-f9ebf36970df6e61142dbe7590482cd240fdb66a.zip
Update psql for some features of new FE/BE protocol. There is a
client-side AUTOCOMMIT mode now: '\set AUTOCOMMIT off' supports SQL-spec commit behavior. Get rid of LO_TRANSACTION hack --- the LO operations just work now, using libpq's ability to track the transaction status. Add a VERBOSE variable to control verboseness of error message display, and add a %T prompt-string code to show current transaction-block status. Superuser state display in the prompt string correctly follows SET SESSION AUTHORIZATION commands. Control-C works to get out of COPY IN state.
Diffstat (limited to 'src/bin/psql/command.c')
-rw-r--r--src/bin/psql/command.c118
1 files changed, 77 insertions, 41 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index fd6193dd243..c105f0bd9d8 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3,7 +3,7 @@
*
* Copyright 2000-2002 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.96 2003/05/14 03:26:02 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.97 2003/06/28 00:12:40 tgl Exp $
*/
#include "postgres_fe.h"
#include "command.h"
@@ -457,20 +457,30 @@ exec_command(const char *cmd,
char *encoding = scan_option(&string, OT_NORMAL, NULL, false);
if (!encoding)
- /* show encoding */
+ {
+ /* show encoding --- first check for change sent from server */
+ if (pset.encoding != PQclientEncoding(pset.db) &&
+ PQclientEncoding(pset.db) >= 0)
+ {
+ pset.encoding = PQclientEncoding(pset.db);
+ pset.popt.topt.encoding = pset.encoding;
+ SetVariable(pset.vars, "ENCODING",
+ pg_encoding_to_char(pset.encoding));
+ }
puts(pg_encoding_to_char(pset.encoding));
+ }
else
{
/* set encoding */
if (PQsetClientEncoding(pset.db, encoding) == -1)
psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
-
else
{
/* save encoding info into psql internal data */
pset.encoding = PQclientEncoding(pset.db);
- pset.popt.topt.encoding = PQclientEncoding(pset.db);
- SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
+ pset.popt.topt.encoding = pset.encoding;
+ SetVariable(pset.vars, "ENCODING",
+ pg_encoding_to_char(pset.encoding));
}
free(encoding);
}
@@ -694,7 +704,13 @@ exec_command(const char *cmd,
free(opt);
}
- if (!SetVariable(pset.vars, opt0, newval))
+ if (SetVariable(pset.vars, opt0, newval))
+ {
+ /* Check for special variables */
+ if (strcmp(opt0, "VERBOSE") == 0)
+ SyncVerboseVariable();
+ }
+ else
{
psql_error("\\%s: error\n", cmd);
success = false;
@@ -1327,11 +1343,7 @@ do_connect(const char *new_dbname, const char *new_user)
bool success = false;
/* Delete variables (in case we fail before setting them anew) */
- SetVariable(pset.vars, "DBNAME", NULL);
- SetVariable(pset.vars, "USER", NULL);
- SetVariable(pset.vars, "HOST", NULL);
- SetVariable(pset.vars, "PORT", NULL);
- SetVariable(pset.vars, "ENCODING", NULL);
+ UnsyncVariables();
/* If dbname is "" then use old name, else new one (even if NULL) */
if (oldconn && new_dbname && PQdb(oldconn) && strcmp(new_dbname, "") == 0)
@@ -1429,51 +1441,75 @@ do_connect(const char *new_dbname, const char *new_user)
}
PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
- pset.encoding = PQclientEncoding(pset.db);
- pset.popt.topt.encoding = PQclientEncoding(pset.db);
/* Update variables */
+ SyncVariables();
+
+ return success;
+}
+
+
+/*
+ * SyncVariables
+ *
+ * Make psql's internal variables agree with connection state upon
+ * establishing a new connection.
+ */
+void
+SyncVariables(void)
+{
+ /* get stuff from connection */
+ pset.encoding = PQclientEncoding(pset.db);
+ pset.popt.topt.encoding = pset.encoding;
+
SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
SetVariable(pset.vars, "USER", PQuser(pset.db));
SetVariable(pset.vars, "HOST", PQhost(pset.db));
SetVariable(pset.vars, "PORT", PQport(pset.db));
SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
- pset.issuper = test_superuser(PQuser(pset.db));
-
- return success;
+ /* send stuff to it, too */
+ SyncVerboseVariable();
}
-
-
/*
- * Test if the given user is a database superuser.
- * (Is used to set up the prompt right.)
+ * UnsyncVariables
+ *
+ * Clear variables that should be not be set when there is no connection.
*/
-bool
-test_superuser(const char *username)
+void
+UnsyncVariables(void)
{
- PGresult *res;
- PQExpBufferData buf;
- bool answer;
-
- if (!username)
- return false;
-
- initPQExpBuffer(&buf);
- printfPQExpBuffer(&buf, "SELECT usesuper FROM pg_catalog.pg_user WHERE usename = '%s'", username);
- res = PSQLexec(buf.data, true);
- termPQExpBuffer(&buf);
-
- answer =
- (res && PQntuples(res) > 0 && PQnfields(res) > 0
- && !PQgetisnull(res, 0, 0)
- && PQgetvalue(res, 0, 0)
- && strcmp(PQgetvalue(res, 0, 0), "t") == 0);
- PQclear(res);
- return answer;
+ SetVariable(pset.vars, "DBNAME", NULL);
+ SetVariable(pset.vars, "USER", NULL);
+ SetVariable(pset.vars, "HOST", NULL);
+ SetVariable(pset.vars, "PORT", NULL);
+ SetVariable(pset.vars, "ENCODING", NULL);
}
+/*
+ * Update connection state from VERBOSE variable
+ */
+void
+SyncVerboseVariable(void)
+{
+ switch (SwitchVariable(pset.vars, "VERBOSE",
+ "default", "terse", "verbose", NULL))
+ {
+ case 1: /* default */
+ PQsetErrorVerbosity(pset.db, PQERRORS_DEFAULT);
+ break;
+ case 2: /* terse */
+ PQsetErrorVerbosity(pset.db, PQERRORS_TERSE);
+ break;
+ case 3: /* verbose */
+ PQsetErrorVerbosity(pset.db, PQERRORS_VERBOSE);
+ break;
+ default: /* not set or unrecognized value */
+ PQsetErrorVerbosity(pset.db, PQERRORS_DEFAULT);
+ break;
+ }
+}
/*