From 816b008eaf1a1ff1069f3bafff363a9a8bf04a21 Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Thu, 14 Oct 2010 17:55:07 +0200
Subject: [PATCH] Applied patch by Itagaki Takahiro to fix incorrect status
 calculation in ecpglib. Instead of parsing the statement just as ask the
 database server. This patch removes the whole client side track keeping of
 the current transaction status.

---
 src/interfaces/ecpg/ecpglib/connect.c | 7 ++-----
 src/interfaces/ecpg/ecpglib/execute.c | 3 +--
 src/interfaces/ecpg/ecpglib/extern.h  | 1 -
 src/interfaces/ecpg/ecpglib/misc.c    | 7 +------
 4 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 56a732a4980..0091b5dc98f 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -167,25 +167,23 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
 
 	if (con->autocommit == true && strncmp(mode, "off", strlen("off")) == 0)
 	{
-		if (con->committed)
+		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE)
 		{
 			results = PQexec(con->connection, "begin transaction");
 			if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
 				return false;
 			PQclear(results);
-			con->committed = false;
 		}
 		con->autocommit = false;
 	}
 	else if (con->autocommit == false && strncmp(mode, "on", strlen("on")) == 0)
 	{
-		if (!con->committed)
+		if (PQtransactionStatus(con->connection) != PQTRANS_IDLE)
 		{
 			results = PQexec(con->connection, "commit");
 			if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
 				return false;
 			PQclear(results);
-			con->committed = true;
 		}
 		con->autocommit = true;
 	}
@@ -540,7 +538,6 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	pthread_mutex_unlock(&connections_mutex);
 #endif
 
-	this->committed = true;
 	this->autocommit = autocommit;
 
 	PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this);
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 817724abe68..970fa935099 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1427,7 +1427,7 @@ ecpg_execute(struct statement * stmt)
 
 	/* The request has been build. */
 
-	if (stmt->connection->committed && !stmt->connection->autocommit)
+	if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
 	{
 		results = PQexec(stmt->connection->connection, "begin transaction");
 		if (!ecpg_check_PQresult(results, stmt->lineno, stmt->connection->connection, stmt->compat))
@@ -1436,7 +1436,6 @@ ecpg_execute(struct statement * stmt)
 			return false;
 		}
 		PQclear(results);
-		stmt->connection->committed = false;
 	}
 
 	ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, nParams, stmt->connection->name);
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 0193ad1418f..2d9636d798b 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -76,7 +76,6 @@ struct connection
 {
 	char	   *name;
 	PGconn	   *connection;
-	bool		committed;
 	int			autocommit;
 	struct ECPGtype_information_cache *cache_head;
 	struct prepared_statement *prep_stmts;
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 20725e44e52..98e0597b03c 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -206,7 +206,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 		 * developers have to take care themselves. However, if the command is
 		 * a begin statement, we just execute it once.
 		 */
-		if (con->committed && !con->autocommit && strncmp(transaction, "begin", 5) != 0 && strncmp(transaction, "start", 5) != 0)
+		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE && !con->autocommit && strncmp(transaction, "begin", 5) != 0 && strncmp(transaction, "start", 5) != 0)
 		{
 			res = PQexec(con->connection, "begin transaction");
 			if (!ecpg_check_PQresult(res, lineno, con->connection, ECPG_COMPAT_PGSQL))
@@ -218,11 +218,6 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 		if (!ecpg_check_PQresult(res, lineno, con->connection, ECPG_COMPAT_PGSQL))
 			return FALSE;
 		PQclear(res);
-
-		if (strncmp(transaction, "commit", 6) == 0 || strncmp(transaction, "rollback", 8) == 0)
-			con->committed = true;
-		else
-			con->committed = false;
 	}
 
 	return true;
-- 
GitLab