changeset 67:87ba760038b6 embedded

More cleanup. About to start the tuple conversions.
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Tue, 06 Dec 2016 18:13:54 +0100 (2016-12-06)
parents 7307caacc2d5
children 86967be24645
files src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java src/main/java/nl/cwi/monetdb/mcl/connection/EmbeddedConnection.java src/main/java/nl/cwi/monetdb/mcl/connection/MapiConnection.java src/main/java/nl/cwi/monetdb/mcl/connection/MonetDBConnectionFactory.java src/main/java/nl/cwi/monetdb/mcl/io/AbstractMCLReader.java src/main/java/nl/cwi/monetdb/mcl/io/AbstractMCLWriter.java src/main/java/nl/cwi/monetdb/mcl/io/BufferedMCLReader.java src/main/java/nl/cwi/monetdb/mcl/io/BufferedMCLWriter.java src/main/java/nl/cwi/monetdb/mcl/parser/HeaderLineParser.java src/main/java/nl/cwi/monetdb/mcl/parser/MCLParseException.java src/main/java/nl/cwi/monetdb/mcl/parser/MCLParser.java src/main/java/nl/cwi/monetdb/mcl/parser/TupleLineParser.java src/main/java/nl/cwi/monetdb/mcl/parser/socket/SocketTupleLineParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/MCLParseException.java src/main/java/nl/cwi/monetdb/mcl/protocol/embedded/EmbeddedProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/IIncompleteResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java src/main/java/nl/cwi/monetdb/mcl/responses/SchemaResponse.java src/main/java/nl/cwi/monetdb/merovingian/Control.java src/main/java/nl/cwi/monetdb/merovingian/SabaothDB.java src/main/java/nl/cwi/monetdb/util/CmdLineOpts.java src/main/java/nl/cwi/monetdb/util/Extract.java src/main/java/nl/cwi/monetdb/util/SQLExporter.java src/main/java/nl/cwi/monetdb/util/SQLRestore.java src/main/java/nl/cwi/monetdb/util/XMLExporter.java
diffstat 37 files changed, 453 insertions(+), 1142 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -5,7 +5,7 @@ import nl.cwi.monetdb.jdbc.types.URL;
 import nl.cwi.monetdb.mcl.connection.MCLException;
 import nl.cwi.monetdb.mcl.connection.Debugger;
 import nl.cwi.monetdb.mcl.connection.MonetDBLanguage;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
 import nl.cwi.monetdb.mcl.responses.*;
@@ -1398,7 +1398,7 @@ public abstract class MonetConnection ex
         /** The sequence number of this ResponseList */
         private final int seqnr;
         /** A list of the Responses associated with the query, in the right order */
-        private List<IResponse> responses = new ArrayList<>();
+        private final List<IResponse> responses = new ArrayList<>();
         /** A map of ResultSetResponses, used for additional DataBlockResponse mapping */
         private Map<Integer, ResultSetResponse> rsresponses;
         /** The current header returned by getNextResponse() */
@@ -1414,7 +1414,7 @@ public abstract class MonetConnection ex
          * @param rstype the type of result sets to produce
          * @param rsconcur the concurrency of result sets to produce
          */
-        public ResponseList(int cachesize, int maxrows, int rstype, int rsconcur) throws SQLException {
+        ResponseList(int cachesize, int maxrows, int rstype, int rsconcur) throws SQLException {
             this.cachesize = cachesize;
             this.maxrows = maxrows;
             this.rstype = rstype;
@@ -1439,8 +1439,7 @@ public abstract class MonetConnection ex
         }
 
         /**
-         * Retrieves the next available response, or null if there are
-         * no more responses.
+         * Retrieves the next available response, or null if there are no more responses.
          *
          * @return the next Response available or null
          */
@@ -1495,8 +1494,7 @@ public abstract class MonetConnection ex
         }
 
         /**
-         * Closes this ResponseList by closing all the Responses in this
-         * ResponseList.
+         * Closes this ResponseList by closing all the Responses in this ResponseList.
          */
         public void close() {
             for (int i = 0; i < responses.size(); i++) {
@@ -1505,10 +1503,9 @@ public abstract class MonetConnection ex
         }
 
         /**
-         * Returns whether this ResponseList has still unclosed
-         * Responses.
+         * Returns whether this ResponseList has still unclosed Responses.
          */
-        public boolean hasUnclosedResponses() {
+        boolean hasUnclosedResponses() {
             for (IResponse r : responses) {
                 if (r != null)
                     return true;
@@ -1517,13 +1514,12 @@ public abstract class MonetConnection ex
         }
 
         /**
-         * Executes the query contained in this ResponseList, and
-         * stores the Responses resulting from this query in this
+         * Executes the query contained in this ResponseList, and stores the Responses resulting from this query in this
          * ResponseList.
          *
          * @throws SQLException if a database error occurs
          */
-        public void processQuery(String query) throws SQLException {
+        void processQuery(String query) throws SQLException {
             this.executeQuery(language.getQueryTemplates(), query);
         }
 
@@ -1534,7 +1530,7 @@ public abstract class MonetConnection ex
          * @param query the query to execute
          * @throws SQLException if a database error occurs
          */
-        @SuppressWarnings({"fallthrough", "unchecked"})
+        @SuppressWarnings("fallthrough")
         public void executeQuery(byte[][] templ, String query) throws SQLException {
             String error = null;
 
@@ -1555,7 +1551,8 @@ public abstract class MonetConnection ex
                 int size = cachesize == 0 ? DEF_FETCHSIZE : cachesize;
                 size = maxrows != 0 ? Math.min(maxrows, size) : size;
                 // don't do work if it's not needed
-                if (language == MonetDBLanguage.LANG_SQL && size != curReplySize && !Arrays.deepEquals(templ, language.getCommandTemplates())) {
+                if (language == MonetDBLanguage.LANG_SQL && size != curReplySize &&
+                        !Arrays.deepEquals(templ, language.getCommandTemplates())) {
                     sendControlCommand("reply_size " + size);
 
                     // store the reply size after a successful change
@@ -1581,7 +1578,8 @@ public abstract class MonetConnection ex
                 } else {
                     // this is a simple call, which is a lot cheaper and will
                     // always succeed for small queries.
-                    protocol.writeNextCommand((templ[0] == null) ? MonetDBLanguage.EmptyString : templ[0], query.getBytes(), (templ[1] == null) ? MonetDBLanguage.EmptyString : templ[1]);
+                    protocol.writeNextCommand((templ[0] == null) ? MonetDBLanguage.EmptyString : templ[0],
+                            query.getBytes(), (templ[1] == null) ? MonetDBLanguage.EmptyString : templ[1]);
                 }
 
                 // go for new results
@@ -1589,8 +1587,7 @@ public abstract class MonetConnection ex
                 ServerResponses nextResponse = protocol.getCurrentServerResponseHeader();
                 IResponse res = null;
                 while (nextResponse != ServerResponses.PROMPT) {
-                    // each response should start with a start of header
-                    // (or error)
+                    // each response should start with a start of header (or error)
                     switch (nextResponse) {
                         case SOHEADER:
                             // make the response object, and fill it
@@ -1600,8 +1597,9 @@ public abstract class MonetConnection ex
                                         throw new MCLParseException("Q_PARSE header not allowed here", 1);
                                     case Q_TABLE:
                                     case Q_PREPARE: {
-                                        res = protocol.getNextResultSetResponse(MonetConnection.this, ResponseList.this, seqnr);
-                                        ResultSetResponse<?> rsreponse = (ResultSetResponse<?>) res;
+                                        res = protocol.getNextResultSetResponse(MonetConnection.this,
+                                                ResponseList.this, this.seqnr);
+                                        ResultSetResponse rsreponse = (ResultSetResponse) res;
                                         // only add this resultset to
                                         // the hashmap if it can possibly
                                         // have an additional datablock
@@ -1628,7 +1626,7 @@ public abstract class MonetConnection ex
                                         MonetConnection.this.autoCommit = isAutoCommit;
                                         break;
                                     case Q_BLOCK: {
-                                        DataBlockResponse<?> next = protocol.getNextDatablockResponse(rsresponses);
+                                        DataBlockResponse next = protocol.getNextDatablockResponse(rsresponses);
                                         if (next == null) {
                                             error = "M0M12!No ResultSetResponse for a DataBlock found";
                                             break;
@@ -1646,16 +1644,14 @@ public abstract class MonetConnection ex
                                 break;
                             }
 
-                            // immediately handle errors after parsing
-                            // the header (res may be null)
+                            // immediately handle errors after parsing the header (res may be null)
                             if (error != null) {
                                protocol.waitUntilPrompt();
                                nextResponse = protocol.getCurrentServerResponseHeader();
                                break;
                             }
 
-                            // here we have a res object, which
-                            // we can start filling
+                            // here we have a res object, which we can start filling
                             if(res instanceof IIncompleteResponse) {
                                 IIncompleteResponse iter = (IIncompleteResponse) res;
                                 while (iter.wantsMore()) {
@@ -1663,8 +1659,7 @@ public abstract class MonetConnection ex
                                         protocol.fetchNextResponseData();
                                         iter.addLine(protocol.getCurrentServerResponseHeader(), protocol.getCurrentData());
                                     } catch (MCLParseException ex) {
-                                        // right, some protocol violation,
-                                        // skip the rest of the result
+                                        // right, some protocol violation, skip the rest of the result
                                         error = "M0M10!" + ex.getMessage();
                                         protocol.waitUntilPrompt();
                                         nextResponse = protocol.getCurrentServerResponseHeader();
@@ -1676,33 +1671,25 @@ public abstract class MonetConnection ex
                             if (error != null) {
                                 break;
                             }
-                            // it is of no use to store
-                            // DataBlockResponses, you never want to
+
+                            // it is of no use to store DataBlockResponses, you never want to
                             // retrieve them directly anyway
                             if (!(res instanceof DataBlockResponse)) {
                                 responses.add(res);
                             }
-
-                            // read the next line (can be prompt, new
-                            // result, error, etc.) before we start the
-                            // loop over
+                            // read the next line (can be prompt, new result, error, etc.) before we start the loop over
                             protocol.fetchNextResponseData();
                             nextResponse = protocol.getCurrentServerResponseHeader();
                             break;
                         case INFO:
                             addWarning(protocol.getRemainingStringLine(1), "01000");
-
-                            // read the next line (can be prompt, new
-                            // result, error, etc.) before we start the
-                            // loop over
+                            // read the next line (can be prompt, new result, error, etc.) before we start the loop over
                             protocol.fetchNextResponseData();
                             nextResponse = protocol.getCurrentServerResponseHeader();
                             break;
                         case ERROR:
-                            // read everything till the prompt (should be
-                            // error) we don't know if we ignore some
-                            // garbage here... but the log should reveal
-                            // that
+                            // read everything till the prompt (should be error) we don't know if we ignore some
+                            // garbage here... but the log should reveal that
                             protocol.waitUntilPrompt();
                             nextResponse = protocol.getCurrentServerResponseHeader();
                             error = protocol.getRemainingStringLine(1);
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetDriver.java
@@ -331,7 +331,7 @@ final public class MonetDriver implement
 	 * @return the mathing java.sql.Types constant or java.sql.Types.OTHER if
 	 *         nothing matched on the given string
 	 */
-	static int getJavaType(String type) {
+	public static int getJavaType(String type) {
 		// match the currentColumns type on a java.sql.Types constant
 		Integer tp = typeMap.get(type);
 		if (tp != null) {
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetPreparedStatement.java
@@ -428,8 +428,7 @@ public class MonetPreparedStatement exte
 					case Types.BIGINT:
 						String monettype = getColumnTypeName(column);
 						if (monettype != null) {
-							if ("oid".equals(monettype)
-							 || "ptr".equals(monettype))
+							if ("oid".equals(monettype) || "ptr".equals(monettype))
 								return false;
 						}
 						return true;
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
@@ -10,8 +10,7 @@ package nl.cwi.monetdb.jdbc;
 
 import nl.cwi.monetdb.jdbc.types.INET;
 import nl.cwi.monetdb.jdbc.types.URL;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
-import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.responses.ResultSetResponse;
 
 import java.io.ByteArrayInputStream;
@@ -72,7 +71,6 @@ public class MonetResultSet extends Mone
 
 	/** The current position of the cursor for this ResultSet object */
 	int curRow = 0;
-
 	// a blank final is immutable once assigned in the constructor
 	/** A Header to retrieve lines from */
 	private final ResultSetResponse header;
@@ -84,10 +82,8 @@ public class MonetResultSet extends Mone
 	private final int[] JdbcSQLTypes;
 	/** The number of rows in this ResultSet */
 	final int tupleCount;
-
 	/** The parental Statement object */
 	private final Statement statement;
-
 	/** The type of this ResultSet (forward or scrollable) */
 	private int type = TYPE_FORWARD_ONLY;
 	/** The concurrency of this ResultSet (currently only read-only) */
@@ -98,10 +94,9 @@ public class MonetResultSet extends Mone
 	private boolean lastReadWasNull = true;
 	/** Just a dummy variable to keep store the fetchsize set. */
 	private int fetchSize;
+	/** The current row's values */
+	Object[] values;
 
-	final Object[] values;
-
-	private final AbstractProtocol<?> protocol;
 	/**
 	 * Main constructor backed by the given Header.
 	 *
@@ -123,20 +118,12 @@ public class MonetResultSet extends Mone
 		/* if we have a header object, the fetchSize used for this result set
 		   is the header's cacheSize */
 		this.fetchSize = header.getCacheSize();
-		// well there is only one supported concurrency, so we don't have to
-		// bother about that
-
-		// throws SQLException on getters of Header, so we find out immediately
-		// if an error occurred for this query
+		// well there is only one supported concurrency, so we don't have to bother about that
+		// throws SQLException on getters of Header, so we find out immediately if an error occurred for this query
+		this.tupleCount = header.getTuplecount();
 		this.columns = header.getNames();
 		this.types = header.getTypes();
-		this.tupleCount = header.getTuplecount();
-
-		// create result array
-		this.protocol = ((MonetConnection)statement.getConnection()).getProtocol();
-		this.values = new Object[this.columns.length];
-		this.JdbcSQLTypes = new int[types.length];
-		populateJdbcSQLtypesArray();
+		this.JdbcSQLTypes = header.getJdbcSQLTypes();
 	}
 
 	/**
@@ -149,7 +136,8 @@ public class MonetResultSet extends Mone
 	 * @param results the number of rows in the ResultSet
 	 * @throws IllegalArgumentException if communicating with monet failed
 	 */
-	MonetResultSet(Statement statement, String[] columns, String[] types, int results) throws IllegalArgumentException {
+	MonetResultSet(Statement statement, String[] columns, String[] types, int[] JdbcSQLTypes, int results)
+			throws IllegalArgumentException {
 		if (statement == null) {
 			throw new IllegalArgumentException("Statement may not be null!");
 		}
@@ -162,42 +150,13 @@ public class MonetResultSet extends Mone
 		if (results < 0) {
 			throw new IllegalArgumentException("Negative rowcount not allowed!");
 		}
-
 		this.statement = statement;
 		this.header = null;
 		this.fetchSize = 0;
-
+		this.tupleCount = results;
 		this.columns = columns;
 		this.types = types;
-		this.tupleCount = results;
-
-		try {
-			this.protocol = ((MonetConnection)statement.getConnection()).getProtocol();
-		} catch (SQLException e) {
-			throw new IllegalArgumentException(e);
-		}
-
-		this.values = new Object[this.columns.length];
-		this.JdbcSQLTypes = new int[types.length];
-		populateJdbcSQLtypesArray();
-	}
-
-	/**
-	 * Internal utility method to fill the JdbcSQLTypes array with derivable values.
-	 * By doing it once (in the constructor) we can avoid doing this in many getXyz() methods again and again
-	 * thereby improving getXyz() method performance.
-	 */
-	private void populateJdbcSQLtypesArray() {
-		for (int i = 0; i < types.length; i++) {
-			int javaSQLtype = MonetDriver.getJavaType(types[i]);
-			JdbcSQLTypes[i] = javaSQLtype;
-			if (javaSQLtype == Types.BLOB) {
-				try {
-					if (((MonetConnection)statement.getConnection()).getBlobAsBinary())
-						JdbcSQLTypes[i] = Types.BINARY;
-				} catch (SQLException se) { /* ignore it */ }
-			}
-		}
+		this.JdbcSQLTypes = JdbcSQLTypes;
 	}
 
 	//== methods of interface ResultSet
@@ -246,19 +205,10 @@ public class MonetResultSet extends Mone
 		if (row < 0) row = 0;	// before first
 		else if (row > tupleCount + 1) row = tupleCount + 1;	// after last
 
-		Object tmpLine = header.getLine(row - 1);
-
+		this.values = header.getLine(row - 1);
 		// store it
-		curRow = row;
-
-		if (tmpLine == null) return false;
-		try {
-			protocol.parseTupleLine(tmpLine, this.values);
-		} catch (MCLParseException e) {
-			throw new SQLException(e.getMessage(), "M0M10");
-		}
-
-		return true;
+		this.curRow = row;
+		return this.values != null;
 	}
 
 	/**
@@ -305,8 +255,9 @@ public class MonetResultSet extends Mone
 		if (header != null && !header.isClosed()) {
 			header.close();
 		}
-		if (statement instanceof MonetStatement)
+		if (statement instanceof MonetStatement) {
 			((MonetStatement)statement).closeIfCompletion();
+		}
 	}
 
 	// Chapter 14.2.3 from Sun JDBC 3.0 specification
@@ -451,8 +402,8 @@ public class MonetResultSet extends Mone
 	}
 
 	/**
-	 * Retrieves the value of the designated column in the current row
-	 * of this ResultSet object as a java.io.Reader object.
+	 * Retrieves the value of the designated column in the current row of this ResultSet object as a java.io.Reader
+	 * object.
 	 *
 	 * @param columnIndex the first column is 1, the second is 2, ...
 	 * @return a java.io.Reader object that contains the column value;
@@ -478,8 +429,8 @@ public class MonetResultSet extends Mone
 	}
 
 	/**
-	 * Retrieves the value of the designated column in the current row
-	 * of this ResultSet object as a java.io.Reader object.
+	 * Retrieves the value of the designated column in the current row of this ResultSet object as a java.io.Reader
+	 * object.
 	 *
 	 * @param columnName the name of the column
 	 * @return a java.io.Reader object that contains the column value;
@@ -531,13 +482,11 @@ public class MonetResultSet extends Mone
 	}
 
 	/**
-	 * Retrieves the value of the designated column in the current row
-	 * of this ResultSet object as a Blob object in the Java programming
-	 * language.
+	 * Retrieves the value of the designated column in the current row of this ResultSet object as a Blob object in
+	 * the Java programming language.
 	 *
 	 * @param columnIndex the first column is 1, the second is 2, ...
-	 * @return a Blob object representing the SQL BLOB value in the
-	 *         specified column
+	 * @return a Blob object representing the SQL BLOB value in the specified column
 	 * @throws SQLException if a database access error occurs
 	 */
 	@Override
@@ -1418,8 +1367,7 @@ public class MonetResultSet extends Mone
 			}
 
 			/**
-			 * Indicates the designated column's normal maximum width in
-			 * characters.
+			 * Indicates the designated column's normal maximum width in characters.
 			 *
 			 * @param column the first column is 1, the second is 2, ...
 			 * @return the normal maximum number of characters allowed as the
@@ -1619,9 +1567,8 @@ public class MonetResultSet extends Mone
 			}
 
 			/**
-			 * Indicates whether the designated column is definitely not
-			 * writable.  MonetDB does not support cursor updates, so
-			 * nothing is writable.
+			 * Indicates whether the designated column is definitely not writable.  MonetDB does not support
+			 * cursor updates, so nothing is writable.
 			 *
 			 * @param column the first column is 1, the second is 2, ...
 			 * @return true if so; false otherwise
@@ -1699,9 +1646,8 @@ public class MonetResultSet extends Mone
 			}
 
 			/**
-			 * Gets the designated column's suggested title for use in
-			 * printouts and displays. This is currently equal to
-			 * getColumnName().
+			 * Gets the designated column's suggested title for use in printouts and displays. This is currently equal
+			 * to getColumnName().
 			 *
 			 * @param column the first column is 1, the second is 2, ...
 			 * @return the suggested column title
@@ -1713,7 +1659,7 @@ public class MonetResultSet extends Mone
 			}
 
 			/**
-			 * Gets the designated column's name
+			 * Gets the designated column's name.
 			 *
 			 * @param column the first column is 1, the second is 2, ...
 			 * @return the column name
@@ -2520,7 +2466,7 @@ public class MonetResultSet extends Mone
 	 * @return the fractional seconds (nanos) or -1 if the value is NULL
 	 * @throws SQLException if a database error occurs
 	 */
-	private int getJavaDate(Calendar cal, int columnIndex, int type) throws SQLException {
+	private int getJavaDate(Calendar cal, int columnIndex, int type) throws SQLException { //TODO check this :(
 		if (cal == null)
 			throw new IllegalArgumentException("No Calendar object given!");
 
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
@@ -60,7 +60,7 @@ public class MonetStatement extends Mone
 	/** Whether this Statement object is closed or not */
 	protected boolean closed;
 	/** Whether the application wants this Statement object to be pooled */
-	protected boolean poolable;
+	private boolean poolable;
 	/** Whether this Statement should be closed if the last ResultSet closes */
 	private boolean closeOnCompletion = false;
 	/** The size of the blocks of results to ask for at the server */
@@ -665,16 +665,15 @@ public class MonetStatement extends Mone
 	 */
 	@Override
 	public ResultSet getGeneratedKeys() throws SQLException {
-		String[] columns, types;
+		String[] columns = new String[1], types = new String[1];
+		int[] jdbcTypes = new int[1];
 		String[][] results;
 
-		columns = new String[1];
-		types = new String[1];
-
 		columns[0] = "GENERATED_KEY";
 		/* the generated key should be an integer, because (wait for it) other 
 		 * frameworks such as spring expect this. */
 		types[0] = "BIGINT";
+		jdbcTypes[0] = MonetDriver.getJavaType(types[0]);
 
 		if (header instanceof UpdateResponse) {
 			String lastid = ((UpdateResponse)header).getLastid();
@@ -689,7 +688,7 @@ public class MonetStatement extends Mone
 		}
 
 		try {
-			return new MonetVirtualResultSet(this, columns, types, results);
+			return new MonetVirtualResultSet(this, columns, types, jdbcTypes, results);
 		} catch (IllegalArgumentException e) {
 			throw new SQLException("Internal driver error: " + e.getMessage(), "M0M03");
 		}
@@ -823,7 +822,7 @@ public class MonetStatement extends Mone
 	 * @throws SQLException if a database access error occurs
 	 */
 	@Override
-	public ResultSet getResultSet() throws SQLException{
+	public ResultSet getResultSet() throws SQLException {
 		return (header instanceof ResultSetResponse) ? new MonetResultSet(this, (ResultSetResponse)header) : null;
 	}
 
@@ -1115,8 +1114,7 @@ public class MonetStatement extends Mone
 	}
 
 	/**
-	 * Returns a value indicating whether the Statement is poolable or
-	 * not.
+	 * Returns a value indicating whether the Statement is poolable or not.
 	 *
 	 * @return true if the Statement is poolable; false otherwise
 	 */
@@ -1207,8 +1205,9 @@ final class MonetVirtualResultSet extend
 	private String results[][];
 	private boolean closed;
 
-	MonetVirtualResultSet(Statement statement, String[] columns, String[] types, String[][] results) throws IllegalArgumentException {
-		super(statement, columns, types, results.length);
+	MonetVirtualResultSet(Statement statement, String[] columns, String[] types, int[] jdbcTypes, String[][] results)
+			throws IllegalArgumentException {
+		super(statement, columns, types, jdbcTypes, results.length);
 		this.results = results;
 		closed = false;
 	}
@@ -1250,9 +1249,8 @@ final class MonetVirtualResultSet extend
 	}
 
 	/**
-	 * Mainly here to prevent errors when the close method is called. There
-	 * is no real need for this object to close it. We simply remove our
-	 * resultset data.
+	 * Mainly here to prevent errors when the close method is called. There is no real need for this object to close it.
+	 * We simply remove our resultset data.
 	 */
 	@Override
 	public void close() {
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/EmbeddedConnection.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/EmbeddedConnection.java
@@ -4,7 +4,7 @@ import nl.cwi.monetdb.embedded.env.Monet
 import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedDatabase;
 import nl.cwi.monetdb.embedded.env.MonetDBEmbeddedException;
 import nl.cwi.monetdb.jdbc.MonetConnection;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.embedded.EmbeddedProtocol;
 
 import java.io.*;
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/MapiConnection.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/MapiConnection.java
@@ -4,7 +4,7 @@ import nl.cwi.monetdb.jdbc.MonetConnecti
 import nl.cwi.monetdb.mcl.io.BufferedMCLReader;
 import nl.cwi.monetdb.mcl.io.BufferedMCLWriter;
 import nl.cwi.monetdb.mcl.io.SocketConnection;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
 import nl.cwi.monetdb.mcl.protocol.oldmapi.OldMapiProtocol;
@@ -63,8 +63,6 @@ import java.util.*;
  *
  * @author Fabian Groffen
  * @version 4.1
- * @see BufferedMCLReader
- * @see BufferedMCLWriter
  */
 public class MapiConnection extends MonetConnection {
 
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/MonetDBConnectionFactory.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/MonetDBConnectionFactory.java
@@ -2,7 +2,7 @@ package nl.cwi.monetdb.mcl.connection;
 
 import nl.cwi.monetdb.jdbc.MonetConnection;
 import nl.cwi.monetdb.jdbc.MonetDriver;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 
 import java.io.File;
 import java.io.IOException;
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/io/AbstractMCLReader.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package nl.cwi.monetdb.mcl.io;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * Created by ferreira on 11/24/16.
- */
-public abstract class AbstractMCLReader extends BufferedReader {
-
-    /** "there is currently no line", or the the type is unknown is
-     represented by UNKNOWN */
-    public final static int UNKNOWN   = 0;
-    /** a line starting with ! indicates ERROR */
-    public final static int ERROR     = '!';
-    /** a line starting with % indicates HEADER */
-    public final static int HEADER    = '%';
-    /** a line starting with [ indicates RESULT */
-    public final static int RESULT    = '[';
-    /** a line which matches the pattern of prompt1 is a PROMPT */
-    public final static int PROMPT    = '.';
-    /** a line which matches the pattern of prompt2 is a MORE */
-    public final static int MORE      = ',';
-    /** a line starting with &amp; indicates the start of a header block */
-    public final static int SOHEADER  = '&';
-    /** a line starting with ^ indicates REDIRECT */
-    public final static int REDIRECT  = '^';
-    /** a line starting with # indicates INFO */
-    public final static int INFO      = '#';
-
-    /** The type of the last line read */
-    protected int lineType;
-
-    public AbstractMCLReader(Reader in) {
-        super(in);
-    }
-
-    /**
-     * getLineType returns the type of the last line read.
-     *
-     * @return an integer representing the kind of line this is, one of the
-     *         following constants: UNKNOWN, HEADER, ERROR, PROMPT,
-     *         RESULT, REDIRECT, INFO
-     */
-    public int getLineType() {
-        return lineType;
-    }
-
-    public abstract String waitForPrompt() throws IOException;
-}
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/io/AbstractMCLWriter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package nl.cwi.monetdb.mcl.io;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * Created by ferreira on 11/24/16.
- */
-public abstract class AbstractMCLWriter extends BufferedWriter {
-
-    protected AbstractMCLReader reader;
-
-    public AbstractMCLWriter(Writer out) {
-        super(out);
-    }
-
-    /**
-     * Registers the given reader in this writer.  A registered reader
-     * receives a linetype reset when a line is written from this
-     * writer.
-     *
-     * @param r an AbstractMCLReader
-     */
-    public void registerReader(AbstractMCLReader r) {
-        this.reader = r;
-    }
-
-    public abstract void writeLine(String line) throws IOException;
-}
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/io/BufferedMCLReader.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0.  If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.
- */
-
-package nl.cwi.monetdb.mcl.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Read text from a character-input stream, buffering characters so as
- * to provide a means for efficient reading of characters, arrays and
- * lines.  This class is based on the BufferedReader class, and provides
- * extra functionality useful for MCL.
- * 
- * The BufferedMCLReader is typically used as layer in between an
- * InputStream and a specific interpreter of the data.
- * <pre>
- *                         / Response
- * BufferedMCLReader ---o &lt;- Tuple
- *                         \ DataBlock
- * </pre>
- * Because the BufferedMCLReader provides an efficient way to access the
- * data from the stream in a line-wise fashion, whereby each line is
- * identified as a certain type, consumers can easily decide how to
- * parse each retrieved line.  The line parsers from
- * nl.cwi.monetdb.mcl.parser are well suited to work with the lines
- * outputted by the BufferedMCLReader.
- * This class is client-oriented, as it doesn't take into account the
- * messages as the server receives them.
- *
- * @author Fabian Groffen <Fabian.Groffen>
- * @see BufferedMCLWriter
- */
-public class BufferedMCLReader extends AbstractMCLReader {
-
-	/**
-	 * Create a buffering character-input stream that uses a
-	 * default-sized input buffer.
-	 *
-	 * @param in A Reader
-	 */
-	public BufferedMCLReader(Reader in) {
-		super(in);
-	}
-
-	/**
-	 * Create a buffering character-input stream that uses a
-	 * default-sized input buffer, from an InputStream.
-	 *
-	 * @param in An InputStream
-	 * @param enc Encoding
-	 */
-	public BufferedMCLReader(InputStream in, String enc)
-		throws UnsupportedEncodingException
-	{
-		super(new InputStreamReader(in, enc));
-	}
-
-	/**
-	 * Sets the linetype to the type of the string given.  If the string
-	 * is null, lineType is set to UNKNOWN.
-	 *
-	 * @param line the string to examine
-	 */
-	void setLineType(String line) {
-		lineType = UNKNOWN;
-		if (line == null || line.length() == 0)
-			return;
-		switch (line.charAt(0)) {
-			case '!':
-				lineType = ERROR;
-				break;
-			case '&':
-				lineType = SOHEADER;
-				break;
-			case '%':
-				lineType = HEADER;
-				break;
-			case '[':
-				lineType = RESULT;
-				break;
-			case '=':
-				lineType = RESULT;
-				break;
-			case '^':
-				lineType = REDIRECT;
-				break;
-			case '#':
-				lineType = INFO;
-				break;
-			case '.':
-				lineType = PROMPT;
-				break;
-			case ',':
-				lineType = MORE;
-				break;
-		}
-	}
-
-	/**
-	 * Read a line of text.  A line is considered to be terminated by
-	 * any one of a line feed ('\n'), a carriage return ('\r'), or a
-	 * carriage return followed immediately by a linefeed.  Before this
-	 * method returns, it sets the linetype to any of the in MCL
-	 * recognised line types.
-	 *
-	 * Warning: until the server properly prefixes all of its error
-	 * messages with SQLSTATE codes, this method prefixes all errors it
-	 * sees without sqlstate with the generic data exception code
-	 * (22000).
-	 *
-	 * @return A String containing the contents of the line, not
-	 *         including any line-termination characters, or null if the
-	 *         end of the stream has been reached
-	 * @throws IOException If an I/O error occurs
-	 */
-	@Override
-	public String readLine() throws IOException {
-		String r = super.readLine();
-		this.setLineType(r);
-		if (lineType == ERROR && !r.matches("^![0-9A-Z]{5}!.+"))
-			r = "!22000!" + r.substring(1);
-		return r;
-	}
-
-	/**
-	 * Reads up till the MonetDB prompt, indicating the server is ready
-	 * for a new command.  All read data is discarded.  If the last line
-	 * read by readLine() was a prompt, this method will immediately
-	 * return.
-	 *
-	 * If there are errors present in the lines that are read, then they
-	 * are put in one string and returned <b>after</b> the prompt has
-	 * been found. If no errors are present, null will be returned.
-	 *
-	 * @return a string containing error messages, or null if there aren't any
-	 * @throws IOException if an IO exception occurs while talking to the server
-	 */
-	@Override
-	public synchronized String waitForPrompt() throws IOException {
-		StringBuilder res = new StringBuilder();
-		String tmp;
-		while (lineType != PROMPT) {
-			if ((tmp = this.readLine()) == null)
-				throw new IOException("Connection to server lost!");
-			if (lineType == ERROR)
-				res.append("\n").append(tmp.substring(1));
-		}
-		return res.toString().trim();
-	}
-}
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/io/BufferedMCLWriter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0.  If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.
- */
-
-package nl.cwi.monetdb.mcl.io;
-
-import java.io.*;
-
-/**
- * Write text to a character-output stream, buffering characters so as
- * to provide a means for efficient writing of single characters,
- * arrays, and strings.
- *
- * In contrast to the BufferedWriter class, this class' newLine()
- * method always writes the newline character '\n', regardless the
- * platform's own notion of line separator.  Apart from that there are
- * no differences in the behaviour of this class, compared to its parent
- * class, the BufferedWriter.  A small convenience is built into this
- * class for cooperation with the BufferedMCLReader, via the
- * registerReader() method.  It causes the reader to be reset upon each
- * write performed though this class.  This effectuates the MCL protocol
- * flow where a write invalidates the state of the read buffers, since
- * each write must be answered by the server.  That also makes this
- * class client-oriented when a reader is registered.
- *
- * @author Fabian Groffen <Fabian.Groffen>
- * @see BufferedMCLWriter
- */
-public class BufferedMCLWriter extends AbstractMCLWriter {
-
-	/**
-	 * Create a buffered character-output stream that uses a
-	 * default-sized output buffer.
-	 *
-	 * @param in A Writer
-	 */
-	public BufferedMCLWriter(Writer in) {
-		super(in);
-	}
-
-	/**
-	 * Create a buffered character-output stream that uses a
-	 * default-sized output buffer, from an OutputStream.
-	 *
-	 * @param in An OutputStream
-	 * @param enc Encoding
-	 */
-	public BufferedMCLWriter(OutputStream in, String enc)
-		throws UnsupportedEncodingException
-	{
-		super(new OutputStreamWriter(in, enc));
-	}
-
-	/**
-	 * Write a line separator.  The line separator string is in this
-	 * class always the single newline character '\n'.
-	 *
-	 * @throws IOException If an I/O error occurs
-	 */
-	@Override
-	public void newLine() throws IOException {
-		this.write('\n');
-	}
-
-	@Override
-	public void writeLine(String line) throws IOException {
-		this.write(line);
-		this.flush();
-		// reset reader state, last line isn't valid any more now
-		if (reader != null) ((BufferedMCLReader)reader).setLineType(null);
-	}
-}
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/parser/HeaderLineParser.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package nl.cwi.monetdb.mcl.parser;
-
-/**
- * Created by ferreira on 11/25/16.
- */
-public abstract class HeaderLineParser extends MCLParser {
-
-    public final static int NAME       = 1;
-    public final static int LENGTH     = 2;
-    public final static int TABLE      = 3;
-    public final static int TYPE       = 4;
-
-    protected int type;
-
-    /**
-     * Creates an MCLParser targeted at a given number of field values.
-     * The lines parsed by an instance of this MCLParser should have
-     * exactly capacity field values.
-     *
-     * @param capacity the number of field values to expect
-     */
-    protected HeaderLineParser(int capacity) {
-        super(capacity);
-    }
-}
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/parser/MCLParser.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0.  If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.
- */
-
-package nl.cwi.monetdb.mcl.parser;
-
-/**
- * Interface for parsers in MCL.  The parser family in MCL is set up as
- * a reusable object.  This allows the same parser to be used again for
- * the same type of work.  While this is a very unnatural solution in
- * the Java language, it prevents many object creations on a low level
- * of the protocol.  This favours performance.
- * 
- * A typical parser has a method parse() which takes a String, and the
- * methods hasNext() and next() to retrieve the values that were
- * extracted by the parser.  Parser specific methods may be available to
- * perform common tasks.
- *
- * @author Fabian Groffen
- */
-public abstract class MCLParser {
-	/** The String values found while parsing.  Public, you may touch it. */
-	public final String values[];
-	/** The int values found while parsing.  Public, you may touch it. */
-	public final int intValues[];
-
-	protected int colnr;
-
-	/**
-	 * Creates an MCLParser targeted at a given number of field values.
-	 * The lines parsed by an instance of this MCLParser should have
-	 * exactly capacity field values.
-	 *
-	 * @param capacity the number of field values to expect
-	 */
-	protected MCLParser(int capacity) {
-		values = new String[capacity];
-		intValues = new int[capacity];
-	}
-
-	/**
-	 * Parse the given string, and populate the internal field array
-	 * to allow for next() and hasNext() calls.
-	 *
-	 * @param source the String containing the line to parse
-	 * @return value
-	 * @throws MCLParseException if source cannot be (fully) parsed by
-	 * this parser
-	 * @see #next()
-	 * @see #nextInt()
-	 * @see #hasNext()
-	 */
-	public abstract int parse(String source) throws MCLParseException;
-
-	/**
-	 * Repositions the internal field offset to the start, such that the
-	 * next call to next() will return the first field again.
-	 */
-	public final void reset() {
-		colnr = 0;
-	}
-
-	/**
-	 * Returns whether the next call to next() or nextInt() succeeds.
-	 *
-	 * @return true if the next call to next() or nextInt() is bound to
-	 * succeed
-	 * @see #next()
-	 * @see #nextInt()
-	 */
-	public final boolean hasNext() {
-		return colnr < values.length;
-	}
-
-	/**
-	 * Returns the current field value, and advances the field counter
-	 * to the next value.  This method may fail with a RuntimeError if
-	 * the current field counter is out of bounds.  Call hasNext() to
-	 * determine if the call to next() will succeed.
-	 *
-	 * @return the current field value
-	 * @see #nextInt()
-	 * @see #hasNext()
-	 */
-	public final String next() {
-		return values[colnr++];
-	}
-
-	/**
-	 * Returns the current field value as integer, and advances the
-	 * field counter to the next value.  This method has the same
-	 * characteristics as the next() method, apart from returning the
-	 * field value as an integer.
-	 *
-	 * @return the current field value as integer
-	 * @see #next()
-	 */
-	public final int nextInt() {
-		return intValues[colnr++];
-	}
-}
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/parser/TupleLineParser.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package nl.cwi.monetdb.mcl.parser;
-
-/**
- * Created by ferreira on 11/25/16.
- */
-public abstract class TupleLineParser extends MCLParser {
-    /**
-     * Creates an MCLParser targeted at a given number of field values.
-     * The lines parsed by an instance of this MCLParser should have
-     * exactly capacity field values.
-     *
-     * @param capacity the number of field values to expect
-     */
-    protected TupleLineParser(int capacity) {
-        super(capacity);
-    }
-}
deleted file mode 100644
--- a/src/main/java/nl/cwi/monetdb/mcl/parser/socket/SocketTupleLineParser.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0.  If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.
- */
-
-package nl.cwi.monetdb.mcl.parser.socket;
-
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
-import nl.cwi.monetdb.mcl.parser.TupleLineParser;
-
-/**
- * The SocketTupleLineParser extracts the values from a given tuple.  The
- * number of values that are expected are known upfront to speed up
- * allocation and validation.
- *
- * @author Fabian Groffen <Fabian.Groffen>
- */
-public class SocketTupleLineParser extends TupleLineParser {
-
-	/**
-	 * Constructs a SocketTupleLineParser which expects columncount columns.
-	 *
-	 * @param columncount the number of columns in the to be parsed string
-	 */
-	public SocketTupleLineParser(int columncount) {
-		super(columncount);
-	}
-
-	/**
-	 * Parses the given String source as tuple line.  If source cannot
-	 * be parsed, a ParseException is thrown.  The columncount argument
-	 * is used for allocation of the returned array.  While this seems
-	 * illogical, the caller should know this size, since the
-	 * StartOfHeader contains this information.
-	 *
-	 * @param source a String which should be parsed
-	 * @return 0, as there is no 'type' of TupleLine
-	 * @throws MCLParseException if an error occurs during parsing
-	 */
-	@Override
-	public int parse(String source) throws MCLParseException {
-		int len = source.length();
-		char[] chrLine = new char[len];
-		source.getChars(0, len, chrLine, 0);
-
-		// first detect whether this is a single value line (=) or a
-		// real tuple ([)
-		if (chrLine[0] == '=') {
-			if (values.length != 1)
-				throw new MCLParseException(values.length +
-						" columns expected, but only single value found");
-
-			// return the whole string but the leading =
-			values[0] = source.substring(1);
-
-			// reset colnr
-			reset();
-
-			return 0;
-		}
-
-		// extract separate fields by examining string, char for char
-		boolean inString = false, escaped = false;
-		int cursor = 2, column = 0, i = 2;
-		StringBuilder uesc = new StringBuilder();
-		for (; i < len; i++) {
-			switch(chrLine[i]) {
-				default:
-					escaped = false;
-				break;
-				case '\\':
-					escaped = !escaped;
-				break;
-				case '"':
-					/**
-					 * If all strings are wrapped between two quotes, a \" can
-					 * never exist outside a string. Thus if we believe that we
-					 * are not within a string, we can safely assume we're about
-					 * to enter a string if we find a quote.
-					 * If we are in a string we should stop being in a string if
-					 * we find a quote which is not prefixed by a \, for that
-					 * would be an escaped quote. However, a nasty situation can
-					 * occur where the string is like "test \\" as obvious, a
-					 * test for a \ in front of a " doesn't hold here for all
-					 * cases. Because "test \\\"" can exist as well, we need to
-					 * know if a quote is prefixed by an escaping slash or not.
-					 */
-					if (!inString) {
-						inString = true;
-					} else if (!escaped) {
-						inString = false;
-					}
-
-					// reset escaped flag
-					escaped = false;
-				break;
-				case '\t':
-					if (!inString &&
-						(i > 0 && chrLine[i - 1] == ',') ||
-						(i + 1 == len - 1 && chrLine[++i] == ']')) // dirty
-					{
-						// split!
-						if (chrLine[cursor] == '"' &&
-							chrLine[i - 2] == '"')
-						{
-							// reuse the StringBuilder by cleaning it
-							uesc.delete(0, uesc.length());
-							// prevent capacity increasements
-							uesc.ensureCapacity((i - 2) - (cursor + 1));
-							for (int pos = cursor + 1; pos < i - 2; pos++) {
-								if (chrLine[pos] == '\\' && pos + 1 < i - 2) {
-									pos++;
-									// strToStr and strFromStr in gdk_atoms.mx only
-									// support \t \n \\ \" and \377
-									switch (chrLine[pos]) {
-										case '\\':
-											uesc.append('\\');
-										break;
-										case 'n':
-											uesc.append('\n');
-										break;
-										case 't':
-											uesc.append('\t');
-										break;
-										case '"':
-											uesc.append('"');
-										break;
-										case '0': case '1': case '2': case '3':
-											// this could be an octal number, let's check it out
-											if (pos + 2 < i - 2 &&
-												chrLine[pos + 1] >= '0' && chrLine[pos + 1] <= '7' &&
-												chrLine[pos + 2] >= '0' && chrLine[pos + 2] <= '7'
-											) {
-												// we got the number!
-												try {
-													uesc.append((char)(Integer.parseInt("" + chrLine[pos] + chrLine[pos + 1] + chrLine[pos + 2], 8)));
-													pos += 2;
-												} catch (NumberFormatException e) {
-													// hmmm, this point should never be reached actually...
-													throw new AssertionError("Flow error, should never try to parse non-number");
-												}
-											} else {
-												// do default action if number seems not to be correct
-												uesc.append(chrLine[pos]);
-											}
-										break;
-										default:
-											// this is wrong, just ignore the escape, and print the char
-											uesc.append(chrLine[pos]);
-										break;
-									}
-								} else {
-									uesc.append(chrLine[pos]);
-								}
-							}
-
-							// put the unescaped string in the right place
-							values[column++] = uesc.toString();
-						} else if ((i - 1) - cursor == 4 &&
-								source.indexOf("NULL", cursor) == cursor)
-						{
-							values[column++] = null;
-						} else {
-							values[column++] =
-								source.substring(cursor, i - 1);
-						}
-						cursor = i + 1;
-					}
-
-					// reset escaped flag
-					escaped = false;
-				break;
-			}
-		}
-		// check if this result is of the size we expected it to be
-		if (column != values.length)
-			throw new MCLParseException("illegal result length: " + column + "\nlast read: " + (column > 0 ? values[column - 1] : "<none>"));
-
-		// reset colnr
-		reset();
-		
-		return 0;
-	}
-}
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java
@@ -1,7 +1,6 @@
 package nl.cwi.monetdb.mcl.protocol;
 
 import nl.cwi.monetdb.jdbc.MonetConnection;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
 import nl.cwi.monetdb.mcl.responses.AutoCommitResponse;
 import nl.cwi.monetdb.mcl.responses.SchemaResponse;
 import nl.cwi.monetdb.mcl.responses.UpdateResponse;
@@ -35,8 +34,7 @@ public abstract class AbstractProtocol<T
 
     public abstract StarterHeaders getNextStarterHeader();
 
-
-    public abstract ResultSetResponse<T> getNextResultSetResponse(MonetConnection con, MonetConnection.ResponseList list, int seqnr) throws MCLParseException;
+    public abstract ResultSetResponse getNextResultSetResponse(MonetConnection con, MonetConnection.ResponseList list, int seqnr) throws MCLParseException;
 
     public abstract UpdateResponse getNextUpdateResponse() throws MCLParseException;
 
@@ -46,15 +44,13 @@ public abstract class AbstractProtocol<T
 
     public abstract AutoCommitResponse getNextAutoCommitResponse() throws MCLParseException;
 
-    public abstract DataBlockResponse<T> getNextDatablockResponse(Map<Integer, ResultSetResponse> rsresponses) throws MCLParseException;
-
+    public abstract DataBlockResponse getNextDatablockResponse(Map<Integer, ResultSetResponse> rsresponses) throws MCLParseException;
 
     public abstract TableResultHeaders getNextTableHeader(Object line, String[] stringValues, int[] intValues) throws MCLParseException;
 
-    public abstract void parseTupleLine(Object line, Object[] values) throws MCLParseException;
+    public abstract int parseTupleLine(Object line, Object[] values, int[] typesMap) throws MCLParseException;
 
     public abstract String getRemainingStringLine(int startIndex);
 
     public abstract void writeNextCommand(byte[] prefix, byte[] query, byte[] suffix) throws IOException;
-
 }
rename from src/main/java/nl/cwi/monetdb/mcl/parser/MCLParseException.java
rename to src/main/java/nl/cwi/monetdb/mcl/protocol/MCLParseException.java
--- a/src/main/java/nl/cwi/monetdb/mcl/parser/MCLParseException.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/MCLParseException.java
@@ -6,7 +6,7 @@
  * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.
  */
 
-package nl.cwi.monetdb.mcl.parser;
+package nl.cwi.monetdb.mcl.protocol;
 
 import java.text.ParseException;
 
@@ -20,9 +20,7 @@ import java.text.ParseException;
  * that the error message includes the offending data read.
  */
 public class MCLParseException extends ParseException {
-	/**
-	 * 
-	 */
+
 	private static final long serialVersionUID = 1L;
 
 	public MCLParseException(String e) {
--- 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,7 +1,8 @@
 package nl.cwi.monetdb.mcl.protocol.embedded;
 
 import nl.cwi.monetdb.jdbc.MonetConnection;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.io.JDBCEmbeddedConnection;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
 import nl.cwi.monetdb.mcl.protocol.StarterHeaders;
 import nl.cwi.monetdb.mcl.protocol.TableResultHeaders;
@@ -18,6 +19,16 @@ import java.util.Map;
  */
 public class EmbeddedProtocol extends AbstractProtocol<Object[]> {
 
+    private final JDBCEmbeddedConnection connection;
+
+    public EmbeddedProtocol(JDBCEmbeddedConnection con) {
+        this.connection = con;
+    }
+
+    public JDBCEmbeddedConnection getEmbeddedConnection() {
+        return this.connection;
+    }
+
     @Override
     public void fetchNextResponseData() {
 
@@ -34,7 +45,7 @@ public class EmbeddedProtocol extends Ab
     }
 
     @Override
-    public ResultSetResponse<Object[]> getNextResultSetResponse(MonetConnection con, MonetConnection.ResponseList list, int seqnr) throws MCLParseException {
+    public ResultSetResponse getNextResultSetResponse(MonetConnection con, MonetConnection.ResponseList list, int seqnr) throws MCLParseException {
         return null;
     }
 
@@ -49,7 +60,7 @@ public class EmbeddedProtocol extends Ab
     }
 
     @Override
-    public DataBlockResponse<Object[]> getNextDatablockResponse(Map<Integer, ResultSetResponse> rsresponses) throws MCLParseException {
+    public DataBlockResponse getNextDatablockResponse(Map<Integer, ResultSetResponse> rsresponses) throws MCLParseException {
         return null;
     }
 
@@ -59,8 +70,8 @@ public class EmbeddedProtocol extends Ab
     }
 
     @Override
-    public void parseTupleLine(Object line, Object[] values) throws MCLParseException {
-
+    public int parseTupleLine(Object line, Object[] values) throws MCLParseException {
+        return 0;
     }
 
     @Override
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java
@@ -1,7 +1,8 @@
 package nl.cwi.monetdb.mcl.protocol.newmapi;
 
 import nl.cwi.monetdb.jdbc.MonetConnection;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.io.SocketConnection;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
 import nl.cwi.monetdb.mcl.protocol.StarterHeaders;
 import nl.cwi.monetdb.mcl.protocol.TableResultHeaders;
@@ -18,6 +19,12 @@ import java.util.Map;
  */
 public class NewMapiProtocol extends AbstractProtocol {
 
+    private final SocketConnection connection;
+
+    public NewMapiProtocol(SocketConnection con) {
+        this.connection = con;
+    }
+
     @Override
     public void fetchNextResponseData() {
 
@@ -54,8 +61,8 @@ public class NewMapiProtocol extends Abs
     }
 
     @Override
-    public void parseTupleLine(Object line, Object[] values) throws MCLParseException {
-
+    public int parseTupleLine(Object line, Object[] values) throws MCLParseException {
+        return 0;
     }
 
     @Override
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
@@ -2,7 +2,7 @@ package nl.cwi.monetdb.mcl.protocol.oldm
 
 import nl.cwi.monetdb.jdbc.MonetConnection;
 import nl.cwi.monetdb.mcl.io.SocketConnection;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
 import nl.cwi.monetdb.mcl.protocol.StarterHeaders;
@@ -25,13 +25,16 @@ public class OldMapiProtocol extends Abs
 
     private final SocketConnection connection;
 
-    StringBuilder builder;
+    final StringBuilder builder;
 
     int currentPointer = 0;
 
+    final StringBuilder tupleLineBuilder;
+
     public OldMapiProtocol(SocketConnection con) {
         this.connection = con;
         this.builder = new StringBuilder(STRING_BUILDER_INITIAL_SIZE);
+        this.tupleLineBuilder = new StringBuilder(STRING_BUILDER_INITIAL_SIZE);
     }
 
     public SocketConnection getConnection() {
@@ -78,17 +81,18 @@ public class OldMapiProtocol extends Abs
     }
 
     @Override
-    public ResultSetResponse<StringBuilder> getNextResultSetResponse(MonetConnection con, MonetConnection.ResponseList list, int seqnr) throws MCLParseException {
+    public ResultSetResponse getNextResultSetResponse(MonetConnection con, MonetConnection.ResponseList list, int seqnr)
+            throws MCLParseException {
         int id = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
         int tuplecount = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
         int columncount = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
         int rowcount = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
-        return new ResultSetResponse<>(con, list, seqnr, id, rowcount, tuplecount, columncount);
+        return new ResultSetResponse(con, list, seqnr, id, rowcount, tuplecount, columncount);
     }
 
     @Override
     public UpdateResponse getNextUpdateResponse() throws MCLParseException {
-        int count = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
+        int count = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this); //The order cannot be switched!!
         String lastId = OldMapiStartOfHeaderParser.GetNextResponseDataAsString(this);
         return new UpdateResponse(lastId, count);
     }
@@ -100,19 +104,17 @@ public class OldMapiProtocol extends Abs
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public DataBlockResponse<StringBuilder> getNextDatablockResponse(Map<Integer, ResultSetResponse> rsresponses) throws MCLParseException {
+    public DataBlockResponse getNextDatablockResponse(Map<Integer, ResultSetResponse> rsresponses) throws MCLParseException {
         int id = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
-        OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);	// pass the columncount --- Must do this!
+        int columncount = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
         int rowcount = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
         int offset = OldMapiStartOfHeaderParser.GetNextResponseDataAsInt(this);
-        ResultSetResponse<StringBuilder> resultSetResponse = rsresponses.get(id);
-        if (resultSetResponse == null) {
+
+        ResultSetResponse rs = rsresponses.get(id);
+        if (rs == null) {
             return null;
         }
-        DataBlockResponse<StringBuilder> res = new DataBlockResponse<>(rowcount, resultSetResponse.getRSType() == ResultSet.TYPE_FORWARD_ONLY, StringBuilder.class);
-        resultSetResponse.addDataBlockResponse(offset, res);
-        return res;
+        return rs.addDataBlockResponse(offset, rowcount, columncount, this);
     }
 
     @Override
@@ -121,8 +123,8 @@ public class OldMapiProtocol extends Abs
     }
 
     @Override
-    public void parseTupleLine(Object line, Object[] values) throws MCLParseException {
-
+    public int parseTupleLine(Object line, Object[] values, int[] typesMap) throws MCLParseException {
+        return OldMapiTupleLineParser.OldMapiParseTupleLine((StringBuilder) line, values, this.tupleLineBuilder, typesMap);
     }
 
     @Override
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java
@@ -5,7 +5,7 @@ import nl.cwi.monetdb.mcl.protocol.Serve
 /**
  * Created by ferreira on 11/30/16.
  */
-public final class OldMapiServerResponseParser {
+final class OldMapiServerResponseParser {
 
     static ServerResponses ParseOldMapiServerResponse(OldMapiProtocol protocol) {
         ServerResponses res;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
@@ -1,12 +1,12 @@
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
 
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.StarterHeaders;
 
 /**
  * Created by ferreira on 12/6/16.
  */
-public class OldMapiStartOfHeaderParser {
+final class OldMapiStartOfHeaderParser {
 
     static StarterHeaders GetNextStartHeaderOnOldMapi(OldMapiProtocol protocol) {
         StarterHeaders res;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java
@@ -1,12 +1,12 @@
 package nl.cwi.monetdb.mcl.protocol.oldmapi;
 
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.TableResultHeaders;
 
 /**
  * Created by ferreira on 12/6/16.
  */
-public class OldMapiTableHeaderParser {
+final class OldMapiTableHeaderParser {
 
     static TableResultHeaders GetNextTableHeader(StringBuilder builder, String[] stringValues, int[] intValues) throws MCLParseException {
         TableResultHeaders res = TableResultHeaders.UNKNOWN;
new file mode 100644
--- /dev/null
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
@@ -0,0 +1,131 @@
+package nl.cwi.monetdb.mcl.protocol.oldmapi;
+
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
+
+/**
+ * Created by ferreira on 12/6/16.
+ */
+final class OldMapiTupleLineParser {
+
+    static int OldMapiParseTupleLine(StringBuilder line, Object[] values, StringBuilder helper, int[] typesMap) throws MCLParseException {
+        int len = line.length();
+
+        // first detect whether this is a single value line (=) or a real tuple ([)
+        if (line.charAt(0) == '=') {
+            if (values.length != 1) {
+                throw new MCLParseException(values.length + " columns expected, but only single value found");
+            }
+            // return the whole string but the leading =
+            values[0] = line.substring(1);
+            return 1;
+        }
+
+        // extract separate fields by examining string, char for char
+        boolean inString = false, escaped = false;
+        int cursor = 2, column = 0, i = 2;
+        for (; i < len; i++) {
+            switch(line.charAt(i)) {
+                default:
+                    escaped = false;
+                    break;
+                case '\\':
+                    escaped = !escaped;
+                    break;
+                case '"':
+                    /**
+                     * If all strings are wrapped between two quotes, a \" can
+                     * never exist outside a string. Thus if we believe that we
+                     * are not within a string, we can safely assume we're about
+                     * to enter a string if we find a quote.
+                     * If we are in a string we should stop being in a string if
+                     * we find a quote which is not prefixed by a \, for that
+                     * would be an escaped quote. However, a nasty situation can
+                     * occur where the string is like "test \\" as obvious, a
+                     * test for a \ in front of a " doesn't hold here for all
+                     * cases. Because "test \\\"" can exist as well, we need to
+                     * know if a quote is prefixed by an escaping slash or not.
+                     */
+                    if (!inString) {
+                        inString = true;
+                    } else if (!escaped) {
+                        inString = false;
+                    }
+
+                    // reset escaped flag
+                    escaped = false;
+                    break;
+                case '\t':
+                    if (!inString && (i > 0 && line.charAt(i - 1) == ',') || (i + 1 == len - 1 && line.charAt(++i) == ']')) { // dirty
+                        // split!
+                        if (line.charAt(cursor) == '"' && line.charAt(i - 2) == '"') {
+                            // reuse the StringBuilder by cleaning it
+                            helper.setLength(0);
+                            // prevent capacity increases
+                            helper.ensureCapacity((i - 2) - (cursor + 1));
+                            for (int pos = cursor + 1; pos < i - 2; pos++) {
+                                if (line.charAt(pos) == '\\' && pos + 1 < i - 2) {
+                                    pos++;
+                                    // strToStr and strFromStr in gdk_atoms.mx only
+                                    // support \t \n \\ \" and \377
+                                    switch (line.charAt(pos)) {
+                                        case '\\':
+                                            helper.append('\\');
+                                            break;
+                                        case 'n':
+                                            helper.append('\n');
+                                            break;
+                                        case 't':
+                                            helper.append('\t');
+                                            break;
+                                        case '"':
+                                            helper.append('"');
+                                            break;
+                                        case '0': case '1': case '2': case '3':
+                                            // this could be an octal number, let's check it out
+                                            if (pos + 2 < i - 2 &&
+                                                    line.charAt(pos + 1) >= '0' && line.charAt(pos + 1) <= '7' &&
+                                                    line.charAt(pos + 2) >= '0' && line.charAt(pos + 2) <= '7') {
+                                                // we got the number!
+                                                try {
+                                                    helper.append((char)(Integer.parseInt("" + line.charAt(pos) + line.charAt(pos + 1) + line.charAt(pos + 2), 8)));
+                                                    pos += 2;
+                                                } catch (NumberFormatException e) {
+                                                    // hmmm, this point should never be reached actually...
+                                                    throw new AssertionError("Flow error, should never try to parse non-number");
+                                                }
+                                            } else {
+                                                // do default action if number seems not to be correct
+                                                helper.append(line.charAt(pos));
+                                            }
+                                            break;
+                                        default:
+                                            // this is wrong, just ignore the escape, and print the char
+                                            helper.append(line.charAt(pos));
+                                            break;
+                                    }
+                                } else {
+                                    helper.append(line.charAt(pos));
+                                }
+                            }
+
+                            // put the unescaped string in the right place
+                            values[column++] = helper.toString();
+                        } else if ((i - 1) - cursor == 4 && line.indexOf("NULL", cursor) == cursor) {
+                            values[column++] = null;
+                        } else {
+                            values[column++] = line.substring(cursor, i - 1);
+                        }
+                        cursor = i + 1;
+                    }
+                    // reset escaped flag
+                    escaped = false;
+                    break;
+            }
+        }
+        // check if this result is of the size we expected it to be
+        if (column != values.length)
+            throw new MCLParseException("illegal result length: " + column + "\nlast read: " + (column > 0 ? values[column - 1] : "<none>"));
+
+        return column;
+    }
+}
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java
@@ -1,9 +1,9 @@
 package nl.cwi.monetdb.mcl.responses;
 
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
 
-import java.lang.reflect.Array;
 import java.sql.SQLException;
 
 /**
@@ -23,48 +23,51 @@ import java.sql.SQLException;
  * rows from it.  When multiple threads will retrieve rows from this
  * object, it is possible for threads to get the same data.
  */
-public class DataBlockResponse<T> implements IIncompleteResponse {
+public class DataBlockResponse implements IIncompleteResponse {
 
-    /** The String array to keep the data in */
-    private final T[] data;
+    /** The array to keep the data in */
+    private final Object[][] data;
     /** The counter which keeps the current position in the data array */
     private int pos;
     /** Whether we can discard lines as soon as we have read them */
     private boolean forwardOnly;
+    /** The connection protocol to parse the tuple lines */
+    private final AbstractProtocol<?> protocol;
+    /** The JdbcSQLTypes mapping */
+    private final int[] jdbcSQLTypes;
 
     /**
      * Constructs a DataBlockResponse object
-     * @param size the size of the data array to create
+     * @param rowcount the number of rows
+     * @param columncount the number of columns
      * @param forward whether this is a forward only result
      */
-    @SuppressWarnings("unchecked")
-    public DataBlockResponse(int size, boolean forward, Class<T> jClass) {
+    DataBlockResponse(int rowcount, int columncount, boolean forward, AbstractProtocol<?> protocol, int[] JdbcSQLTypes) {
         this.pos = -1;
-        this.data = (T[]) Array.newInstance(jClass, size);
         this.forwardOnly = forward;
+        this.data = new Object[rowcount][columncount];
+        this.protocol = protocol;
+        this.jdbcSQLTypes = JdbcSQLTypes;
     }
 
     /**
-     * addLine adds a String of data to this object's data array.
-     * Note that an IndexOutOfBoundsException can be thrown when an
-     * attempt is made to add more than the original construction size
-     * specified.
+     * addLine adds a String of data to this object's data array. Note that an IndexOutOfBoundsException can be thrown
+     * when an attempt is made to add more than the original construction size specified.
      *
      * @param line the header line as String
      * @param response the line type according to the MAPI protocol
      * @throws MCLParseException If the result line is not expected
      */
-    @SuppressWarnings("unchecked")
     public void addLine(ServerResponses response, Object line) throws MCLParseException {
         if (response != ServerResponses.RESULT)
             throw new MCLParseException("protocol violation: unexpected line in data block: " + line.toString());
         // add to the backing array
-        data[++pos] = (T) line;
+        Object[] next = this.data[++this.pos];
+        this.protocol.parseTupleLine(line, next, this.jdbcSQLTypes);
     }
 
     /**
-     * Returns whether this Response expects more lines to be added
-     * to it.
+     * Returns whether this Response expects more lines to be added to it.
      *
      * @return true if a next line should be added, false otherwise
      */
@@ -75,10 +78,8 @@ public class DataBlockResponse<T> implem
     }
 
     /**
-     * Indicates that no more header lines will be added to this
-     * Response implementation.  In most cases this is a redundant
-     * operation because the data array is full.  However... it can
-     * happen that this is NOT the case!
+     * Indicates that no more header lines will be added to this Response implementation. In most cases this is a
+     * redundant operation because the data array is full.  However... it can happen that this is NOT the case!
      *
      * @throws SQLException if not all rows are filled
      */
@@ -90,8 +91,7 @@ public class DataBlockResponse<T> implem
     }
 
     /**
-     * Instructs the Response implementation to close and do the
-     * necessary clean up procedures.
+     * Instructs the Response implementation to close and do the necessary clean up procedures.
      */
     @Override
     public void close() {
@@ -102,16 +102,15 @@ public class DataBlockResponse<T> implem
     }
 
     /**
-     * Retrieves the required row.  Warning: if the requested rows
-     * is out of bounds, an IndexOutOfBoundsException will be
-     * thrown.
+     * Retrieves the required row.  Warning: if the requested rows is out of bounds, an IndexOutOfBoundsException will
+     * be thrown.
      *
      * @param line the row to retrieve
      * @return the requested row as String
      */
-    public T getRow(int line) {
+    Object[] getRow(int line) {
         if (forwardOnly) {
-            T ret = data[line];
+            Object[] ret = data[line];
             data[line] = null;
             return ret;
         } else {
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/IIncompleteResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/IIncompleteResponse.java
@@ -1,6 +1,6 @@
 package nl.cwi.monetdb.mcl.responses;
 
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
 
 import java.sql.SQLException;
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java
@@ -1,13 +1,14 @@
 package nl.cwi.monetdb.mcl.responses;
 
 import nl.cwi.monetdb.jdbc.MonetConnection;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
+import nl.cwi.monetdb.jdbc.MonetDriver;
+import nl.cwi.monetdb.mcl.protocol.AbstractProtocol;
+import nl.cwi.monetdb.mcl.protocol.MCLParseException;
 import nl.cwi.monetdb.mcl.protocol.ServerResponses;
 
-import java.lang.reflect.Array;
-import java.lang.reflect.ParameterizedType;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Types;
 
 /**
  * The ResultSetResponse represents a tabular result sent by the
@@ -21,16 +22,9 @@ import java.sql.SQLException;
  * there the first line consists out of<br />
  * <tt>&amp;"qt" "id" "tc" "cc" "rc"</tt>.
  */
-public class ResultSetResponse<T> implements IIncompleteResponse {
+public class ResultSetResponse implements IIncompleteResponse {
 
-    private static boolean CheckBooleanValuesAllTrue(boolean[] array) {
-        for (boolean anArray : array) {
-            if (!anArray) {
-                return false;
-            }
-        }
-        return true;
-    }
+    private static final byte IsSetFinalValue = 15;
 
     /** The number of columns in this result */
     private final int columncount;
@@ -46,6 +40,8 @@ public class ResultSetResponse<T> implem
     private final String[] name;
     /** The types of the columns in this result */
     private final String[] type;
+    /** The JDBC SQL types of the columns in this ResultSet. The content will be derived from the MonetDB types[] */
+    private final int[] JdbcSQLTypes;
     /** The max string length for each column in this result */
     private final int[] columnLengths;
     /** The table for each column in this result */
@@ -53,7 +49,7 @@ public class ResultSetResponse<T> implem
     /** The query sequence number */
     private final int seqnr;
     /** A bitmap telling whether the headers are set or not */
-    private boolean[] isSet = new boolean[4];
+    private byte isSet;
     /** Whether this Response is closed */
     private boolean closed;
 
@@ -68,7 +64,7 @@ public class ResultSetResponse<T> implem
     /** the offset to be used on Xexport queries */
     private int blockOffset = 0;
     /** A List of result blocks (chunks of size fetchSize/cacheSize) */
-    private DataBlockResponse<T>[] resultBlocks;
+    private final DataBlockResponse[] resultBlocks;
 
     /**
      * Sole constructor, which requires a MonetConnection parent to
@@ -82,15 +78,13 @@ public class ResultSetResponse<T> implem
      *               supply new result blocks when necessary
      * @param seq the query sequence number
      */
-    @SuppressWarnings("unchecked")
-    public ResultSetResponse(MonetConnection con, MonetConnection.ResponseList parent, int id, int seq, int rowcount, int tuplecount, int columncount) {
+    public ResultSetResponse(MonetConnection con, MonetConnection.ResponseList parent, int id, int seq, int rowcount,
+                             int tuplecount, int columncount) {
         this.con = con;
         this.parent = parent;
         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. */
+            /* 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();
             cacheSizeSetExplicitly = false;
         } else {
@@ -98,14 +92,10 @@ public class ResultSetResponse<T> implem
             cacheSizeSetExplicitly = true;
         }
 
-        /* So far, so good.  Now the problem with EXPLAIN, DOT, etc
-         * queries is, that they don't support any block fetching,
-         * so we need to always fetch everything at once.  For that
-         * reason, the cache size is here set to the rowcount if
-         * it's larger, such that we do a full fetch at once.
-         * (Because we always set a reply_size, we can only get a
-         * larger rowcount from the server if it doesn't paginate,
-         * because it's a pseudo SQL result.) */
+        /* So far, so good.  Now the problem with EXPLAIN, DOT, etc queries is, that they don't support any block
+           fetching, so we need to always fetch everything at once.  For that reason, the cache size is here set to the
+           rowcount if it's larger, such that we do a full fetch at once. (Because we always set a reply_size, we can
+           only get a larger rowcount from the server if it doesn't paginate, because it's a pseudo SQL result.) */
         if (rowcount > cacheSize) {
             cacheSize = rowcount;
         }
@@ -122,48 +112,63 @@ public class ResultSetResponse<T> implem
         this.type = new String[this.columncount];
         this.tableNames = new String[this.columncount];
         this.columnLengths = new int[this.columncount];
+        this.JdbcSQLTypes = new int[this.columncount];
 
-        Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
-        this.resultBlocks = (DataBlockResponse<T>[]) Array.newInstance(DataBlockResponse.class, (tuplecount / cacheSize) + 1);
-        this.resultBlocks[0] = new DataBlockResponse<>(rowcount, parent.getRstype() == ResultSet.TYPE_FORWARD_ONLY, persistentClass);
+        this.resultBlocks = new DataBlockResponse[(tuplecount / cacheSize) + 1];
+        this.resultBlocks[0] = new DataBlockResponse(rowcount, columncount,
+                parent.getRstype() == ResultSet.TYPE_FORWARD_ONLY, con.getProtocol(), this.JdbcSQLTypes);
     }
 
     /**
-     * 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.
+     * Internal utility method to fill the JdbcSQLTypes array with derivable values.
+     * By doing it once (in the constructor) we can avoid doing this in many getXyz() methods again and again
+     * thereby improving getXyz() method performance.
      */
-    @Override
-    public boolean wantsMore() {
-        return !CheckBooleanValuesAllTrue(isSet) || resultBlocks[0].wantsMore();
+    private void populateJdbcSQLTypesArray() {
+        for (int i = 0; i < this.type.length; i++) {
+            int javaSQLtype = MonetDriver.getJavaType(this.type[i]);
+            this.JdbcSQLTypes[i] = javaSQLtype;
+            if (javaSQLtype == Types.BLOB && con.getBlobAsBinary()) {
+                this.JdbcSQLTypes[i] = Types.BINARY;
+            }
+        }
     }
 
     /**
-     * Adds the given DataBlockResponse to this ResultSetResponse at
-     * the given block position.
-     *
-     * @param offset the offset number of rows for this block
-     * @param rr the DataBlockResponse to add
+     * 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.
      */
-    public void addDataBlockResponse(int offset, DataBlockResponse<T> rr) {
-        int block = (offset - blockOffset) / cacheSize;
-        resultBlocks[block] = rr;
+    @Override
+    public boolean wantsMore() {
+        return this.isSet < IsSetFinalValue || resultBlocks[0].wantsMore();
     }
 
     /**
-     * Marks this Response as being completed.  A complete Response
-     * needs to be consistent with regard to its internal data.
+     * Adds the given DataBlockResponse to this ResultSetResponse at the given block position.
      *
-     * @throws SQLException if the data currently in this Response is not
-     *                      sufficient to be consistent
+     * @param offset the offset number of rows for this block
+     */
+    public DataBlockResponse addDataBlockResponse(int offset, int rowcount, int columncount, AbstractProtocol proto) {
+        int block = (offset - blockOffset) / cacheSize;
+        DataBlockResponse res = new DataBlockResponse(rowcount, columncount,
+                parent.getRstype() == ResultSet.TYPE_FORWARD_ONLY, proto, JdbcSQLTypes);
+        resultBlocks[block] = res;
+        return res;
+    }
+
+    /**
+     * Marks this Response as being completed.  A complete Response needs to be consistent with regard to its internal
+     * data.
+     *
+     * @throws SQLException if the data currently in this Response is not sufficient to be consistent
      */
     @Override
     public void complete() throws SQLException {
         String error = "";
-        if (!isSet[0]) error += "name header missing\n";
-        if (!isSet[1]) error += "column width header missing\n";
-        if (!isSet[2]) error += "table name header missing\n";
-        if (!isSet[3]) error += "type header missing\n";
+        if ((isSet & 1) == 0) error += "name header missing\n";
+        if ((isSet & 2) == 0) error += "column width header missing\n";
+        if ((isSet & 4) == 0) error += "table name header missing\n";
+        if ((isSet & 8) == 0) error += "type header missing\n";
         if (!error.equals("")) throw new SQLException(error, "M0M10");
     }
 
@@ -201,6 +206,10 @@ public class ResultSetResponse<T> implem
         return type;
     }
 
+    public int[] getJdbcSQLTypes() {
+        return JdbcSQLTypes;
+    }
+
     /**
      * Returns the tables of the columns
      *
@@ -256,17 +265,15 @@ public class ResultSetResponse<T> implem
     }
 
     /**
-     * Parses the given string and changes the value of the matching
-     * header appropriately, or passes it on to the underlying
-     * DataResponse.
+     * Parses the given string and changes the value of the matching header appropriately, or passes it on to the
+     * underlying DataResponse.
      *
      * @param line the string that contains the header
      * @throws MCLParseException if has a wrong header
      */
-    @SuppressWarnings("unchecked")
     public void addLine(ServerResponses response, Object line) throws MCLParseException {
-        if (CheckBooleanValuesAllTrue(isSet)) {
-            resultBlocks[0].addLine(response, line);
+        if (this.isSet >= IsSetFinalValue) {
+            this.resultBlocks[0].addLine(response, line);
         }
         if (response != ServerResponses.HEADER) {
             throw new MCLParseException("header expected, got: " + response.toString());
@@ -275,17 +282,18 @@ public class ResultSetResponse<T> implem
             switch (con.getProtocol().getNextTableHeader(line, this.tableNames, this.columnLengths)) {
                 case NAME:
                     System.arraycopy(this.tableNames, 0, this.name, 0, this.columncount);
-                    isSet[0] = true;
+                    isSet |= 1;
                     break;
                 case LENGTH:
-                    isSet[1] = true;
+                    isSet |= 2;
                     break;
                 case TYPE:
                     System.arraycopy(this.tableNames, 0, this.type, 0, this.columncount);
-                    isSet[2] = true;
+                    this.populateJdbcSQLTypesArray(); //VERY IMPORTANT!
+                    isSet |= 4;
                     break;
                 case TABLE:
-                    isSet[3] = true;
+                    isSet |= 8;
                     break;
             }
         }
@@ -302,8 +310,7 @@ public class ResultSetResponse<T> implem
      *         is out of the scope of the result set
      * @throws SQLException if an database error occurs
      */
-    @SuppressWarnings("unchecked")
-    public T getLine(int row) throws SQLException {
+    public Object[] getLine(int row) throws SQLException {
         if (row >= tuplecount || row < 0)
             return null;
 
@@ -311,7 +318,7 @@ public class ResultSetResponse<T> implem
         int blockLine = (row - blockOffset) % cacheSize;
 
         // do we have the right block loaded? (optimistic try)
-        DataBlockResponse<T> rawr;
+        DataBlockResponse rawr;
         // load block if appropriate
         if ((rawr = resultBlocks[block]) == null) {
             /// TODO: ponder about a maximum number of blocks to keep
@@ -355,13 +362,13 @@ public class ResultSetResponse<T> implem
             }
 
             // ok, need to fetch cache block first
-            parent.executeQuery(con.getLanguage().getCommandTemplates(), "export " + id + " " + ((block * cacheSize) + blockOffset) + " " + cacheSize);
+            parent.executeQuery(con.getLanguage().getCommandTemplates(), "export " + id + " "
+                    + ((block * cacheSize) + blockOffset) + " " + cacheSize);
             rawr = resultBlocks[block];
             if (rawr == null) {
                 throw new AssertionError("block " + block + " should have been fetched by now :(");
             }
         }
-
         return rawr.getRow(blockLine);
     }
 
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/SchemaResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/SchemaResponse.java
@@ -13,10 +13,8 @@ import java.sql.Statement;
  */
 public class SchemaResponse implements IResponse {
 
-    private final int state = Statement.SUCCESS_NO_INFO;
-
     public int getState() {
-        return state;
+        return Statement.SUCCESS_NO_INFO;
     }
 
     @Override
--- a/src/main/java/nl/cwi/monetdb/merovingian/Control.java
+++ b/src/main/java/nl/cwi/monetdb/merovingian/Control.java
@@ -8,23 +8,7 @@
 
 package nl.cwi.monetdb.merovingian;
 
-import nl.cwi.monetdb.mcl.io.AbstractMCLReader;
-import nl.cwi.monetdb.mcl.io.AbstractMCLWriter;
-import nl.cwi.monetdb.mcl.connection.DeleteMe;
-import nl.cwi.monetdb.mcl.connection.MCLException;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
-
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.net.Socket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
 
 /**
  * A Control class to perform operations on a remote merovingian
@@ -44,7 +28,7 @@ import java.util.Properties;
  * @author Fabian Groffen
  * @version 1.0
  */
-public class Control {
+public class Control { //TODO make me working again
 	/** The host to connect to */
 	private final String host;
 	/** The port to connect to */
@@ -54,16 +38,13 @@ public class Control {
 	/** The file we should write MapiSocket debuglog to */
 	private String debug;
 
-
 	/**
 	 * Constructs a new Control object.
 	 *
 	 * @throws IllegalArgumentException if host, port or passphrase are
 	 * null or &lt;= 0
 	 */
-	public Control(String host, int port, String passphrase)
-		throws IllegalArgumentException
-	{
+	public Control(String host, int port, String passphrase) throws IllegalArgumentException {
 		this.host = host;
 		this.port = port;
 		this.passphrase = passphrase;
@@ -111,10 +92,8 @@ public class Control {
 	
 	final static private String RESPONSE_OK = "OK";
 
-	private List<String> sendCommand(
-			String database, String command, boolean hasOutput)
-		throws MerovingianException, IOException
-	{
+	/*private List<String> sendCommand(String database, String command, boolean hasOutput)
+			throws MerovingianException, IOException {
 		AbstractMCLReader min;
 		AbstractMCLWriter mout;
 		DeleteMe ms = new DeleteMe(host, port, "monetdb", "monetdb", false, "sql", "SHA256");
@@ -141,7 +120,7 @@ public class Control {
 					new InputStreamReader(s.getInputStream()));
 			try {
 				/* login ritual, step 1: get challenge from server */
-				String response = in.readLine();
+				/*String response = in.readLine();
 				if (response == null)
 					throw new MerovingianException("server closed the connection");
 
@@ -173,12 +152,12 @@ public class Control {
 				}
 
 				/* send command, form is simple: "<db> <cmd>\n" */
-				out.print(database + " " + command + "\n");
+				//out.print(database + " " + command + "\n");
 
 				/* Response has the first line either "OK\n" or an error
 				 * message.  In case of a command with output, the data will
 				 * follow the first line */
-				response = in.readLine();
+				/*response = in.readLine();
 				if (response == null) {
 					throw new MerovingianException("server closed the connection");
 				}
@@ -226,58 +205,42 @@ public class Control {
 
 		ms.close();
 		return l;
-	}
+	}*/
 
-	public void start(String database)
-		throws MerovingianException, IOException
-	{
+	/*public void start(String database) throws MerovingianException, IOException {
 		sendCommand(database, "start", false);
 	}
 
-	public void stop(String database)
-		throws MerovingianException, IOException 
-	{   
+	public void stop(String database) throws MerovingianException, IOException {
 		sendCommand(database, "stop", false);
 	}
 
-	public void kill(String database)
-		throws MerovingianException, IOException
-	{
+	public void kill(String database) throws MerovingianException, IOException {
 		sendCommand(database, "kill", false);
 	}
 
-	public void create(String database)
-		throws MerovingianException, IOException
-	{
+	public void create(String database) throws MerovingianException, IOException {
 		sendCommand(database, "create", false);
 	}
 
-	public void destroy(String database)
-		throws MerovingianException, IOException
-	{
+	public void destroy(String database) throws MerovingianException, IOException {
 		sendCommand(database, "destroy", false);
 	}
 
-	public void lock(String database)
-		throws MerovingianException, IOException
-	{
+	public void lock(String database) throws MerovingianException, IOException {
 		sendCommand(database, "lock", false);
 	}
 
-	public void release(String database)
-		throws MerovingianException, IOException
-	{
+	public void release(String database) throws MerovingianException, IOException {
 		sendCommand(database, "release", false);
 	}
 
-	public void rename(String database, String newname)
-		throws MerovingianException, IOException
-	{
+	public void rename(String database, String newname) throws MerovingianException, IOException {
 		if (newname == null)
 			newname = ""; /* force error from merovingian */
 
-		sendCommand(database, "name=" + newname, false);
-	}
+		/*sendCommand(database, "name=" + newname, false);
+	}*/
 
 	/**
 	 * Sets property for database to value.  If value is null, the
@@ -291,27 +254,21 @@ public class Control {
 	 * @throws IOException if connecting to or communicating with
 	 *         merovingian failed
 	 */
-	public void setProperty(String database, String property, String value)
-		throws MerovingianException, IOException
-	{
+	public void setProperty(String database, String property, String value) throws MerovingianException, IOException {
 		/* inherit: set to empty string */
 		if (value == null)
 			value = "";
 
-		sendCommand(database, property + "=" + value, false);
+		//sendCommand(database, property + "=" + value, false);
 	}
 
-	public void inheritProperty(String database, String property)
-		throws MerovingianException, IOException
-	{
+	public void inheritProperty(String database, String property) throws MerovingianException, IOException {
 		setProperty(database, property, null);
 	}
 
-	public Properties getProperties(String database)
-		throws MerovingianException, IOException
-	{
+	/*public Properties getProperties(String database) throws MerovingianException, IOException {
 		Properties ret = new Properties();
-		List<String> response = sendCommand(database, "get", true);
+		//List<String> response = sendCommand(database, "get", true);
 		for (String responseLine : response) {
 			if (responseLine.startsWith("#"))
 				continue;
@@ -325,15 +282,11 @@ public class Control {
 		return ret;
 	}
 
-	public Properties getDefaultProperties()
-		throws MerovingianException, IOException
-	{
+	public Properties getDefaultProperties() throws MerovingianException, IOException {
 		return(getProperties("#defaults"));
 	}
 
-	public SabaothDB getStatus(String database)
-		throws MerovingianException, IOException
-	{
+	public SabaothDB getStatus(String database) throws MerovingianException, IOException {
 		List<String> response = sendCommand(database, "status", true);
 		if (response.isEmpty())
 			throw new MerovingianException("communication error");
@@ -348,9 +301,7 @@ public class Control {
 	 * @throws MerovingianException
 	 * @throws IOException
 	 */
-	public boolean exists(String database)
-		throws MerovingianException, IOException
-	{
+	/*public boolean exists(String database) throws MerovingianException, IOException {
 		List<SabaothDB> all = getAllStatuses();
 		for (SabaothDB db : all) {
 			if (db.getName().equals(database)) {
@@ -360,9 +311,7 @@ public class Control {
 		return false;
 	}
 
-	public List<SabaothDB> getAllStatuses()
-		throws MerovingianException, IOException
-	{
+	public List<SabaothDB> getAllStatuses() throws MerovingianException, IOException {
 		List<SabaothDB> l = new ArrayList<>();
 		List<String> response = sendCommand("#all", "status", true);
 		try {
@@ -375,9 +324,7 @@ public class Control {
 		return Collections.unmodifiableList(l);
 	}
 
-	public List<URI> getAllNeighbours()
-		throws MerovingianException, IOException
-	{
+	public List<URI> getAllNeighbours() throws MerovingianException, IOException {
 		List<URI> l = new ArrayList<URI>();
 		List<String> response = sendCommand("anelosimus", "eximius", true);
 		try {
@@ -397,5 +344,5 @@ public class Control {
 			throw new MerovingianException(e.getMessage());
 		}
 		return Collections.unmodifiableList(l);
-	}
+	}*/
 }
--- a/src/main/java/nl/cwi/monetdb/merovingian/SabaothDB.java
+++ b/src/main/java/nl/cwi/monetdb/merovingian/SabaothDB.java
@@ -24,15 +24,13 @@ import java.util.*;
 public class SabaothDB {
 	/** The name of the database */
 	private String dbname;
-	/** The URI how to connect to this database, or null if not
-	 * shared */
+	/** The URI how to connect to this database, or null if not shared */
 	private String uri;
 	/** Whether or not the database is under maintenance */
 	private boolean locked;
 	/** The state of this database, one of SABdbState */
 	private SABdbState state;
-	/** A list of Strings representing the available scenarios of this
-	 * database */
+	/** A list of Strings representing the available scenarios of this database */
 	private String[] scenarios;
 	/** The number of times this database was started */
 	private int startCounter;
@@ -58,17 +56,12 @@ public class SabaothDB {
 	private double crashAvg10;
 	/** Average of crashes in the last 30 start attempts */
 	private double crashAvg30;
-
 	/** The serialised format header */
 	private final String sabdbhdr = "sabdb:";
 
 	/** Sabaoth state enumeration */
 	public enum SABdbState {
-		SABdbIllegal (0),
-		SABdbRunning (1),
-		SABdbCrashed (2),
-		SABdbInactive(3),
-		SABdbStarting(4);
+		SABdbIllegal (0), SABdbRunning (1), SABdbCrashed (2), SABdbInactive(3), SABdbStarting(4);
 
 		private final int cValue;
 
@@ -88,20 +81,16 @@ public class SabaothDB {
 					return(s);
 				}
 			}
-			throw new IllegalArgumentException("No such state with value: "
-					+ val);
+			throw new IllegalArgumentException("No such state with value: " + val);
 		}
 	}
 
-	
 	/**
 	 * Constructs a new SabaothDB object from a String.
 	 *
 	 * @param sabdb the serialised sabdb C-struct
 	 */
-	public SabaothDB(String sabdb)
-		throws IllegalArgumentException
-	{
+	public SabaothDB(String sabdb) throws IllegalArgumentException {
 		if (sabdb == null)
 			throw new IllegalArgumentException("String is null");
 		if (!sabdb.startsWith(sabdbhdr))
--- a/src/main/java/nl/cwi/monetdb/util/CmdLineOpts.java
+++ b/src/main/java/nl/cwi/monetdb/util/CmdLineOpts.java
@@ -31,21 +31,9 @@ public class CmdLineOpts {
 	public CmdLineOpts() {
 	}
 
-	public void addOption(
-			String shorta,
-			String longa,
-			int type,
-			String defaulta,
-			String descriptiona)
-		throws OptionsException {
-		OptionContainer oc =
-			new OptionContainer(
-				shorta,
-				longa,
-				type,
-				defaulta,
-				descriptiona
-			);
+	public void addOption(String shorta, String longa, int type, String defaulta, String descriptiona)
+			throws OptionsException {
+		OptionContainer oc = new OptionContainer(shorta, longa, type, defaulta, descriptiona);
 		if (shorta != null) opts.put(shorta, oc);
 		if (longa != null) opts.put(longa, oc);
 	}
@@ -287,14 +275,8 @@ public class CmdLineOpts {
 		String descriptiona;
 		boolean present;
 
-		public OptionContainer(
-				String shorta,
-				String longa,
-				int cardinality,
-				String defaulta,
-				String descriptiona)
-			throws IllegalArgumentException
-		{
+		public OptionContainer(String shorta, String longa, int cardinality, String defaulta, String descriptiona)
+				throws IllegalArgumentException {
 			this.cardinality = cardinality;
 			this.shorta = shorta;
 			this.longa = longa;
@@ -302,11 +284,8 @@ public class CmdLineOpts {
 			this.descriptiona = descriptiona;
 			this.present = false;
 
-			if (cardinality != CAR_ZERO &&
-					cardinality != CAR_ONE &&
-					cardinality != CAR_ZERO_ONE &&
-					cardinality != CAR_ZERO_MANY &&
-					cardinality != CAR_ONE_MANY)
+			if (cardinality != CAR_ZERO && cardinality != CAR_ONE && cardinality != CAR_ZERO_ONE
+					&& cardinality != CAR_ZERO_MANY && cardinality != CAR_ONE_MANY)
 				throw new IllegalArgumentException("unknown cardinality");
 			if (shorta != null && shorta.length() != 1) throw
 				new IllegalArgumentException("short option should consist of exactly one character");
--- a/src/main/java/nl/cwi/monetdb/util/Extract.java
+++ b/src/main/java/nl/cwi/monetdb/util/Extract.java
@@ -27,8 +27,6 @@ import java.io.InputStreamReader;
 public class Extract {
 	private static final int DEFAULT_BUFSIZE = 16386;
 
-    public Extract() {}
-
     /**
      * Extracts a file from the Jar package which includes this class to
      * the given destination
@@ -40,17 +38,14 @@ public class Extract {
      * @throws IOException If any error happens during
      * creating/reading/writing files.
      */
-	public static void extractFile(String fromFile, String toFile)
-		throws FileNotFoundException, IOException
-	{
+	public static void extractFile(String fromFile, String toFile) throws FileNotFoundException, IOException {
 		char[] cbuf = new char[DEFAULT_BUFSIZE];
 		int ret;
 
 		InputStream is = Extract.class.getResourceAsStream(fromFile);
 
 		if(is == null) {
-			throw new FileNotFoundException("File " + fromFile +
-					" does not exist in the JAR package.");
+			throw new FileNotFoundException("File " + fromFile + " does not exist in the JAR package.");
 		}
 
 		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
--- a/src/main/java/nl/cwi/monetdb/util/SQLExporter.java
+++ b/src/main/java/nl/cwi/monetdb/util/SQLExporter.java
@@ -47,14 +47,8 @@ public class SQLExporter extends Exporte
 	 * @param name the table to describe in SQL CREATE format (not null)
 	 * @throws SQLException if a database related error occurs
 	 */
-	public void dumpSchema(
-			DatabaseMetaData dbmd,
-			String type,
-			String catalog,
-			String schema,
-			String name)
-		throws SQLException
-	{
+	public void dumpSchema(DatabaseMetaData dbmd, String type, String catalog, String schema, String name)
+			throws SQLException {
 		assert dbmd != null;
 		assert type != null;
 		assert schema != null;
@@ -371,9 +365,7 @@ public class SQLExporter extends Exporte
 	 * @param rs the ResultSet to convert into INSERT INTO statements
 	 * @throws SQLException if a database related error occurs
 	 */
-	private void resultSetToSQL(ResultSet rs)
-		throws SQLException
-	{
+	private void resultSetToSQL(ResultSet rs) throws SQLException {
 		ResultSetMetaData rsmd = rs.getMetaData();
 		String statement = "INSERT INTO ";
 		if (!useSchema) {
--- a/src/main/java/nl/cwi/monetdb/util/SQLRestore.java
+++ b/src/main/java/nl/cwi/monetdb/util/SQLRestore.java
@@ -8,24 +8,14 @@
 
 package nl.cwi.monetdb.util;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import nl.cwi.monetdb.mcl.connection.MCLException;
-import nl.cwi.monetdb.mcl.io.AbstractMCLReader;
-import nl.cwi.monetdb.mcl.io.AbstractMCLWriter;
-import nl.cwi.monetdb.mcl.connection.DeleteMe;
-import nl.cwi.monetdb.mcl.parser.MCLParseException;
 
 /**
  * Use this class to restore an SQL dump file.
  */
 public class SQLRestore {
 
-	private final String _host;
+	/*private final String _host; TODO make me working again!
 	private final int _port;
 	private final String _user;
 	private final String _password;
@@ -77,25 +67,25 @@ public class SQLRestore {
 					// ignore errors
 				}
 			}
-		}
+		}*/
 		
 		/**
 		 * @return whether the server has responded with an error. Any
 		 *         error is regarded as fatal.
 		 */
-		public boolean inErrorState() {
+		/*public boolean inErrorState() {
 			return _errorState.get();
-		}
+		}*/
 		
 		/**
 		 * @return the error message if inErrorState() is true. Behaviour is 
 		 * 		   not defined if called before inErrorState is true.
 		 */
-		public String getErrorMessage() {
+		/*public String getErrorMessage() {
 			return _errorMessage;
-		}
+		}*/
 		
-	}
+	//}
 	
 	/**
 	 * Restores a given SQL dump to the database.
@@ -103,7 +93,7 @@ public class SQLRestore {
 	 * @param source File location of the SQL dump
 	 * @throws IOException
 	 */
-	public void restore(File source) throws IOException {
+	/*public void restore(File source) throws IOException {
 		DeleteMe ms = new DeleteMe(_host, _port, _dbName, _user, false, "sql", "SHA256");
 		try {
 			ms.connect(_user, _password);
@@ -188,5 +178,5 @@ public class SQLRestore {
 		} finally {
 			md.close();
 		}
-	}
+	}*/
 }
--- a/src/main/java/nl/cwi/monetdb/util/XMLExporter.java
+++ b/src/main/java/nl/cwi/monetdb/util/XMLExporter.java
@@ -24,14 +24,8 @@ public class XMLExporter extends Exporte
 		super(out);
 	}
 
-	public void dumpSchema(
-			DatabaseMetaData dbmd,
-			String type,
-			String catalog,
-			String schema,
-			String name)
-		throws SQLException
-	{
+	public void dumpSchema(DatabaseMetaData dbmd, String type, String catalog, String schema, String name)
+			throws SQLException {
 		if (type.contains("VIEW")) {
 			String[] types = new String[1];
 			types[0] = type;
@@ -309,10 +303,8 @@ public class XMLExporter extends Exporte
 		out.println("</xsd:schema>");
 	}
 
-	private final static SimpleDateFormat xsd_ts =
-		new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-	private final static SimpleDateFormat xsd_tstz =
-		new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+	private final static SimpleDateFormat xsd_ts = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+	private final static SimpleDateFormat xsd_tstz = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
 
 	/**
 	 * Generates an XML representation of the given ResultSet.