This is an automated email from the git hooks/post-receive script. ebourg-guest pushed a commit to tag REL8_2_508 in repository libpostgresql-jdbc-java.
commit 80e10ffbabd5d319f3c6b4f51442ac61fbdd2300 Author: Kris Jurka <[email protected]> Date: Mon Jan 28 10:09:16 2008 +0000 While the driver currently doesn't support the copy protocol, it needs to understand it enough to ignore it. Now the connection will not be irreparably broken when a COPY request is sent. Altaf Malik --- org/postgresql/core/v3/QueryExecutorImpl.java | 63 ++++++++++++++----- org/postgresql/test/jdbc2/CopyTest.java | 89 +++++++++++++++++++++++++++ org/postgresql/test/jdbc2/Jdbc2TestSuite.java | 4 +- 3 files changed, 140 insertions(+), 16 deletions(-) diff --git a/org/postgresql/core/v3/QueryExecutorImpl.java b/org/postgresql/core/v3/QueryExecutorImpl.java index e303075..4efb141 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.33.2.1 2007/09/24 12:34:15 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/v3/QueryExecutorImpl.java,v 1.33.2.2 2007/10/15 08:06:39 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -1425,23 +1425,46 @@ public class QueryExecutorImpl implements QueryExecutor { break; case 'G': // CopyInResponse - case 'H': // CopyOutResponse - case 'c': // CopyDone - case 'd': // CopyData - { - // COPY FROM STDIN / COPY TO STDOUT, neither of which are currently - // supported. + if (logger.logDebug()) { + logger.debug(" <=BE CopyInResponse"); + logger.debug(" FE=> CopyFail"); + } - // CopyInResponse can only occur in response to an Execute we sent. - // Every Execute we send is followed by either a Bind or a ClosePortal, - // so we don't need to send a CopyFail; the server will fail the copy - // automatically when it sees the next message. + // COPY sub-protocol is not implemented yet + // We'll send a CopyFail message for COPY FROM STDIN so that + // server does not wait for the data. + + byte[] buf = Utils.encodeUTF8("The JDBC driver currently does not support COPY operations."); + pgStream.SendChar('f'); + pgStream.SendInteger4(buf.length + 4 + 1); + pgStream.Send(buf); + pgStream.SendChar(0); + pgStream.flush(); + sendSync(); // send sync message + skipMessage(); // skip the response message + break; - int l_len = pgStream.ReceiveIntegerR(4); - /* discard */ - pgStream.Receive(l_len); + case 'H': // CopyOutResponse + if (logger.logDebug()) + logger.debug(" <=BE CopyOutResponse"); + + skipMessage(); + // In case of CopyOutResponse, we cannot abort data transfer, + // so just throw an error and ignore CopyData messages + handler.handleError(new PSQLException(GT.tr("The driver currently does not support COPY operations."), PSQLState.NOT_IMPLEMENTED)); + break; + + case 'c': // CopyDone + skipMessage(); + if (logger.logDebug()) { + logger.debug(" <=BE CopyDone"); + } + break; - handler.handleError(new PSQLException(GT.tr("The driver currently does not support COPY operations."), PSQLState.NOT_IMPLEMENTED)); + case 'd': // CopyData + skipMessage(); + if (logger.logDebug()) { + logger.debug(" <=BE CopyData"); } break; @@ -1452,6 +1475,16 @@ public class QueryExecutorImpl implements QueryExecutor { } } + /** + * Ignore the response message by reading the message length and skipping + * over those bytes in the communication stream. + */ + private void skipMessage() throws IOException { + int l_len = pgStream.ReceiveIntegerR(4); + // skip l_len-4 (length includes the 4 bytes for message length itself + pgStream.Skip(l_len - 4); + } + public synchronized void fetch(ResultCursor cursor, ResultHandler handler, int fetchSize) throws SQLException { final Portal portal = (Portal)cursor; diff --git a/org/postgresql/test/jdbc2/CopyTest.java b/org/postgresql/test/jdbc2/CopyTest.java new file mode 100644 index 0000000..0e4546f --- /dev/null +++ b/org/postgresql/test/jdbc2/CopyTest.java @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------- +* +* Copyright (c) 2008, PostgreSQL Global Development Group +* +* IDENTIFICATION +* $PostgreSQL$ +* +*------------------------------------------------------------------------- +*/ + +package org.postgresql.test.jdbc2; + +import org.postgresql.test.TestUtil; +import junit.framework.TestCase; +import java.sql.*; + +/** + * Even though the driver doesn't support the copy protocol, if a user + * issues a copy command, the driver shouldn't destroy the whole connection. + */ + +public class CopyTest extends TestCase +{ + private Connection conn; + + public CopyTest(String name) + { + super(name); + } + + protected void setUp() throws Exception + { + conn = TestUtil.openDB(); + TestUtil.createTempTable(conn, "copytest", "a int"); + } + + protected void tearDown() throws Exception + { + TestUtil.dropTable(conn, "copytest"); + TestUtil.closeDB(conn); + } + + public void testCopyIn() throws SQLException + { + if (!TestUtil.isProtocolVersion(conn, 3)) + return; + + Statement stmt = conn.createStatement(); + try { + stmt.execute("COPY copytest FROM STDIN"); + fail("Should have failed because copy doesn't work."); + } catch (SQLException sqle) { } + stmt.close(); + + ensureConnectionWorks(); + } + + public void testCopyOut() throws SQLException + { + if (!TestUtil.isProtocolVersion(conn, 3)) + return; + + Statement stmt = conn.createStatement(); + if (TestUtil.haveMinimumServerVersion(conn, "8.0")) { + stmt.execute("INSERT INTO copytest SELECT generate_series(1, 1000)"); + } else { + stmt.execute("INSERT INTO copytest VALUES (1)"); + } + + try { + stmt.execute("COPY copytest TO STDOUT"); + fail("Should have failed because copy doesn't work."); + } catch (SQLException sqle) { } + stmt.close(); + + ensureConnectionWorks(); + } + + private void ensureConnectionWorks() throws SQLException + { + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT 1"); + assertTrue(rs.next()); + assertEquals(1, rs.getInt(1)); + rs.close(); + stmt.close(); + } + +} diff --git a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java index a590f9a..37d01d6 100644 --- a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java +++ b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java @@ -3,7 +3,7 @@ * Copyright (c) 2004-2005, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java,v 1.22 2005/04/29 20:41:43 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java,v 1.23 2005/08/01 06:54:15 oliver Exp $ * *------------------------------------------------------------------------- */ @@ -87,6 +87,8 @@ public class Jdbc2TestSuite extends TestSuite suite.addTestSuite(LoginTimeoutTest.class); + suite.addTestSuite(CopyTest.class); + // That's all folks return suite; } -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libpostgresql-jdbc-java.git _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

