$NetBSD: patch-aa,v 1.3 2003/01/17 16:41:39 mjl Exp $

--- dbdimp.c.orig	Wed Jan  8 23:08:17 2003
+++ dbdimp.c	Fri Jan 17 17:23:37 2003
@@ -40,6 +40,30 @@
 
 
 int
+_dbd_begin(imp_dbh_t *imp_dbh)
+{
+	PGresult *result = NULL;
+	ExecStatusType status;
+
+	if (DBIc_has(imp_dbh, DBIcf_AutoCommit) != FALSE)
+		return 1;
+
+	if (imp_dbh->need_begin == 0)
+		return 1;
+
+	imp_dbh->need_begin = 0;
+
+	result = PQexec(imp_dbh->conn, "begin");
+	status = result ? PQresultStatus(result) : -1;
+	PQclear(result);
+	if (status != PGRES_COMMAND_OK) {
+		return 0;
+	}
+
+	return 1;
+}
+
+int
 dbd_discon_all (drh, imp_drh)
     SV *drh;
     imp_drh_t *imp_drh;
@@ -192,6 +216,7 @@
     imp_dbh->init_commit = 1;			/* initialize AutoCommit */
     imp_dbh->pg_auto_escape = 1;		/* initialize pg_auto_escape */
     imp_dbh->pg_bool_tf = 0;                    /* initialize pg_bool_tf */
+    imp_dbh->need_begin = 1;
 
     DBIc_IMPSET_on(imp_dbh);			/* imp_dbh set up now */
     DBIc_ACTIVE_on(imp_dbh);			/* call disconnect before freeing */
@@ -283,6 +308,9 @@
         PGresult* result = 0;
         ExecStatusType commitstatus, beginstatus;
 
+        if (imp_dbh->need_begin)
+            return 1;
+
         /* execute commit */
         result = PQexec(imp_dbh->conn, "commit");
         commitstatus = result ? PQresultStatus(result) : -1;
@@ -294,21 +322,12 @@
 	    pg_error(dbh, commitstatus, PQerrorMessage(imp_dbh->conn));
         }
 
-        /* start new transaction.  AutoCommit must be FALSE, ref. 20 lines up */
-        result = PQexec(imp_dbh->conn, "begin");
-        beginstatus = result ? PQresultStatus(result) : -1;
-        PQclear(result);
-        if (beginstatus != PGRES_COMMAND_OK) {
-	    /* Maybe add some loud barf here? Raising some very high error? */
-            pg_error(dbh, beginstatus, "begin failed\n");
-            return 0;
-        }
-
 	/* if the initial COMMIT failed, return 0 now */
 	if (commitstatus != PGRES_COMMAND_OK) {
             return 0;
         }
-        
+
+        imp_dbh->need_begin = 1;
         return 1;
     }
     
@@ -332,6 +351,9 @@
         PGresult* result = 0;
         ExecStatusType status;
         
+	if (imp_dbh->need_begin)
+		return 1;
+
         /* execute rollback */
         result = PQexec(imp_dbh->conn, "rollback");
         status = result ? PQresultStatus(result) : -1;
@@ -343,15 +365,8 @@
             return 0;
         }
 
-        /* start new transaction.  AutoCommit must be FALSE, ref. 20 lines up */
-        result = PQexec(imp_dbh->conn, "begin");
-        status = result ? PQresultStatus(result) : -1;
-        PQclear(result);
-        if (status != PGRES_COMMAND_OK) {
-            pg_error(dbh, status, "begin failed\n");
-            return 0;
-        }
-        
+        imp_dbh->need_begin = 1;
+
         return 1;
     }
 
@@ -374,7 +389,8 @@
 
     if (NULL != imp_dbh->conn) {
         /* rollback if AutoCommit = off */
-        if (DBIc_has(imp_dbh, DBIcf_AutoCommit) == FALSE) {
+        if ((imp_dbh->need_begin == 0)
+	    && (DBIc_has(imp_dbh, DBIcf_AutoCommit) == FALSE)) {
             PGresult* result = 0;
             ExecStatusType status;
             result = PQexec(imp_dbh->conn, "rollback");
@@ -450,16 +466,7 @@
             if (dbis->debug >= 2) { PerlIO_printf(DBILOGFP, "dbd_db_STORE: switch AutoCommit to on: commit\n"); }
         } else if ((oldval != FALSE && newval == FALSE) || (oldval == FALSE && newval == FALSE && imp_dbh->init_commit)) {
             if (NULL != imp_dbh->conn) {
-                /* start new transaction */
-                PGresult* result = 0;
-                ExecStatusType status;
-                result = PQexec(imp_dbh->conn, "begin");
-                status = result ? PQresultStatus(result) : -1;
-                PQclear(result);
-                if (status != PGRES_COMMAND_OK) {
-                    pg_error(dbh, status, "begin failed\n");
-                    return 0;
-                }
+		    imp_dbh->need_begin = 1;
             }
             if (dbis->debug >= 2) { PerlIO_printf(DBILOGFP, "dbd_db_STORE: switch AutoCommit to off: begin\n"); }
         }
@@ -1142,6 +1149,11 @@
         return -2;
     }   
     
+    if (_dbd_begin(imp_dbh) == 0) {
+		 pg_error(sth, -1, "executing begin failed\n");
+	    return -2;
+	 }
+
     statement = imp_sth->statement;
     if (! statement) {
         /* are we prepared ? */
