]> granicus.if.org Git - postgresql/commitdiff
Fixed bug reported by Marko Strukelj and Keith Wannamaker. Using executeBatch
authorBarry Lind <barry@xythos.com>
Wed, 20 Nov 2002 07:34:32 +0000 (07:34 +0000)
committerBarry Lind <barry@xythos.com>
Wed, 20 Nov 2002 07:34:32 +0000 (07:34 +0000)
on a preparedStatement would reset the prepared statment causing subsequent
uses of the preparedStatement to fail (i.e. the following series of calls
would fail: addBatch() executeBatch() addBatch() executBatch()).  This is
a regression from 7.2 where this worked correctly.  The regression test has
also been modified to explicitly test for this case.

 Modified Files:
  jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
  jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
  jdbc/org/postgresql/test/jdbc2/BatchExecuteTest.java

src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
src/interfaces/jdbc/org/postgresql/test/jdbc2/BatchExecuteTest.java

index 2953cff56fe943a4459b2e73c85792727a623304..2aeb5323db0378562da2e7668211ccd6455d5955 100644 (file)
@@ -8,7 +8,7 @@ import java.util.Vector;
 import org.postgresql.largeobject.*;
 import org.postgresql.util.*;
 
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.13 2002/11/14 05:35:45 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.14 2002/11/20 07:34:32 barry Exp $
  * This class defines methods of the jdbc1 specification.  This class is
  * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
  * methods.  The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
@@ -47,7 +47,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
        private String[] m_origSqlFragments;
        private String[] m_executeSqlFragments;
        protected Object[] m_binds = new Object[0];
-       private String[] m_bindTypes = new String[0];
+       protected String[] m_bindTypes = new String[0];
        private String m_statementName = null;
        private boolean m_useServerPrepare = false;
        private static int m_preparedCount = 1;
index 9a7bfe27017fb18489c0298324f436edd645274d..0d2661e561cc3ffc65432db901cec0302044767d 100644 (file)
@@ -8,7 +8,7 @@ import java.util.Vector;
 import org.postgresql.largeobject.*;
 import org.postgresql.util.PSQLException;
 
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.8 2002/10/30 04:33:29 barry Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.9 2002/11/20 07:34:32 barry Exp $
  * This class defines methods of the jdbc2 specification.  This class extends
  * org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1
  * methods.  The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement
@@ -59,7 +59,8 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
        {
                if (batch == null)
                        batch = new Vector();
-               batch.addElement(p_sql);
+        Object[] l_statement = new Object[] {new String[] {p_sql}, new Object[0], new String[0]};
+               batch.addElement(l_statement);
        }
 
        public void clearBatch() throws SQLException
@@ -76,8 +77,25 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
                int i = 0;
                try
                {
-                       for (i = 0;i < size;i++)
-                               result[i] = this.executeUpdate((String)batch.elementAt(i));
+            //copy current state of statement
+                       String[] l_origSqlFragments = m_sqlFragments;
+                       Object[] l_origBinds = m_binds;
+                       String[] l_origBindTypes = m_bindTypes;
+
+                       for (i = 0;i < size;i++) {
+                //set state from batch
+                Object[] l_statement = (Object[])batch.elementAt(i);
+                               this.m_sqlFragments = (String[])l_statement[0];
+                               this.m_binds = (Object[])l_statement[1];
+                               this.m_bindTypes = (String[])l_statement[2];
+                               result[i] = this.executeUpdate();
+                       }
+
+            //restore state of statement
+            String[] m_sqlFragments = l_origSqlFragments;
+                       Object[] m_binds = l_origBinds;
+                       String[] m_bindTypes = l_origBindTypes;
+
                }
                catch (SQLException e)
                {
@@ -150,7 +168,21 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
 
        public void addBatch() throws SQLException
        {
-               addBatch(this.toString());
+               if (batch == null)
+                       batch = new Vector();
+
+               //we need to create copies, otherwise the values can be changed
+               Object[] l_newSqlFragments = null;
+               if (m_sqlFragments != null) { 
+                       l_newSqlFragments = new String[m_sqlFragments.length];
+                       System.arraycopy(m_sqlFragments,0,l_newSqlFragments,0,m_sqlFragments.length);
+               }
+               Object[] l_newBinds = new String[m_binds.length];
+        System.arraycopy(m_binds,0,l_newBinds,0,m_binds.length);
+               String[] l_newBindTypes = new String[m_bindTypes.length];
+        System.arraycopy(m_bindTypes,0,l_newBindTypes,0,m_bindTypes.length);
+        Object[] l_statement = new Object[] {l_newSqlFragments, l_newBinds, l_newBindTypes};
+               batch.addElement(l_statement);
        }
 
        public java.sql.ResultSetMetaData getMetaData() throws SQLException
index 1c2569296bee1a9856a37089e9e48e864ad30386..e7f27ed575eb97eb24efe0e7f8384cf9d1e104d6 100644 (file)
@@ -157,11 +157,19 @@ public class BatchExecuteTest extends TestCase
                pstmt.executeBatch();
                assertCol1HasValue(7);
 
-               con.commit();
+               //now test to see that we can still use the statement after the execute
+               pstmt.setInt(1, 3);
+               pstmt.addBatch();
                assertCol1HasValue(7);
 
+               pstmt.executeBatch();
+               assertCol1HasValue(10);
+
+               con.commit();
+               assertCol1HasValue(10);
+
                con.rollback();
-               assertCol1HasValue(7);
+               assertCol1HasValue(10);
 
                pstmt.close();
        }