Permalink
Browse files

allow the first query to be binary

  • Loading branch information...
Nick White
Nick White committed Apr 4, 2013
1 parent 471a09e commit 51d820891617c7168d4168039f03a7d9a4cd4bbe
@@ -9,6 +9,8 @@
import java.sql.SQLException;
+import org.postgresql.core.Field;
+
public interface PGResultSetMetaData
{
@@ -36,4 +38,12 @@
*/
public String getBaseSchemaName(int column) throws SQLException;
+ /**
+ * Is a column Text or Binary?
+ *
+ * @see Field#BINARY_FORMAT
+ * @see Field#TEXT_FORMAT
+ * @since 9.4
+ */
+ public int getFormat(int column) throws SQLException;
}
@@ -334,6 +334,17 @@ public int getColumnType(int column) throws SQLException
return getSQLType(column);
}
+ /*
+ * Is a column Text or Binary?
+ *
+ * @param column the first column is 1, the second is 2...
+ * @return column name, or "" if not applicable
+ * @exception SQLException if a database access error occurs
+ */
+ public int getFormat(int column) throws SQLException {
+ return getField(column).getFormat();
+ }
+
/*
* Whats is the column's data source specific type name?
*
@@ -525,7 +525,8 @@ protected void execute(Query queryToExecute, ParameterList queryParameters, int
flags &= ~(QueryExecutor.QUERY_NO_RESULTS);
}
- // Only use named statements after we hit the threshold
+ // Only use named statements after we hit the threshold. Note that only
+ // named statements can be transferred in binary format.
if (preparedQuery != null)
{
++m_useCount; // We used this statement once more.
@@ -540,7 +541,7 @@ protected void execute(Query queryToExecute, ParameterList queryParameters, int
if (concurrency != ResultSet.CONCUR_READ_ONLY)
flags |= QueryExecutor.QUERY_NO_BINARY_TRANSFER;
- if (ForceBinaryTransfers) {
+ if (ForceBinaryTransfers || (flags & QueryExecutor.QUERY_ONESHOT) == 0) {

This comment has been minimized.

Show comment Hide comment
@gmokki

gmokki Apr 15, 2013

If I remember correctly the QUERY_DESCRIBE_ONLY causes an extra round trip to the database, which is why it has previously been only enabled with the force flag (which itself is meant for testing purpuses).
Have you checked with wireshark or some tool if enabling this code path causes any extra traffic?

@gmokki

gmokki Apr 15, 2013

If I remember correctly the QUERY_DESCRIBE_ONLY causes an extra round trip to the database, which is why it has previously been only enabled with the force flag (which itself is meant for testing purpuses).
Have you checked with wireshark or some tool if enabling this code path causes any extra traffic?

int flags2 = flags | QueryExecutor.QUERY_DESCRIBE_ONLY;
StatementResultHandler handler2 = new StatementResultHandler();
connection.getQueryExecutor().execute(queryToExecute, queryParameters, handler2, 0, 0, flags2);
@@ -0,0 +1,94 @@
+package org.postgresql.test.jdbc4;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.postgresql.PGConnection;
+import org.postgresql.PGResultSetMetaData;
+import org.postgresql.PGStatement;
+import org.postgresql.core.Field;
+import org.postgresql.test.TestUtil;
+
+import junit.framework.TestCase;
+
+/**
+ * We don't want to use the binary protocol for one-off queries as it involves
+ * another round-trip to the server to 'describe' the query. If we use the query
+ * enough times (see {@link PGConnection#setPrepareThreshold(int)} then we'll
+ * change to using the binary protocol to save bandwidth and reduce decoding
+ * time.
+ */
+public class BinaryTest extends TestCase {
+ private Connection connection;
+ private ResultSet results;
+ private PreparedStatement statement;
+
+ public BinaryTest(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ connection = TestUtil.openDB();
+ statement = connection.prepareStatement("select 1");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ TestUtil.closeDB(connection);
+ }
+
+ public void testPreparedStatement_3() throws Exception {
+ ((PGStatement) statement).setPrepareThreshold(3);
+
+ results = statement.executeQuery();
+ assertEquals(Field.TEXT_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.TEXT_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.BINARY_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.BINARY_FORMAT, getFormat(results));
+ }
+
+ public void testPreparedStatement_1() throws Exception {
+ ((PGStatement) statement).setPrepareThreshold(1);
+
+ results = statement.executeQuery();
+ assertEquals(Field.BINARY_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.BINARY_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.BINARY_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.BINARY_FORMAT, getFormat(results));
+ }
+
+ public void testPreparedStatement_0() throws Exception {
+ ((PGStatement) statement).setPrepareThreshold(0);
+
+ results = statement.executeQuery();
+ assertEquals(Field.TEXT_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.TEXT_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.TEXT_FORMAT, getFormat(results));
+
+ results = statement.executeQuery();
+ assertEquals(Field.TEXT_FORMAT, getFormat(results));
+ }
+
+ private int getFormat(ResultSet results) throws SQLException {
+ return ((PGResultSetMetaData) results.getMetaData()).getFormat(1);
+ }
+}
@@ -31,6 +31,7 @@ public static TestSuite suite() throws Exception
suite.addTestSuite(ArrayTest.class);
suite.addTestSuite(ConnectionTest.class);
suite.addTestSuite(WrapperTest.class);
+ suite.addTestSuite(BinaryTest.class);
Connection connection = TestUtil.openDB();
try

0 comments on commit 51d8208

Please sign in to comment.