[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