Skip site navigation (1) Skip section navigation (2)

Peripheral Links

Header And Logo

PostgreSQL
| The world's most advanced open source database.

Site Navigation

Search for
  Advanced Search

Some more patches for binary resultset transfer



Hi,

Some more patches:

debuglogfix
- fixes a null pointer in the extended logging v4 patch introduced

infinite-time
- adds infinite handling to binaryresult set
- only supports infinite for timestamp type because that is the only
  type for which postgresql 8.1.5 supports infinite. time and date 
  fields transform it to null
- I do not like the integertime=yes infinite handling but I still
  added it for compatibility with the text transfer result sets

updateable-rs-no-bin
- adds a new flag to queryexecutor to disallow use of binary transfer
- uses the flag for updateable result sets
- also contains an update to the updateable results test case which
  shows that the current code cannot handle correctly updating of
  byte[]/binarystreams

Kris, I believe that I have now answered all your concerns with the
previous v5 patch except the naming of the configuration option.
And also my patches make the binary transfer default to on, do you 
think it should initially default to off?

-Mikko
diff -ur --exclude=CVS --exclude='*.class' --exclude='*.txt' postgres-v5/org/postgresql/core/v3/QueryExecutorImpl.java postgres-clean2/org/postgresql/core/v3/QueryExecutorImpl.java
--- postgres-v5/org/postgresql/core/v3/QueryExecutorImpl.java	2006-11-26 13:37:51.000000000 +0200
+++ postgres-clean2/org/postgresql/core/v3/QueryExecutorImpl.java	2006-11-27 20:13:28.000000000 +0200
@@ -1370,6 +1370,7 @@
                     } else {
                         length = 0;
                         for (int i=0; i< tuple.length; ++i) {
+                            if (tuple[i] == null) continue;
                             length += tuple[i].length;
                         }
                     }
diff -ur --exclude=CVS --exclude='*.class' --exclude='*.txt' postgres-v5/org/postgresql/jdbc2/TimestampUtils.java postgres-clean2/org/postgresql/jdbc2/TimestampUtils.java
--- postgres-v5/org/postgresql/jdbc2/TimestampUtils.java	2006-11-26 13:37:51.000000000 +0200
+++ postgres-clean2/org/postgresql/jdbc2/TimestampUtils.java	2006-11-28 08:46:06.000000000 +0200
@@ -700,12 +700,26 @@
         
         if (usesDouble) {
             double time = ByteConverter.float8(bytes, 0);
-
+            if (time == Double.POSITIVE_INFINITY) {
+                return new Timestamp(PGStatement.DATE_POSITIVE_INFINITY);
+            } else if (time == Double.NEGATIVE_INFINITY) {
+                return new Timestamp(PGStatement.DATE_NEGATIVE_INFINITY);
+            }
+            
             secs = (long) time;
             nanos = (int) ((time - secs) * 1000000);
         } else {
             long time = ByteConverter.int8(bytes, 0);
             
+            // compatibility with text based receiving, not strictly necessary
+            // and can actually be confusing because there are timestamps
+            // that are larger than infinite 
+            if (time == Long.MAX_VALUE) {
+                return new Timestamp(PGStatement.DATE_POSITIVE_INFINITY);
+            } else if (time == Long.MIN_VALUE) {
+                return new Timestamp(PGStatement.DATE_NEGATIVE_INFINITY);
+            }
+            
             secs = time / 1000000;
             nanos = (int) (time - secs * 1000000);
         }
diff -ur --exclude=CVS --exclude='*.class' --exclude='*.txt' postgres-v5/org/postgresql/core/QueryExecutor.java postgres-clean2/org/postgresql/core/QueryExecutor.java
--- postgres-v5/org/postgresql/core/QueryExecutor.java	2006-11-20 21:42:41.000000000 +0200
+++ postgres-clean2/org/postgresql/core/QueryExecutor.java	2006-11-28 22:02:20.000000000 +0200
@@ -84,6 +84,11 @@
     static int QUERY_DESCRIBE_ONLY = 32;
 
     /**
+     * Flag for query execution to avoid using binary transfer.
+     */
+    static int QUERY_NO_BINARY_TRANSFER = 64;
+
+    /**
      * Execute a Query, passing results to a provided ResultHandler.
      *
      * @param query the query to execute; must be a query returned from
diff -ur --exclude=CVS --exclude='*.class' --exclude='*.txt' postgres-v5/org/postgresql/core/v3/QueryExecutorImpl.java postgres-clean2/org/postgresql/core/v3/QueryExecutorImpl.java
--- postgres-v5/org/postgresql/core/v3/QueryExecutorImpl.java	2006-11-26 13:37:51.000000000 +0200
+++ postgres-clean2/org/postgresql/core/v3/QueryExecutorImpl.java	2006-11-28 22:06:57.000000000 +0200
@@ -774,7 +774,8 @@
         pendingParseQueue.add(new Object[]{query, query.getStatementName()});
     }
 
-    private void sendBind(SimpleQuery query, SimpleParameterList params, Portal portal) throws IOException {
+    private void sendBind(SimpleQuery query, SimpleParameterList params,
+                          Portal portal, boolean noBinaryTransfer) throws IOException {
         //
         // Send Bind.
         //
@@ -814,7 +815,7 @@
 
         int numBinaryFields = 0;
         Field[] fields = query.getFields();
-        if (fields != null) {
+        if (!noBinaryTransfer && fields != null) {
             for (int i = 0; i < fields.length; ++i) {
                 if (useBinary(fields[i])) {
                     fields[i].setFormat(Field.BINARY_FORMAT);
@@ -1044,6 +1045,7 @@
         boolean usePortal = (flags & QueryExecutor.QUERY_FORWARD_CURSOR) != 0 && !noResults && !noMeta && fetchSize > 0 && !describeOnly;
         boolean oneShot = (flags & QueryExecutor.QUERY_ONESHOT) != 0 && !usePortal;
         boolean describeStatement = describeOnly || (params.hasUnresolvedTypes() && !oneShot);
+        boolean noBinaryTransfer = (flags & QUERY_NO_BINARY_TRANSFER) != 0;
 
         // Work out how many rows to fetch in this pass.
 
@@ -1081,7 +1083,7 @@
             portal = new Portal(query, portalName);
         }
 
-        sendBind(query, params, portal);
+        sendBind(query, params, portal, noBinaryTransfer);
 
         // A statement describe will also output a RowDescription,
         // so don't reissue it here if we've already done so.
diff -ur --exclude=CVS --exclude='*.class' --exclude='*.txt' postgres-v5/org/postgresql/jdbc2/AbstractJdbc2Statement.java postgres-clean2/org/postgresql/jdbc2/AbstractJdbc2Statement.java
--- postgres-v5/org/postgresql/jdbc2/AbstractJdbc2Statement.java	2006-11-05 07:58:22.000000000 +0200
+++ postgres-clean2/org/postgresql/jdbc2/AbstractJdbc2Statement.java	2006-11-28 22:03:40.000000000 +0200
@@ -446,6 +446,10 @@
 
         if (connection.getAutoCommit())
             flags |= QueryExecutor.QUERY_SUPPRESS_BEGIN;
+        
+        // updateable result sets do not yet support binary updates
+        if (concurrency != ResultSet.CONCUR_READ_ONLY)
+            flags |= QueryExecutor.QUERY_NO_BINARY_TRANSFER;
 
         StatementResultHandler handler = new StatementResultHandler();
         result = null;
diff -ur --exclude=CVS --exclude='*.class' --exclude='*.txt' postgres-v5/org/postgresql/test/jdbc2/UpdateableResultTest.java postgres-clean2/org/postgresql/test/jdbc2/UpdateableResultTest.java
--- postgres-v5/org/postgresql/test/jdbc2/UpdateableResultTest.java	2006-11-20 20:41:28.000000000 +0200
+++ postgres-clean2/org/postgresql/test/jdbc2/UpdateableResultTest.java	2006-11-28 21:42:55.000000000 +0200
@@ -10,6 +10,8 @@
 package org.postgresql.test.jdbc2;
 
 import java.sql.*;
+import java.util.Arrays;
+
 import junit.framework.TestCase;
 
 import java.io.InputStream;
@@ -215,25 +217,26 @@
         String string = "Hello";
         InputStream asi = new ByteArrayInputStream(string.getBytes("US-ASCII"));
         Reader chr = new StringReader(string);
-        InputStream bin = new ByteArrayInputStream(string.getBytes("US-ASCII"));
+        byte[] bytes = new byte[]{0,'\\',(byte) 128,(byte) 255};
+        InputStream bin = new ByteArrayInputStream(bytes);
 
         rs.updateInt("id", 2);
         rs.updateAsciiStream("asi", asi, 5);
         rs.updateCharacterStream("chr", chr, 5);
-        rs.updateBinaryStream("bin", bin, 5);
+        rs.updateBinaryStream("bin", bin, bytes.length);
         rs.updateRow();
 
         assertEquals(2, rs.getInt(1));
         assertEquals(string, rs.getString(2));
         assertEquals(string, rs.getString(3));
-        assertEquals(string, rs.getString(4));
+        assertTrue(Arrays.equals(bytes, rs.getBytes(4)));
 
         rs.refreshRow();
 
         assertEquals(2, rs.getInt(1));
         assertEquals(string, rs.getString(2));
         assertEquals(string, rs.getString(3));
-        assertEquals(string, rs.getString(4));
+        assertTrue(Arrays.equals(bytes, rs.getBytes(4)));
 
         rs.close();
         stmt.close();


Home | Main Index | Thread Index

Privacy Policy | PostgreSQL Archives hosted by Command Prompt, Inc. | Designed by tinysofa
Copyright © 1996 – 2008 PostgreSQL Global Development Group