From c959d370bfb8a92684593fd40a2117b80fcbf347 Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Mon, 12 Sep 2005 11:57:53 +0000
Subject: [PATCH] Fixed transaction command handling to not ignore savepoints
 and to correctly check for errors.

---
 src/interfaces/ecpg/ChangeLog      |  7 ++++++-
 src/interfaces/ecpg/ecpglib/misc.c | 32 +++++++++++++++++-------------
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index dcb8d4242e1..502c8afb164 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -1933,8 +1933,13 @@ Thu Jun  2 14:22:32 CEST 2005
 Wed Aug 24 12:17:48 CEST 2005
 
 	- Check for NULL before checking whether argument is an array.
-	- Removed stray character from string quoting.
+	- Remove stray character from string quoting.
 	- Fixed check to report missing varchar pointer implementation.
+
+Mon Sep 12 13:53:35 CEST 2005
+
+	- Fixed transaction command handling to not ignore savepoints
+	  and to correctly check for errors.
 	- Set ecpg library version to 5.1.
 	- Set ecpg version to 4.1.1.
 
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 709fd56f8ff..a5619a69bf0 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.24 2004/10/14 20:23:46 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.25 2005/09/12 11:57:53 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -186,31 +186,35 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 	/* if we have no connection we just simulate the command */
 	if (con && con->connection)
 	{
-		/*
-		 * if we are not in autocommit mode, already have committed the
-		 * transaction and get another commit, just ignore it
+		/* If we got a transaction command but have no open transaction,
+		 * we have to start one, unless we are in autocommit, where the
+		 * developers have to take care themselves.
+		 * However, if the command is a begin statement, we just execute it once.
 		 */
-		if (!con->committed || con->autocommit)
+		if (con->committed && !con->autocommit && strncmp(transaction, "begin", 5) != 0 && strncmp(transaction, "start", 5) != 0)
 		{
-			if ((res = PQexec(con->connection, transaction)) == NULL)
+			res = PQexec(con->connection, "begin transaction");
+			if (res == NULL || PQresultStatus(res) != PGRES_COMMAND_OK)
 			{
 				ECPGraise(lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL);
 				return FALSE;
 			}
 			PQclear(res);
 		}
+		
+		res = PQexec(con->connection, transaction);
+		if (res == NULL || PQresultStatus(res) != PGRES_COMMAND_OK)
+		{
+			ECPGraise(lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL);
+			return FALSE;
+		}
+		PQclear(res);
 	}
 
 	if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0)
-	{
 		con->committed = true;
-
-#if 0
-		/* deallocate all prepared statements */
-		if (!ECPGdeallocate_all(lineno))
-			return false;
-#endif
-	}
+	else
+		con->committed = false;
 
 	return true;
 }
-- 
GitLab