[libpostgresql-jdbc-java] 03/06: 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.
Emmanuel Bourg
ebourg-guest at moszumanska.debian.org
Mon Jan 9 10:20:30 UTC 2017
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 <books at ejurka.com>
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
More information about the pkg-java-commits
mailing list