changeset 81:a3c686217ca1 embedded

Made many fixes for the embedded connection
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Fri, 16 Dec 2016 18:41:09 +0100 (2016-12-16)
parents 0ae34196c54e
children 4231a7f5cdc3
files src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedConnection.java src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java src/main/java/nl/cwi/monetdb/mcl/connection/embedded/EmbeddedConnection.java src/main/java/nl/cwi/monetdb/mcl/connection/embedded/JDBCEmbeddedConnection.java src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java src/main/java/nl/cwi/monetdb/mcl/protocol/embedded/EmbeddedProtocol.java src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java
diffstat 10 files changed, 130 insertions(+), 156 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedConnection.java
+++ b/src/main/java/nl/cwi/monetdb/embedded/env/MonetDBEmbeddedConnection.java
@@ -30,7 +30,7 @@ public class MonetDBEmbeddedConnection {
 
 	protected MonetDBEmbeddedConnection(long connectionPointer) { this.connectionPointer = connectionPointer; }
 
-    long getConnectionPointer() { return connectionPointer; }
+    public long getConnectionPointer() { return connectionPointer; }
 
     /**
      * Gets the current schema set on the connection.
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -46,15 +46,9 @@ import java.util.concurrent.Executor;
  */
 public abstract class MonetConnection extends MonetWrapper implements Connection {
 
-    /** the default number of rows that are (attempted to) read at once */
-    private static int DEF_FETCHSIZE = 250;
     /** The sequence counter */
     private static int SeqCounter = 0;
 
-    public static int GetDefFetchsize() {
-        return DEF_FETCHSIZE;
-    }
-
     public static int GetSeqCounter() {
         return SeqCounter;
     }
@@ -150,6 +144,8 @@ public abstract class MonetConnection ex
 
     public abstract int getBlockSize();
 
+    public abstract int getDefFetchsize();
+
     public abstract int getSoTimeout();
 
     public abstract void setSoTimeout(int s);
@@ -164,6 +160,10 @@ public abstract class MonetConnection ex
 
     public abstract void sendControlCommand(ControlCommands con, int data) throws SQLException;
 
+    public abstract ResponseList createResponseList(int fetchSize, int maxRows, int resultSetType, int resultSetConcurrency) throws SQLException;
+
+    public abstract void setServerMaxRows(int maxRows) throws SQLException;
+
     /**
      * Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be
      * automatically released. All Statements created from this Connection will be closed when this method is called.
@@ -1167,8 +1167,7 @@ public abstract class MonetConnection ex
      * Sets the given schema name to access.
      *
      * @param schema the name of a schema in which to work
-     * @throws SQLException if a database access error occurs or this
-     *         method is called on a closed connection
+     * @throws SQLException if a database access error occurs or this method is called on a closed connection
      * @since 1.7
      */
     @Override
@@ -1190,8 +1189,7 @@ public abstract class MonetConnection ex
      * Retrieves this Connection object's current schema name.
      *
      * @return the current schema name or null if there is none
-     * @throws SQLException if a database access error occurs or this
-     *         method is called on a closed connection
+     * @throws SQLException if a database access error occurs or this method is called on a closed connection
      */
     @Override
     public String getSchema() throws SQLException {
@@ -1225,12 +1223,9 @@ public abstract class MonetConnection ex
      * Calling abort marks the connection closed and releases any
      * resources. Calling abort on a closed connection is a no-op.
      *
-     * @param executor The Executor implementation which will be used by
-     *        abort
-     * @throws SQLException if a database access error occurs or the
-     *         executor is null
-     * @throws SecurityException if a security manager exists and
-     *         its checkPermission method denies calling abort
+     * @param executor The Executor implementation which will be used by abort
+     * @throws SQLException if a database access error occurs or the executor is null
+     * @throws SecurityException if a security manager exists and its checkPermission method denies calling abort
      */
     @Override
     public void abort(Executor executor) throws SQLException {
@@ -1253,13 +1248,10 @@ public abstract class MonetConnection ex
      * isClosed or Connection.isValid methods, will result in a
      * SQLException.
      *
-     * @param executor The Executor implementation which will be used by
-     *        setNetworkTimeout
-     * @param millis The time in milliseconds to wait for the
-     *        database operation to complete
-     * @throws SQLException if a database access error occurs, this
-     *         method is called on a closed connection, the executor is
-     *         null, or the value specified for seconds is less than 0.
+     * @param executor The Executor implementation which will be used by setNetworkTimeout
+     * @param millis The time in milliseconds to wait for the database operation to complete
+     * @throws SQLException if a database access error occurs, this method is called on a closed connection, the
+     * executor is null, or the value specified for seconds is less than 0.
      */
     @Override
     public void setNetworkTimeout(Executor executor, int millis) throws SQLException {
@@ -1274,14 +1266,11 @@ public abstract class MonetConnection ex
     }
 
     /**
-     * Retrieves the number of milliseconds the driver will wait for a
-     * database request to complete. If the limit is exceeded, a
-     * SQLException is thrown.
+     * Retrieves the number of milliseconds the driver will wait for a database request to complete. If the limit is
+     * exceeded, a SQLException is thrown.
      *
-     * @return the current timeout limit in milliseconds; zero means
-     *         there is no limit
-     * @throws SQLException if a database access error occurs or
-     *         this method is called on a closed Connection
+     * @return the current timeout limit in milliseconds; zero means there is no limit
+     * @throws SQLException if a database access error occurs or this method is called on a closed Connection
      */
     @Override
     public int getNetworkTimeout() throws SQLException {
@@ -1301,10 +1290,8 @@ public abstract class MonetConnection ex
     }
 
     /**
-     * Sends the given string to MonetDB as regular statement, making
-     * sure there is a prompt after the command is sent.  All possible
-     * returned information is discarded.  Encountered errors are
-     * reported.
+     * Sends the given string to MonetDB as regular statement, making sure there is a prompt after the command is sent.
+     * All possible returned information is discarded. Encountered errors are reported.
      *
      * @param command the exact string to send to MonetDB
      * @throws SQLException if an IO exception or a database error occurs
@@ -1326,10 +1313,8 @@ public abstract class MonetConnection ex
     }
 
     /**
-     * Adds a warning to the pile of warnings this Connection object
-     * has.  If there were no warnings (or clearWarnings was called)
-     * this warning will be the first, otherwise this warning will get
-     * appended to the current warning.
+     * Adds a warning to the pile of warnings this Connection object has. If there were no warnings (or clearWarnings
+     * was called) this warning will be the first, otherwise this warning will get appended to the current warning.
      *
      * @param reason the warning message
      */
@@ -1373,7 +1358,7 @@ public abstract class MonetConnection ex
          * @param rstype the type of result sets to produce
          * @param rsconcur the concurrency of result sets to produce
          */
-        ResponseList(int cachesize, int maxrows, int rstype, int rsconcur) throws SQLException {
+        public ResponseList(int cachesize, int maxrows, int rstype, int rsconcur) throws SQLException {
             this.cachesize = cachesize;
             this.maxrows = maxrows;
             this.rstype = rstype;
@@ -1504,13 +1489,12 @@ public abstract class MonetConnection ex
                  * to use, then ignore this call.  If it is set to 0 we get a prompt after the server sent it's
                  * header.
                  */
-                int size = cachesize == 0 ? DEF_FETCHSIZE : cachesize;
+                int size = cachesize == 0 ? MonetConnection.this.getDefFetchsize() : cachesize;
                 size = maxrows != 0 ? Math.min(maxrows, size) : size;
                 // don't do work if it's not needed
                 if (language == MapiLanguage.LANG_SQL && size != curReplySize &&
                         !Arrays.deepEquals(templ, language.getCommandTemplates())) {
-                    sendControlCommand(ControlCommands.REPLY_SIZE, size);
-
+                    setServerMaxRows(size);
                     // store the reply size after a successful change
                     curReplySize = size;
                 }
@@ -1529,8 +1513,7 @@ public abstract class MonetConnection ex
                     // tell it to do some work!
                     senderThread.runQuery(templ, query);
                 } else {
-                    // this is a simple call, which is a lot cheaper and will
-                    // always succeed for small queries.
+                    // this is a simple call, which is a lot cheaper and will always succeed for small queries.
                     protocol.writeNextQuery((templ[0] == null) ? "" : templ[0], query,
                             (templ[1] == null) ? "" : templ[1]);
                 }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
@@ -46,9 +46,6 @@ import java.util.concurrent.locks.Reentr
  * @version 0.7
  */
 public class MonetStatement extends MonetWrapper implements Statement {
-	/** the default value of maxRows, 0 indicates unlimited */
-	private static final int DEF_MAXROWS = 0;
-
 	/** The parental Connection object */
 	private MonetConnection connection;
 	/** The last ResponseList object this Statement produced */
@@ -65,8 +62,8 @@ public class MonetStatement extends Mone
 	private boolean closeOnCompletion = false;
 	/** The size of the blocks of results to ask for at the server */
 	private int fetchSize = 0;
-	/** The maximum number of rows to return in a ResultSet */
-	private int maxRows = DEF_MAXROWS;
+	/** The maximum number of rows to return in a ResultSet, 0 indicates unlimited */
+	private int maxRows = 0;
 	/** The suggested direction of fetching data (implemented but not used) */
 	private int fetchDirection = ResultSet.FETCH_FORWARD;
 	/** The type of ResultSet to produce; i.e. forward only, random access */
@@ -477,7 +474,7 @@ public class MonetStatement extends Mone
 		}
 
 		// create a container for the result
-		lastResponseList = connection.new ResponseList(fetchSize, maxRows, resultSetType, resultSetConcurrency);
+		lastResponseList = connection.createResponseList(fetchSize, maxRows, resultSetType, resultSetConcurrency);
 		// fill the header list by processing the query
 		lastResponseList.processQuery(sql);
 
@@ -642,8 +639,7 @@ public class MonetStatement extends Mone
 	 * setFetchSize, or the method setFetchSize was called as such to let
 	 * the driver ignore the hint, 0 is returned.
 	 *
-	 * @return the default fetch size for result sets generated from this
-	 *         Statement object
+	 * @return the default fetch size for result sets generated from this Statement object
 	 */
 	@Override
 	public int getFetchSize() {
@@ -655,8 +651,8 @@ public class MonetStatement extends Mone
 	 * executing this Statement object.  If this Statement object did not
 	 * generate any keys, an empty ResultSet object is returned.
 	 *
-	 * @return a ResultSet object containing the auto-generated key(s)
-	 *         generated by the execution of this Statement object
+	 * @return a ResultSet object containing the auto-generated key(s) generated by the execution of this Statement
+	 * object
 	 * @throws SQLException - if a database access error occurs
 	 */
 	@Override
@@ -1091,7 +1087,7 @@ public class MonetStatement extends Mone
 	/**
 	 * Requests that a Statement be pooled or not pooled. The value
 	 * specified is a hint to the statement pool implementation
-	 * indicating whether the applicaiton wants the statement to be
+	 * indicating whether the application wants the statement to be
 	 * pooled. It is up to the statement pool manager as to whether the
 	 * hint is used.
 	 *
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java
@@ -96,7 +96,7 @@ public class SenderThread extends Thread
         this.sendLock.lock();
         try {
             if (this.state != SendThreadStatus.WAIT) {
-                throw new SQLException("SendThread already in use or shutting down!", "M0M03");
+                throw new SQLException("Sender Thread already in use or shutting down!", "M0M03");
             }
             this.templ = templ;
             this.query = query;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/embedded/EmbeddedConnection.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/embedded/EmbeddedConnection.java
@@ -63,6 +63,11 @@ public final class EmbeddedConnection ex
     }
 
     @Override
+    public int getDefFetchsize() {
+        return Integer.MAX_VALUE;
+    }
+
+    @Override
     public int getSoTimeout() {
         this.addWarning("Cannot get a timeout on a embedded connection!", "M1M05");
         return -1;
@@ -83,23 +88,32 @@ public final class EmbeddedConnection ex
         try {
             switch (con) {
                 case AUTO_COMMIT:
-                    ((EmbeddedProtocol)protocol).sendAutocommitCommand(data);
-                    break;
-                case REPLY_SIZE:
-                    ((EmbeddedProtocol)protocol).sendReplySizeCommand(data);
+                    ((EmbeddedProtocol)protocol).getEmbeddedConnection().sendAutocommitCommand(data);
                     break;
                 case RELEASE:
-                    ((EmbeddedProtocol)protocol).sendReleaseCommand(data);
+                    ((EmbeddedProtocol)protocol).getEmbeddedConnection().sendReleaseCommand(data);
                     break;
                 case CLOSE:
-                    ((EmbeddedProtocol)protocol).sendCloseCommand(data);
+                    ((EmbeddedProtocol)protocol).getEmbeddedConnection().sendCloseCommand(data);
+                case REPLY_SIZE:
+                    throw new SQLException("Cannot set reply size on a Embedded connection!", "M1M05");
             }
             protocol.waitUntilPrompt();
             if (protocol.getCurrentServerResponseHeader() == ServerResponses.ERROR) {
                 throw new SQLException(protocol.getRemainingStringLine(0));
             }
-        } catch (IOException | ProtocolException ex) {
+        } catch (IOException ex) {
             throw new SQLException(ex);
         }
     }
+
+    @Override
+    public ResponseList createResponseList(int fetchSize, int maxRows, int resultSetType, int resultSetConcurrency) throws SQLException {
+        return new MonetConnection.ResponseList(this.getDefFetchsize(), maxRows, resultSetType, resultSetConcurrency);
+    }
+
+    @Override
+    public void setServerMaxRows(int maxRows) throws SQLException {
+        ((EmbeddedProtocol)protocol).getEmbeddedConnection().setMaxRows(maxRows);
+    }
 }
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/embedded/JDBCEmbeddedConnection.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/embedded/JDBCEmbeddedConnection.java
@@ -1,7 +1,6 @@
 package nl.cwi.monetdb.mcl.connection.embedded;
 
 import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedConnection;
-import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
 import nl.cwi.monetdb.mcl.protocol.StarterHeaders;
 import nl.cwi.monetdb.mcl.protocol.TableResultHeaders;
@@ -12,9 +11,11 @@ import nl.cwi.monetdb.mcl.responses.IRes
  */
 public class JDBCEmbeddedConnection extends MonetDBEmbeddedConnection {
 
+    private int maxRows = Integer.MAX_VALUE;
+
     private long lastResultSetPointer;
 
-    private final ServerResponses[] lineResponse = new ServerResponses[8];
+    private final ServerResponses[] lineResponse = new ServerResponses[4];
 
     private int currentLineResponseState;
 
@@ -30,6 +31,10 @@ public class JDBCEmbeddedConnection exte
         super(connectionPointer);
     }
 
+    void setMaxRows(int maxRows) {
+        this.maxRows = maxRows;
+    }
+
     public ServerResponses getNextServerResponse() {
         return lineResponse[currentLineResponseState++];
     }
@@ -47,54 +52,51 @@ public class JDBCEmbeddedConnection exte
     }
 
     public TableResultHeaders fillTableHeaders(String[] columnNames, int[] columnLengths, String[] types,
-                                               String[] tableNames) throws MonetDBEmbeddedException {
-        this.getNextTableHeader(this.connectionPointer, this.lastResultSetPointer, columnNames, columnLengths,
+                                               String[] tableNames) {
+        this.getNextTableHeaderInternal(this.connectionPointer, this.lastResultSetPointer, columnNames, columnLengths,
                 types, tableNames);
-        return TableResultHeaders.TABLE;
+        return TableResultHeaders.ALL;
     }
 
-    public int parseTupleLines(int[] typesMap, Object[] values, boolean[][] nulls) throws MonetDBEmbeddedException {
-        return this.parseTupleLines(this.connectionPointer, this.lastResultSetPointer, typesMap, values, nulls);
+    public int parseTupleLines(int[] typesMap, Object[] values, boolean[][] nulls) {
+        return this.parseTupleLinesInternal(this.connectionPointer, this.lastResultSetPointer, typesMap, values, nulls);
     }
 
     public String getLastError() {
         return lastError;
     }
 
-    public void processNextQuery(String query) throws MonetDBEmbeddedException {
+    public void processNextQuery(String query) {
         if (!query.endsWith(";")) {
             query += ";";
         }
+        this.currentLineResponseState = 0;
         this.sendQueryInternal(this.connectionPointer, query, true);
     }
 
-    public void sendAutocommitCommand(int flag) throws MonetDBEmbeddedException { //1 or 0
+    void sendAutocommitCommand(int flag) { //1 or 0
         this.sendAutocommitCommandInternal(this.connectionPointer, flag);
     }
 
-    public void sendReleaseCommand(int commandId) throws MonetDBEmbeddedException {
+    void sendReleaseCommand(int commandId) {
         this.sendReleaseCommandInternal(this.connectionPointer, commandId);
     }
 
-    public void sendCloseCommand(int commandId) throws MonetDBEmbeddedException {
+    void sendCloseCommand(int commandId) {
         this.sendCloseCommandInternal(this.connectionPointer, commandId);
     }
 
-    private native void getNextTableHeader(long connectionPointer, long resultSetPointer, String[] columnNames,
-                                           int[] columnLengths, String[] types, String[] tableNames)
-            throws MonetDBEmbeddedException;
+    private native void getNextTableHeaderInternal(long connectionPointer, long resultSetPointer, String[] columnNames,
+                                                   int[] columnLengths, String[] types, String[] tableNames);
 
-    private native int parseTupleLines(long connectionPointer, long resultSetPointer, int[] typesMap, Object[] values,
-                                       boolean[][] nulls) throws MonetDBEmbeddedException;
+    private native int parseTupleLinesInternal(long connectionPointer, long resultSetPointer, int[] typesMap,
+                                               Object[] values, boolean[][] nulls);
 
-    private native void sendQueryInternal(long connectionPointer, String query, boolean execute)
-            throws MonetDBEmbeddedException;
+    private native void sendQueryInternal(long connectionPointer, String query, boolean execute);
 
-    private native void sendAutocommitCommandInternal(long connectionPointer, int flag)
-            throws MonetDBEmbeddedException;
+    private native void sendAutocommitCommandInternal(long connectionPointer, int flag);
 
-    private native void sendReleaseCommandInternal(long connectionPointer, int commandId)
-            throws MonetDBEmbeddedException;
+    private native void sendReleaseCommandInternal(long connectionPointer, int commandId);
 
-    private native void sendCloseCommandInternal(long connectionPointer, int commandId) throws MonetDBEmbeddedException;
+    private native void sendCloseCommandInternal(long connectionPointer, int commandId);
 }
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java
@@ -19,8 +19,10 @@ import java.sql.SQLException;
 import java.util.*;
 
 public class MapiConnection extends MonetConnection {
-
-    public static final char PROMPT_CHAR = '.';
+    /** the PROMPT ASCII char sent by the server */
+    static final char PROMPT_CHAR = '.';
+    /** the default number of rows that are (attempted to) read at once */
+    private static final int DEF_FETCHSIZE = 250;
 
     /** The hostname to connect to */
     private final String hostname;
@@ -111,6 +113,11 @@ public class MapiConnection extends Mone
         return ((OldMapiProtocol)protocol).getSocket().getBlockSize();
     }
 
+    @Override
+    public int getDefFetchsize() {
+        return DEF_FETCHSIZE;
+    }
+
     /**
      * Gets the SO_TIMEOUT from the underlying Socket.
      *
@@ -210,6 +217,16 @@ public class MapiConnection extends Mone
     }
 
     @Override
+    public ResponseList createResponseList(int fetchSize, int maxRows, int resultSetType, int resultSetConcurrency) throws SQLException {
+        return new MonetConnection.ResponseList(fetchSize, maxRows, resultSetType, resultSetConcurrency);
+    }
+
+    @Override
+    public void setServerMaxRows(int maxRows) throws SQLException {
+        this.sendControlCommand(ControlCommands.REPLY_SIZE, maxRows);
+    }
+
+    @Override
     public List<String> connect(String user, String pass) throws IOException, ProtocolException, MCLException {
         // Wrap around the internal connect that needs to know if it should really make a TCP connection or not.
         List<String> res = connect(this.hostname, this.port, user, pass, true);
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java
@@ -6,9 +6,20 @@ package nl.cwi.monetdb.mcl.protocol;
 public enum TableResultHeaders {
 
     /* Please don't change the order */
-    NAME,
-    LENGTH,
-    TABLE,
-    TYPE,
-    UNKNOWN
+    NAME(1),
+    LENGTH(2),
+    TABLE(4),
+    TYPE(8),
+    ALL(15),
+    UNKNOWN(0);
+
+    private final int valueForBitMap;
+
+    TableResultHeaders(int valueForBitMap) {
+        this.valueForBitMap = valueForBitMap;
+    }
+
+    public int getValueForBitMap() {
+        return valueForBitMap;
+    }
 }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/embedded/EmbeddedProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/embedded/EmbeddedProtocol.java
@@ -1,6 +1,5 @@
 package nl.cwi.monetdb.mcl.protocol.embedded;
 
-import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException;
 import nl.cwi.monetdb.jdbc.MonetConnection;
 import nl.cwi.monetdb.mcl.connection.embedded.JDBCEmbeddedConnection;
 import nl.cwi.monetdb.mcl.protocol.*;
@@ -81,20 +80,12 @@ public class EmbeddedProtocol extends Ab
     @Override
     public TableResultHeaders getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types,
                                                  String[] tableNames) throws ProtocolException {
-        try {
-            return connection.fillTableHeaders(columnNames, columnLengths, types, tableNames);
-        } catch (MonetDBEmbeddedException ex) {
-            throw new ProtocolException(ex.getMessage());
-        }
+        return connection.fillTableHeaders(columnNames, columnLengths, types, tableNames);
     }
 
     @Override
     public int parseTupleLines(int lineNumber, int[] typesMap, Object[] values, boolean[][] nulls) throws ProtocolException {
-        try {
-            return connection.parseTupleLines(typesMap, values, nulls);
-        } catch (MonetDBEmbeddedException ex) {
-            throw new ProtocolException(ex.getMessage());
-        }
+        return connection.parseTupleLines(typesMap, values, nulls);
     }
 
     @Override
@@ -104,38 +95,6 @@ public class EmbeddedProtocol extends Ab
 
     @Override
     public void writeNextQuery(String prefix, String query, String suffix) throws IOException {
-        try {
-            connection.processNextQuery(query);
-        } catch (MonetDBEmbeddedException ex) {
-            throw new IOException(ex.getMessage());
-        }
-    }
-
-    public void sendAutocommitCommand(int flag) throws ProtocolException { //1 or 0
-        try {
-            connection.sendAutocommitCommand(flag);
-        } catch (MonetDBEmbeddedException ex) {
-            throw new ProtocolException(ex.getMessage());
-        }
-    }
-
-    public void sendReplySizeCommand(int size) throws ProtocolException {
-        //do nothing for now :)
-    }
-
-    public void sendReleaseCommand(int commandId) throws ProtocolException {
-        try {
-            connection.sendReleaseCommand(commandId);
-        } catch (MonetDBEmbeddedException ex) {
-            throw new ProtocolException(ex.getMessage());
-        }
-    }
-
-    public void sendCloseCommand(int commandId) throws ProtocolException {
-        try {
-            connection.sendCloseCommand(commandId);
-        } catch (MonetDBEmbeddedException ex) {
-            throw new ProtocolException(ex.getMessage());
-        }
+        connection.processNextQuery(query);
     }
 }
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java
@@ -6,6 +6,7 @@ import nl.cwi.monetdb.mcl.connection.Con
 import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
 import nl.cwi.monetdb.mcl.protocol.ProtocolException;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
+import nl.cwi.monetdb.mcl.protocol.TableResultHeaders;
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -25,7 +26,7 @@ import java.sql.Types;
  */
 public class ResultSetResponse implements IIncompleteResponse {
 
-    private static final byte IS_SET_FINAL_VALUE = 4;
+    private static final byte IS_SET_FINAL_VALUE = 15;
 
     /** The number of columns in this result */
     private final int columncount;
@@ -57,7 +58,7 @@ public class ResultSetResponse implement
     private MonetConnection con;
     /** The Connection that we should use when requesting a new block */
     private MonetConnection.ResponseList parent;
-    /** Whether the fetchSize was explitly set by the user */
+    /** Whether the fetchSize was explicitly set by the user */
     private boolean cacheSizeSetExplicitly = false;
     /** Whether we should send an Xclose command to the server if we close this Response */
     private boolean destroyOnClose;
@@ -83,7 +84,7 @@ public class ResultSetResponse implement
         if (parent.getCachesize() == 0) {
             /* Below we have to calculate how many "chunks" we need to allocate to store the entire result. However, if
                the user didn't set a cache size, as in this case, we need to stick to our defaults. */
-            cacheSize = MonetConnection.GetDefFetchsize();
+            cacheSize = con.getDefFetchsize();
             cacheSizeSetExplicitly = false;
         } else {
             cacheSize = parent.getCachesize();
@@ -135,6 +136,7 @@ public class ResultSetResponse implement
      * Returns whether this ResultSetResponse needs more lines. This method returns true if not all headers are set,
      * or the first DataBlockResponse reports to want more.
      */
+    @Override
     public boolean wantsMore() {
         return this.isSet < IS_SET_FINAL_VALUE || resultBlocks[0].wantsMore();
     }
@@ -262,20 +264,10 @@ public class ResultSetResponse implement
         } else if (protocol.getCurrentServerResponseHeader() != ServerResponses.HEADER) {
             throw new ProtocolException("header expected, got: " + protocol.getRemainingStringLine(0));
         } else {
-            switch (con.getProtocol().getNextTableHeader(this.name, this.columnLengths, this.type, this.tableNames)) {
-                case NAME:
-                    isSet = 1;
-                    break;
-                case LENGTH:
-                    isSet = 2;
-                    break;
-                case TYPE:
-                    isSet = 3;
-                    break;
-                case TABLE:
-                    isSet = 4;
-                    this.populateJdbcSQLTypesArray(); //VERY IMPORTANT!
-                    break;
+            TableResultHeaders next = con.getProtocol().getNextTableHeader(this.name, this.columnLengths, this.type, this.tableNames);
+            this.isSet |= next.getValueForBitMap();
+            if(this.isSet >= IS_SET_FINAL_VALUE) {
+                this.populateJdbcSQLTypesArray(); //VERY IMPORTANT
             }
         }
     }
@@ -309,7 +301,7 @@ public class ResultSetResponse implement
                     resultBlocks[i] = null;
 
                 if (MonetConnection.GetSeqCounter() - 1 == seqnr && !cacheSizeSetExplicitly &&
-                        tuplecount - row > cacheSize && cacheSize < MonetConnection.GetDefFetchsize() * 10) {
+                        tuplecount - row > cacheSize && cacheSize < con.getDefFetchsize() * 10) {
                     // there has no query been issued after this one, so we can consider this an uninterrupted
                     // continuation request.  Let's once increase the cacheSize as it was not explicitly set,
                     // since the chances are high that we won't bother anyone else by doing so, and just gaining