postgresql-jdbc.git / summary / log / commit / refs

commit    4e02faa7553b700d0a6f1f81034d05b7d208ea48
Author:   Kris Jurka <books@ejurka.com>
Date:     Fri Dec 04 19:53:20 2009 +0000

    When a COPY operation is the first statement issued in a transaction,
    it was not sending the BEGIN necessary to start the transaction.
    Refactor the non-query BEGIN code path used in fastpath calls to a
    common function that copy can use as well.
    
    Maciek Sakrejda


org/postgresql/copy/CopyManager.java | 8 +++--- org/postgresql/core/QueryExecutor.java | 4 +-- org/postgresql/core/v2/QueryExecutorImpl.java | 4 +-- org/postgresql/core/v3/QueryExecutorImpl.java | 38 +++++++++++++++++---------- org/postgresql/test/jdbc2/CopyTest.java | 9 ++++++- 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/org/postgresql/copy/CopyManager.java b/org/postgresql/copy/CopyManager.java index 2463a24c..eef5630c 100644 --- a/org/postgresql/copy/CopyManager.java +++ b/org/postgresql/copy/CopyManager.java @@ -3,7 +3,7 @@ * Copyright (c) 2009, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL$ +* $PostgreSQL: pgjdbc/org/postgresql/copy/CopyManager.java,v 1.1 2009/07/01 05:00:39 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -40,16 +40,18 @@ public class CopyManager { private final Encoding encoding; private final QueryExecutor queryExecutor; + private final BaseConnection connection; public CopyManager(BaseConnection connection) throws SQLException { this.encoding = connection.getEncoding(); this.queryExecutor = connection.getQueryExecutor(); + this.connection = connection; } public CopyIn copyIn(String sql) throws SQLException { CopyOperation op = null; try { - op = queryExecutor.startCopy(sql); + op = queryExecutor.startCopy(sql, connection.getAutoCommit()); return (CopyIn) op; } catch(ClassCastException cce) { op.cancelCopy(); @@ -60,7 +62,7 @@ public class CopyManager { public CopyOut copyOut(String sql) throws SQLException { CopyOperation op = null; try { - op = queryExecutor.startCopy(sql); + op = queryExecutor.startCopy(sql, connection.getAutoCommit()); return (CopyOut) op; } catch(ClassCastException cce) { op.cancelCopy(); diff --git a/org/postgresql/core/QueryExecutor.java b/org/postgresql/core/QueryExecutor.java index 2e4a1551..7162fdd0 100644 --- a/org/postgresql/core/QueryExecutor.java +++ b/org/postgresql/core/QueryExecutor.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/QueryExecutor.java,v 1.43 2008/11/15 17:48:52 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/QueryExecutor.java,v 1.44 2009/07/01 05:00:40 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -220,5 +220,5 @@ public interface QueryExecutor { * Implemented for protocol version 3 only. * @throws SQLException when initializing the given query fails */ - CopyOperation startCopy(String sql) throws SQLException; + CopyOperation startCopy(String sql, boolean suppressBegin) throws SQLException; } diff --git a/org/postgresql/core/v2/QueryExecutorImpl.java b/org/postgresql/core/v2/QueryExecutorImpl.java index 4bb299a4..0515c067 100644 --- a/org/postgresql/core/v2/QueryExecutorImpl.java +++ b/org/postgresql/core/v2/QueryExecutorImpl.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/v2/QueryExecutorImpl.java,v 1.21 2008/11/15 17:48:52 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/v2/QueryExecutorImpl.java,v 1.22 2009/07/01 05:00:40 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -607,7 +607,7 @@ public class QueryExecutorImpl implements QueryExecutor { private final PGStream pgStream; private final Logger logger; - public CopyOperation startCopy(String sql) throws SQLException { + public CopyOperation startCopy(String sql, boolean suppressBegin) throws SQLException { throw new PSQLException(GT.tr("Copy not implemented for protocol version 2"), PSQLState.NOT_IMPLEMENTED); } } diff --git a/org/postgresql/core/v3/QueryExecutorImpl.java b/org/postgresql/core/v3/QueryExecutorImpl.java index 8327894e..f37b79c6 100644 --- a/org/postgresql/core/v3/QueryExecutorImpl.java +++ b/org/postgresql/core/v3/QueryExecutorImpl.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/v3/QueryExecutorImpl.java,v 1.44 2009/04/20 21:44:08 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/v3/QueryExecutorImpl.java,v 1.45 2009/07/01 05:00:40 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -472,11 +472,28 @@ public class QueryExecutorImpl implements QueryExecutor { public synchronized byte[] fastpathCall(int fnid, ParameterList parameters, boolean suppressBegin) throws SQLException { waitOnLock(); - if (protoConnection.getTransactionState() == ProtocolConnection.TRANSACTION_IDLE && !suppressBegin) + if (!suppressBegin) + { + doSubprotocolBegin(); + } + try + { + sendFastpathCall(fnid, (SimpleParameterList)parameters); + return receiveFastpathResult(); + } + catch (IOException ioe) + { + protoConnection.close(); + throw new PSQLException(GT.tr("An I/O error occured while sending to the backend."), PSQLState.CONNECTION_FAILURE, ioe); + } + } + + public void doSubprotocolBegin() throws SQLException { + if (protoConnection.getTransactionState() == ProtocolConnection.TRANSACTION_IDLE) { if (logger.logDebug()) - logger.debug("Issuing BEGIN before fastpath call."); + logger.debug("Issuing BEGIN before fastpath or copy call."); ResultHandler handler = new ResultHandler() { private boolean sawBegin = false; @@ -537,16 +554,6 @@ public class QueryExecutorImpl implements QueryExecutor { } } - try - { - sendFastpathCall(fnid, (SimpleParameterList)parameters); - return receiveFastpathResult(); - } - catch (IOException ioe) - { - protoConnection.close(); - throw new PSQLException(GT.tr("An I/O error occured while sending to the backend."), PSQLState.CONNECTION_FAILURE, ioe); - } } public ParameterList createFastpathParameters(int count) { @@ -699,8 +706,11 @@ public class QueryExecutorImpl implements QueryExecutor { * @return CopyIn or CopyOut operation object * @throws SQLException on failure */ - public synchronized CopyOperation startCopy(String sql) throws SQLException { + public synchronized CopyOperation startCopy(String sql, boolean suppressBegin) throws SQLException { waitOnLock(); + if (!suppressBegin) { + doSubprotocolBegin(); + } byte buf[] = Utils.encodeUTF8(sql); try { diff --git a/org/postgresql/test/jdbc2/CopyTest.java b/org/postgresql/test/jdbc2/CopyTest.java index f91634a0..f9cc76ec 100644 --- a/org/postgresql/test/jdbc2/CopyTest.java +++ b/org/postgresql/test/jdbc2/CopyTest.java @@ -3,7 +3,7 @@ * Copyright (c) 2008, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/test/jdbc2/CopyTest.java,v 1.1 2008/01/28 10:08:58 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/test/jdbc2/CopyTest.java,v 1.2 2009/07/01 05:00:40 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -257,4 +257,11 @@ public class CopyTest extends TestCase { assertEquals(1000, count); } + public void testCopyRollback() throws SQLException { + con.setAutoCommit(false); + testCopyInByRow(); + con.rollback(); + assertEquals(0, getCount()); + } + } [parent: 611e1294eb99]