summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-10-15 02:24:16 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-10-15 02:24:16 +0000
commit951ec872c703886626c56d08254d38c0cd88fc9e (patch)
treee40bfcd906109d01230e57b5c298675300e7403b /src
parente258a2b436ab9f9a435904fc8dd2acadfbc851b5 (diff)
Fix psql to cope with autocommit off, at least during startup.
Behavior of backslash commands (especially for large objects) may still require some thought.
Diffstat (limited to 'src')
-rw-r--r--src/bin/psql/command.c12
-rw-r--r--src/bin/psql/common.c44
-rw-r--r--src/bin/psql/common.h4
-rw-r--r--src/bin/psql/copy.c4
-rw-r--r--src/bin/psql/describe.c46
-rw-r--r--src/bin/psql/large_obj.c22
6 files changed, 78 insertions, 54 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index a9477c68ed9..963c3aed3b1 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.82 2002/10/03 17:09:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.83 2002/10/15 02:24:15 tgl Exp $
*/
#include "postgres_fe.h"
#include "command.h"
@@ -1464,13 +1464,17 @@ test_superuser(const char *username)
if (!username)
return false;
+ /*
+ * Use begin/commit to avoid starting a transaction block if server
+ * has autocommit off by default.
+ */
initPQExpBuffer(&buf);
- printfPQExpBuffer(&buf, "SELECT usesuper FROM pg_catalog.pg_user WHERE usename = '%s'", username);
- res = PSQLexec(buf.data);
+ printfPQExpBuffer(&buf, "BEGIN; SELECT usesuper FROM pg_catalog.pg_user WHERE usename = '%s'; COMMIT", username);
+ res = PSQLexec(buf.data, true);
termPQExpBuffer(&buf);
answer =
- (PQntuples(res) > 0 && PQnfields(res) > 0
+ (res && PQntuples(res) > 0 && PQnfields(res) > 0
&& !PQgetisnull(res, 0, 0)
&& PQgetvalue(res, 0, 0)
&& strcmp(PQgetvalue(res, 0, 0), "t") == 0);
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index c451640ee0d..46186e55692 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.46 2002/10/03 17:09:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.47 2002/10/15 02:24:16 tgl Exp $
*/
#include "postgres_fe.h"
@@ -204,12 +204,19 @@ handle_sigint(SIGNAL_ARGS)
*
* This is the way to send "backdoor" queries (those not directly entered
* by the user). It is subject to -E but not -e.
+ *
+ * If the given querystring generates multiple PGresults, normally the last
+ * one is returned to the caller. However, if ignore_command_ok is TRUE,
+ * then PGresults with status PGRES_COMMAND_OK are ignored. This is intended
+ * mainly to allow locutions such as "begin; select ...; commit".
*/
PGresult *
-PSQLexec(const char *query)
+PSQLexec(const char *query, bool ignore_command_ok)
{
- PGresult *res;
+ PGresult *res = NULL;
+ PGresult *newres;
const char *var;
+ ExecStatusType rstatus;
if (!pset.db)
{
@@ -230,18 +237,31 @@ PSQLexec(const char *query)
return NULL;
cancelConn = pset.db;
- res = PQexec(pset.db, query);
- if (PQresultStatus(res) == PGRES_COPY_IN)
- copy_in_state = true;
+ if (PQsendQuery(pset.db, query))
+ {
+ while ((newres = PQgetResult(pset.db)) != NULL)
+ {
+ if (ignore_command_ok &&
+ PQresultStatus(newres) == PGRES_COMMAND_OK)
+ {
+ PQclear(newres);
+ continue;
+ }
+ PQclear(res);
+ res = newres;
+ }
+ }
+ rstatus = PQresultStatus(res);
/* keep cancel connection for copy out state */
- if (PQresultStatus(res) != PGRES_COPY_OUT)
+ if (rstatus != PGRES_COPY_OUT)
cancelConn = NULL;
+ if (rstatus == PGRES_COPY_IN)
+ copy_in_state = true;
- if (res && (PQresultStatus(res) == PGRES_COMMAND_OK ||
- PQresultStatus(res) == PGRES_TUPLES_OK ||
- PQresultStatus(res) == PGRES_COPY_IN ||
- PQresultStatus(res) == PGRES_COPY_OUT)
- )
+ if (res && (rstatus == PGRES_COMMAND_OK ||
+ rstatus == PGRES_TUPLES_OK ||
+ rstatus == PGRES_COPY_IN ||
+ rstatus == PGRES_COPY_OUT))
return res;
else
{
diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h
index f11a7981278..a5b0881245c 100644
--- a/src/bin/psql/common.h
+++ b/src/bin/psql/common.h
@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.18 2002/07/06 20:12:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.19 2002/10/15 02:24:16 tgl Exp $
*/
#ifndef COMMON_H
#define COMMON_H
@@ -33,7 +33,7 @@ extern PGconn *cancelConn;
extern void handle_sigint(SIGNAL_ARGS);
#endif /* not WIN32 */
-extern PGresult *PSQLexec(const char *query);
+extern PGresult *PSQLexec(const char *query, bool ignore_command_ok);
extern bool SendQuery(const char *query);
diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c
index 926641f5f41..7e1b05d5fe8 100644
--- a/src/bin/psql/copy.c
+++ b/src/bin/psql/copy.c
@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.26 2002/10/03 17:09:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.27 2002/10/15 02:24:16 tgl Exp $
*/
#include "postgres_fe.h"
#include "copy.h"
@@ -324,7 +324,7 @@ do_copy(const char *args)
return false;
}
- result = PSQLexec(query.data);
+ result = PSQLexec(query.data, false);
termPQExpBuffer(&query);
switch (PQresultStatus(result))
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 9c4c93c0df4..017afbc83c7 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3,7 +3,7 @@
*
* Copyright 2000-2002 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.69 2002/09/22 20:44:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.70 2002/10/15 02:24:16 tgl Exp $
*/
#include "postgres_fe.h"
#include "describe.h"
@@ -91,7 +91,7 @@ describeAggregates(const char *pattern, bool verbose)
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 3;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -161,7 +161,7 @@ describeFunctions(const char *pattern, bool verbose)
appendPQExpBuffer(&buf, "ORDER BY 2, 3, 1, 4;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -229,7 +229,7 @@ describeTypes(const char *pattern, bool verbose)
appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -276,7 +276,7 @@ describeOperators(const char *pattern)
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 3, 4;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -321,7 +321,7 @@ listAllDbs(bool verbose)
"\n LEFT JOIN pg_catalog.pg_user u ON d.datdba = u.usesysid\n"
"ORDER BY 1;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -374,7 +374,7 @@ permissionsList(const char *pattern)
appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
if (!res)
{
termPQExpBuffer(&buf);
@@ -532,7 +532,7 @@ objectDescription(const char *pattern)
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 3;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -576,7 +576,7 @@ describeTableDetails(const char *pattern, bool verbose)
appendPQExpBuffer(&buf, "ORDER BY 2, 3;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -655,7 +655,7 @@ describeOneTableDetails(const char *schemaname,
"SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n"
"FROM pg_catalog.pg_class WHERE oid = '%s'",
oid);
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
if (!res)
goto error_return;
@@ -711,7 +711,7 @@ describeOneTableDetails(const char *schemaname,
appendPQExpBuffer(&buf, " AND a.attrelid = i.indexrelid");
appendPQExpBuffer(&buf, "\nORDER BY a.attnum");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
if (!res)
goto error_return;
@@ -721,7 +721,7 @@ describeOneTableDetails(const char *schemaname,
PGresult *result;
printfPQExpBuffer(&buf, "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid)", oid);
- result = PSQLexec(buf.data);
+ result = PSQLexec(buf.data, false);
if (!result)
goto error_return;
@@ -763,7 +763,7 @@ describeOneTableDetails(const char *schemaname,
"WHERE d.adrelid = '%s' AND d.adnum = %s",
oid, PQgetvalue(res, i, 4));
- result = PSQLexec(buf.data);
+ result = PSQLexec(buf.data, false);
if (cells[i * cols + 2][0])
strcat(cells[i * cols + 2], " ");
@@ -830,7 +830,7 @@ describeOneTableDetails(const char *schemaname,
"AND i.indrelid = c2.oid",
oid);
- result = PSQLexec(buf.data);
+ result = PSQLexec(buf.data, false);
if (!result)
goto error_return;
else if (PQntuples(result) != 1)
@@ -886,7 +886,7 @@ describeOneTableDetails(const char *schemaname,
"FROM pg_catalog.pg_rewrite r\n"
"WHERE r.ev_class = '%s' AND r.rulename != '_RETURN'",
oid);
- result = PSQLexec(buf.data);
+ result = PSQLexec(buf.data, false);
if (!result)
goto error_return;
else
@@ -944,7 +944,7 @@ describeOneTableDetails(const char *schemaname,
"WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
"ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
oid);
- result1 = PSQLexec(buf.data);
+ result1 = PSQLexec(buf.data, false);
if (!result1)
goto error_return;
else
@@ -959,7 +959,7 @@ describeOneTableDetails(const char *schemaname,
"FROM pg_catalog.pg_constraint r\n"
"WHERE r.conrelid = '%s' AND r.contype = 'c'",
oid);
- result2 = PSQLexec(buf.data);
+ result2 = PSQLexec(buf.data, false);
if (!result2)
goto error_return;
else
@@ -974,7 +974,7 @@ describeOneTableDetails(const char *schemaname,
"FROM pg_catalog.pg_rewrite r\n"
"WHERE r.ev_class = '%s'",
oid);
- result3 = PSQLexec(buf.data);
+ result3 = PSQLexec(buf.data, false);
if (!result3)
goto error_return;
else
@@ -994,7 +994,7 @@ describeOneTableDetails(const char *schemaname,
" JOIN pg_catalog.pg_constraint c ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) "
" WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))",
oid);
- result4 = PSQLexec(buf.data);
+ result4 = PSQLexec(buf.data, false);
if (!result4)
goto error_return;
else
@@ -1010,7 +1010,7 @@ describeOneTableDetails(const char *schemaname,
"FROM pg_catalog.pg_constraint r\n"
"WHERE r.conrelid = '%s' AND r.contype = 'f'",
oid);
- result5 = PSQLexec(buf.data);
+ result5 = PSQLexec(buf.data, false);
if (!result5)
goto error_return;
else
@@ -1206,7 +1206,7 @@ describeUsers(const char *pattern)
appendPQExpBuffer(&buf, "ORDER BY 1;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -1312,7 +1312,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose)
appendPQExpBuffer(&buf, "ORDER BY 1,2;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
@@ -1374,7 +1374,7 @@ listDomains(const char *pattern)
appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
- res = PSQLexec(buf.data);
+ res = PSQLexec(buf.data, false);
termPQExpBuffer(&buf);
if (!res)
return false;
diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c
index 9bf51622cc4..fbe8a32a183 100644
--- a/src/bin/psql/large_obj.c
+++ b/src/bin/psql/large_obj.c
@@ -3,7 +3,7 @@
*
* Copyright 2000-2002 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.22 2002/10/03 17:09:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.23 2002/10/15 02:24:16 tgl Exp $
*/
#include "postgres_fe.h"
#include "large_obj.h"
@@ -53,7 +53,7 @@ handle_transaction(void)
notice[0] = '\0';
old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL);
- res = PSQLexec(commit ? "COMMIT" : "ROLLBACK");
+ res = PSQLexec(commit ? "COMMIT" : "ROLLBACK", false);
if (!res)
return false;
@@ -104,7 +104,7 @@ do_lo_export(const char *loid_arg, const char *filename_arg)
if (!handle_transaction())
return false;
- if (!(res = PSQLexec("BEGIN")))
+ if (!(res = PSQLexec("BEGIN", false)))
return false;
PQclear(res);
@@ -125,7 +125,7 @@ do_lo_export(const char *loid_arg, const char *filename_arg)
if (own_transaction)
{
- if (!(res = PSQLexec("COMMIT")))
+ if (!(res = PSQLexec("COMMIT", false)))
{
res = PQexec(pset.db, "ROLLBACK");
PQclear(res);
@@ -171,7 +171,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
if (!handle_transaction())
return false;
- if (!(res = PSQLexec("BEGIN")))
+ if (!(res = PSQLexec("BEGIN", false)))
return false;
PQclear(res);
@@ -222,7 +222,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
}
strcpy(bufptr, "')");
- if (!(res = PSQLexec(cmdbuf)))
+ if (!(res = PSQLexec(cmdbuf, false)))
{
if (own_transaction)
{
@@ -239,7 +239,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
if (own_transaction)
{
- if (!(res = PSQLexec("COMMIT")))
+ if (!(res = PSQLexec("COMMIT", false)))
{
res = PQexec(pset.db, "ROLLBACK");
PQclear(res);
@@ -288,7 +288,7 @@ do_lo_unlink(const char *loid_arg)
if (!handle_transaction())
return false;
- if (!(res = PSQLexec("BEGIN")))
+ if (!(res = PSQLexec("BEGIN", false)))
return false;
PQclear(res);
@@ -314,7 +314,7 @@ do_lo_unlink(const char *loid_arg)
sprintf(buf, "DELETE FROM pg_catalog.pg_description WHERE objoid = '%u' "
"AND classoid = 'pg_catalog.pg_largeobject'::regclass",
loid);
- if (!(res = PSQLexec(buf)))
+ if (!(res = PSQLexec(buf, false)))
{
if (own_transaction)
{
@@ -327,7 +327,7 @@ do_lo_unlink(const char *loid_arg)
if (own_transaction)
{
- if (!(res = PSQLexec("COMMIT")))
+ if (!(res = PSQLexec("COMMIT", false)))
{
res = PQexec(pset.db, "ROLLBACK");
PQclear(res);
@@ -362,7 +362,7 @@ do_lo_list(void)
"ORDER BY \"ID\"",
gettext("Description"));
- res = PSQLexec(buf);
+ res = PSQLexec(buf, false);
if (!res)
return false;