Fix psql to cope with autocommit off, at least during startup.
Behavior of backslash commands (especially for large objects) may still require some thought.
This commit is contained in:
parent
e258a2b436
commit
951ec872c7
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user