diff --git a/asterix-jdbc-core/NOTICE b/asterix-jdbc-core/NOTICE
deleted file mode 100644
index 2596d30..0000000
--- a/asterix-jdbc-core/NOTICE
+++ /dev/null
@@ -1,4 +0,0 @@
-Couchbase asterixdb-jdbc-core
-Copyright 2021 Couchbase, Inc.
- 
-This product includes software developed at Couchbase, Inc.
diff --git a/asterix-jdbc-core/pom.xml b/asterix-jdbc-core/pom.xml
deleted file mode 100644
index 87fb7c8..0000000
--- a/asterix-jdbc-core/pom.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<!--
- ! Licensed to the Apache Software Foundation (ASF) under one
- ! or more contributor license agreements.  See the NOTICE file
- ! distributed with this work for additional information
- ! regarding copyright ownership.  The ASF licenses this file
- ! to you under the Apache License, Version 2.0 (the
- ! "License"); you may not use this file except in compliance
- ! with the License.  You may obtain a copy of the License at
- !
- !   http://www.apache.org/licenses/LICENSE-2.0
- !
- ! Unless required by applicable law or agreed to in writing,
- ! software distributed under the License is distributed on an
- ! "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- ! KIND, either express or implied.  See the License for the
- ! specific language governing permissions and limitations
- ! under the License.
- !-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <artifactId>apache-asterixdb</artifactId>
-    <groupId>org.apache.asterix</groupId>
-    <version>0.9.7-SNAPSHOT</version>
-  </parent>
-  <artifactId>asterix-jdbc-core</artifactId>
-
-  <licenses>
-    <license>
-      <name>Apache License, Version 2.0</name>
-      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-      <distribution>repo</distribution>
-      <comments>A business-friendly OSS license</comments>
-    </license>
-  </licenses>
-
-  <properties>
-    <root.dir>${basedir}/..</root.dir>
-    <source.jdk.version>1.8</source.jdk.version>
-    <target.jdk.version>1.8</target.jdk.version>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-annotations</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-</project>
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBColumn.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBColumn.java
deleted file mode 100644
index eb2de01..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBColumn.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.util.Objects;
-
-final class ADBColumn {
-
-    private final String name;
-
-    private final ADBDatatype type;
-
-    private final boolean optional;
-
-    ADBColumn(String name, ADBDatatype type, boolean optional) {
-        this.name = Objects.requireNonNull(name);
-        this.type = Objects.requireNonNull(type);
-        this.optional = optional || type.isNullOrMissing() || type == ADBDatatype.ANY;
-    }
-
-    String getName() {
-        return name;
-    }
-
-    ADBDatatype getType() {
-        return type;
-    }
-
-    boolean isOptional() {
-        return optional;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("%s:%s%s", name, type.getTypeName(), optional ? "?" : "");
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBConnection.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBConnection.java
deleted file mode 100644
index 46e38bc..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBConnection.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.CallableStatement;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.NClob;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLClientInfoException;
-import java.sql.SQLException;
-import java.sql.SQLPermission;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.sql.Struct;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class ADBConnection extends ADBWrapperSupport implements Connection {
-
-    final ADBProtocol protocol;
-
-    final String url;
-
-    final String databaseVersion;
-
-    private final AtomicBoolean closed;
-
-    private final ConcurrentLinkedQueue<ADBStatement> statements;
-
-    private volatile SQLWarning warning;
-
-    private volatile ADBMetaStatement metaStatement;
-
-    volatile String catalog;
-
-    volatile String schema;
-
-    // Lifecycle
-
-    protected ADBConnection(ADBProtocol protocol, String url, String databaseVersion, String catalog, String schema,
-            SQLWarning connectWarning) {
-        this.url = Objects.requireNonNull(url);
-        this.protocol = Objects.requireNonNull(protocol);
-        this.databaseVersion = databaseVersion;
-        this.statements = new ConcurrentLinkedQueue<>();
-        this.warning = connectWarning;
-        this.catalog = catalog;
-        this.schema = schema;
-        this.closed = new AtomicBoolean(false);
-    }
-
-    @Override
-    public void close() throws SQLException {
-        closeImpl(null);
-    }
-
-    @Override
-    public void abort(Executor executor) throws SQLException {
-        if (executor == null) {
-            throw getErrorReporter().errorParameterValueNotSupported("executor");
-        }
-        SecurityManager sec = System.getSecurityManager();
-        if (sec != null) {
-            sec.checkPermission(new SQLPermission("callAbort"));
-        }
-        closeImpl(executor);
-    }
-
-    void closeImpl(Executor executor) throws SQLException {
-        boolean wasClosed = closed.getAndSet(true);
-        if (wasClosed) {
-            return;
-        }
-        if (executor == null) {
-            closeStatementsAndProtocol();
-        } else {
-            executor.execute(() -> {
-                try {
-                    closeStatementsAndProtocol();
-                } catch (SQLException e) {
-                    if (getLogger().isLoggable(Level.FINE)) {
-                        getLogger().log(Level.FINE, e.getMessage(), e);
-                    }
-                }
-            });
-        }
-    }
-
-    private void closeStatementsAndProtocol() throws SQLException {
-        SQLException err = null;
-        try {
-            closeRegisteredStatements();
-        } catch (SQLException e) {
-            err = e;
-        }
-        try {
-            protocol.close();
-        } catch (SQLException e) {
-            if (err != null) {
-                e.addSuppressed(err);
-            }
-            err = e;
-        }
-        if (err != null) {
-            throw err;
-        }
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closed.get();
-    }
-
-    private void checkClosed() throws SQLException {
-        if (isClosed()) {
-            throw getErrorReporter().errorObjectClosed(Connection.class);
-        }
-    }
-
-    // Connectivity
-
-    @Override
-    public boolean isValid(int timeoutSeconds) throws SQLException {
-        if (isClosed()) {
-            return false;
-        }
-        if (timeoutSeconds < 0) {
-            throw getErrorReporter().errorParameterValueNotSupported("timeoutSeconds");
-        }
-        return protocol.ping(timeoutSeconds);
-    }
-
-    @Override
-    public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "setNetworkTimeout");
-    }
-
-    @Override
-    public int getNetworkTimeout() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "getNetworkTimeout");
-    }
-
-    // Metadata
-
-    @Override
-    public DatabaseMetaData getMetaData() throws SQLException {
-        checkClosed();
-        ADBMetaStatement metaStatement = getOrCreateMetaStatement();
-        return createDatabaseMetaData(metaStatement);
-    }
-
-    private ADBMetaStatement getOrCreateMetaStatement() {
-        ADBMetaStatement stmt = metaStatement;
-        if (stmt == null) {
-            synchronized (this) {
-                stmt = metaStatement;
-                if (stmt == null) {
-                    stmt = createMetaStatement();
-                    registerStatement(stmt);
-                    metaStatement = stmt;
-                }
-            }
-        }
-        return stmt;
-    }
-
-    protected ADBMetaStatement createMetaStatement() {
-        return new ADBMetaStatement(this);
-    }
-
-    protected ADBDatabaseMetaData createDatabaseMetaData(ADBMetaStatement metaStatement) {
-        return new ADBDatabaseMetaData(metaStatement, databaseVersion);
-    }
-
-    // Statement construction
-
-    @Override
-    public Statement createStatement() throws SQLException {
-        checkClosed();
-        return createStatementImpl();
-    }
-
-    @Override
-    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
-        return createStatement(resultSetType, resultSetConcurrency, getHoldability());
-    }
-
-    @Override
-    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
-            throws SQLException {
-        checkClosed();
-        checkResultSetConfig(resultSetType, resultSetConcurrency, resultSetHoldability);
-        return createStatementImpl();
-    }
-
-    private void checkResultSetConfig(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
-            throws SQLException {
-        boolean ok = resultSetType == ResultSet.TYPE_FORWARD_ONLY && resultSetConcurrency == ResultSet.CONCUR_READ_ONLY;
-        if (!ok) {
-            throw getErrorReporter().errorParameterValueNotSupported("resultSetType/resultSetConcurrency");
-        }
-        if (resultSetHoldability != ADBResultSet.RESULT_SET_HOLDABILITY) {
-            if (getLogger().isLoggable(Level.FINE)) {
-                getLogger().log(Level.FINE,
-                        getErrorReporter().warningParameterValueNotSupported("ResultSetHoldability"));
-            }
-        }
-    }
-
-    private ADBStatement createStatementImpl() {
-        ADBStatement stmt = new ADBStatement(this, catalog, schema);
-        registerStatement(stmt);
-        return stmt;
-    }
-
-    @Override
-    public PreparedStatement prepareStatement(String sql) throws SQLException {
-        checkClosed();
-        return prepareStatementImpl(sql);
-    }
-
-    @Override
-    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
-            throws SQLException {
-        return prepareStatement(sql, resultSetType, resultSetConcurrency, getHoldability());
-    }
-
-    @Override
-    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
-            int resultSetHoldability) throws SQLException {
-        checkClosed();
-        checkResultSetConfig(resultSetType, resultSetConcurrency, resultSetHoldability);
-        return prepareStatementImpl(sql);
-    }
-
-    @Override
-    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "prepareStatement");
-    }
-
-    @Override
-    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "prepareStatement");
-    }
-
-    @Override
-    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "prepareStatement");
-    }
-
-    private ADBPreparedStatement prepareStatementImpl(String sql) throws SQLException {
-        ADBPreparedStatement stmt = new ADBPreparedStatement(this, sql, catalog, schema);
-        registerStatement(stmt);
-        return stmt;
-    }
-
-    @Override
-    public CallableStatement prepareCall(String sql) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "prepareCall");
-    }
-
-    @Override
-    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "prepareCall");
-    }
-
-    @Override
-    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
-            int resultSetHoldability) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "prepareCall");
-    }
-
-    @Override
-    public String nativeSQL(String sql) throws SQLException {
-        checkClosed();
-        return sql;
-    }
-
-    @Override
-    public String getCatalog() throws SQLException {
-        checkClosed();
-        return catalog;
-    }
-
-    @Override
-    public void setCatalog(String catalog) throws SQLException {
-        checkClosed();
-        this.catalog = catalog;
-    }
-
-    @Override
-    public String getSchema() throws SQLException {
-        checkClosed();
-        return schema;
-    }
-
-    @Override
-    public void setSchema(String schema) throws SQLException {
-        checkClosed();
-        this.schema = schema;
-    }
-
-    // Statement lifecycle
-
-    private void registerStatement(ADBStatement stmt) {
-        statements.add(Objects.requireNonNull(stmt));
-    }
-
-    void deregisterStatement(ADBStatement stmt) {
-        statements.remove(Objects.requireNonNull(stmt));
-    }
-
-    private void closeRegisteredStatements() throws SQLException {
-        SQLException err = null;
-        ADBStatement statement;
-        while ((statement = statements.poll()) != null) {
-            try {
-                statement.closeImpl(true, false);
-            } catch (SQLException e) {
-                if (err != null) {
-                    e.addSuppressed(err);
-                }
-                err = e;
-            }
-        }
-        if (err != null) {
-            throw err;
-        }
-    }
-
-    // Transaction control
-
-    @Override
-    public int getTransactionIsolation() throws SQLException {
-        checkClosed();
-        return Connection.TRANSACTION_READ_COMMITTED;
-    }
-
-    @Override
-    public void setTransactionIsolation(int level) throws SQLException {
-        checkClosed();
-        switch (level) {
-            case Connection.TRANSACTION_READ_COMMITTED:
-                break;
-            case Connection.TRANSACTION_READ_UNCOMMITTED:
-            case Connection.TRANSACTION_REPEATABLE_READ:
-            case Connection.TRANSACTION_SERIALIZABLE:
-                if (getLogger().isLoggable(Level.FINE)) {
-                    getLogger().log(Level.FINE,
-                            getErrorReporter().warningParameterValueNotSupported("TransactionIsolationLevel"));
-                }
-                break;
-            default:
-                throw getErrorReporter().errorParameterValueNotSupported("TransactionIsolationLevel");
-        }
-    }
-
-    @Override
-    public int getHoldability() throws SQLException {
-        checkClosed();
-        return ResultSet.HOLD_CURSORS_OVER_COMMIT;
-    }
-
-    @Override
-    public void setHoldability(int holdability) throws SQLException {
-        checkClosed();
-        switch (holdability) {
-            case ResultSet.HOLD_CURSORS_OVER_COMMIT:
-                break;
-            case ResultSet.CLOSE_CURSORS_AT_COMMIT:
-                if (getLogger().isLoggable(Level.FINE)) {
-                    getLogger().log(Level.FINE, getErrorReporter().warningParameterValueNotSupported("Holdability"));
-                }
-                break;
-            default:
-                throw getErrorReporter().errorParameterValueNotSupported("Holdability");
-        }
-    }
-
-    @Override
-    public boolean getAutoCommit() throws SQLException {
-        checkClosed();
-        return true;
-    }
-
-    @Override
-    public void setAutoCommit(boolean autoCommit) throws SQLException {
-        checkClosed();
-    }
-
-    @Override
-    public void commit() throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("AutoCommit");
-    }
-
-    @Override
-    public void rollback() throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("AutoCommit");
-    }
-
-    @Override
-    public Savepoint setSavepoint() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "setSavepoint");
-    }
-
-    @Override
-    public Savepoint setSavepoint(String name) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "setSavepoint");
-    }
-
-    @Override
-    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "releaseSavepoint");
-    }
-
-    @Override
-    public void rollback(Savepoint savepoint) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "rollback");
-    }
-
-    // Value construction
-
-    @Override
-    public Clob createClob() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "createClob");
-    }
-
-    @Override
-    public Blob createBlob() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "createBlob");
-    }
-
-    @Override
-    public NClob createNClob() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "createNClob");
-    }
-
-    @Override
-    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "createArrayOf");
-    }
-
-    @Override
-    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "createStruct");
-    }
-
-    @Override
-    public SQLXML createSQLXML() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "createSQLXML");
-    }
-
-    @Override
-    public Map<String, Class<?>> getTypeMap() throws SQLException {
-        checkClosed();
-        return Collections.emptyMap();
-    }
-
-    @Override
-    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Connection.class, "setTypeMap");
-    }
-
-    // Unsupported hints (ignored)
-
-    @Override
-    public boolean isReadOnly() throws SQLException {
-        checkClosed();
-        return false;
-    }
-
-    @Override
-    public void setReadOnly(boolean readOnly) throws SQLException {
-        checkClosed();
-    }
-
-    // Errors and warnings
-
-    @Override
-    public SQLWarning getWarnings() throws SQLException {
-        checkClosed();
-        return warning;
-    }
-
-    @Override
-    public void clearWarnings() throws SQLException {
-        checkClosed();
-        warning = null;
-    }
-
-    @Override
-    protected ADBErrorReporter getErrorReporter() {
-        return protocol.driverContext.errorReporter;
-    }
-
-    protected Logger getLogger() {
-        return protocol.driverContext.logger;
-    }
-
-    // Miscellaneous unsupported features (error is raised)
-
-    @Override
-    public String getClientInfo(String name) throws SQLException {
-        checkClosed();
-        return null;
-    }
-
-    @Override
-    public Properties getClientInfo() throws SQLException {
-        checkClosed();
-        return new Properties();
-    }
-
-    @Override
-    public void setClientInfo(Properties properties) throws SQLClientInfoException {
-        throw getErrorReporter().errorClientInfoMethodNotSupported(Connection.class, "setClientInfo");
-    }
-
-    @Override
-    public void setClientInfo(String name, String value) throws SQLClientInfoException {
-        throw getErrorReporter().errorClientInfoMethodNotSupported(Connection.class, "setClientInfo");
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatabaseMetaData.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatabaseMetaData.java
deleted file mode 100644
index a090498..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatabaseMetaData.java
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.RowIdLifetime;
-import java.sql.SQLException;
-import java.util.Objects;
-
-final class ADBDatabaseMetaData extends ADBWrapperSupport implements DatabaseMetaData {
-
-    /*
-     * See org.apache.asterix.metadata.utils.MetadataConstants.METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8
-     */
-    private static final int METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8 = 251;
-
-    private final ADBMetaStatement metaStatement;
-
-    private final String databaseVersionText;
-
-    private volatile ADBProductVersion databaseVersion;
-
-    ADBDatabaseMetaData(ADBMetaStatement metaStatement, String databaseVersionText) {
-        this.metaStatement = Objects.requireNonNull(metaStatement);
-        this.databaseVersionText = databaseVersionText;
-    }
-
-    // Driver name and version
-
-    @Override
-    public String getDriverName() {
-        return metaStatement.connection.protocol.driverContext.driverVersion.productName;
-    }
-
-    @Override
-    public String getDriverVersion() {
-        return metaStatement.connection.protocol.driverContext.driverVersion.productVersion;
-    }
-
-    @Override
-    public int getDriverMajorVersion() {
-        return metaStatement.connection.protocol.driverContext.driverVersion.majorVersion;
-    }
-
-    @Override
-    public int getDriverMinorVersion() {
-        return metaStatement.connection.protocol.driverContext.driverVersion.minorVersion;
-    }
-
-    @Override
-    public int getJDBCMajorVersion() {
-        return ADBDriverBase.JDBC_MAJOR_VERSION;
-    }
-
-    @Override
-    public int getJDBCMinorVersion() {
-        return ADBDriverBase.JDBC_MINOR_VERSION;
-    }
-
-    // Database name and version
-
-    @Override
-    public String getDatabaseProductName() {
-        return getDatabaseVersion().productName;
-    }
-
-    @Override
-    public String getDatabaseProductVersion() {
-        return getDatabaseVersion().productVersion;
-    }
-
-    @Override
-    public int getDatabaseMajorVersion() {
-        return getDatabaseVersion().majorVersion;
-    }
-
-    @Override
-    public int getDatabaseMinorVersion() {
-        return getDatabaseVersion().minorVersion;
-    }
-
-    private ADBProductVersion getDatabaseVersion() {
-        ADBProductVersion result = databaseVersion;
-        if (result == null) {
-            databaseVersion = result = ADBProductVersion.parseDatabaseVersion(databaseVersionText);
-        }
-        return result;
-    }
-
-    // Database objects
-
-    // Catalogs and schemas
-
-    @Override
-    public ADBResultSet getCatalogs() throws SQLException {
-        return metaStatement.executeGetCatalogsQuery();
-    }
-
-    @Override
-    public int getMaxCatalogNameLength() {
-        return METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8;
-    }
-
-    @Override
-    public ADBResultSet getSchemas() throws SQLException {
-        return getSchemas(metaStatement.connection.catalog, null);
-    }
-
-    @Override
-    public ADBResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
-        return metaStatement.executeGetSchemasQuery(catalog, schemaPattern);
-    }
-
-    @Override
-    public int getMaxSchemaNameLength() {
-        return METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8;
-    }
-
-    // Tables
-
-    @Override
-    public ADBResultSet getTableTypes() throws SQLException {
-        return metaStatement.executeGetTableTypesQuery();
-    }
-
-    @Override
-    public ADBResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
-            throws SQLException {
-        return metaStatement.executeGetTablesQuery(catalog, schemaPattern, tableNamePattern, types);
-    }
-
-    @Override
-    public ADBResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public int getMaxTableNameLength() {
-        return METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8;
-    }
-
-    @Override
-    public int getMaxColumnsInTable() {
-        return 0;
-    }
-
-    @Override
-    public int getMaxRowSize() {
-        return 0;
-    }
-
-    @Override
-    public boolean doesMaxRowSizeIncludeBlobs() {
-        return true;
-    }
-
-    // Columns
-
-    @Override
-    public ADBResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern,
-            String columnNamePattern) throws SQLException {
-        return metaStatement.executeGetColumnsQuery(catalog, schemaPattern, tableNamePattern, columnNamePattern);
-    }
-
-    @Override
-    public ADBResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern,
-            String columnNamePattern) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
-            throws SQLException {
-        // TODO:primary keys?
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public int getMaxColumnNameLength() {
-        return 0;
-    }
-
-    // Keys
-
-    @Override
-    public ADBResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
-        return metaStatement.executeGetPrimaryKeysQuery(catalog, schema, table);
-    }
-
-    @Override
-    public ADBResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable,
-            String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    // Indexes
-
-    @Override
-    public ADBResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public int getMaxColumnsInIndex() {
-        return 0;
-    }
-
-    @Override
-    public int getMaxIndexLength() {
-        return 0;
-    }
-
-    // Datatypes
-
-    @Override
-    public ADBResultSet getTypeInfo() throws SQLException {
-        return metaStatement.executeGetTypeInfoQuery();
-    }
-
-    @Override
-    public ADBResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern,
-            String attributeNamePattern) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public RowIdLifetime getRowIdLifetime() {
-        return RowIdLifetime.ROWID_UNSUPPORTED;
-    }
-
-    @Override
-    public long getMaxLogicalLobSize() {
-        return 0;
-    }
-
-    @Override
-    public boolean supportsRefCursors() {
-        return false;
-    }
-
-    // User-defined functions and procedures
-
-    @Override
-    public boolean supportsStoredProcedures() {
-        return false;
-    }
-
-    @Override
-    public ADBResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern,
-            String columnNamePattern) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
-            String columnNamePattern) throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public int getMaxProcedureNameLength() {
-        return METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8;
-    }
-
-    // Security
-
-    @Override
-    public ADBResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    @Override
-    public ADBResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
-            throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    // Other database objects
-
-    @Override
-    public ADBResultSet getClientInfoProperties() throws SQLException {
-        return metaStatement.executeEmptyResultQuery();
-    }
-
-    // SQL dialect: general
-
-    @Override
-    public boolean supportsMinimumSQLGrammar() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsCoreSQLGrammar() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsExtendedSQLGrammar() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsANSI92EntryLevelSQL() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsANSI92IntermediateSQL() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsANSI92FullSQL() {
-        return false;
-    }
-
-    @Override
-    public String getSQLKeywords() {
-        // keywords that are not also SQL:2003 keywords
-        return "adapter,apply,asc,autogenerated,btree,closed,compaction,compact,correlate,collection,dataset,"
-                + "dataverse,definition,desc,disconnect,div,explain,enforced,every,feed,flatten,fulltext,hints,if,"
-                + "index,ingestion,internal,keyword,key,known,letting,let,limit,load,missing,mod,nodegroup,ngram,"
-                + "offset,path,policy,pre-sorted,raw,refresh,returning,rtree,run,satisfies,secondary,some,stop,"
-                + "synonym,temporary,type,upsert,use,view,write";
-    }
-
-    @Override
-    public String getCatalogTerm() {
-        return "catalog";
-    }
-
-    @Override
-    public String getSchemaTerm() {
-        return "schema";
-    }
-
-    @Override
-    public String getProcedureTerm() {
-        return "procedure";
-    }
-
-    @Override
-    public int getMaxStatementLength() {
-        return 0;
-    }
-
-    // SQL dialect: identifiers
-
-    @Override
-    public String getExtraNameCharacters() {
-        return "";
-    }
-
-    @Override
-    public String getIdentifierQuoteString() {
-        return "`";
-    }
-
-    @Override
-    public boolean supportsMixedCaseIdentifiers() {
-        return true;
-    }
-
-    @Override
-    public boolean storesMixedCaseIdentifiers() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsMixedCaseQuotedIdentifiers() {
-        return true;
-    }
-
-    @Override
-    public boolean storesMixedCaseQuotedIdentifiers() {
-        return false;
-    }
-
-    @Override
-    public boolean storesLowerCaseIdentifiers() {
-        return false;
-    }
-
-    @Override
-    public boolean storesLowerCaseQuotedIdentifiers() {
-        return false;
-    }
-
-    @Override
-    public boolean storesUpperCaseIdentifiers() {
-        return false;
-    }
-
-    @Override
-    public boolean storesUpperCaseQuotedIdentifiers() {
-        return false;
-    }
-
-    // SQL dialect: literals and parameters
-
-    @Override
-    public int getMaxBinaryLiteralLength() {
-        return 0;
-    }
-
-    @Override
-    public int getMaxCharLiteralLength() {
-        return 0;
-    }
-
-    @Override
-    public boolean supportsNamedParameters() {
-        // Procedures (CallableStatement) are not supported
-        return false;
-    }
-
-    // SQL dialect: functions and operators
-
-    @Override
-    public String getNumericFunctions() {
-        // NOTE: JDBC escape clause is not yet supported
-        // "add,div,mod,mult,neg,sub,abs,acos,asin,atan,atan2,ceil,cos,deg,degrees,e,exp,ln,log,floor,inf,nan,neginf,pi,posinf,power,rad,radians,random,round,sign,sin,sqrt,tan,trunc";
-        return "";
-    }
-
-    @Override
-    public String getStringFunctions() {
-        // NOTE: JDBC escape clause is not yet supported
-        // "contains,initcap,length,lower,ltrim,position,pos,regex_contains,regex_like,regex_position,regex_pos,regex_replace,repeat,replace,rtrim,split,substr,title,trim,upper";
-        return "";
-    }
-
-    @Override
-    public String getSystemFunctions() {
-        // NOTE: JDBC escape clause is not yet supported
-        return "";
-    }
-
-    @Override
-    public String getTimeDateFunctions() {
-        // TODO:review
-        return "current_date,current_time,current_datetime";
-    }
-
-    @Override
-    public boolean supportsConvert() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsConvert(int fromType, int toType) {
-        return false;
-    }
-
-    @Override
-    public String getSearchStringEscape() {
-        return "\\";
-    }
-
-    @Override
-    public boolean supportsLikeEscapeClause() {
-        return false;
-    }
-
-    @Override
-    public boolean nullPlusNonNullIsNull() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsStoredFunctionsUsingCallSyntax() {
-        return false;
-    }
-
-    // SQL dialect: SELECT clause
-
-    @Override
-    public int getMaxColumnsInSelect() {
-        return 0;
-    }
-
-    @Override
-    public boolean supportsColumnAliasing() {
-        return true;
-    }
-
-    // SQL dialect: FROM clause
-
-    @Override
-    public boolean allTablesAreSelectable() {
-        return true;
-    }
-
-    @Override
-    public int getMaxTablesInSelect() {
-        return 0;
-    }
-
-    @Override
-    public boolean isCatalogAtStart() {
-        return true;
-    }
-
-    @Override
-    public String getCatalogSeparator() {
-        return ".";
-    }
-
-    @Override
-    public boolean supportsTableCorrelationNames() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsDifferentTableCorrelationNames() {
-        return true;
-    }
-
-    // SQL dialect: JOIN clause
-
-    @Override
-    public boolean supportsOuterJoins() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsLimitedOuterJoins() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsFullOuterJoins() {
-        return false;
-    }
-
-    // SQL dialect: ORDER BY clause
-
-    @Override
-    public int getMaxColumnsInOrderBy() {
-        return 0;
-    }
-
-    @Override
-    public boolean supportsOrderByUnrelated() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsExpressionsInOrderBy() {
-        return true;
-    }
-
-    @Override
-    public boolean nullsAreSortedHigh() {
-        return false;
-    }
-
-    @Override
-    public boolean nullsAreSortedLow() {
-        return true;
-    }
-
-    @Override
-    public boolean nullsAreSortedAtStart() {
-        return false;
-    }
-
-    @Override
-    public boolean nullsAreSortedAtEnd() {
-        return false;
-    }
-
-    // SQL dialect: GROUP BY clause
-
-    @Override
-    public boolean supportsGroupBy() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsGroupByUnrelated() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsGroupByBeyondSelect() {
-        return true;
-    }
-
-    @Override
-    public int getMaxColumnsInGroupBy() {
-        return 0;
-    }
-
-    // SQL dialect: Subquery
-
-    @Override
-    public boolean supportsSubqueriesInComparisons() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsSubqueriesInExists() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsSubqueriesInIns() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsSubqueriesInQuantifieds() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsCorrelatedSubqueries() {
-        return true;
-    }
-
-    // SQL dialect: Set operations
-
-    @Override
-    public boolean supportsUnion() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsUnionAll() {
-        return true;
-    }
-
-    // SQL dialect: DML statements
-
-    @Override
-    public boolean supportsCatalogsInDataManipulation() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsSchemasInDataManipulation() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsPositionedDelete() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsPositionedUpdate() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsSelectForUpdate() {
-        return false;
-    }
-
-    // SQL dialect: DDL statements
-
-    // DDL: CREATE DATASET
-
-    @Override
-    public boolean supportsCatalogsInTableDefinitions() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsSchemasInTableDefinitions() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsNonNullableColumns() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsAlterTableWithAddColumn() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsAlterTableWithDropColumn() {
-        return false;
-    }
-
-    // DDL: CREATE INDEX
-
-    @Override
-    public boolean supportsCatalogsInIndexDefinitions() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsSchemasInIndexDefinitions() {
-        return true;
-    }
-
-    // DDL: GRANT / REVOKE (not supported)
-
-    @Override
-    public boolean supportsCatalogsInPrivilegeDefinitions() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsSchemasInPrivilegeDefinitions() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsIntegrityEnhancementFacility() {
-        return false;
-    }
-
-    // SQL dialect: User-defined functions and procedures
-
-    @Override
-    public boolean allProceduresAreCallable() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsCatalogsInProcedureCalls() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsSchemasInProcedureCalls() {
-        return false;
-    }
-
-    // Transactions
-
-    @Override
-    public boolean supportsTransactions() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsMultipleTransactions() {
-        return true;
-    }
-
-    @Override
-    public int getDefaultTransactionIsolation() {
-        return Connection.TRANSACTION_READ_COMMITTED;
-    }
-
-    @Override
-    public boolean supportsTransactionIsolationLevel(int level) {
-        return Connection.TRANSACTION_READ_COMMITTED == level;
-    }
-
-    @Override
-    public boolean supportsDataDefinitionAndDataManipulationTransactions() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsDataManipulationTransactionsOnly() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsOpenStatementsAcrossCommit() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsOpenCursorsAcrossCommit() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsOpenStatementsAcrossRollback() {
-        return true;
-    }
-
-    @Override
-    public boolean supportsOpenCursorsAcrossRollback() {
-        return false;
-    }
-
-    @Override
-    public boolean dataDefinitionCausesTransactionCommit() {
-        return false;
-    }
-
-    @Override
-    public boolean dataDefinitionIgnoredInTransactions() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsSavepoints() {
-        return false;
-    }
-
-    @Override
-    public boolean autoCommitFailureClosesAllResultSets() {
-        return false;
-    }
-
-    // Connection
-
-    @Override
-    public Connection getConnection() throws SQLException {
-        return metaStatement.connection;
-    }
-
-    @Override
-    public int getMaxConnections() {
-        return 0;
-    }
-
-    @Override
-    public String getURL() {
-        return metaStatement.connection.url;
-    }
-
-    @Override
-    public String getUserName() {
-        return metaStatement.connection.protocol.user;
-    }
-
-    @Override
-    public int getMaxUserNameLength() {
-        return 0;
-    }
-
-    // Statement
-
-    @Override
-    public int getMaxStatements() {
-        return 0;
-    }
-
-    @Override
-    public boolean supportsStatementPooling() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsBatchUpdates() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsGetGeneratedKeys() {
-        return false;
-    }
-
-    @Override
-    public boolean generatedKeyAlwaysReturned() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsMultipleResultSets() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsMultipleOpenResults() {
-        return false;
-    }
-
-    @Override
-    public boolean locatorsUpdateCopy() {
-        return false;
-    }
-
-    // ResultSet
-
-    @Override
-    public boolean supportsResultSetType(int type) {
-        return type == ResultSet.TYPE_FORWARD_ONLY;
-    }
-
-    @Override
-    public boolean supportsResultSetConcurrency(int type, int concurrency) {
-        return type == ResultSet.TYPE_FORWARD_ONLY && concurrency == ResultSet.CONCUR_READ_ONLY;
-    }
-
-    @Override
-    public boolean supportsResultSetHoldability(int holdability) {
-        return holdability == ADBResultSet.RESULT_SET_HOLDABILITY;
-    }
-
-    @Override
-    public int getResultSetHoldability() {
-        return ADBResultSet.RESULT_SET_HOLDABILITY;
-    }
-
-    @Override
-    public boolean ownInsertsAreVisible(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean othersInsertsAreVisible(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean insertsAreDetected(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean ownUpdatesAreVisible(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean othersUpdatesAreVisible(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean updatesAreDetected(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean ownDeletesAreVisible(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean othersDeletesAreVisible(int type) {
-        return false;
-    }
-
-    @Override
-    public boolean deletesAreDetected(int type) {
-        return false;
-    }
-
-    @Override
-    public int getMaxCursorNameLength() {
-        return 0;
-    }
-
-    // Miscellaneous
-
-    @Override
-    public boolean isReadOnly() {
-        return false;
-    }
-
-    @Override
-    public boolean usesLocalFiles() {
-        return false;
-    }
-
-    @Override
-    public boolean usesLocalFilePerTable() {
-        return false;
-    }
-
-    // Errors and warnings
-
-    @Override
-    public int getSQLStateType() {
-        return sqlStateSQL;
-    }
-
-    @Override
-    protected ADBErrorReporter getErrorReporter() {
-        return metaStatement.getErrorReporter();
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatatype.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatatype.java
deleted file mode 100644
index e6634b5..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatatype.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.sql.JDBCType;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-enum ADBDatatype {
-    TINYINT(1, "int8", JDBCType.TINYINT, Byte.class),
-    SMALLINT(2, "int16", JDBCType.SMALLINT, Short.class),
-    INTEGER(3, "int32", JDBCType.INTEGER, Integer.class),
-    BIGINT(4, "int64", JDBCType.BIGINT, Long.class),
-
-    //UINT8(5, null, JDBCType.OTHER),
-    //UINT16(6, null, JDBCType.OTHER),
-    //UINT32(7, null, JDBCType.OTHER),
-    //UINT64(8, null, JDBCType.OTHER),
-    //BINARY(9, "binary", JDBCType.VARBINARY, byte[].class),
-    //BITARRAY(10, null, JDBCType.VARBINARY),
-
-    FLOAT(11, "float", JDBCType.REAL, Float.class),
-    DOUBLE(12, "double", JDBCType.DOUBLE, Double.class),
-    STRING(13, "string", JDBCType.VARCHAR, String.class),
-    MISSING(14, "missing", JDBCType.OTHER, Void.class), // don't report as JDBCType.NULL
-    BOOLEAN(15, "boolean", JDBCType.BOOLEAN, Boolean.class),
-    DATETIME(16, "datetime", JDBCType.TIMESTAMP, java.sql.Timestamp.class),
-    DATE(17, "date", JDBCType.DATE, java.sql.Date.class),
-    TIME(18, "time", JDBCType.TIME, java.sql.Time.class),
-    DURATION(19, "duration", JDBCType.OTHER, String.class),
-
-    //POINT(20, "point", JDBCType.OTHER, Object.class),
-    //POINT3D(21, "point3d", JDBCType.OTHER, Object.class),
-
-    ARRAY(22, "array", JDBCType.OTHER, List.class),
-    MULTISET(23, "multiset", JDBCType.OTHER, List.class),
-    OBJECT(24, "object", JDBCType.OTHER, Map.class),
-
-    //SPARSOBJECT(25, null, null, JDBCType.OTHER),
-    //UNION(26, null, JDBCType.OTHER),
-    //ENUM(27, null, JDBCType.OTHER),
-    //TYPE(28, null, JDBCType.OTHER),
-
-    ANY(29, "any", JDBCType.OTHER, String.class),
-
-    //LINE(30, "line", JDBCType.OTHER, Object.class),
-    //POLYGON(31, "polygon", JDBCType.OTHER, Object.class),
-    //CIRCLE(32, "circle", JDBCType.OTHER, Object.class),
-    //RECTANGLE(33, "rectangle", JDBCType.OTHER, Object.class),
-    //INTERVAL(34, "interval", JDBCType.OTHER, Object.class),
-    //SYSTEM_NULL(35, null, null, JDBCType.OTHER),
-
-    YEARMONTHDURATION(36, "year-month-duration", JDBCType.OTHER, java.time.Period.class),
-    DAYTIMEDURATION(37, "day-time-duration", JDBCType.OTHER, java.time.Duration.class),
-    UUID(38, "uuid", JDBCType.OTHER, java.util.UUID.class),
-
-    //SHORTWITHOUTTYPEINFO(40, null, null, JDBCType.OTHER),
-
-    NULL(41, "null", JDBCType.NULL, Void.class);
-
-    //GEOMETRY(42, "geometry", JDBCType.OTHER, Object.class)
-
-    private static final ADBDatatype[] BY_TYPE_TAG;
-
-    private static final Map<String, ADBDatatype> BY_TYPE_NAME;
-
-    private final byte typeTag;
-
-    private final String typeName;
-
-    private final JDBCType jdbcType;
-
-    private final Class<?> javaClass;
-
-    ADBDatatype(int typeTag, String typeName, JDBCType jdbcType, Class<?> javaClass) {
-        this.typeTag = (byte) typeTag;
-        this.typeName = Objects.requireNonNull(typeName);
-        this.jdbcType = Objects.requireNonNull(jdbcType);
-        this.javaClass = Objects.requireNonNull(javaClass);
-    }
-
-    byte getTypeTag() {
-        return typeTag;
-    }
-
-    String getTypeName() {
-        return typeName;
-    }
-
-    JDBCType getJdbcType() {
-        return jdbcType;
-    }
-
-    Class<?> getJavaClass() {
-        return javaClass;
-    }
-
-    @Override
-    public String toString() {
-        return getTypeName();
-    }
-
-    boolean isDerived() {
-        return this == OBJECT || isList();
-    }
-
-    boolean isList() {
-        return this == ARRAY || this == MULTISET;
-    }
-
-    boolean isNullOrMissing() {
-        return this == NULL || this == MISSING;
-    }
-
-    static {
-        ADBDatatype[] allTypes = ADBDatatype.values();
-        ADBDatatype[] byTypeTag = new ADBDatatype[findMaxTypeTag(allTypes) + 1];
-        Map<String, ADBDatatype> byTypeName = new HashMap<>();
-        for (ADBDatatype t : allTypes) {
-            byTypeTag[t.typeTag] = t;
-            byTypeName.put(t.typeName, t);
-        }
-        BY_TYPE_TAG = byTypeTag;
-        BY_TYPE_NAME = byTypeName;
-    }
-
-    public static ADBDatatype findByTypeTag(byte typeTag) {
-        return typeTag >= 0 && typeTag < BY_TYPE_TAG.length ? BY_TYPE_TAG[typeTag] : null;
-    }
-
-    public static ADBDatatype findByTypeName(String typeName) {
-        return BY_TYPE_NAME.get(typeName);
-    }
-
-    private static int findMaxTypeTag(ADBDatatype[] allTypes) {
-        int maxTypeTag = 0;
-        for (ADBDatatype type : allTypes) {
-            if (type.typeTag < 0) {
-                throw new IllegalStateException(type.getTypeName());
-            }
-            maxTypeTag = Math.max(type.typeTag, maxTypeTag);
-        }
-        return maxTypeTag;
-    }
-
-    static String getDerivedRecordName(ADBDatatype type) {
-        switch (type) {
-            case OBJECT:
-                return "Record";
-            case ARRAY:
-                return "OrderedList";
-            case MULTISET:
-                return "UnorderedList";
-            default:
-                throw new IllegalArgumentException(String.valueOf(type));
-        }
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverBase.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverBase.java
deleted file mode 100644
index 5d89612..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverBase.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.DriverPropertyInfo;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
-
-public abstract class ADBDriverBase {
-
-    static final int JDBC_MAJOR_VERSION = 4;
-
-    static final int JDBC_MINOR_VERSION = 2;
-
-    static final String JDBC_SCHEME = "jdbc:";
-
-    static final String LOGGING_PROPERTY_SUFFIX = ".log.stderr";
-
-    protected final String urlScheme;
-
-    protected final int defaultApiPort;
-
-    protected volatile ADBDriverContext context;
-
-    public ADBDriverBase(String driverScheme, int defaultApiPort) {
-        this.urlScheme = JDBC_SCHEME + Objects.requireNonNull(driverScheme);
-        this.defaultApiPort = defaultApiPort;
-    }
-
-    protected static void registerDriver(java.sql.Driver driver) {
-        try {
-            DriverManager.registerDriver(driver);
-        } catch (SQLException e) {
-            DriverManager.println(String.format("Error registering driver %s. %s", driver.getClass().getName(), e));
-        }
-    }
-
-    private static void parseConnectionProperties(List<NameValuePair> inProps1, Properties inProps2,
-            ADBDriverContext driverContext, Map<ADBDriverProperty, Object> outProperties, SQLWarning outWarning)
-            throws SQLException {
-        for (NameValuePair pair : inProps1) {
-            String name = pair.getName();
-            String value = pair.getValue();
-            parseConnectionProperty(name, value, driverContext, outProperties, outWarning);
-        }
-        if (inProps2 != null) {
-            for (Enumeration<?> en = inProps2.propertyNames(); en.hasMoreElements();) {
-                String name = en.nextElement().toString();
-                String value = inProps2.getProperty(name);
-                parseConnectionProperty(name, value, driverContext, outProperties, outWarning);
-            }
-        }
-    }
-
-    private static void parseConnectionProperty(String name, String textValue, ADBDriverContext driverContext,
-            Map<ADBDriverProperty, Object> outProperties, SQLWarning outWarning) throws SQLException {
-        ADBDriverProperty property = driverContext.supportedProperties.get(name);
-        if (property == null) {
-            outWarning.setNextWarning(new SQLWarning(driverContext.errorReporter.warningParameterNotSupported(name)));
-            return;
-        }
-        if (textValue == null || textValue.isEmpty()) {
-            return;
-        }
-        Object value;
-        try {
-            value = Objects.requireNonNull(property.getValueParser().apply(textValue));
-        } catch (RuntimeException e) {
-            throw driverContext.errorReporter.errorParameterValueNotSupported(name);
-        }
-        outProperties.put(property, value);
-    }
-
-    private static Logger getParentLogger(Class<?> driverClass) {
-        return Logger.getLogger(driverClass.getPackage().getName());
-    }
-
-    protected static void setupLogging(Class<? extends java.sql.Driver> driverClass) {
-        String logLevel = System.getProperty(driverClass.getPackage().getName() + LOGGING_PROPERTY_SUFFIX);
-        if (logLevel == null) {
-            return;
-        }
-        Level level;
-        try {
-            level = Boolean.TRUE.toString().equals(logLevel) ? Level.ALL : Level.parse(logLevel.toUpperCase());
-        } catch (IllegalArgumentException e) {
-            // ignore
-            return;
-        }
-
-        ConsoleHandler ch = new ConsoleHandler();
-        ch.setLevel(level);
-        Logger parentLogger = getParentLogger(driverClass);
-        parentLogger.setLevel(level);
-        parentLogger.addHandler(ch);
-    }
-
-    public boolean acceptsURL(String url) {
-        return url.startsWith(urlScheme);
-    }
-
-    public Connection connect(String url, Properties info) throws SQLException {
-        if (!acceptsURL(url)) {
-            return null;
-        }
-        URI subUri;
-        try {
-            subUri = new URI(url.substring(JDBC_SCHEME.length()));
-        } catch (URISyntaxException e) {
-            throw createErrorReporter().errorParameterValueNotSupported("URL");
-        }
-        String host = subUri.getHost();
-        if (host == null) {
-            throw createErrorReporter().errorParameterValueNotSupported("URL");
-        }
-        int port = subUri.getPort();
-        if (port <= 0) {
-            port = defaultApiPort;
-        }
-
-        String catalog = ADBProtocol.DEFAULT_DATAVERSE;
-        String schema = null;
-        String path = subUri.getPath();
-        if (path != null && path.length() > 1 && path.startsWith("/")) {
-            String[] dataverse = path.substring(1).split("/");
-            switch (dataverse.length) {
-                case 2:
-                    schema = dataverse[1];
-                    // fall thru to 1
-                case 1:
-                    catalog = dataverse[0];
-                    break;
-            }
-        }
-
-        List<NameValuePair> urlParams = URLEncodedUtils.parse(subUri, StandardCharsets.UTF_8);
-
-        ADBDriverContext driverContext = getOrCreateDriverContext();
-        Map<ADBDriverProperty, Object> properties = new HashMap<>();
-        SQLWarning warning = new SQLWarning();
-        parseConnectionProperties(urlParams, info, driverContext, properties, warning);
-        warning = warning.getNextWarning() != null ? warning.getNextWarning() : null;
-
-        ADBProtocol protocol = createProtocol(host, port, properties, driverContext);
-        try {
-            String databaseVersion = protocol.connect();
-            return createConnection(protocol, url, databaseVersion, catalog, schema, warning);
-        } catch (SQLException e) {
-            try {
-                protocol.close();
-            } catch (SQLException e2) {
-                e.addSuppressed(e2);
-            }
-            throw e;
-        }
-    }
-
-    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
-        Collection<ADBDriverProperty> supportedProperties = getOrCreateDriverContext().supportedProperties.values();
-        DriverPropertyInfo[] result = new DriverPropertyInfo[supportedProperties.size()];
-        int i = 0;
-        for (ADBDriverProperty property : supportedProperties) {
-            result[i++] = new DriverPropertyInfo(property.getPropertyName(),
-                    property.getDefaultValue() != null ? property.getDefaultValue().toString() : null);
-        }
-        return result;
-    }
-
-    public int getMajorVersion() {
-        return getOrCreateDriverContext().driverVersion.majorVersion;
-    }
-
-    public int getMinorVersion() {
-        return getOrCreateDriverContext().driverVersion.minorVersion;
-    }
-
-    public boolean jdbcCompliant() {
-        return false;
-    }
-
-    public Logger getParentLogger() {
-        return getParentLogger(getClass());
-    }
-
-    private ADBDriverContext getOrCreateDriverContext() {
-        ADBDriverContext ctx = context;
-        if (ctx == null) {
-            synchronized (this) {
-                ctx = context;
-                if (ctx == null) {
-                    context = ctx = createDriverContext();
-                }
-            }
-        }
-        return ctx;
-    }
-
-    protected ADBDriverContext createDriverContext() {
-        return new ADBDriverContext(getClass(), getDriverSupportedProperties(), createErrorReporter());
-    }
-
-    protected Collection<ADBDriverProperty> getDriverSupportedProperties() {
-        return Arrays.asList(ADBDriverProperty.Common.values());
-    }
-
-    protected ADBErrorReporter createErrorReporter() {
-        return new ADBErrorReporter();
-    }
-
-    protected ADBProtocol createProtocol(String host, int port, Map<ADBDriverProperty, Object> properties,
-            ADBDriverContext driverContext) throws SQLException {
-        return new ADBProtocol(host, port, properties, driverContext);
-    }
-
-    protected ADBConnection createConnection(ADBProtocol protocol, String url, String databaseVersion, String catalog,
-            String schema, SQLWarning connectWarning) {
-        return new ADBConnection(protocol, url, databaseVersion, catalog, schema, connectWarning);
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverContext.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverContext.java
deleted file mode 100644
index 89f01e9..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverContext.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.logging.Logger;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectReader;
-import com.fasterxml.jackson.databind.ObjectWriter;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-
-final class ADBDriverContext {
-
-    final Class<? extends ADBDriverBase> driverClass;
-
-    final ADBErrorReporter errorReporter;
-
-    final ADBProductVersion driverVersion;
-
-    final Map<String, ADBDriverProperty> supportedProperties;
-
-    final Logger logger;
-
-    final ObjectReader genericObjectReader;
-
-    final ObjectWriter genericObjectWriter;
-
-    final ObjectReader admFormatObjectReader;
-
-    final ObjectWriter admFormatObjectWriter;
-
-    ADBDriverContext(Class<? extends ADBDriverBase> driverClass,
-            Collection<ADBDriverProperty> driverSupportedProperties, ADBErrorReporter errorReporter) {
-        this.driverClass = Objects.requireNonNull(driverClass);
-        this.errorReporter = Objects.requireNonNull(errorReporter);
-        this.logger = Logger.getLogger(driverClass.getName());
-        this.driverVersion = ADBProductVersion.parseDriverVersion(driverClass.getPackage());
-        this.supportedProperties = createPropertyIndexByName(driverSupportedProperties);
-
-        ObjectMapper genericObjectMapper = ADBProtocol.createObjectMapper();
-        this.genericObjectReader = genericObjectMapper.reader();
-        this.genericObjectWriter = genericObjectMapper.writer();
-        ObjectMapper admFormatObjectMapper = createADMFormatObjectMapper();
-        this.admFormatObjectReader = admFormatObjectMapper.reader();
-        this.admFormatObjectWriter = admFormatObjectMapper.writer();
-    }
-
-    protected ObjectMapper createADMFormatObjectMapper() {
-        ObjectMapper mapper = new ObjectMapper();
-        SimpleModule serdeModule = new SimpleModule(driverClass.getName());
-        ADBStatement.configureSerialization(serdeModule);
-        ADBRowStore.configureDeserialization(mapper, serdeModule);
-        mapper.registerModule(serdeModule);
-        return mapper;
-    }
-
-    private Map<String, ADBDriverProperty> createPropertyIndexByName(Collection<ADBDriverProperty> properties) {
-        Map<String, ADBDriverProperty> m = new LinkedHashMap<>();
-        for (ADBDriverProperty p : properties) {
-            m.put(p.getPropertyName(), p);
-        }
-        return Collections.unmodifiableMap(m);
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverProperty.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverProperty.java
deleted file mode 100644
index 1d1e67e..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverProperty.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.util.Objects;
-import java.util.function.Function;
-
-interface ADBDriverProperty {
-
-    String getPropertyName();
-
-    Function<String, ?> getValueParser();
-
-    Object getDefaultValue();
-
-    enum Common implements ADBDriverProperty {
-
-        USER("user", Function.identity(), null),
-        PASSWORD("password", Function.identity(), null),
-        CONNECT_TIMEOUT("connectTimeout", Integer::parseInt, null),
-        SOCKET_TIMEOUT("socketTimeout", Integer::parseInt, null),
-        MAX_WARNINGS("maxWarnings", Integer::parseInt, 10);
-
-        private final String propertyName;
-
-        private final Function<String, ?> valueParser;
-
-        private final Object defaultValue;
-
-        Common(String propertyName, Function<String, ?> valueParser, Object defaultValue) {
-            this.propertyName = Objects.requireNonNull(propertyName);
-            this.valueParser = Objects.requireNonNull(valueParser);
-            this.defaultValue = defaultValue;
-        }
-
-        @Override
-        public String getPropertyName() {
-            return propertyName;
-        }
-
-        public Function<String, ?> getValueParser() {
-            return valueParser;
-        }
-
-        public Object getDefaultValue() {
-            return defaultValue;
-        }
-
-        @Override
-        public String toString() {
-            return getPropertyName();
-        }
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBErrorReporter.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBErrorReporter.java
deleted file mode 100644
index f31e18a..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBErrorReporter.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.io.IOException;
-import java.sql.SQLClientInfoException;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.sql.SQLInvalidAuthorizationSpecException;
-import java.sql.SQLNonTransientConnectionException;
-import java.sql.SQLTimeoutException;
-import java.sql.SQLTransientConnectionException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import org.apache.http.conn.ConnectTimeoutException;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-
-final class ADBErrorReporter {
-
-    private static final List<Class<? extends IOException>> TRANSIENT_CONNECTION_ERRORS =
-            Arrays.asList(java.net.NoRouteToHostException.class, org.apache.http.NoHttpResponseException.class,
-                    org.apache.http.conn.HttpHostConnectException.class);
-
-    protected SQLException errorObjectClosed(Class<?> jdbcInterface) {
-        return new SQLException(String.format("%s is closed", jdbcInterface.getSimpleName()));
-    }
-
-    protected SQLFeatureNotSupportedException errorMethodNotSupported(Class<?> jdbcInterface, String methodName) {
-        return new SQLFeatureNotSupportedException(
-                String.format("Method %s.%s() is not supported", jdbcInterface.getName(), methodName));
-    }
-
-    protected SQLClientInfoException errorClientInfoMethodNotSupported(Class<?> jdbcInterface, String methodName) {
-        return new SQLClientInfoException(
-                String.format("Method %s.%s() is not supported", jdbcInterface.getName(), methodName),
-                Collections.emptyMap());
-    }
-
-    protected SQLException errorParameterNotSupported(String parameterName) {
-        return new SQLException(String.format("Unsupported parameter %s", parameterName));
-    }
-
-    protected String warningParameterNotSupported(String parameterName) {
-        return String.format("Unsupported parameter %s", parameterName);
-    }
-
-    protected SQLException errorParameterValueNotSupported(String parameterName) {
-        return new SQLException(String.format("Unsupported or invalid value of %s parameter", parameterName));
-    }
-
-    protected String warningParameterValueNotSupported(String parameterName) {
-        return String.format("Ignored unsupported or invalid value of %s parameter", parameterName);
-    }
-
-    protected SQLException errorIncompatibleMode(String mode) {
-        return new SQLException(String.format("Operation cannot be performed in %s mode", mode));
-    }
-
-    protected SQLException errorInProtocol() {
-        return new SQLNonTransientConnectionException("Protocol error", SQLState.CONNECTION_FAILURE.code);
-    }
-
-    protected SQLException errorInProtocol(String badValue) {
-        return new SQLNonTransientConnectionException(String.format("Protocol error. Unexpected %s", badValue),
-                SQLState.CONNECTION_FAILURE.code);
-    }
-
-    protected SQLException errorInProtocol(JsonProcessingException e) {
-        return new SQLNonTransientConnectionException(String.format("Protocol error. %s", getMessage(e)),
-                SQLState.CONNECTION_FAILURE.code, e);
-    }
-
-    protected SQLException errorInConnection(String badValue) {
-        return new SQLNonTransientConnectionException(String.format("Connection error. Unexpected %s", badValue),
-                SQLState.CONNECTION_FAILURE.code);
-    }
-
-    protected SQLException errorInConnection(IOException e) {
-        String message = String.format("Connection error. %s", getMessage(e));
-        return e instanceof ConnectTimeoutException ? errorTimeout(message, e)
-                : couldBeTransientConnectionError(e)
-                        ? new SQLTransientConnectionException(message, SQLState.CONNECTION_FAILURE.code, e)
-                        : new SQLNonTransientConnectionException(message, SQLState.CONNECTION_FAILURE.code, e);
-    }
-
-    protected SQLException errorClosingResource(IOException e) {
-        return new SQLException(String.format("Error closing resources. %s", getMessage(e)), e);
-    }
-
-    protected SQLInvalidAuthorizationSpecException errorAuth() {
-        return new SQLInvalidAuthorizationSpecException("Authentication/authorization error",
-                SQLState.CONNECTION_REJECTED.code);
-    }
-
-    protected SQLException errorColumnNotFound(String columnNameOrNumber) {
-        return new SQLException(String.format("Column %s was not found", columnNameOrNumber));
-    }
-
-    protected SQLException errorUnexpectedColumnValue(ADBDatatype type, String columnName) {
-        return new SQLException(
-                String.format("Unexpected value of type %s for column %s", type.getTypeName(), columnName));
-    }
-
-    protected SQLException errorUnwrapTypeMismatch(Class<?> iface) {
-        return new SQLException(String.format("Cannot unwrap to %s", iface.getName()));
-    }
-
-    protected SQLException errorInvalidStatementCategory() {
-        return new SQLException("Invalid statement category");
-    }
-
-    protected SQLException errorUnexpectedType(Class<?> type) {
-        return new SQLException(String.format("Unexpected type %s", type.getName()), SQLState.INVALID_DATE_TYPE.code);
-    }
-
-    protected SQLException errorUnexpectedType(byte typeTag) {
-        return new SQLException(String.format("Unexpected type %s", typeTag), SQLState.INVALID_DATE_TYPE.code);
-    }
-
-    protected SQLException errorUnexpectedType(ADBDatatype type) {
-        return new SQLException(String.format("Unexpected type %s", type.getTypeName()),
-                SQLState.INVALID_DATE_TYPE.code);
-    }
-
-    protected SQLException errorInvalidValueOfType(ADBDatatype type) {
-        return new SQLException(String.format("Invalid value of type %s", type), SQLState.INVALID_DATE_TYPE.code);
-    }
-
-    protected SQLException errorNoResult() {
-        return new SQLException("Result is unavailable");
-    }
-
-    protected SQLException errorBadResultSignature() {
-        return new SQLException("Cannot infer result columns");
-    }
-
-    protected SQLException errorNoCurrentRow() {
-        return new SQLException("No current row", SQLState.INVALID_CURSOR_POSITION.code);
-    }
-
-    protected SQLException errorInRequestGeneration(IOException e) {
-        return new SQLException(String.format("Cannot create request. %s", getMessage(e)), e);
-    }
-
-    protected SQLException errorInResultHandling(IOException e) {
-        return new SQLException(String.format("Cannot reading result. %s", getMessage(e)), e);
-    }
-
-    protected SQLTimeoutException errorTimeout() {
-        return new SQLTimeoutException();
-    }
-
-    protected SQLTimeoutException errorTimeout(String message, IOException cause) {
-        return new SQLTimeoutException(message, cause);
-    }
-
-    protected boolean couldBeTransientConnectionError(IOException e) {
-        if (e != null) {
-            for (Class<? extends IOException> c : TRANSIENT_CONNECTION_ERRORS) {
-                if (c.isInstance(e)) {
-                    return true;
-                }
-            }
-
-        }
-        return false;
-    }
-
-    protected String getMessage(Exception e) {
-        String message = e != null ? e.getMessage() : null;
-        return message != null ? message : "";
-    }
-
-    public enum SQLState {
-        CONNECTION_REJECTED("08004"),
-        CONNECTION_FAILURE("08006"),
-        INVALID_DATE_TYPE("HY004"),
-        INVALID_CURSOR_POSITION("HY108");
-
-        private final String code;
-
-        SQLState(String code) {
-            this.code = Objects.requireNonNull(code);
-        }
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBMetaStatement.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBMetaStatement.java
deleted file mode 100644
index 7fa8127..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBMetaStatement.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.sql.DatabaseMetaData;
-import java.sql.JDBCType;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-public class ADBMetaStatement extends ADBStatement {
-
-    public static final String SCHEMALESS = "SCHEMALESS";
-    public static final String TABLE = "TABLE";
-    public static final String VIEW = "VIEW";
-
-    protected ADBMetaStatement(ADBConnection connection) {
-        super(connection, null, null);
-    }
-
-    ADBResultSet executeGetCatalogsQuery() throws SQLException {
-        checkClosed();
-
-        StringBuilder sql = new StringBuilder(256);
-
-        sql.append("select TABLE_CAT ");
-        sql.append("from Metadata.`Dataverse` ");
-        sql.append("let name = decode_dataverse_name(DataverseName), ");
-        sql.append("TABLE_CAT = name[0] ");
-        sql.append("where array_length(name) between 1 and 2 ");
-        sql.append("group by TABLE_CAT ");
-        sql.append("order by TABLE_CAT");
-
-        return executeQueryImpl(sql.toString(), null);
-    }
-
-    ADBResultSet executeGetSchemasQuery(String catalog, String schemaPattern) throws SQLException {
-        checkClosed();
-
-        StringBuilder sql = new StringBuilder(512);
-        sql.append("select TABLE_SCHEM, TABLE_CATALOG ");
-        sql.append("from Metadata.`Dataverse` ");
-        sql.append("let name = decode_dataverse_name(DataverseName), ");
-        sql.append("TABLE_CATALOG = name[0], ");
-        sql.append("TABLE_SCHEM = case array_length(name) when 1 then null else name[1] end ");
-        sql.append("where array_length(name) between 1 and 2 ");
-        if (catalog != null) {
-            sql.append("and TABLE_CATALOG = $1 ");
-        }
-        if (schemaPattern != null) {
-            sql.append("and if_null(TABLE_SCHEM, '') like $2 ");
-        }
-        sql.append("order by TABLE_CATALOG, TABLE_SCHEM");
-
-        return executeQueryImpl(sql.toString(), Arrays.asList(catalog, schemaPattern));
-    }
-
-    ADBResultSet executeGetTablesQuery(String catalog, String schemaPattern, String tableNamePattern, String[] types)
-            throws SQLException {
-        checkClosed();
-
-        String datasetTermTabular = getDatasetTerm(true);
-        String datasetTermNonTabular = getDatasetTerm(false);
-        String viewTermTabular = getViewTerm(true);
-        String viewTermNonTabular = getViewTerm(false);
-
-        StringBuilder sql = new StringBuilder(1024);
-        sql.append("select TABLE_CAT, TABLE_SCHEM, TABLE_NAME, TABLE_TYPE, null REMARKS, null TYPE_CAT, ");
-        sql.append("null TYPE_SCHEM, null TYPE_NAME, null SELF_REFERENCING_COL_NAME, null REF_GENERATION ");
-        sql.append("from Metadata.`Dataset` ds join Metadata.`Datatype` dt ");
-        sql.append("on ds.DatatypeDataverseName = dt.DataverseName and ds.DatatypeName = dt.DatatypeName ");
-        sql.append("let dvname = decode_dataverse_name(ds.DataverseName), ");
-        sql.append("isDataset = (ds.DatasetType = 'INTERNAL' or ds.DatasetType = 'EXTERNAL'), ");
-        sql.append("isView = ds.DatasetType = 'VIEW', ");
-        sql.append("hasFields = array_length(dt.Derived.Record.Fields) > 0, ");
-        sql.append("TABLE_CAT = dvname[0], ");
-        sql.append("TABLE_SCHEM = case array_length(dvname) when 1 then null else dvname[1] end, ");
-        sql.append("TABLE_NAME = ds.DatasetName, ");
-        sql.append("TABLE_TYPE = case ");
-        sql.append("when isDataset then (case when hasFields then '").append(datasetTermTabular).append("' else '")
-                .append(datasetTermNonTabular).append("' end) ");
-        sql.append("when isView then (case when hasFields then '").append(viewTermTabular).append("' else '")
-                .append(viewTermNonTabular).append("' end) ");
-        sql.append("else null end ");
-        sql.append("where array_length(dvname) between 1 and 2 ");
-        if (catalog != null) {
-            sql.append("and TABLE_CAT = $1 ");
-        }
-        if (schemaPattern != null) {
-            sql.append("and if_null(TABLE_SCHEM, '') like $2 ");
-        }
-        if (tableNamePattern != null) {
-            sql.append("and TABLE_NAME like $3 ");
-        }
-        sql.append("and TABLE_TYPE ").append(types != null ? "in $4" : "is not null").append(" ");
-        sql.append("order by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM, TABLE_NAME");
-
-        return executeQueryImpl(sql.toString(),
-                Arrays.asList(catalog, schemaPattern, tableNamePattern, types != null ? Arrays.asList(types) : null));
-    }
-
-    ADBResultSet executeGetColumnsQuery(String catalog, String schemaPattern, String tableNamePattern,
-            String columnNamePattern) throws SQLException {
-        checkClosed();
-
-        StringBuilder sql = new StringBuilder(2048);
-        sql.append("select TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_SIZE, ");
-        sql.append("1 BUFFER_LENGTH, null DECIMAL_DIGITS, 2 NUM_PREC_RADIX, NULLABLE, ");
-        sql.append("null REMARKS, null COLUMN_DEF, DATA_TYPE SQL_DATA_TYPE,");
-        sql.append("0 SQL_DATETIME_SUB, COLUMN_SIZE CHAR_OCTET_LENGTH, ORDINAL_POSITION, ");
-        sql.append("case NULLABLE when 0 then 'NO' else 'YES' end IS_NULLABLE, ");
-        sql.append("null SCOPE_CATALOG, null SCOPE_SCHEMA, null SCOPE_TABLE, null SOURCE_DATA_TYPE, ");
-        sql.append("'NO' IS_AUTOINCREMENT, 'NO' IS_GENERATEDCOLUMN ");
-        sql.append("from Metadata.`Dataset` ds ");
-        sql.append("join Metadata.`Datatype` dt ");
-        sql.append("on ds.DatatypeDataverseName = dt.DataverseName and ds.DatatypeName = dt.DatatypeName ");
-        sql.append("unnest dt.Derived.Record.Fields as field at fieldpos ");
-        sql.append("left join Metadata.`Datatype` dt2 ");
-        sql.append(
-                "on field.FieldType = dt2.DatatypeName and ds.DataverseName = dt2.DataverseName and dt2.Derived is known ");
-        sql.append("let dvname = decode_dataverse_name(ds.DataverseName), ");
-        sql.append("TABLE_CAT = dvname[0], ");
-        sql.append("TABLE_SCHEM = case array_length(dvname) when 1 then null else dvname[1] end, ");
-        sql.append("TABLE_NAME = ds.DatasetName, ");
-        sql.append("COLUMN_NAME = field.FieldName, ");
-        sql.append("TYPE_NAME = case ");
-        for (ADBDatatype nestedType : new ADBDatatype[] { ADBDatatype.OBJECT, ADBDatatype.ARRAY,
-                ADBDatatype.MULTISET }) {
-            sql.append(String.format("when dt2.Derived.%s is known then '%s' ",
-                    ADBDatatype.getDerivedRecordName(nestedType), nestedType.getTypeName()));
-        }
-        sql.append("else field.FieldType end, ");
-        sql.append("DATA_TYPE = ");
-        sql.append("case TYPE_NAME ");
-        for (ADBDatatype type : ADBDatatype.values()) {
-            JDBCType jdbcType = type.getJdbcType();
-            if (type.isNullOrMissing() || jdbcType.equals(JDBCType.OTHER)) {
-                // will be handled by the 'else' clause
-                continue;
-            }
-            sql.append("when '").append(type.getTypeName()).append("' ");
-            sql.append("then ").append(jdbcType.getVendorTypeNumber()).append(" ");
-        }
-        sql.append("else ").append(JDBCType.OTHER.getVendorTypeNumber()).append(" end, ");
-
-        sql.append("COLUMN_SIZE = case field.FieldType when 'string' then 32767 else 8 end, "); // TODO:based on type
-        sql.append("ORDINAL_POSITION = fieldpos, ");
-        sql.append("NULLABLE = case when field.IsNullable or field.IsMissable then 1 else 0 end ");
-        sql.append("where array_length(dvname) between 1 and 2 ");
-
-        sql.append("and array_length(dt.Derived.Record.Fields) > 0 ");
-        if (catalog != null) {
-            sql.append("and TABLE_CAT = $1 ");
-        }
-        if (schemaPattern != null) {
-            sql.append("and if_null(TABLE_SCHEM, '') like $2 ");
-        }
-        if (tableNamePattern != null) {
-            sql.append("and TABLE_NAME like $3 ");
-        }
-        if (columnNamePattern != null) {
-            sql.append("and COLUMN_NAME like $4 ");
-        }
-        sql.append("order by TABLE_CAT, TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION");
-
-        return executeQueryImpl(sql.toString(),
-                Arrays.asList(catalog, schemaPattern, tableNamePattern, columnNamePattern));
-    }
-
-    ADBResultSet executeGetPrimaryKeysQuery(String catalog, String schema, String table) throws SQLException {
-        checkClosed();
-
-        StringBuilder sql = new StringBuilder(1024);
-        sql.append("select TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, KEY_SEQ, null PK_NAME ");
-        sql.append("from Metadata.`Dataset` ds unnest ds.InternalDetails.PrimaryKey pki at pkipos ");
-        sql.append("let dvname = decode_dataverse_name(ds.DataverseName), ");
-        sql.append("TABLE_CAT = dvname[0], ");
-        sql.append("TABLE_SCHEM = case array_length(dvname) when 1 then null else dvname[1] end, ");
-        sql.append("TABLE_NAME = ds.DatasetName, ");
-        sql.append("COLUMN_NAME = pki[0], ");
-        sql.append("KEY_SEQ = pkipos ");
-        sql.append("where array_length(dvname) between 1 and 2 ");
-        sql.append("and (every pk in ds.InternalDetails.PrimaryKey satisfies array_length(pk) = 1 end) ");
-        sql.append("and (every si in ds.InternalDetails.KeySourceIndicator satisfies si = 0 end ) ");
-        if (catalog != null) {
-            sql.append("and TABLE_CAT = $1 ");
-        }
-        if (schema != null) {
-            sql.append("and if_null(TABLE_SCHEM, '') like $2 ");
-        }
-        if (table != null) {
-            sql.append("and TABLE_NAME like $3 ");
-        }
-        sql.append("order by COLUMN_NAME");
-
-        return executeQueryImpl(sql.toString(), Arrays.asList(catalog, schema, table));
-    }
-
-    ADBResultSet executeGetTableTypesQuery() throws SQLException {
-        checkClosed();
-
-        LinkedHashSet<String> tableTypes = new LinkedHashSet<>();
-        tableTypes.add(getDatasetTerm(true));
-        tableTypes.add(getDatasetTerm(false));
-        tableTypes.add(getViewTerm(true));
-        tableTypes.add(getViewTerm(false));
-
-        List<ADBColumn> columns = Collections.singletonList(new ADBColumn("TABLE_TYPE", ADBDatatype.STRING, false));
-
-        AbstractValueSerializer stringSer = getADMFormatSerializer(String.class);
-        ArrayNode result = (ArrayNode) connection.protocol.driverContext.genericObjectReader.createArrayNode();
-        for (String tableType : tableTypes) {
-            result.addObject().put("TABLE_TYPE", stringSer.serializeToString(tableType));
-        }
-
-        return createSystemResultSet(columns, result);
-    }
-
-    ADBResultSet executeGetTypeInfoQuery() throws SQLException {
-        checkClosed();
-
-        AbstractValueSerializer int16Ser = getADMFormatSerializer(Short.class);
-        AbstractValueSerializer int32Ser = getADMFormatSerializer(Integer.class);
-        AbstractValueSerializer stringSer = getADMFormatSerializer(String.class);
-
-        List<ADBColumn> columns = new ArrayList<>();
-        columns.add(new ADBColumn("TYPE_NAME", ADBDatatype.STRING, false));
-        columns.add(new ADBColumn("DATA_TYPE", ADBDatatype.INTEGER, false));
-        columns.add(new ADBColumn("PRECISION", ADBDatatype.INTEGER, true));
-        columns.add(new ADBColumn("LITERAL_PREFIX", ADBDatatype.STRING, true));
-        columns.add(new ADBColumn("LITERAL_SUFFIX", ADBDatatype.STRING, true));
-        columns.add(new ADBColumn("CREATE_PARAMS", ADBDatatype.STRING, true));
-        columns.add(new ADBColumn("NULLABLE", ADBDatatype.SMALLINT, true));
-        columns.add(new ADBColumn("CASE_SENSITIVE", ADBDatatype.BOOLEAN, true));
-        columns.add(new ADBColumn("SEARCHABLE", ADBDatatype.SMALLINT, true));
-        columns.add(new ADBColumn("UNSIGNED_ATTRIBUTE", ADBDatatype.BOOLEAN, true));
-        columns.add(new ADBColumn("FIXED_PREC_SCALE", ADBDatatype.BOOLEAN, true));
-        columns.add(new ADBColumn("AUTO_INCREMENT", ADBDatatype.BOOLEAN, true));
-        columns.add(new ADBColumn("LOCAL_TYPE_NAME", ADBDatatype.STRING, true));
-        columns.add(new ADBColumn("MINIMUM_SCALE", ADBDatatype.SMALLINT, true));
-        columns.add(new ADBColumn("MAXIMUM_SCALE", ADBDatatype.SMALLINT, true));
-        columns.add(new ADBColumn("SQL_DATA_TYPE", ADBDatatype.INTEGER, true));
-        columns.add(new ADBColumn("SQL_DATETIME_SUB", ADBDatatype.INTEGER, true));
-        columns.add(new ADBColumn("NUM_PREC_RADIX", ADBDatatype.INTEGER, true));
-
-        ArrayNode result = (ArrayNode) connection.protocol.driverContext.genericObjectReader.createArrayNode();
-        populateTypeInfo(result.addObject(), ADBDatatype.BOOLEAN, 1, null, null, null, null, null, null, int16Ser,
-                int32Ser, stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.TINYINT, 3, 10, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.SMALLINT, 5, 10, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.INTEGER, 10, 10, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.BIGINT, 19, 10, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.FLOAT, 7, 2, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.DOUBLE, 15, 2, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.DATE, 32, null, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer); // TODO:precision
-        populateTypeInfo(result.addObject(), ADBDatatype.TIME, 32, null, 0, 0, false, null, null, int16Ser, int32Ser,
-                stringSer); // TODO:precision
-        populateTypeInfo(result.addObject(), ADBDatatype.DATETIME, 32, null, 0, 0, false, null, null, int16Ser,
-                int32Ser, stringSer); // TODO:precision
-        populateTypeInfo(result.addObject(), ADBDatatype.YEARMONTHDURATION, 32, null, 0, 0, false, null, null, int16Ser,
-                int32Ser, stringSer); // TODO:precision
-        populateTypeInfo(result.addObject(), ADBDatatype.DAYTIMEDURATION, 32, null, 0, 0, false, null, null, int16Ser,
-                int32Ser, stringSer); // TODO:precision
-        populateTypeInfo(result.addObject(), ADBDatatype.DURATION, 32, null, 0, 0, false, null, null, int16Ser,
-                int32Ser, stringSer); // TODO:precision
-        populateTypeInfo(result.addObject(), ADBDatatype.STRING, 32767, null, null, null, true, "'", "'", int16Ser,
-                int32Ser, stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.ARRAY, 32767, null, 0, 0, false, null, null, int16Ser,
-                int32Ser, stringSer);
-        populateTypeInfo(result.addObject(), ADBDatatype.OBJECT, 32767, null, 0, 0, false, null, null, int16Ser,
-                int32Ser, stringSer);
-
-        return createSystemResultSet(columns, result);
-    }
-
-    private void populateTypeInfo(ObjectNode typeInfo, ADBDatatype type, int precision, Integer precisionRadix,
-            Integer minScale, Integer maxScale, Boolean searchable, String literalPrefix, String literalSuffix,
-            ADBPreparedStatement.AbstractValueSerializer int16Ser,
-            ADBPreparedStatement.AbstractValueSerializer int32Ser,
-            ADBPreparedStatement.AbstractValueSerializer stringSer) {
-        typeInfo.put("TYPE_NAME", stringSer.serializeToString(type.getTypeName()));
-        typeInfo.put("DATA_TYPE", int32Ser.serializeToString(type.getJdbcType().getVendorTypeNumber()));
-        typeInfo.put("PRECISION", int32Ser.serializeToString(precision));
-        typeInfo.put("LITERAL_PREFIX", literalPrefix != null ? stringSer.serializeToString(literalPrefix) : null);
-        typeInfo.put("LITERAL_SUFFIX", literalSuffix != null ? stringSer.serializeToString(literalSuffix) : null);
-        typeInfo.putNull("CREATE_PARAMS");
-        typeInfo.put("NULLABLE", int16Ser.serializeToString((short) DatabaseMetaData.typeNullable));
-        typeInfo.put("CASE_SENSITIVE", false);
-        typeInfo.put("SEARCHABLE",
-                int16Ser.serializeToString((short) (searchable == null ? DatabaseMetaData.typePredNone
-                        : searchable ? DatabaseMetaData.typeSearchable : DatabaseMetaData.typePredBasic)));
-        typeInfo.put("UNSIGNED_ATTRIBUTE", false);
-        typeInfo.put("FIXED_PREC_SCALE", false);
-        typeInfo.putNull("AUTO_INCREMENT");
-        typeInfo.putNull("LOCAL_TYPE_NAME");
-        typeInfo.put("MINIMUM_SCALE", minScale != null ? int16Ser.serializeToString(minScale.shortValue()) : null);
-        typeInfo.put("MAXIMUM_SCALE", maxScale != null ? int16Ser.serializeToString(maxScale.shortValue()) : null);
-        typeInfo.put("SQL_DATA_TYPE", int32Ser.serializeToString(type.getTypeTag()));
-        typeInfo.putNull("SQL_DATETIME_SUB");
-        typeInfo.put("NUM_PREC_RADIX", int32Ser.serializeToString(precisionRadix != null ? precisionRadix : 10));
-    }
-
-    ADBResultSet executeEmptyResultQuery() throws SQLException {
-        checkClosed();
-        return createEmptyResultSet();
-    }
-
-    @Override
-    ADBStatement getResultSetStatement(ADBResultSet rs) {
-        return null;
-    }
-
-    protected String getDatasetTerm(boolean tabular) {
-        return tabular ? TABLE : SCHEMALESS + " " + TABLE;
-    }
-
-    protected String getViewTerm(boolean tabular) {
-        return tabular ? VIEW : SCHEMALESS + " " + VIEW;
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBParameterMetaData.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBParameterMetaData.java
deleted file mode 100644
index d612b3f..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBParameterMetaData.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.sql.ParameterMetaData;
-import java.sql.Types;
-import java.util.Objects;
-
-final class ADBParameterMetaData extends ADBWrapperSupport implements ParameterMetaData {
-
-    final ADBPreparedStatement statement;
-
-    final int parameterCount;
-
-    public ADBParameterMetaData(ADBPreparedStatement statement, int parameterCount) {
-        this.statement = Objects.requireNonNull(statement);
-        this.parameterCount = parameterCount;
-    }
-
-    @Override
-    public int getParameterCount() {
-        return parameterCount;
-    }
-
-    @Override
-    public int getParameterMode(int parameterIndex) {
-        return parameterModeIn;
-    }
-
-    @Override
-    public int getParameterType(int parameterIndex) {
-        return Types.OTHER; // any
-    }
-
-    @Override
-    public String getParameterTypeName(int parameterIndex) {
-        return "";
-    }
-
-    @Override
-    public String getParameterClassName(int parameterIndex) {
-        return Object.class.getName();
-    }
-
-    @Override
-    public int isNullable(int parameterIndex) {
-        return parameterNullable;
-    }
-
-    @Override
-    public boolean isSigned(int parameterIndex) {
-        return false;
-    }
-
-    @Override
-    public int getPrecision(int parameterIndex) {
-        return 0;
-    }
-
-    @Override
-    public int getScale(int parameterIndex) {
-        return 0;
-    }
-
-    @Override
-    protected ADBErrorReporter getErrorReporter() {
-        return statement.getErrorReporter();
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBPreparedStatement.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBPreparedStatement.java
deleted file mode 100644
index 98129fd..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBPreparedStatement.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.NClob;
-import java.sql.ParameterMetaData;
-import java.sql.PreparedStatement;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLType;
-import java.sql.SQLXML;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.List;
-
-final class ADBPreparedStatement extends ADBStatement implements PreparedStatement {
-
-    final String sql;
-
-    final List<Object> args;
-
-    final List<ADBColumn> resultColumns;
-
-    ADBPreparedStatement(ADBConnection connection, String sql, String catalog, String schema) throws SQLException {
-        super(connection, catalog, schema);
-        // TODO:timeout
-        ADBProtocol.QueryServiceResponse response =
-                connection.protocol.submitStatement(sql, null, false, true, 0, catalog, schema);
-        int parameterCount = connection.protocol.getStatementParameterCount(response);
-        boolean isQuery = connection.protocol.isStatementCategory(response,
-                ADBProtocol.QueryServiceResponse.StatementCategory.QUERY);
-        List<ADBColumn> columns = isQuery ? connection.protocol.getColumns(response) : Collections.emptyList();
-        this.sql = sql;
-        this.args = Arrays.asList(new Object[parameterCount]);
-        this.resultColumns = columns;
-    }
-
-    // Metadata
-
-    @Override
-    public ParameterMetaData getParameterMetaData() throws SQLException {
-        checkClosed();
-        return new ADBParameterMetaData(this, args.size());
-    }
-
-    @Override
-    public ResultSetMetaData getMetaData() throws SQLException {
-        checkClosed();
-        return new ADBResultSetMetaData(this, resultColumns);
-    }
-
-    // Execution
-
-    @Override
-    public ResultSet executeQuery() throws SQLException {
-        checkClosed();
-        return executeQueryImpl(sql, args);
-    }
-
-    @Override
-    public ADBResultSet executeQuery(String sql) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeQuery");
-    }
-
-    @Override
-    public long executeLargeUpdate() throws SQLException {
-        return executeUpdateImpl(sql, args);
-    }
-
-    @Override
-    public int executeUpdate() throws SQLException {
-        return executeUpdateImpl(sql, args);
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeLargeUpdate");
-    }
-
-    @Override
-    public int executeUpdate(String sql) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeUpdate");
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeLargeUpdate");
-    }
-
-    @Override
-    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeUpdate");
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeLargeUpdate");
-    }
-
-    @Override
-    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeUpdate");
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeLargeUpdate");
-    }
-
-    @Override
-    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "executeUpdate");
-    }
-
-    @Override
-    public boolean execute() throws SQLException {
-        return executeImpl(sql, args);
-    }
-
-    @Override
-    public boolean execute(String sql) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "execute");
-    }
-
-    @Override
-    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "execute");
-    }
-
-    @Override
-    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "execute");
-    }
-
-    @Override
-    public boolean execute(String sql, String[] columnNames) throws SQLException {
-        // Prohibited on PreparedStatement
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "execute");
-    }
-
-    @Override
-    public void addBatch() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "addBatch");
-    }
-
-    @Override
-    public void setEscapeProcessing(boolean enable) throws SQLException {
-        checkClosed();
-        // ignore as the statement has already been parsed
-    }
-
-    // Parameter bindings
-
-    @Override
-    public void clearParameters() throws SQLException {
-        checkClosed();
-        for (int i = 0, n = args.size(); i < n; i++) {
-            args.set(i, null);
-        }
-    }
-
-    private int argIndex(int parameterIndex) throws SQLException {
-        boolean ok = 0 < parameterIndex && parameterIndex <= args.size();
-        if (!ok) {
-            throw getErrorReporter().errorParameterValueNotSupported("parameterIndex");
-        }
-        return parameterIndex - 1;
-    }
-
-    private void setArg(int parameterIndex, Object v) throws SQLException {
-        args.set(argIndex(parameterIndex), v);
-    }
-
-    // Basic types
-
-    @Override
-    public void setNull(int parameterIndex, int sqlType) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, null);
-    }
-
-    @Override
-    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
-        checkClosed();
-        setNull(parameterIndex, sqlType);
-    }
-
-    @Override
-    public void setBoolean(int parameterIndex, boolean v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setByte(int parameterIndex, byte v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setShort(int parameterIndex, short v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setInt(int parameterIndex, int v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setLong(int parameterIndex, long v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setFloat(int parameterIndex, float v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setDouble(int parameterIndex, double v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setBigDecimal(int parameterIndex, BigDecimal v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setString(int parameterIndex, String v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setNString(int parameterIndex, String v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setDate(int parameterIndex, java.sql.Date v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setDate(int parameterIndex, java.sql.Date v, Calendar cal) throws SQLException {
-        checkClosed();
-        setDate(parameterIndex, v);
-    }
-
-    @Override
-    public void setTime(int parameterIndex, java.sql.Time v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setTime(int parameterIndex, java.sql.Time v, Calendar cal) throws SQLException {
-        checkClosed();
-        setTime(parameterIndex, v);
-    }
-
-    @Override
-    public void setTimestamp(int parameterIndex, java.sql.Timestamp v) throws SQLException {
-        checkClosed();
-        setArg(parameterIndex, v);
-    }
-
-    @Override
-    public void setTimestamp(int parameterIndex, java.sql.Timestamp v, Calendar cal) throws SQLException {
-        checkClosed();
-        setTimestamp(parameterIndex, v);
-    }
-
-    // Generic (setObject)
-
-    @Override
-    public void setObject(int parameterIndex, Object v) throws SQLException {
-        checkClosed();
-        if (v == null || isSetObjectCompatible(v.getClass())) {
-            setArg(parameterIndex, v);
-        } else {
-            throw getErrorReporter().errorParameterValueNotSupported("object");
-        }
-    }
-
-    @Override
-    public void setObject(int parameterIndex, Object v, int targetSqlType) throws SQLException {
-        setObject(parameterIndex, v); // TODO:revisit
-    }
-
-    @Override
-    public void setObject(int parameterIndex, Object v, SQLType targetSqlType) throws SQLException {
-        setObject(parameterIndex, v, targetSqlType.getVendorTypeNumber()); // TODO:revisit
-    }
-
-    @Override
-    public void setObject(int parameterIndex, Object v, int targetSqlType, int scaleOrLength) throws SQLException {
-        setObject(parameterIndex, v, targetSqlType); // TODO:revisit
-    }
-
-    @Override
-    public void setObject(int parameterIndex, Object v, SQLType targetSqlType, int scaleOrLength) throws SQLException {
-        setObject(parameterIndex, v, targetSqlType.getVendorTypeNumber()); // TODO:revisit
-    }
-
-    // Unsupported
-
-    @Override
-    public void setBytes(int parameterIndex, byte[] v) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setBytes");
-    }
-
-    @Override
-    public void setRef(int parameterIndex, Ref x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setRef");
-    }
-
-    @Override
-    public void setRowId(int parameterIndex, RowId x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setRowId");
-    }
-
-    @Override
-    public void setURL(int parameterIndex, URL v) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setURL");
-    }
-
-    // Unsupported - streams
-
-    @Override
-    public void setAsciiStream(int parameterIndex, InputStream v) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setAsciiStream");
-    }
-
-    @Override
-    public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setAsciiStream");
-    }
-
-    @Override
-    public void setAsciiStream(int parameterIndex, InputStream v, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setAsciiStream");
-    }
-
-    @Override
-    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setBinaryStream");
-    }
-
-    @Override
-    public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setBinaryStream");
-    }
-
-    @Override
-    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setBinaryStream");
-    }
-
-    @Override
-    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setCharacterStream");
-    }
-
-    @Override
-    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setCharacterStream");
-    }
-
-    @Override
-    public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setCharacterStream");
-    }
-
-    @Override
-    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setNCharacterStream");
-    }
-
-    @Override
-    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setNCharacterStream");
-    }
-
-    @Override
-    public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setUnicodeStream");
-    }
-
-    // Unsupported - LOB, Array, SQLXML
-
-    @Override
-    public void setArray(int parameterIndex, Array x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setArray");
-    }
-
-    @Override
-    public void setBlob(int parameterIndex, Blob x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setBlob");
-    }
-
-    @Override
-    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setBlob");
-    }
-
-    @Override
-    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setBlob");
-    }
-
-    @Override
-    public void setClob(int parameterIndex, Clob x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setClob");
-    }
-
-    @Override
-    public void setClob(int parameterIndex, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setClob");
-    }
-
-    @Override
-    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setClob");
-    }
-
-    @Override
-    public void setNClob(int parameterIndex, NClob value) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setNClob");
-    }
-
-    @Override
-    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setNClob");
-    }
-
-    @Override
-    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setNClob");
-    }
-
-    @Override
-    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(PreparedStatement.class, "setSQLXML");
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProductVersion.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProductVersion.java
deleted file mode 100644
index 5255d75..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProductVersion.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-final class ADBProductVersion {
-
-    public static final String ASTERIXDB = "Apache AsterixDB";
-
-    private static final Pattern DATABASE_VERSION_PATTERN =
-            Pattern.compile("(?<name>[^/]+)(?:/(?<ver>(?:(?<vermj>\\d+)(?:\\.(?<vermn>\\d+))?)?.*))?");
-
-    final String productName;
-
-    final String productVersion;
-
-    final int majorVersion;
-
-    final int minorVersion;
-
-    private ADBProductVersion(String productName, String productVersion, int majorVersion, int minorVersion) {
-        this.productName = productName != null ? productName : ASTERIXDB;
-        this.productVersion = productVersion != null ? productVersion : majorVersion + "." + minorVersion;
-        this.majorVersion = majorVersion;
-        this.minorVersion = minorVersion;
-    }
-
-    static ADBProductVersion parseDriverVersion(Package driverPackage) {
-        int majorVersion = 0, minorVersion = 0;
-        String productName = driverPackage.getImplementationTitle();
-        if (productName == null) {
-            productName = ASTERIXDB;
-        }
-        String productVersion = driverPackage.getImplementationVersion();
-        if (productVersion != null) {
-            String[] v = productVersion.split("\\.");
-            try {
-                majorVersion = Integer.parseInt(v[0]);
-                if (v.length > 1) {
-                    minorVersion = Integer.parseInt(v[1]);
-                }
-            } catch (NumberFormatException e) {
-                // ignore
-            }
-        }
-        return new ADBProductVersion(productName, productVersion, majorVersion, minorVersion);
-    }
-
-    static ADBProductVersion parseDatabaseVersion(String serverVersion) {
-        String dbProductName = null;
-        String dbProductVersion = null;
-        int dbMajorVersion = 0;
-        int dbMinorVersion = 0;
-        if (serverVersion != null) {
-            Matcher m = DATABASE_VERSION_PATTERN.matcher(serverVersion);
-            if (m.matches()) {
-                dbProductName = m.group("name");
-                dbProductVersion = m.group("ver");
-                String vermj = m.group("vermj");
-                String vermn = m.group("vermn");
-                if (vermj != null) {
-                    try {
-                        dbMajorVersion = Integer.parseInt(vermj);
-                    } catch (NumberFormatException e) {
-                        // ignore (overflow)
-                    }
-                }
-                if (vermn != null) {
-                    try {
-                        dbMinorVersion = Integer.parseInt(vermn);
-                    } catch (NumberFormatException e) {
-                        // ignore (overflow)
-                    }
-                }
-            }
-        }
-        return new ADBProductVersion(dbProductName, dbProductVersion, dbMajorVersion, dbMinorVersion);
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProtocol.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProtocol.java
deleted file mode 100644
index e8a36f5..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProtocol.java
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHeaders;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpStatus;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.AuthCache;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpOptions;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.config.SocketConfig;
-import org.apache.http.conn.HttpClientConnectionManager;
-import org.apache.http.entity.ContentProducer;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.EntityTemplate;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-import org.apache.http.message.BasicNameValuePair;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
-import com.fasterxml.jackson.core.JsonEncoding;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.MapperFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-
-public class ADBProtocol {
-
-    private static final String QUERY_ENDPOINT_PATH = "/query/service";
-    private static final String QUERY_RESULT_ENDPOINT_PATH = "/query/service/result";
-
-    private static final String STATEMENT = "statement";
-    private static final String ARGS = "args";
-    private static final String MODE = "mode";
-    private static final String READ_ONLY = "readonly";
-    private static final String DATAVERSE = "dataverse";
-    private static final String TIMEOUT = "timeout";
-    private static final String SIGNATURE = "signature";
-    private static final String COMPILE_ONLY = "compile-only";
-    private static final String CLIENT_TYPE = "client-type";
-    private static final String PLAN_FORMAT = "plan-format";
-    private static final String MAX_WARNINGS = "max-warnings";
-
-    private static final String MODE_DEFERRED = "deferred";
-    private static final String CLIENT_TYPE_JDBC = "jdbc";
-    private static final String RESULTS = "results";
-    private static final String FORMAT_LOSSLESS_ADM = "lossless-adm";
-    private static final String PLAN_FORMAT_STRING = "string";
-
-    private static final String OPTIONAL_TYPE_SUFFIX = "?";
-    static final char TEXT_DELIMITER = ':';
-    static final String EXPLAIN_ONLY_RESULT_COLUMN_NAME = "$1";
-    static final String DEFAULT_DATAVERSE = "Default";
-
-    final ADBDriverContext driverContext;
-    final HttpClientConnectionManager httpConnectionManager;
-    final HttpClientContext httpClientContext;
-    final CloseableHttpClient httpClient;
-    final URI queryEndpoint;
-    final URI queryResultEndpoint;
-    final String user;
-    final int maxWarnings;
-
-    protected ADBProtocol(String host, int port, Map<ADBDriverProperty, Object> params, ADBDriverContext driverContext)
-            throws SQLException {
-        URI queryEndpoint = createEndpointUri(host, port, QUERY_ENDPOINT_PATH, driverContext.errorReporter);
-        URI queryResultEndpoint =
-                createEndpointUri(host, port, QUERY_RESULT_ENDPOINT_PATH, driverContext.errorReporter);
-        PoolingHttpClientConnectionManager httpConnectionManager = new PoolingHttpClientConnectionManager();
-        int maxConnections = Math.max(16, Runtime.getRuntime().availableProcessors());
-        httpConnectionManager.setDefaultMaxPerRoute(maxConnections);
-        httpConnectionManager.setMaxTotal(maxConnections);
-        SocketConfig.Builder socketConfigBuilder = null;
-        Number socketTimeoutMillis = (Number) params.get(ADBDriverProperty.Common.SOCKET_TIMEOUT);
-        if (socketTimeoutMillis != null) {
-            socketConfigBuilder = SocketConfig.custom();
-            socketConfigBuilder.setSoTimeout(socketTimeoutMillis.intValue());
-        }
-        if (socketConfigBuilder != null) {
-            httpConnectionManager.setDefaultSocketConfig(socketConfigBuilder.build());
-        }
-        RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
-        Number connectTimeoutMillis = (Number) params.get(ADBDriverProperty.Common.CONNECT_TIMEOUT);
-        if (connectTimeoutMillis != null) {
-            requestConfigBuilder.setConnectionRequestTimeout(connectTimeoutMillis.intValue());
-            requestConfigBuilder.setConnectTimeout(connectTimeoutMillis.intValue());
-        }
-        if (socketTimeoutMillis != null) {
-            requestConfigBuilder.setSocketTimeout(socketTimeoutMillis.intValue());
-        }
-        RequestConfig requestConfig = requestConfigBuilder.build();
-
-        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
-        httpClientBuilder.setConnectionManager(httpConnectionManager);
-        httpClientBuilder.setConnectionManagerShared(true);
-        httpClientBuilder.setDefaultRequestConfig(requestConfig);
-        String user = (String) params.get(ADBDriverProperty.Common.USER);
-        if (user != null) {
-            String password = (String) params.get(ADBDriverProperty.Common.PASSWORD);
-            httpClientBuilder.setDefaultCredentialsProvider(createCredentialsProvider(user, password));
-        }
-
-        Number maxWarnings = ((Number) params.getOrDefault(ADBDriverProperty.Common.MAX_WARNINGS,
-                ADBDriverProperty.Common.MAX_WARNINGS.getDefaultValue()));
-
-        this.user = user;
-        this.queryEndpoint = queryEndpoint;
-        this.queryResultEndpoint = queryResultEndpoint;
-        this.httpConnectionManager = httpConnectionManager;
-        this.httpClient = httpClientBuilder.build();
-        this.httpClientContext = createHttpClientContext(queryEndpoint);
-        this.driverContext = Objects.requireNonNull(driverContext);
-        this.maxWarnings = Math.max(maxWarnings.intValue(), 0);
-    }
-
-    private static URI createEndpointUri(String host, int port, String path, ADBErrorReporter errorReporter)
-            throws SQLException {
-        try {
-            return new URI("http", null, host, port, path, null, null);
-        } catch (URISyntaxException e) {
-            throw errorReporter.errorParameterValueNotSupported("endpoint " + host + ":" + port);
-        }
-    }
-
-    private static CredentialsProvider createCredentialsProvider(String user, String password) {
-        CredentialsProvider cp = new BasicCredentialsProvider();
-        cp.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, password));
-        return cp;
-    }
-
-    void close() throws SQLException {
-        try {
-            httpClient.close();
-        } catch (IOException e) {
-            throw getErrorReporter().errorClosingResource(e);
-        } finally {
-            httpConnectionManager.shutdown();
-        }
-    }
-
-    String connect() throws SQLException {
-        String databaseVersion = pingImpl(-1, true); // TODO:review timeout
-        if (getLogger().isLoggable(Level.FINE)) {
-            getLogger().log(Level.FINE, String.format("connected to '%s' at %s", databaseVersion, queryEndpoint));
-        }
-        return databaseVersion;
-    }
-
-    boolean ping(int timeoutSeconds) {
-        try {
-            pingImpl(timeoutSeconds, false);
-            return true;
-        } catch (SQLException e) {
-            return false;
-        }
-    }
-
-    private String pingImpl(int timeoutSeconds, boolean fetchDatabaseVersion) throws SQLException {
-        //TODO: support timeoutSeconds: -1 = use default, 0 = indefinite ?
-        HttpOptions httpOptions = new HttpOptions(queryEndpoint);
-        try (CloseableHttpResponse response = httpClient.execute(httpOptions, httpClientContext)) {
-            int statusCode = response.getStatusLine().getStatusCode();
-            switch (statusCode) {
-                case HttpStatus.SC_OK:
-                    String databaseVersion = null;
-                    if (fetchDatabaseVersion) {
-                        Header serverHeader = response.getFirstHeader(HttpHeaders.SERVER);
-                        if (serverHeader != null) {
-                            databaseVersion = serverHeader.getValue();
-                        }
-                    }
-                    return databaseVersion;
-                case HttpStatus.SC_UNAUTHORIZED:
-                case HttpStatus.SC_FORBIDDEN:
-                    throw getErrorReporter().errorAuth();
-                default:
-                    throw getErrorReporter().errorInConnection(String.valueOf(response.getStatusLine()));
-            }
-        } catch (IOException e) {
-            throw getErrorReporter().errorInConnection(e);
-        }
-    }
-
-    QueryServiceResponse submitStatement(String sql, List<?> args, boolean forceReadOnly, boolean compileOnly,
-            int timeoutSeconds, String catalog, String schema) throws SQLException {
-        HttpPost httpPost = new HttpPost(queryEndpoint);
-        httpPost.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON
-                .withParameters(new BasicNameValuePair(FORMAT_LOSSLESS_ADM, Boolean.TRUE.toString())).toString());
-
-        ByteArrayOutputStreamImpl baos = new ByteArrayOutputStreamImpl(512);
-        try {
-            JsonGenerator jsonGen = driverContext.genericObjectWriter.createGenerator(baos, JsonEncoding.UTF8);
-            jsonGen.writeStartObject();
-            jsonGen.writeStringField(CLIENT_TYPE, CLIENT_TYPE_JDBC);
-            jsonGen.writeStringField(MODE, MODE_DEFERRED);
-            jsonGen.writeStringField(STATEMENT, sql);
-            jsonGen.writeBooleanField(SIGNATURE, true);
-            jsonGen.writeStringField(PLAN_FORMAT, PLAN_FORMAT_STRING);
-            jsonGen.writeNumberField(MAX_WARNINGS, maxWarnings);
-            if (compileOnly) {
-                jsonGen.writeBooleanField(COMPILE_ONLY, true);
-            }
-            if (forceReadOnly) {
-                jsonGen.writeBooleanField(READ_ONLY, true);
-            }
-            if (timeoutSeconds > 0) {
-                jsonGen.writeStringField(TIMEOUT, timeoutSeconds + "s");
-            }
-            if (catalog != null) {
-                jsonGen.writeStringField(DATAVERSE, schema != null ? catalog + "/" + schema : catalog);
-            }
-            if (args != null && !args.isEmpty()) {
-                jsonGen.writeFieldName(ARGS);
-                driverContext.admFormatObjectWriter.writeValue(jsonGen, args);
-            }
-            jsonGen.writeEndObject();
-            jsonGen.flush();
-        } catch (InvalidDefinitionException e) {
-            throw getErrorReporter().errorUnexpectedType(e.getType().getRawClass());
-        } catch (IOException e) {
-            throw getErrorReporter().errorInRequestGeneration(e);
-        }
-
-        System.err.printf("<ADB_DRIVER_SQL>%n%s%n</ADB_DRIVER_SQL>%n", sql);
-
-        if (getLogger().isLoggable(Level.FINE)) {
-            getLogger().log(Level.FINE, String.format("%s { %s } with args { %s }", compileOnly ? "compile" : "execute",
-                    sql, args != null ? args : ""));
-        }
-
-        httpPost.setEntity(new EntityTemplateImpl(baos, ContentType.APPLICATION_JSON));
-        try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost, httpClientContext)) {
-            return handlePostQueryResponse(httpResponse);
-        } catch (JsonProcessingException e) {
-            throw getErrorReporter().errorInProtocol(e);
-        } catch (IOException e) {
-            throw getErrorReporter().errorInConnection(e);
-        }
-    }
-
-    private QueryServiceResponse handlePostQueryResponse(CloseableHttpResponse httpResponse)
-            throws SQLException, IOException {
-        int httpStatus = httpResponse.getStatusLine().getStatusCode();
-        switch (httpStatus) {
-            case HttpStatus.SC_OK:
-            case HttpStatus.SC_BAD_REQUEST:
-            case HttpStatus.SC_INTERNAL_SERVER_ERROR:
-            case HttpStatus.SC_SERVICE_UNAVAILABLE:
-                break;
-            case HttpStatus.SC_UNAUTHORIZED:
-            case HttpStatus.SC_FORBIDDEN:
-                throw getErrorReporter().errorAuth();
-            default:
-                throw getErrorReporter().errorInProtocol(httpResponse.getStatusLine().toString());
-        }
-        QueryServiceResponse response;
-        try (InputStream contentStream = httpResponse.getEntity().getContent()) {
-            response = driverContext.genericObjectReader.readValue(contentStream, QueryServiceResponse.class);
-        }
-        QueryServiceResponse.Status status = response.status;
-        if (httpStatus == HttpStatus.SC_OK && status == QueryServiceResponse.Status.SUCCESS) {
-            return response;
-        }
-        if (status == QueryServiceResponse.Status.TIMEOUT) {
-            throw getErrorReporter().errorTimeout();
-        }
-        SQLException exc = getErrorIfExists(response);
-        if (exc != null) {
-            throw exc;
-        } else {
-            throw getErrorReporter().errorInProtocol(httpResponse.getStatusLine().toString());
-        }
-    }
-
-    JsonParser fetchResult(QueryServiceResponse response) throws SQLException {
-        if (response.handle == null) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        int p = response.handle.lastIndexOf("/");
-        if (p < 0) {
-            throw getErrorReporter().errorInProtocol(response.handle);
-        }
-        String handlePath = response.handle.substring(p);
-        URI resultRequestURI;
-        try {
-            resultRequestURI = new URI(queryResultEndpoint + handlePath);
-        } catch (URISyntaxException e) {
-            throw getErrorReporter().errorInProtocol(handlePath);
-        }
-        HttpGet httpGet = new HttpGet(resultRequestURI);
-        httpGet.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType());
-
-        CloseableHttpResponse httpResponse = null;
-        InputStream httpContentStream = null;
-        JsonParser parser = null;
-        try {
-            httpResponse = httpClient.execute(httpGet, httpClientContext);
-            int httpStatus = httpResponse.getStatusLine().getStatusCode();
-            if (httpStatus != HttpStatus.SC_OK) {
-                throw getErrorReporter().errorNoResult();
-            }
-            HttpEntity entity = httpResponse.getEntity();
-            httpContentStream = entity.getContent();
-            parser = driverContext.genericObjectReader
-                    .createParser(new InputStreamWithAttachedResource(httpContentStream, httpResponse));
-            if (!advanceToArrayField(parser, RESULTS)) {
-                throw getErrorReporter().errorInProtocol();
-            }
-            parser.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true);
-            return parser;
-        } catch (SQLException e) {
-            closeQuietly(e, parser, httpContentStream, httpResponse);
-            throw e;
-        } catch (JsonProcessingException e) {
-            closeQuietly(e, parser, httpContentStream, httpResponse);
-            throw getErrorReporter().errorInProtocol(e);
-        } catch (IOException e) {
-            closeQuietly(e, parser, httpContentStream, httpResponse);
-            throw getErrorReporter().errorInConnection(e);
-        }
-    }
-
-    private boolean advanceToArrayField(JsonParser parser, String fieldName) throws IOException {
-        if (parser.nextToken() != JsonToken.START_OBJECT) {
-            return false;
-        }
-        for (;;) {
-            JsonToken token = parser.nextValue();
-            if (token == null || token == JsonToken.END_OBJECT) {
-                return false;
-            }
-            if (parser.currentName().equals(fieldName)) {
-                return token == JsonToken.START_ARRAY;
-            } else if (token.isStructStart()) {
-                parser.skipChildren();
-            } else {
-                parser.nextToken();
-            }
-        }
-    }
-
-    ArrayNode fetchExplainOnlyResult(QueryServiceResponse response,
-            ADBPreparedStatement.AbstractValueSerializer stringSer) throws SQLException {
-        if (response.results == null || response.results.isEmpty()) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        Object v = response.results.get(0);
-        if (!(v instanceof String)) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        try (BufferedReader br = new BufferedReader(new StringReader(v.toString()))) {
-            ArrayNode arrayNode = (ArrayNode) driverContext.genericObjectReader.createArrayNode();
-            String line;
-            while ((line = br.readLine()) != null) {
-                arrayNode.addObject().put(ADBProtocol.EXPLAIN_ONLY_RESULT_COLUMN_NAME,
-                        stringSer.serializeToString(line));
-            }
-            return arrayNode;
-        } catch (IOException e) {
-            throw getErrorReporter().errorInResultHandling(e);
-        }
-    }
-
-    private HttpClientContext createHttpClientContext(URI uri) {
-        HttpClientContext hcCtx = HttpClientContext.create();
-        AuthCache ac = new BasicAuthCache();
-        ac.put(new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()), new BasicScheme());
-        hcCtx.setAuthCache(ac);
-        return hcCtx;
-    }
-
-    boolean isStatementCategory(QueryServiceResponse response, QueryServiceResponse.StatementCategory category) {
-        return response.plans != null && category.equals(response.plans.statementCategory);
-    }
-
-    int getUpdateCount(QueryServiceResponse response) {
-        // TODO:need to get update count through the response
-        return isStatementCategory(response, QueryServiceResponse.StatementCategory.UPDATE) ? 1 : 0;
-    }
-
-    SQLException getErrorIfExists(QueryServiceResponse response) {
-        if (response.errors != null && !response.errors.isEmpty()) {
-            QueryServiceResponse.Message err = response.errors.get(0);
-            return new SQLException(err.msg, null, err.code);
-        }
-        return null;
-    }
-
-    List<QueryServiceResponse.Message> getWarningIfExists(QueryServiceResponse response) {
-        return response.warnings != null && !response.warnings.isEmpty() ? response.warnings : null;
-    }
-
-    SQLWarning createSQLWarning(List<QueryServiceResponse.Message> warnings) {
-        SQLWarning sqlWarning = null;
-        ListIterator<QueryServiceResponse.Message> i = warnings.listIterator(warnings.size());
-        while (i.hasPrevious()) {
-            QueryServiceResponse.Message w = i.previous();
-            SQLWarning sw = new SQLWarning(w.msg, null, w.code);
-            if (sqlWarning != null) {
-                sw.setNextWarning(sqlWarning);
-            }
-            sqlWarning = sw;
-        }
-        return sqlWarning;
-    }
-
-    List<ADBColumn> getColumns(QueryServiceResponse response) throws SQLException {
-        if (isExplainOnly(response)) {
-            return Collections.singletonList(new ADBColumn(EXPLAIN_ONLY_RESULT_COLUMN_NAME, ADBDatatype.STRING, false));
-        }
-        QueryServiceResponse.Signature signature = response.signature;
-        if (signature == null) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        List<String> nameList = signature.name;
-        List<String> typeList = signature.type;
-        if (nameList == null || nameList.isEmpty() || typeList == null || typeList.isEmpty()) {
-            throw getErrorReporter().errorBadResultSignature();
-        }
-        int count = nameList.size();
-        List<ADBColumn> result = new ArrayList<>(count);
-        for (int i = 0; i < count; i++) {
-            String columnName = nameList.get(i);
-            String typeName = typeList.get(i);
-            boolean optional = false;
-            if (typeName.endsWith(OPTIONAL_TYPE_SUFFIX)) {
-                optional = true;
-                typeName = typeName.substring(0, typeName.length() - OPTIONAL_TYPE_SUFFIX.length());
-            }
-            ADBDatatype columnType = ADBDatatype.findByTypeName(typeName);
-            if (columnType == null) {
-                throw getErrorReporter().errorBadResultSignature();
-            }
-            result.add(new ADBColumn(columnName, columnType, optional));
-        }
-        return result;
-    }
-
-    boolean isExplainOnly(QueryServiceResponse response) {
-        return response.plans != null && Boolean.TRUE.equals(response.plans.explainOnly);
-    }
-
-    int getStatementParameterCount(QueryServiceResponse response) throws SQLException {
-        QueryServiceResponse.Plans plans = response.plans;
-        if (plans == null) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        if (plans.statementParameters == null) {
-            return 0;
-        }
-        int paramPos = 0;
-        for (Object param : plans.statementParameters) {
-            if (param instanceof Number) {
-                paramPos = Math.max(paramPos, ((Number) param).intValue());
-            } else {
-                throw getErrorReporter().errorParameterNotSupported(String.valueOf(param));
-            }
-        }
-        return paramPos;
-    }
-
-    JsonParser createJsonParser(JsonNode node) {
-        return driverContext.genericObjectReader.treeAsTokens(node);
-    }
-
-    ADBErrorReporter getErrorReporter() {
-        return driverContext.errorReporter;
-    }
-
-    Logger getLogger() {
-        return driverContext.logger;
-    }
-
-    static ObjectMapper createObjectMapper() {
-        ObjectMapper om = new ObjectMapper();
-        om.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.NON_PRIVATE);
-        // serialization
-        om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
-
-        // deserialization
-        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        om.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
-        om.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);
-        return om;
-    }
-
-    private static void closeQuietly(Exception mainExc, java.io.Closeable... closeableList) {
-        for (Closeable closeable : closeableList) {
-            if (closeable != null) {
-                try {
-                    closeable.close();
-                } catch (IOException e) {
-                    if (mainExc != null) {
-                        mainExc.addSuppressed(e);
-                    }
-                }
-            }
-        }
-    }
-
-    static final class ByteArrayOutputStreamImpl extends ByteArrayOutputStream implements ContentProducer {
-        private ByteArrayOutputStreamImpl(int size) {
-            super(size);
-        }
-    }
-
-    static final class EntityTemplateImpl extends EntityTemplate {
-
-        private final long contentLength;
-
-        private EntityTemplateImpl(ByteArrayOutputStreamImpl baos, ContentType contentType) {
-            super(baos);
-            contentLength = baos.size();
-            setContentType(contentType.toString());
-        }
-
-        @Override
-        public long getContentLength() {
-            return contentLength;
-        }
-    }
-
-    static final class InputStreamWithAttachedResource extends FilterInputStream {
-
-        private final Closeable resource;
-
-        private InputStreamWithAttachedResource(InputStream delegate, Closeable resource) {
-            super(delegate);
-            this.resource = Objects.requireNonNull(resource);
-        }
-
-        @Override
-        public void close() throws IOException {
-            try {
-                super.close();
-            } finally {
-                resource.close();
-            }
-        }
-    }
-
-    public static class QueryServiceResponse {
-
-        public Status status;
-        public Plans plans;
-        public Signature signature;
-        public String handle;
-        public List<?> results; // currently only used for EXPLAIN results
-        public List<Message> errors;
-        public List<Message> warnings;
-
-        public enum Status {
-            RUNNING,
-            SUCCESS,
-            TIMEOUT,
-            FAILED,
-            FATAL
-        }
-
-        public static class Signature {
-            List<String> name;
-            List<String> type;
-        }
-
-        public static class Plans {
-            StatementCategory statementCategory;
-            List<Object> statementParameters;
-            Boolean explainOnly;
-        }
-
-        public static class Message {
-            int code;
-            String msg;
-        }
-
-        public enum StatementCategory {
-            QUERY,
-            UPDATE,
-            DDL,
-            PROCEDURE
-        }
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBResultSet.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBResultSet.java
deleted file mode 100644
index 965855c..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBResultSet.java
+++ /dev/null
@@ -1,1536 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLType;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.ObjectReader;
-
-final class ADBResultSet extends ADBWrapperSupport implements java.sql.ResultSet {
-
-    static final int RESULT_SET_HOLDABILITY = HOLD_CURSORS_OVER_COMMIT;
-
-    static final int ST_BEFORE_FIRST = 0;
-    static final int ST_NEXT = 1;
-    static final int ST_AFTER_LAST = 2;
-
-    // lifecycle
-    final AtomicBoolean closed = new AtomicBoolean(false);
-
-    // metadata
-    final ADBResultSetMetaData metadata;
-
-    // navigation
-    final JsonParser rowParser;
-    final boolean rowParserOwnsResources;
-    final long maxRows;
-
-    int state;
-    long rowNumber;
-    ADBRowStore rowStore;
-    ObjectReader complexColumnReader;
-    int columnIndexOfLatestGet;
-
-    // Lifecycle
-
-    ADBResultSet(ADBResultSetMetaData metadata, JsonParser rowParser, boolean rowParserOwnsResources, long maxRows) {
-        this.metadata = Objects.requireNonNull(metadata);
-        this.rowParser = Objects.requireNonNull(rowParser);
-        this.rowParserOwnsResources = rowParserOwnsResources;
-        this.maxRows = maxRows;
-        this.state = ST_BEFORE_FIRST;
-    }
-
-    @Override
-    public void close() throws SQLException {
-        closeImpl(true);
-    }
-
-    void closeImpl(boolean notifyStatement) throws SQLException {
-        boolean wasClosed = closed.getAndSet(true);
-        if (wasClosed) {
-            return;
-        }
-        try {
-            rowParser.close();
-        } catch (IOException e) {
-            throw getErrorReporter().errorClosingResource(e);
-        } finally {
-            if (notifyStatement) {
-                metadata.statement.deregisterResultSet(this);
-            }
-        }
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closed.get();
-    }
-
-    private void checkClosed() throws SQLException {
-        if (isClosed()) {
-            throw getErrorReporter().errorObjectClosed(ResultSet.class);
-        }
-    }
-
-    // Metadata
-
-    @Override
-    public ResultSetMetaData getMetaData() throws SQLException {
-        checkClosed();
-        return metadata;
-    }
-
-    // Navigation
-
-    @Override
-    public boolean next() throws SQLException {
-        checkClosed();
-        try {
-            switch (state) {
-                case ST_BEFORE_FIRST:
-                    JsonToken token = rowParser.hasCurrentToken() ? rowParser.currentToken() : rowParser.nextToken();
-                    if (token != JsonToken.START_ARRAY) {
-                        throw getErrorReporter().errorInProtocol(String.valueOf(token));
-                    }
-                    initRowStore();
-                    state = ST_NEXT;
-                    // fall thru to ST_NEXT
-                case ST_NEXT:
-                    token = rowParser.nextToken();
-                    switch (token) {
-                        case START_OBJECT:
-                            if (maxRows > 0 && rowNumber == maxRows) {
-                                state = ST_AFTER_LAST;
-                                return false;
-                            } else {
-                                readRow();
-                                rowNumber++;
-                                return true;
-                            }
-                        case END_ARRAY:
-                            state = ST_AFTER_LAST;
-                            return false;
-                        default:
-                            throw getErrorReporter().errorInProtocol(String.valueOf(token));
-                    }
-                case ST_AFTER_LAST:
-                    return false;
-                default:
-                    throw new IllegalStateException(String.valueOf(state));
-            }
-        } catch (JsonProcessingException e) {
-            throw getErrorReporter().errorInProtocol(e);
-        } catch (IOException e) {
-            throw getErrorReporter().errorInConnection(e);
-        }
-    }
-
-    private void initRowStore() {
-        rowStore = createRowStore(metadata.getColumnCount());
-    }
-
-    protected ADBRowStore createRowStore(int columnCount) {
-        return new ADBRowStore(this, columnCount);
-    }
-
-    private void readRow() throws SQLException {
-        rowStore.reset();
-        columnIndexOfLatestGet = -1;
-        if (rowParser.currentToken() != JsonToken.START_OBJECT) {
-            throw new IllegalStateException();
-        }
-        try {
-            while (rowParser.nextToken() == JsonToken.FIELD_NAME) {
-                String fieldName = rowParser.getCurrentName();
-                int columnIndex = metadata.findColumnIndexByName(fieldName);
-                boolean isKnownColumn = columnIndex >= 0;
-                ADBColumn column = isKnownColumn ? metadata.getColumnByIndex(columnIndex) : null;
-
-                switch (rowParser.nextToken()) {
-                    case VALUE_NULL:
-                        if (isKnownColumn) {
-                            typeCheck(column, ADBDatatype.NULL);
-                            rowStore.putNullColumn(columnIndex);
-                        }
-                        break;
-                    case VALUE_TRUE:
-                        if (isKnownColumn) {
-                            typeCheck(column, ADBDatatype.BOOLEAN);
-                            rowStore.putBooleanColumn(columnIndex, true);
-                        }
-                        break;
-                    case VALUE_FALSE:
-                        if (isKnownColumn) {
-                            typeCheck(column, ADBDatatype.BOOLEAN);
-                            rowStore.putBooleanColumn(columnIndex, false);
-                        }
-                        break;
-                    case VALUE_NUMBER_INT:
-                        if (isKnownColumn) {
-                            typeCheck(column, ADBDatatype.BIGINT);
-                            long v = rowParser.getLongValue();
-                            rowStore.putInt64Column(columnIndex, v);
-                        }
-                        break;
-                    case VALUE_STRING:
-                        if (isKnownColumn) {
-                            typeCheck(column, ADBDatatype.STRING);
-                            char[] textChars = rowParser.getTextCharacters();
-                            int textOffset = rowParser.getTextOffset();
-                            int textLength = rowParser.getTextLength();
-                            rowStore.putColumn(columnIndex, textChars, textOffset, textLength);
-                        }
-                        break;
-                    case START_OBJECT:
-                        if (isKnownColumn) {
-                            typeCheck(column, ADBDatatype.OBJECT);
-                            Map<?, ?> valueMap = getComplexColumnReader().readValue(rowParser, Map.class);
-                            rowStore.putRecordColumn(columnIndex, valueMap);
-                        } else {
-                            rowParser.skipChildren();
-                        }
-                        break;
-                    case START_ARRAY:
-                        if (isKnownColumn) {
-                            typeCheck(column, ADBDatatype.ARRAY);
-                            List<?> valueList = getComplexColumnReader().readValue(rowParser, List.class);
-                            rowStore.putArrayColumn(columnIndex, valueList);
-                        } else {
-                            rowParser.skipChildren();
-                        }
-                        break;
-                    default:
-                        throw getErrorReporter().errorInProtocol(String.valueOf(rowParser.currentToken()));
-                }
-            }
-        } catch (JsonProcessingException e) {
-            throw getErrorReporter().errorInProtocol(e);
-        } catch (IOException e) {
-            throw getErrorReporter().errorInConnection(e);
-        }
-    }
-
-    private void typeCheck(ADBColumn column, ADBDatatype parsedType) throws SQLException {
-        ADBDatatype columnType = column.getType();
-
-        boolean typeMatch;
-        switch (parsedType) {
-            case NULL:
-                typeMatch = column.isOptional();
-                break;
-            case STRING:
-                // special handling for parsed 'string' because it can contain any primitive type.
-                // we only need to check that the expected type is not derived (i.e primitive/null/missing/any)
-                typeMatch = !columnType.isDerived();
-                break;
-            case ARRAY:
-                typeMatch = columnType == ADBDatatype.ANY || columnType.isList();
-                break;
-            case BOOLEAN:
-            case BIGINT:
-            case OBJECT:
-                typeMatch = columnType == ADBDatatype.ANY || columnType == parsedType;
-                break;
-            default:
-                // unexpected
-                throw getErrorReporter().errorInProtocol(parsedType.toString());
-        }
-        if (!typeMatch) {
-            throw getErrorReporter().errorUnexpectedColumnValue(parsedType, column.getName());
-        }
-    }
-
-    @Override
-    public void beforeFirst() throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("FORWARD_ONLY");
-    }
-
-    @Override
-    public void afterLast() throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("FORWARD_ONLY");
-    }
-
-    @Override
-    public boolean first() throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("FORWARD_ONLY");
-    }
-
-    @Override
-    public boolean last() throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("FORWARD_ONLY");
-    }
-
-    @Override
-    public boolean previous() throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("FORWARD_ONLY");
-    }
-
-    @Override
-    public boolean relative(int rows) throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("FORWARD_ONLY");
-    }
-
-    @Override
-    public boolean absolute(int row) throws SQLException {
-        checkClosed();
-        throw getErrorReporter().errorIncompatibleMode("FORWARD_ONLY");
-    }
-
-    @Override
-    public boolean isBeforeFirst() {
-        return state == ST_BEFORE_FIRST;
-    }
-
-    @Override
-    public boolean isAfterLast() {
-        return state == ST_AFTER_LAST;
-    }
-
-    @Override
-    public boolean isFirst() {
-        return state == ST_NEXT && rowNumber == 1;
-    }
-
-    @Override
-    public boolean isLast() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "isLast");
-    }
-
-    @Override
-    public int getRow() throws SQLException {
-        checkClosed();
-        return (int) rowNumber;
-    }
-
-    private void checkCursorPosition() throws SQLException {
-        if (state != ST_NEXT) {
-            throw getErrorReporter().errorNoCurrentRow();
-        }
-    }
-
-    private ObjectReader getComplexColumnReader() {
-        if (complexColumnReader == null) {
-            ADBDriverContext ctx = metadata.statement.connection.protocol.driverContext;
-            ADBRowStore tmpStore = createRowStore(1);
-            complexColumnReader = tmpStore.createComplexColumnObjectReader(ctx.admFormatObjectReader);
-        }
-        return complexColumnReader;
-    }
-
-    // Column accessors
-
-    @Override
-    public int findColumn(String columnLabel) throws SQLException {
-        checkClosed();
-        int columnIndex = metadata.findColumnIndexByName(columnLabel);
-        if (columnIndex < 0) {
-            throw getErrorReporter().errorColumnNotFound(columnLabel);
-        }
-        return columnIndex + 1;
-    }
-
-    // Column accessors: basic types
-
-    private int fetchColumnIndex(int columnNumber) throws SQLException {
-        if (columnNumber < 1 || columnNumber > metadata.getColumnCount()) {
-            throw getErrorReporter().errorColumnNotFound(String.valueOf(columnNumber));
-        }
-        return columnNumber - 1;
-    }
-
-    private int fetchColumnIndex(String columnLabel) throws SQLException {
-        int columnIndex = metadata.findColumnIndexByName(columnLabel);
-        if (columnIndex < 0) {
-            throw getErrorReporter().errorColumnNotFound(columnLabel);
-        }
-        return columnIndex;
-    }
-
-    @Override
-    public boolean wasNull() throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        if (columnIndexOfLatestGet < 0) {
-            return false;
-        }
-        ADBDatatype columnValueType = rowStore.getColumnType(columnIndexOfLatestGet);
-        return columnValueType == ADBDatatype.NULL || columnValueType == ADBDatatype.MISSING;
-    }
-
-    @Override
-    public boolean getBoolean(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBooleanImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public boolean getBoolean(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBooleanImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private boolean getBooleanImpl(int columnIndex) throws SQLException {
-        boolean v = rowStore.getBoolean(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public byte getByte(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getByteImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public byte getByte(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getByteImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private byte getByteImpl(int columnIndex) throws SQLException {
-        byte v = rowStore.getByte(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public short getShort(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getShortImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public short getShort(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getShortImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private short getShortImpl(int columnIndex) throws SQLException {
-        short v = rowStore.getShort(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public int getInt(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getIntImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public int getInt(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getIntImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private int getIntImpl(int columnIndex) throws SQLException {
-        int v = rowStore.getInt(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public long getLong(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getLongImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public long getLong(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getLongImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private long getLongImpl(int columnIndex) throws SQLException {
-        long v = rowStore.getLong(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public float getFloat(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getFloatImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public float getFloat(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getFloatImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private float getFloatImpl(int columnIndex) throws SQLException {
-        float v = rowStore.getFloat(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public double getDouble(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getDoubleImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public double getDouble(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getDoubleImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private double getDoubleImpl(int columnIndex) throws SQLException {
-        double v = rowStore.getDouble(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public BigDecimal getBigDecimal(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBigDecimalImpl(fetchColumnIndex(columnNumber), false, -1);
-    }
-
-    @Override
-    public BigDecimal getBigDecimal(int columnNumber, int scale) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBigDecimalImpl(fetchColumnIndex(columnNumber), true, scale);
-    }
-
-    @Override
-    public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBigDecimalImpl(fetchColumnIndex(columnLabel), false, -1);
-    }
-
-    @Override
-    public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBigDecimalImpl(fetchColumnIndex(columnLabel), true, scale);
-    }
-
-    private BigDecimal getBigDecimalImpl(int columnIndex, boolean setScale, int scale) throws SQLException {
-        BigDecimal v = rowStore.getBigDecimal(columnIndex, setScale, scale);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public Date getDate(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getDateImpl(fetchColumnIndex(columnNumber), null);
-    }
-
-    @Override
-    public Date getDate(int columnNumber, Calendar cal) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getDateImpl(fetchColumnIndex(columnNumber), cal);
-    }
-
-    @Override
-    public Date getDate(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getDateImpl(fetchColumnIndex(columnLabel), null);
-    }
-
-    @Override
-    public Date getDate(String columnLabel, Calendar cal) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getDateImpl(fetchColumnIndex(columnLabel), cal);
-    }
-
-    private Date getDateImpl(int columnIndex, Calendar cal) throws SQLException {
-        Date v = rowStore.getDate(columnIndex, cal);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public Time getTime(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimeImpl(fetchColumnIndex(columnNumber), null);
-    }
-
-    @Override
-    public Time getTime(int columnNumber, Calendar cal) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimeImpl(fetchColumnIndex(columnNumber), cal);
-    }
-
-    @Override
-    public Time getTime(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimeImpl(fetchColumnIndex(columnLabel), null);
-    }
-
-    @Override
-    public Time getTime(String columnLabel, Calendar cal) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimeImpl(fetchColumnIndex(columnLabel), cal);
-    }
-
-    private Time getTimeImpl(int columnIndex, Calendar cal) throws SQLException {
-        Time v = rowStore.getTime(columnIndex, cal);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public Timestamp getTimestamp(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimestampImpl(fetchColumnIndex(columnNumber), null);
-    }
-
-    @Override
-    public Timestamp getTimestamp(int columnNumber, Calendar cal) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimestampImpl(fetchColumnIndex(columnNumber), cal);
-    }
-
-    @Override
-    public Timestamp getTimestamp(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimestampImpl(fetchColumnIndex(columnLabel), null);
-    }
-
-    @Override
-    public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getTimestampImpl(fetchColumnIndex(columnLabel), cal);
-    }
-
-    private Timestamp getTimestampImpl(int columnIndex, Calendar cal) throws SQLException {
-        Timestamp v = rowStore.getTimestamp(columnIndex, cal);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public String getString(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getStringImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public String getString(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getStringImpl(fetchColumnIndex(columnLabel));
-    }
-
-    @Override
-    public String getNString(int columnNumber) throws SQLException {
-        return getString(columnNumber);
-    }
-
-    @Override
-    public String getNString(String columnLabel) throws SQLException {
-        return getString(columnLabel);
-    }
-
-    private String getStringImpl(int columnIndex) throws SQLException {
-        String v = rowStore.getString(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public byte[] getBytes(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBytesImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public byte[] getBytes(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBytesImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private byte[] getBytesImpl(int columnIndex) throws SQLException {
-        byte[] v = rowStore.getBinary(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    // Column accessor: Generic (getObject)
-
-    @Override
-    public Object getObject(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getObjectImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public Object getObject(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getObjectImpl(fetchColumnIndex(columnLabel));
-    }
-
-    @Override
-    public <T> T getObject(int columnNumber, Class<T> type) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        if (type == null) {
-            throw getErrorReporter().errorParameterValueNotSupported("type");
-        }
-        return getObjectImpl(fetchColumnIndex(columnNumber), type);
-    }
-
-    @Override
-    public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        if (type == null) {
-            throw getErrorReporter().errorParameterValueNotSupported("type");
-        }
-        return getObjectImpl(fetchColumnIndex(columnLabel), type);
-    }
-
-    private Object getObjectImpl(int columnIndex) throws SQLException {
-        ADBColumn column = metadata.getColumnByIndex(columnIndex);
-        return getObjectImpl(columnIndex, column.getType().getJavaClass());
-    }
-
-    private <T> T getObjectImpl(int columnIndex, Class<T> type) throws SQLException {
-        T v = rowStore.getObject(columnIndex, type);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getObject");
-    }
-
-    @Override
-    public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getObject");
-    }
-
-    // Column accessors: streams
-
-    @Override
-    public InputStream getBinaryStream(int columnIndex) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBinaryStreamImpl(fetchColumnIndex(columnIndex));
-    }
-
-    @Override
-    public InputStream getBinaryStream(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getBinaryStreamImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private InputStream getBinaryStreamImpl(int columnIndex) throws SQLException {
-        InputStream v = rowStore.getInputStream(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public Reader getCharacterStream(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getCharacterStreamImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public Reader getCharacterStream(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getCharacterStreamImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private Reader getCharacterStreamImpl(int columnIndex) throws SQLException {
-        Reader v = rowStore.getCharacterStream(columnIndex);
-        columnIndexOfLatestGet = columnIndex;
-        return v;
-    }
-
-    @Override
-    public Reader getNCharacterStream(int columnIndex) throws SQLException {
-        return getCharacterStream(columnIndex);
-    }
-
-    @Override
-    public Reader getNCharacterStream(String columnLabel) throws SQLException {
-        return getCharacterStream(columnLabel);
-    }
-
-    @Override
-    public InputStream getAsciiStream(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getAsciiStreamImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public InputStream getAsciiStream(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getAsciiStreamImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private InputStream getAsciiStreamImpl(int columnIndex) throws SQLException {
-        String value = getString(columnIndex);
-        return value != null ? new ByteArrayInputStream(value.getBytes(StandardCharsets.US_ASCII)) : null;
-    }
-
-    @Override
-    public InputStream getUnicodeStream(int columnNumber) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getUnicodeStreamImpl(fetchColumnIndex(columnNumber));
-    }
-
-    @Override
-    public InputStream getUnicodeStream(String columnLabel) throws SQLException {
-        checkClosed();
-        checkCursorPosition();
-        return getUnicodeStreamImpl(fetchColumnIndex(columnLabel));
-    }
-
-    private InputStream getUnicodeStreamImpl(int columnIndex) throws SQLException {
-        String value = getString(columnIndex);
-        return value != null ? new ByteArrayInputStream(value.getBytes(StandardCharsets.UTF_16)) : null;
-    }
-
-    // Column accessors: unsupported
-
-    @Override
-    public Ref getRef(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getRef");
-    }
-
-    @Override
-    public Ref getRef(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getRef");
-    }
-
-    @Override
-    public RowId getRowId(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getRowId");
-    }
-
-    @Override
-    public RowId getRowId(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getRowId");
-    }
-
-    @Override
-    public URL getURL(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getURL");
-    }
-
-    @Override
-    public URL getURL(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getURL");
-    }
-
-    // Column accessors: unsupported - LOB, Array, SQLXML
-
-    @Override
-    public Array getArray(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getArray");
-    }
-
-    @Override
-    public Array getArray(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getArray");
-    }
-
-    @Override
-    public Blob getBlob(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getBlob");
-    }
-
-    @Override
-    public Blob getBlob(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getBlob");
-    }
-
-    @Override
-    public Clob getClob(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getClob");
-    }
-
-    @Override
-    public Clob getClob(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getClob");
-    }
-
-    @Override
-    public NClob getNClob(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getNClob");
-    }
-
-    @Override
-    public NClob getNClob(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getNClob");
-    }
-
-    @Override
-    public SQLXML getSQLXML(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getSQLXML");
-    }
-
-    @Override
-    public SQLXML getSQLXML(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "getSQLXML");
-    }
-
-    // Updates (unsupported)
-
-    // Column setters
-
-    @Override
-    public void updateArray(int columnIndex, Array x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateArray");
-    }
-
-    @Override
-    public void updateArray(String columnLabel, Array x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateArray");
-    }
-
-    @Override
-    public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateAsciiStream");
-    }
-
-    @Override
-    public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateAsciiStream");
-    }
-
-    @Override
-    public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateAsciiStream");
-    }
-
-    @Override
-    public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateAsciiStream");
-    }
-
-    @Override
-    public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateAsciiStream");
-    }
-
-    @Override
-    public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateAsciiStream");
-    }
-
-    @Override
-    public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBigDecimal");
-    }
-
-    @Override
-    public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBigDecimal");
-    }
-
-    @Override
-    public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBinaryStream");
-    }
-
-    @Override
-    public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBinaryStream");
-    }
-
-    @Override
-    public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBinaryStream");
-    }
-
-    @Override
-    public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBinaryStream");
-    }
-
-    @Override
-    public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBinaryStream");
-    }
-
-    @Override
-    public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBinaryStream");
-    }
-
-    @Override
-    public void updateBlob(int columnIndex, Blob x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBlob");
-    }
-
-    @Override
-    public void updateBlob(String columnLabel, Blob x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBlob");
-    }
-
-    @Override
-    public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBlob");
-    }
-
-    @Override
-    public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBlob");
-    }
-
-    @Override
-    public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBlob");
-    }
-
-    @Override
-    public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBlob");
-    }
-
-    @Override
-    public void updateBoolean(int columnIndex, boolean x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBoolean");
-    }
-
-    @Override
-    public void updateBoolean(String columnLabel, boolean x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBoolean");
-    }
-
-    @Override
-    public void updateByte(int columnIndex, byte x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateByte");
-    }
-
-    @Override
-    public void updateByte(String columnLabel, byte x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateByte");
-    }
-
-    @Override
-    public void updateBytes(int columnIndex, byte[] x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBytes");
-    }
-
-    @Override
-    public void updateBytes(String columnLabel, byte[] x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateBytes");
-    }
-
-    @Override
-    public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateCharacterStream");
-    }
-
-    @Override
-    public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateCharacterStream");
-    }
-
-    @Override
-    public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateCharacterStream");
-    }
-
-    @Override
-    public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateCharacterStream");
-    }
-
-    @Override
-    public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateCharacterStream");
-    }
-
-    @Override
-    public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateCharacterStream");
-    }
-
-    @Override
-    public void updateClob(int columnIndex, Clob x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateClob");
-    }
-
-    @Override
-    public void updateClob(String columnLabel, Clob x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateClob");
-    }
-
-    @Override
-    public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateClob");
-    }
-
-    @Override
-    public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateClob");
-    }
-
-    @Override
-    public void updateClob(int columnIndex, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateClob");
-    }
-
-    @Override
-    public void updateClob(String columnLabel, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateClob");
-    }
-
-    @Override
-    public void updateDate(int columnIndex, Date x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateDate");
-    }
-
-    @Override
-    public void updateDate(String columnLabel, Date x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateDate");
-    }
-
-    @Override
-    public void updateDouble(int columnIndex, double x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateDouble");
-    }
-
-    @Override
-    public void updateDouble(String columnLabel, double x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateDouble");
-    }
-
-    @Override
-    public void updateFloat(int columnIndex, float x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateFloat");
-    }
-
-    @Override
-    public void updateFloat(String columnLabel, float x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateFloat");
-    }
-
-    @Override
-    public void updateInt(int columnIndex, int x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateInt");
-    }
-
-    @Override
-    public void updateInt(String columnLabel, int x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateInt");
-    }
-
-    @Override
-    public void updateLong(int columnIndex, long x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateLong");
-    }
-
-    @Override
-    public void updateLong(String columnLabel, long x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateLong");
-    }
-
-    @Override
-    public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNCharacterStream");
-    }
-
-    @Override
-    public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNCharacterStream");
-    }
-
-    @Override
-    public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNCharacterStream");
-    }
-
-    @Override
-    public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNCharacterStream");
-    }
-
-    @Override
-    public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNClob");
-    }
-
-    @Override
-    public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNClob");
-    }
-
-    @Override
-    public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNClob");
-    }
-
-    @Override
-    public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNClob");
-    }
-
-    @Override
-    public void updateNClob(int columnIndex, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNClob");
-    }
-
-    @Override
-    public void updateNClob(String columnLabel, Reader reader) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNClob");
-    }
-
-    @Override
-    public void updateNString(int columnIndex, String nString) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNString");
-    }
-
-    @Override
-    public void updateNString(String columnLabel, String nString) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNString");
-    }
-
-    @Override
-    public void updateNull(int columnIndex) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNull");
-    }
-
-    @Override
-    public void updateNull(String columnLabel) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateNull");
-    }
-
-    @Override
-    public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateObject(int columnIndex, Object x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength)
-            throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateObject(int columnIndex, Object x, SQLType targetSqlType) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateObject(String columnLabel, Object x, SQLType targetSqlType) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateObject(String columnLabel, Object x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateObject");
-    }
-
-    @Override
-    public void updateRef(int columnIndex, Ref x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateRef");
-    }
-
-    @Override
-    public void updateRef(String columnLabel, Ref x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateRef");
-    }
-
-    @Override
-    public void updateRowId(int columnIndex, RowId x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateRowId");
-    }
-
-    @Override
-    public void updateRowId(String columnLabel, RowId x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateRowId");
-    }
-
-    @Override
-    public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateSQLXML");
-    }
-
-    @Override
-    public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateSQLXML");
-    }
-
-    @Override
-    public void updateShort(int columnIndex, short x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateShort");
-    }
-
-    @Override
-    public void updateShort(String columnLabel, short x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateShort");
-    }
-
-    @Override
-    public void updateString(int columnIndex, String x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateString");
-    }
-
-    @Override
-    public void updateString(String columnLabel, String x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateString");
-    }
-
-    @Override
-    public void updateTime(int columnIndex, Time x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateTime");
-    }
-
-    @Override
-    public void updateTime(String columnLabel, Time x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateTime");
-    }
-
-    @Override
-    public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateTimestamp");
-    }
-
-    @Override
-    public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateTimestamp");
-    }
-
-    // Update navigation and state (unsupported)
-
-    @Override
-    public void insertRow() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "insertRow");
-    }
-
-    @Override
-    public void updateRow() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "updateRow");
-    }
-
-    @Override
-    public void deleteRow() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "deleteRow");
-    }
-
-    @Override
-    public void refreshRow() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "refreshRow");
-    }
-
-    @Override
-    public void moveToInsertRow() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "moveToInsertRow");
-    }
-
-    @Override
-    public void moveToCurrentRow() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "moveToCurrentRow");
-    }
-
-    @Override
-    public boolean rowInserted() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "rowInserted");
-    }
-
-    @Override
-    public boolean rowUpdated() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "rowUpdated");
-    }
-
-    @Override
-    public boolean rowDeleted() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "rowDeleted");
-
-    }
-
-    @Override
-    public void cancelRowUpdates() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(ResultSet.class, "cancelRowUpdates");
-    }
-
-    // Errors and warnings
-
-    @Override
-    public SQLWarning getWarnings() throws SQLException {
-        checkClosed();
-        return null;
-    }
-
-    @Override
-    public void clearWarnings() throws SQLException {
-        checkClosed();
-    }
-
-    @Override
-    protected ADBErrorReporter getErrorReporter() {
-        return metadata.getErrorReporter();
-    }
-
-    // Ownership
-
-    @Override
-    public Statement getStatement() throws SQLException {
-        checkClosed();
-        return metadata.statement.getResultSetStatement(this);
-    }
-
-    // Cursor - related
-
-    @Override
-    public String getCursorName() throws SQLException {
-        checkClosed();
-        return "";
-    }
-
-    @Override
-    public int getType() throws SQLException {
-        checkClosed();
-        return TYPE_FORWARD_ONLY;
-    }
-
-    @Override
-    public int getConcurrency() throws SQLException {
-        checkClosed();
-        return ResultSet.CONCUR_READ_ONLY;
-    }
-
-    @Override
-    public int getHoldability() throws SQLException {
-        checkClosed();
-        return RESULT_SET_HOLDABILITY;
-    }
-
-    @Override
-    public int getFetchDirection() throws SQLException {
-        checkClosed();
-        return FETCH_FORWARD;
-    }
-
-    @Override
-    public void setFetchDirection(int direction) throws SQLException {
-        checkClosed();
-        if (direction != ResultSet.FETCH_FORWARD) {
-            throw getErrorReporter().errorParameterValueNotSupported("direction");
-        }
-    }
-
-    @Override
-    public int getFetchSize() throws SQLException {
-        checkClosed();
-        return 1;
-    }
-
-    @Override
-    public void setFetchSize(int rows) throws SQLException {
-        checkClosed();
-        // ignore value
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBResultSetMetaData.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBResultSetMetaData.java
deleted file mode 100644
index 67dd217..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBResultSetMetaData.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-final class ADBResultSetMetaData extends ADBWrapperSupport implements ResultSetMetaData {
-
-    final ADBStatement statement;
-
-    private final List<ADBColumn> columns;
-
-    private final Map<String, Integer> indexByName;
-
-    ADBResultSetMetaData(ADBStatement statement, List<ADBColumn> columns) {
-        this.statement = Objects.requireNonNull(statement);
-        this.columns = columns != null ? columns : Collections.emptyList();
-        this.indexByName = createIndexByName(this.columns);
-    }
-
-    @Override
-    public int getColumnCount() {
-        return columns.size();
-    }
-
-    @Override
-    public String getColumnName(int columnNumber) throws SQLException {
-        return getColumnByNumber(columnNumber).getName();
-    }
-
-    @Override
-    public String getColumnLabel(int columnNumber) throws SQLException {
-        return getColumnByNumber(columnNumber).getName();
-    }
-
-    @Override
-    public int getColumnType(int columnNumber) throws SQLException {
-        return getColumnByNumber(columnNumber).getType().getJdbcType().getVendorTypeNumber();
-    }
-
-    @Override
-    public String getColumnTypeName(int columnNumber) throws SQLException {
-        return getColumnByNumber(columnNumber).getType().getTypeName();
-    }
-
-    @Override
-    public String getColumnClassName(int columnNumber) throws SQLException {
-        return getColumnByNumber(columnNumber).getType().getJavaClass().getName();
-    }
-
-    @Override
-    public int getColumnDisplaySize(int columnNumber) {
-        // TODO:based on type
-        return 1;
-    }
-
-    @Override
-    public int getPrecision(int columnNumber) {
-        // TODO:based on type
-        return 0;
-    }
-
-    @Override
-    public int getScale(int columnNumber) {
-        return 0;
-    }
-
-    @Override
-    public boolean isAutoIncrement(int columnNumber) {
-        return false;
-    }
-
-    @Override
-    public boolean isCaseSensitive(int columnNumber) {
-        return false;
-    }
-
-    @Override
-    public boolean isCurrency(int columnNumber) {
-        return false;
-    }
-
-    @Override
-    public int isNullable(int columnNumber) throws SQLException {
-        return getColumnByNumber(columnNumber).isOptional() ? columnNullable : columnNoNulls;
-    }
-
-    @Override
-    public boolean isSearchable(int columnNumber) {
-        return true;
-    }
-
-    @Override
-    public boolean isSigned(int columnNumber) {
-        return false;
-    }
-
-    @Override
-    public boolean isReadOnly(int columnNumber) {
-        return false;
-    }
-
-    @Override
-    public boolean isWritable(int columnNumber) {
-        return false;
-    }
-
-    @Override
-    public boolean isDefinitelyWritable(int columnNumber) {
-        return false;
-    }
-
-    @Override
-    public String getCatalogName(int columnNumber) {
-        return "";
-    }
-
-    @Override
-    public String getSchemaName(int columnNumber) {
-        return "";
-    }
-
-    @Override
-    public String getTableName(int columnNumber) {
-        return "";
-    }
-
-    // Helpers
-
-    private ADBColumn getColumnByNumber(int columnNumber) throws SQLException {
-        return getColumnByIndex(toColumnIndex(columnNumber));
-    }
-
-    private int toColumnIndex(int columnNumber) throws SQLException {
-        boolean ok = 0 < columnNumber && columnNumber <= columns.size();
-        if (!ok) {
-            throw getErrorReporter().errorParameterValueNotSupported("columnNumber");
-        }
-        return columnNumber - 1;
-    }
-
-    ADBColumn getColumnByIndex(int idx) {
-        return columns.get(idx);
-    }
-
-    int findColumnIndexByName(String columnName) {
-        Integer idx = indexByName.get(columnName);
-        return idx != null ? idx : -1;
-    }
-
-    private static Map<String, Integer> createIndexByName(List<ADBColumn> columns) {
-        int n = columns.size();
-        switch (n) {
-            case 0:
-                return Collections.emptyMap();
-            case 1:
-                return Collections.singletonMap(columns.get(0).getName(), 0);
-            default:
-                Map<String, Integer> m = new HashMap<>();
-                for (int i = 0; i < n; i++) {
-                    m.put(columns.get(i).getName(), i);
-                }
-                return m;
-        }
-    }
-
-    @Override
-    protected ADBErrorReporter getErrorReporter() {
-        return statement.getErrorReporter();
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBRowStore.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBRowStore.java
deleted file mode 100644
index da9c5bd..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBRowStore.java
+++ /dev/null
@@ -1,1191 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.nio.charset.StandardCharsets;
-import java.sql.Date;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.Period;
-import java.time.format.DateTimeParseException;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.BeanDescription;
-import com.fasterxml.jackson.databind.DeserializationConfig;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectReader;
-import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-
-final class ADBRowStore {
-
-    private static final String ROW_STORE_ATTR_NAME = ADBRowStore.class.getSimpleName();
-
-    private static final int FLOAT_NAN_BITS = Float.floatToIntBits(Float.NaN);
-    private static final int FLOAT_POSITIVE_ZERO_BITS = Float.floatToIntBits(+0.0f);
-    private static final int FLOAT_NEGATIVE_ZERO_BITS = Float.floatToIntBits(-0.0f);
-    private static final long DOUBLE_NAN_BITS = Double.doubleToLongBits(Double.NaN);
-    private static final long DOUBLE_POSITIVE_ZERO_BITS = Double.doubleToLongBits(+0.0d);
-    private static final long DOUBLE_NEGATIVE_ZERO_BITS = Double.doubleToLongBits(-0.0d);
-
-    static final Map<Class<?>, GetObjectFunction> OBJECT_ACCESSORS_ATOMIC = createAtomicObjectAccessorMap();
-
-    static final List<Class<?>> GET_OBJECT_NON_ATOMIC = Arrays.asList(Collection.class, List.class, Map.class);
-
-    private final ADBResultSet resultSet;
-
-    private final ADBDatatype[] columnTypes;
-    private final Object[] objectStore;
-    private final long[] registerStore; // 2 registers per column
-
-    private int parsedLength;
-    private long currentDateChronon;
-    private JsonGenerator jsonGen;
-    private StringWriter jsonGenBuffer;
-
-    ADBRowStore(ADBResultSet resultSet, int initialColumnCount) {
-        this.resultSet = Objects.requireNonNull(resultSet);
-        columnTypes = new ADBDatatype[initialColumnCount];
-        objectStore = new Object[initialColumnCount];
-        registerStore = new long[initialColumnCount * 2];
-    }
-
-    void reset() {
-        Arrays.fill(columnTypes, ADBDatatype.MISSING);
-        Arrays.fill(registerStore, 0);
-        Arrays.fill(objectStore, null);
-    }
-
-    private void setColumnType(int columnIndex, ADBDatatype columnType) {
-        columnTypes[columnIndex] = columnType;
-    }
-
-    ADBDatatype getColumnType(int columnIndex) {
-        return columnTypes[columnIndex];
-    }
-
-    void putColumn(int columnIndex, char[] textChars, int textOffset, int textLength) throws SQLException {
-        byte valueTypeTag = parseTypeTag(textChars, textOffset, textLength);
-        ADBDatatype valueType = ADBDatatype.findByTypeTag(valueTypeTag);
-        if (valueType == null) {
-            throw getErrorReporter().errorUnexpectedType(valueTypeTag);
-        }
-
-        int nonTaggedOffset = textOffset + parsedLength;
-        int nonTaggedLength = textLength - parsedLength;
-        int nonTaggedEnd = nonTaggedOffset + nonTaggedLength; // = textOffset + textLength
-
-        setColumnType(columnIndex, valueType);
-
-        // NULL, BOOLEAN, BIGINT shouldn't normally happen. only handle here for completeness
-
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                // no content
-                break;
-            case BOOLEAN:
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-            case FLOAT:
-            case DOUBLE:
-            case DATE:
-            case TIME:
-            case DATETIME:
-            case YEARMONTHDURATION:
-            case DAYTIMEDURATION:
-                long r0 = parseInt64(textChars, nonTaggedOffset, nonTaggedEnd);
-                setColumnRegisters(columnIndex, r0, 0);
-                break;
-            case STRING:
-                objectStore[columnIndex] = new String(textChars, nonTaggedOffset, nonTaggedLength);
-                break;
-            case DURATION:
-                int delimiterOffset = indexOf(ADBProtocol.TEXT_DELIMITER, textChars, nonTaggedOffset, nonTaggedEnd);
-                if (delimiterOffset < 0 || delimiterOffset == nonTaggedEnd - 1) {
-                    throw getErrorReporter().errorInProtocol();
-                }
-                r0 = parseInt64(textChars, nonTaggedOffset, delimiterOffset);
-                long r1 = parseInt64(textChars, delimiterOffset + 1, nonTaggedEnd);
-                setColumnRegisters(columnIndex, r0, r1);
-                break;
-            case UUID:
-                // TODO: better encoding as 2 longs?
-                objectStore[columnIndex] = UUID.fromString(new String(textChars, nonTaggedOffset, nonTaggedLength));
-                break;
-            case OBJECT:
-            case ARRAY:
-            case MULTISET:
-                // Unexpected (shouldn't be called)
-                throw new IllegalArgumentException(String.valueOf(valueType));
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    void putNullColumn(int columnIndex) {
-        setColumnType(columnIndex, ADBDatatype.NULL);
-    }
-
-    void putBooleanColumn(int columnIndex, boolean value) {
-        setColumnType(columnIndex, ADBDatatype.BOOLEAN);
-        setColumnRegisters(columnIndex, value ? 1 : 0, 0);
-    }
-
-    void putInt64Column(int columnIndex, long value) {
-        setColumnType(columnIndex, ADBDatatype.BIGINT);
-        setColumnRegisters(columnIndex, value, 0);
-    }
-
-    void putArrayColumn(int columnIndex, List<?> value) {
-        setColumnType(columnIndex, ADBDatatype.ARRAY);
-        objectStore[columnIndex] = Objects.requireNonNull(value);
-    }
-
-    void putRecordColumn(int columnIndex, Map<?, ?> value) {
-        setColumnType(columnIndex, ADBDatatype.OBJECT);
-        objectStore[columnIndex] = Objects.requireNonNull(value);
-    }
-
-    private void setColumnRegisters(int columnIndex, long r0, long r1) {
-        int registerPos = columnIndex * 2;
-        registerStore[registerPos] = r0;
-        registerStore[++registerPos] = r1;
-    }
-
-    private long getColumnRegister(int columnIndex, int registerIndex) {
-        int registerPos = columnIndex * 2;
-        switch (registerIndex) {
-            case 0:
-                break;
-            case 1:
-                registerPos++;
-                break;
-            default:
-                throw new IllegalArgumentException();
-        }
-        return registerStore[registerPos];
-    }
-
-    private boolean getColumnRegisterAsBoolean(int columnIndex, int registerIndex) {
-        return getColumnRegister(columnIndex, registerIndex) != 0;
-    }
-
-    private byte getColumnRegisterAsByte(int columnIndex, int registerIndex) {
-        return (byte) getColumnRegister(columnIndex, registerIndex);
-    }
-
-    private short getColumnRegisterAsShort(int columnIndex, int registerIndex) {
-        return (short) getColumnRegister(columnIndex, registerIndex);
-    }
-
-    private int getColumnRegisterAsInt(int columnIndex, int registerIndex) {
-        return (int) getColumnRegister(columnIndex, registerIndex);
-    }
-
-    private float getColumnRegisterAsFloat(int columnIndex, int registerIndex) {
-        return Float.intBitsToFloat(getColumnRegisterAsFloatBits(columnIndex, registerIndex));
-    }
-
-    private boolean isColumnRegisterZeroOrNanFloat(int columnIndex, int registerIndex) {
-        int bits = getColumnRegisterAsFloatBits(columnIndex, registerIndex);
-        return bits == FLOAT_POSITIVE_ZERO_BITS || bits == FLOAT_NEGATIVE_ZERO_BITS || bits == FLOAT_NAN_BITS;
-    }
-
-    private int getColumnRegisterAsFloatBits(int columnIndex, int registerIndex) {
-        return getColumnRegisterAsInt(columnIndex, registerIndex);
-    }
-
-    private double getColumnRegisterAsDouble(int columnIndex, int registerIndex) {
-        return Double.longBitsToDouble(getColumnRegisterAsDoubleBits(columnIndex, registerIndex));
-    }
-
-    private boolean isColumnRegisterZeroOrNanDouble(int columnIndex, int registerIndex) {
-        long bits = getColumnRegisterAsDoubleBits(columnIndex, registerIndex);
-        return bits == DOUBLE_POSITIVE_ZERO_BITS || bits == DOUBLE_NEGATIVE_ZERO_BITS || bits == DOUBLE_NAN_BITS;
-    }
-
-    private long getColumnRegisterAsDoubleBits(int columnIndex, int registerIndex) {
-        return getColumnRegister(columnIndex, registerIndex);
-    }
-
-    private Period getColumnRegisterAsPeriod(int columnIndex, int registerIndex) {
-        return Period.ofMonths((int) getColumnRegister(columnIndex, registerIndex));
-    }
-
-    private Duration getColumnRegisterAsDuration(int columnIndex, int registerIndex) {
-        return Duration.ofMillis((int) getColumnRegister(columnIndex, registerIndex));
-    }
-
-    private Number getNumberFromObjectStore(int columnIndex) {
-        Object o = objectStore[columnIndex];
-        if (o != null) {
-            return (Number) o;
-        }
-        Number n;
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case TINYINT:
-                n = getColumnRegisterAsByte(columnIndex, 0);
-                break;
-            case SMALLINT:
-                n = getColumnRegisterAsShort(columnIndex, 0);
-                break;
-            case INTEGER:
-                n = getColumnRegisterAsInt(columnIndex, 0);
-                break;
-            case BIGINT:
-                n = getColumnRegister(columnIndex, 0);
-                break;
-            case FLOAT:
-                n = getColumnRegisterAsFloat(columnIndex, 0);
-                break;
-            case DOUBLE:
-                n = getColumnRegisterAsDouble(columnIndex, 0);
-                break;
-            default:
-                throw new IllegalArgumentException(String.valueOf(valueType));
-        }
-        objectStore[columnIndex] = n;
-        return n;
-    }
-
-    private String getStringFromObjectStore(int columnIndex) {
-        return (String) objectStore[columnIndex];
-    }
-
-    private UUID getUUIDFromObjectStore(int columnIndex) {
-        return (UUID) objectStore[columnIndex];
-    }
-
-    private Period getPeriodFromObjectStore(int columnIndex) {
-        Object o = objectStore[columnIndex];
-        if (o != null) {
-            return (Period) o;
-        }
-        ADBDatatype valueType = getColumnType(columnIndex);
-        if (valueType != ADBDatatype.YEARMONTHDURATION) {
-            throw new IllegalArgumentException(String.valueOf(valueType));
-        }
-        Period v = getColumnRegisterAsPeriod(columnIndex, 0);
-        objectStore[columnIndex] = v;
-        return v;
-    }
-
-    private Duration getDurationFromObjectStore(int columnIndex) {
-        Object o = objectStore[columnIndex];
-        if (o != null) {
-            return (Duration) o;
-        }
-        ADBDatatype valueType = getColumnType(columnIndex);
-        if (valueType != ADBDatatype.DAYTIMEDURATION) {
-            throw new IllegalArgumentException(String.valueOf(valueType));
-        }
-        Duration v = getColumnRegisterAsDuration(columnIndex, 0);
-        objectStore[columnIndex] = v;
-        return v;
-    }
-
-    private String getISODurationStringFromObjectStore(int columnIndex) {
-        Object o = objectStore[columnIndex];
-        if (o != null) {
-            return (String) o;
-        }
-        ADBDatatype valueType = getColumnType(columnIndex);
-        if (valueType != ADBDatatype.DURATION) {
-            throw new IllegalArgumentException(String.valueOf(valueType));
-        }
-        String v = getColumnRegisterAsPeriod(columnIndex, 0).toString()
-                + getColumnRegisterAsDuration(columnIndex, 1).toString().substring(1);
-        objectStore[columnIndex] = v;
-        return v;
-    }
-
-    boolean getBoolean(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return false;
-            case BOOLEAN:
-                return getColumnRegisterAsBoolean(columnIndex, 0);
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-                return getColumnRegister(columnIndex, 0) != 0;
-            case FLOAT:
-                return !isColumnRegisterZeroOrNanFloat(columnIndex, 0);
-            case DOUBLE:
-                return !isColumnRegisterZeroOrNanDouble(columnIndex, 0);
-            case STRING:
-                return Boolean.parseBoolean(getStringFromObjectStore(columnIndex));
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    byte getByte(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return 0;
-            case BOOLEAN:
-                return (byte) (getColumnRegisterAsBoolean(columnIndex, 0) ? 1 : 0);
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-                return getColumnRegisterAsByte(columnIndex, 0);
-            case FLOAT:
-                return (byte) getColumnRegisterAsFloat(columnIndex, 0);
-            case DOUBLE:
-                return (byte) getColumnRegisterAsDouble(columnIndex, 0);
-            case STRING:
-                return (byte) parseInt64(getStringFromObjectStore(columnIndex));
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    short getShort(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return 0;
-            case BOOLEAN:
-                return (short) (getColumnRegisterAsBoolean(columnIndex, 0) ? 1 : 0);
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-                return getColumnRegisterAsShort(columnIndex, 0);
-            case FLOAT:
-                return (short) getColumnRegisterAsFloat(columnIndex, 0);
-            case DOUBLE:
-                return (short) getColumnRegisterAsDouble(columnIndex, 0);
-            case STRING:
-                return (short) parseInt64(getStringFromObjectStore(columnIndex));
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    int getInt(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return 0;
-            case BOOLEAN:
-                return getColumnRegisterAsBoolean(columnIndex, 0) ? 1 : 0;
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-            case DATE:
-            case TIME:
-            case YEARMONTHDURATION:
-                return getColumnRegisterAsInt(columnIndex, 0);
-            case FLOAT:
-                return (int) getColumnRegisterAsFloat(columnIndex, 0);
-            case DOUBLE:
-                return (int) getColumnRegisterAsDouble(columnIndex, 0);
-            case STRING:
-                return (int) parseInt64(getStringFromObjectStore(columnIndex));
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    long getLong(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return 0;
-            case BOOLEAN:
-                return getColumnRegisterAsBoolean(columnIndex, 0) ? 1 : 0;
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-            case DATE:
-            case TIME:
-            case DATETIME:
-            case YEARMONTHDURATION:
-            case DAYTIMEDURATION:
-                return getColumnRegister(columnIndex, 0);
-            case FLOAT:
-                return (long) getColumnRegisterAsFloat(columnIndex, 0);
-            case DOUBLE:
-                return (long) getColumnRegisterAsDouble(columnIndex, 0);
-            case STRING:
-                return parseInt64(getStringFromObjectStore(columnIndex));
-            default:
-                // TODO:support temporal types?
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    float getFloat(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return 0;
-            case BOOLEAN:
-                return getColumnRegisterAsBoolean(columnIndex, 0) ? 1f : 0f;
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-                return getColumnRegister(columnIndex, 0);
-            case FLOAT:
-                return getColumnRegisterAsFloat(columnIndex, 0);
-            case DOUBLE:
-                return (float) getColumnRegisterAsDouble(columnIndex, 0);
-            case STRING:
-                try {
-                    return Float.parseFloat(getStringFromObjectStore(columnIndex));
-                } catch (NumberFormatException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    double getDouble(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return 0;
-            case BOOLEAN:
-                return getColumnRegisterAsBoolean(columnIndex, 0) ? 1d : 0d;
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-                return getColumnRegister(columnIndex, 0);
-            case FLOAT:
-                return getColumnRegisterAsFloat(columnIndex, 0);
-            case DOUBLE:
-                return getColumnRegisterAsDouble(columnIndex, 0);
-            case STRING:
-                try {
-                    return Double.parseDouble(getStringFromObjectStore(columnIndex));
-                } catch (NumberFormatException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    BigDecimal getBigDecimal(int columnIndex) throws SQLException {
-        return getBigDecimal(columnIndex, false, 0);
-    }
-
-    @SuppressWarnings("UnpredictableBigDecimalConstructorCall")
-    BigDecimal getBigDecimal(int columnIndex, boolean setScale, int scale) throws SQLException {
-        BigDecimal dec;
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case BOOLEAN:
-                dec = getColumnRegisterAsBoolean(columnIndex, 0) ? BigDecimal.ONE : BigDecimal.ZERO;
-                break;
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-            case DATE:
-            case TIME:
-            case DATETIME:
-            case YEARMONTHDURATION:
-            case DAYTIMEDURATION:
-                dec = BigDecimal.valueOf(getColumnRegister(columnIndex, 0));
-                break;
-            case FLOAT:
-                try {
-                    dec = new BigDecimal(getColumnRegisterAsFloat(columnIndex, 0));
-                } catch (NumberFormatException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-                break;
-            case DOUBLE:
-                try {
-                    dec = new BigDecimal(getColumnRegisterAsDouble(columnIndex, 0));
-                } catch (NumberFormatException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-                break;
-            case STRING:
-                try {
-                    dec = new BigDecimal(getStringFromObjectStore(columnIndex));
-                } catch (NumberFormatException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-                break;
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-
-        return setScale ? dec.setScale(scale, RoundingMode.DOWN) : dec;
-    }
-
-    private Date getDate(int columnIndex) throws SQLException {
-        return getDate(columnIndex, null);
-    }
-
-    Date getDate(int columnIndex, Calendar cal) throws SQLException {
-        // TODO:cal is not used
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case DATE:
-                return toDateFromDateChronon(getColumnRegister(columnIndex, 0));
-            case DATETIME:
-                return toDateFromDatetimeChronon(getColumnRegister(columnIndex, 0));
-            case STRING:
-                try {
-                    LocalDate d = LocalDate.parse(getStringFromObjectStore(columnIndex)); // TODO:review
-                    return new Date(d.getYear() - 1900, d.getMonthValue() - 1, d.getDayOfMonth());
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    LocalDate getLocalDate(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case DATE:
-                return toLocalDateFromDateChronon(getColumnRegister(columnIndex, 0));
-            case DATETIME:
-                return toLocalDateFromDatetimeChronon(getColumnRegister(columnIndex, 0));
-            case STRING:
-                try {
-                    return LocalDate.parse(getStringFromObjectStore(columnIndex)); // TODO:review
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    private Time getTime(int columnIndex) throws SQLException {
-        return getTime(columnIndex, null);
-    }
-
-    Time getTime(int columnIndex, Calendar cal) throws SQLException {
-        // TODO:cal not used
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case TIME:
-                return toTimeFromTimeChronon(getColumnRegister(columnIndex, 0));
-            case DATETIME:
-                return toTimeFromDatetimeChronon(getColumnRegister(columnIndex, 0));
-            case STRING:
-                try {
-                    LocalTime t = LocalTime.parse(getStringFromObjectStore(columnIndex)); // TODO:review
-                    return toTimeFromTimeChronon(TimeUnit.NANOSECONDS.toMillis(t.toNanoOfDay()));
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    LocalTime getLocalTime(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case TIME:
-                return toLocalTimeFromTimeChronon(getColumnRegister(columnIndex, 0));
-            case DATETIME:
-                return toLocalTimeFromDatetimeChronon(getColumnRegister(columnIndex, 0));
-            case STRING:
-                try {
-                    return LocalTime.parse(getStringFromObjectStore(columnIndex)); // TODO:review
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    private Timestamp getTimestamp(int columnIndex) throws SQLException {
-        return getTimestamp(columnIndex, null);
-    }
-
-    Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
-        //TODO:FIXME:CAL NOT USED
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case DATE:
-                return toTimestampFromDateChronon(getColumnRegister(columnIndex, 0));
-            case DATETIME:
-                return toTimestampFromDatetimeChronon(getColumnRegister(columnIndex, 0));
-            case STRING:
-                try {
-                    Instant i = Instant.parse(getStringFromObjectStore(columnIndex));
-                    long millis0 = TimeUnit.SECONDS.toMillis(i.getEpochSecond());
-                    long millis1 = TimeUnit.NANOSECONDS.toMillis(i.getNano());
-                    return new Timestamp(millis0 + millis1);
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    Instant getInstant(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case DATE:
-                return toInstantFromDateChronon(getColumnRegister(columnIndex, 0));
-            case DATETIME:
-                return toInstantFromDatetimeChronon(getColumnRegister(columnIndex, 0));
-            case STRING:
-                try {
-                    return Instant.parse(getStringFromObjectStore(columnIndex)); // TODO:review
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    Period getPeriod(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case YEARMONTHDURATION:
-                return getPeriodFromObjectStore(columnIndex);
-            case DURATION:
-                return getColumnRegisterAsPeriod(columnIndex, 0);
-            case STRING:
-                try {
-                    return Period.parse(getStringFromObjectStore(columnIndex)); // TODO:review
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    Duration getDuration(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case DAYTIMEDURATION:
-                return getDurationFromObjectStore(columnIndex);
-            case DURATION:
-                return getColumnRegisterAsDuration(columnIndex, 1);
-            case STRING:
-                try {
-                    return Duration.parse(getStringFromObjectStore(columnIndex)); // TODO:review
-                } catch (DateTimeParseException e) {
-                    throw getErrorReporter().errorInvalidValueOfType(valueType);
-                }
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    byte[] getBinary(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case STRING:
-                return getStringFromObjectStore(columnIndex).getBytes(StandardCharsets.UTF_8);
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    UUID getUUID(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case UUID:
-                return getUUIDFromObjectStore(columnIndex);
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    String getString(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case BOOLEAN:
-                return Boolean.toString(getColumnRegisterAsBoolean(columnIndex, 0));
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-                return Long.toString(getColumnRegister(columnIndex, 0));
-            case FLOAT:
-                return Float.toString(getColumnRegisterAsFloat(columnIndex, 0));
-            case DOUBLE:
-                return Double.toString(getColumnRegisterAsDouble(columnIndex, 0));
-            case DATE:
-                return toLocalDateFromDateChronon(getColumnRegister(columnIndex, 0)).toString(); // TODO:review
-            case TIME:
-                return toLocalTimeFromTimeChronon(getColumnRegister(columnIndex, 0)).toString(); // TODO:review
-            case DATETIME:
-                return toInstantFromDatetimeChronon(getColumnRegister(columnIndex, 0)).toString(); // TODO:review
-            case YEARMONTHDURATION:
-                return getPeriodFromObjectStore(columnIndex).toString(); // TODO:review
-            case DAYTIMEDURATION:
-                return getDurationFromObjectStore(columnIndex).toString(); // TODO:review
-            case DURATION:
-                return getISODurationStringFromObjectStore(columnIndex); // TODO:review
-            case STRING:
-                return getStringFromObjectStore(columnIndex);
-            case UUID:
-                return getUUIDFromObjectStore(columnIndex).toString();
-            case OBJECT:
-            case ARRAY:
-                return printAsJson(objectStore[columnIndex]);
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    Reader getCharacterStream(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case STRING:
-                return new StringReader(getStringFromObjectStore(columnIndex));
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    InputStream getInputStream(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case STRING:
-                return new ByteArrayInputStream(getStringFromObjectStore(columnIndex).getBytes(StandardCharsets.UTF_8));
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    Object getObject(int columnIndex) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            case BOOLEAN:
-                return getColumnRegisterAsBoolean(columnIndex, 0);
-            case TINYINT:
-            case SMALLINT:
-            case INTEGER:
-            case BIGINT:
-            case FLOAT:
-            case DOUBLE:
-                return getNumberFromObjectStore(columnIndex);
-            case DATE:
-                return toDateFromDateChronon(getColumnRegister(columnIndex, 0));
-            case TIME:
-                return toTimeFromTimeChronon(getColumnRegister(columnIndex, 0));
-            case DATETIME:
-                return toTimestampFromDatetimeChronon(getColumnRegister(columnIndex, 0));
-            case YEARMONTHDURATION:
-                return getPeriodFromObjectStore(columnIndex);
-            case DAYTIMEDURATION:
-                return getDurationFromObjectStore(columnIndex);
-            case DURATION:
-                return getISODurationStringFromObjectStore(columnIndex);
-            case STRING:
-                return getStringFromObjectStore(columnIndex);
-            case UUID:
-                return getUUIDFromObjectStore(columnIndex);
-            case OBJECT:
-            case ARRAY:
-                return objectStore[columnIndex]; // TODO:how to make immutable?
-            default:
-                throw getErrorReporter().errorUnexpectedType(valueType);
-        }
-    }
-
-    <T> T getObject(int columnIndex, Class<T> targetType) throws SQLException {
-        ADBDatatype valueType = getColumnType(columnIndex);
-        switch (valueType) {
-            case MISSING:
-            case NULL:
-                return null;
-            default:
-                GetObjectFunction getter = OBJECT_ACCESSORS_ATOMIC.get(targetType);
-                Object v;
-                if (getter != null) {
-                    v = getter.getObject(this, columnIndex);
-                } else if (GET_OBJECT_NON_ATOMIC.contains(targetType)) {
-                    v = getObject(columnIndex);
-                } else {
-                    throw getErrorReporter().errorUnexpectedType(targetType);
-                }
-                return targetType.cast(v);
-        }
-    }
-
-    interface GetObjectFunction {
-        Object getObject(ADBRowStore rowStore, int columnIndex) throws SQLException;
-    }
-
-    private static Map<Class<?>, GetObjectFunction> createAtomicObjectAccessorMap() {
-        Map<Class<?>, GetObjectFunction> map = new HashMap<>();
-        map.put(Boolean.TYPE, ADBRowStore::getBoolean);
-        map.put(Boolean.class, ADBRowStore::getBoolean);
-        map.put(Byte.TYPE, ADBRowStore::getByte);
-        map.put(Byte.class, ADBRowStore::getByte);
-        map.put(Short.TYPE, ADBRowStore::getShort);
-        map.put(Short.class, ADBRowStore::getShort);
-        map.put(Integer.TYPE, ADBRowStore::getInt);
-        map.put(Integer.class, ADBRowStore::getInt);
-        map.put(Long.TYPE, ADBRowStore::getLong);
-        map.put(Long.class, ADBRowStore::getLong);
-        map.put(Float.TYPE, ADBRowStore::getFloat);
-        map.put(Float.class, ADBRowStore::getFloat);
-        map.put(Double.TYPE, ADBRowStore::getDouble);
-        map.put(Double.class, ADBRowStore::getDouble);
-        map.put(BigDecimal.class, ADBRowStore::getBigDecimal);
-        map.put(Date.class, ADBRowStore::getDate);
-        map.put(LocalDate.class, ADBRowStore::getLocalDate);
-        map.put(Time.class, ADBRowStore::getTime);
-        map.put(LocalTime.class, ADBRowStore::getLocalTime);
-        map.put(Timestamp.class, ADBRowStore::getTimestamp);
-        map.put(Instant.class, ADBRowStore::getInstant);
-        map.put(Period.class, ADBRowStore::getPeriod);
-        map.put(Duration.class, ADBRowStore::getDuration);
-        map.put(UUID.class, ADBRowStore::getUUID);
-        map.put(String.class, ADBRowStore::getString);
-        return map;
-    }
-
-    private Date toDateFromDateChronon(long dateChrononInDays) {
-        return new Date(TimeUnit.DAYS.toMillis(dateChrononInDays));
-    }
-
-    private Date toDateFromDatetimeChronon(long datetimeChrononInMillis) {
-        return new Date(datetimeChrononInMillis);
-    }
-
-    private LocalDate toLocalDateFromDateChronon(long dateChrononInDays) {
-        return LocalDate.ofEpochDay(dateChrononInDays);
-    }
-
-    private LocalDate toLocalDateFromDatetimeChronon(long datetimeChrononInMillis) {
-        return LocalDate.ofEpochDay(TimeUnit.MILLISECONDS.toDays(datetimeChrononInMillis));
-    }
-
-    private Time toTimeFromTimeChronon(long timeChrononInMillis) {
-        long datetimeChrononInMillis = getCurrentDateChrononInMillis() + timeChrononInMillis;
-        return new Time(datetimeChrononInMillis);
-    }
-
-    private Time toTimeFromDatetimeChronon(long datetimeChrononInMillis) {
-        return new Time(datetimeChrononInMillis);
-    }
-
-    private LocalTime toLocalTimeFromTimeChronon(long timeChrononInMillis) {
-        return LocalTime.ofNanoOfDay(TimeUnit.MILLISECONDS.toNanos(timeChrononInMillis));
-    }
-
-    private LocalTime toLocalTimeFromDatetimeChronon(long datetimeChrononInMillis) {
-        return LocalTime.ofNanoOfDay(TimeUnit.MILLISECONDS.toNanos(datetimeChrononInMillis));
-    }
-
-    private Timestamp toTimestampFromDatetimeChronon(long datetimeChrononInMillis) {
-        return new Timestamp(datetimeChrononInMillis);
-    }
-
-    private Timestamp toTimestampFromDateChronon(long dateChrononInDays) {
-        return new Timestamp(TimeUnit.DAYS.toMillis(dateChrononInDays));
-    }
-
-    private Instant toInstantFromDatetimeChronon(long datetimeChrononInMillis) {
-        return Instant.ofEpochMilli(datetimeChrononInMillis);
-    }
-
-    private Instant toInstantFromDateChronon(long dateChrononInDays) {
-        return Instant.ofEpochMilli(TimeUnit.DAYS.toMillis(dateChrononInDays));
-    }
-
-    private long getCurrentDateChrononInMillis() {
-        if (currentDateChronon == 0) {
-            long chrononOfDay = TimeUnit.DAYS.toMillis(1);
-            currentDateChronon = System.currentTimeMillis() / chrononOfDay * chrononOfDay;
-        }
-        return currentDateChronon;
-    }
-
-    private String printAsJson(Object value) throws SQLException {
-        if (jsonGenBuffer == null) {
-            jsonGenBuffer = new StringWriter();
-            try {
-                //TODO:FIXME:need to configure generator to print java.sql.Date/Times properly
-                jsonGen = resultSet.metadata.statement.connection.protocol.driverContext.genericObjectWriter
-                        .createGenerator(jsonGenBuffer);
-            } catch (IOException e) {
-                throw getErrorReporter().errorInResultHandling(e);
-            }
-        }
-        try {
-            jsonGen.writeObject(value);
-            jsonGen.flush();
-            return jsonGenBuffer.getBuffer().toString();
-        } catch (IOException e) {
-            throw getErrorReporter().errorInResultHandling(e);
-        } finally {
-            jsonGenBuffer.getBuffer().setLength(0);
-        }
-    }
-
-    ObjectReader createComplexColumnObjectReader(ObjectReader templateReader) {
-        return templateReader.withAttribute(ROW_STORE_ATTR_NAME, this);
-    }
-
-    static void configureDeserialization(ObjectMapper objectMapper, SimpleModule serdeModule) {
-        objectMapper.configure(DeserializationFeature.USE_LONG_FOR_INTS, true);
-        serdeModule.setDeserializerModifier(createADMFormatDeserializerModifier());
-    }
-
-    private static BeanDeserializerModifier createADMFormatDeserializerModifier() {
-        return new BeanDeserializerModifier() {
-            @Override
-            public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc,
-                    JsonDeserializer<?> deserializer) {
-                if (String.class.equals(beanDesc.getClassInfo().getAnnotated())) {
-                    ADBRowStore rowStore = (ADBRowStore) config.getAttributes().getAttribute(ROW_STORE_ATTR_NAME);
-                    return rowStore.createADMFormatStringDeserializer();
-                } else {
-                    return deserializer;
-                }
-            }
-        };
-    }
-
-    private JsonDeserializer<?> createADMFormatStringDeserializer() {
-        return new JsonDeserializer<Object>() {
-            @Override
-            public Object deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
-                if (!parser.hasToken(JsonToken.VALUE_STRING)) {
-                    throw new IOException("Unexpected token");
-                }
-                try {
-                    ADBRowStore.this.reset();
-                    ADBRowStore.this.putColumn(0, parser.getTextCharacters(), parser.getTextOffset(),
-                            parser.getTextLength());
-                    return ADBRowStore.this.getObject(0);
-                } catch (SQLException e) {
-                    throw new IOException(e);
-                }
-            }
-        };
-    }
-
-    @FunctionalInterface
-    public interface ICharAccessor<T> {
-        char charAt(T input, int index);
-    }
-
-    private long parseInt64(CharSequence buffer) throws SQLException {
-        return parseInt64(buffer, 0, buffer.length(), CharSequence::charAt);
-    }
-
-    private long parseInt64(char[] buffer, int begin, int end) throws SQLException {
-        return parseInt64(buffer, begin, end, (input, index) -> input[index]);
-    }
-
-    private <T> long parseInt64(T buffer, int begin, int end, ICharAccessor<T> charAccessor) throws SQLException {
-        if (end < begin) {
-            throw new IllegalArgumentException();
-        }
-        boolean positive = true;
-        long value = 0;
-        int offset = begin;
-        char c = charAccessor.charAt(buffer, offset);
-        if (c == '+') {
-            offset++;
-        } else if (c == '-') {
-            offset++;
-            positive = false;
-        }
-        try {
-            for (; offset < end; offset++) {
-                c = charAccessor.charAt(buffer, offset);
-                if (c >= '0' && c <= '9') {
-                    value = Math.addExact(Math.multiplyExact(value, 10L), '0' - c);
-                } else {
-                    throw getErrorReporter().errorInProtocol(String.valueOf(c));
-                }
-            }
-            if (positive) {
-                value = Math.multiplyExact(value, -1L);
-            }
-            return value;
-        } catch (ArithmeticException e) {
-            throw getErrorReporter().errorInProtocol();
-        }
-    }
-
-    private byte parseTypeTag(char[] textChars, int textOffset, int textLength) throws SQLException {
-        if (textLength == 0) {
-            // empty string
-            parsedLength = 0;
-            return ADBDatatype.STRING.getTypeTag();
-        }
-        if (textChars[textOffset] == ADBProtocol.TEXT_DELIMITER) {
-            // any string
-            parsedLength = 1;
-            return ADBDatatype.STRING.getTypeTag();
-        }
-        // any type
-        int typeTagLength = 2;
-        if (textLength < typeTagLength) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        byte parsedTypeTag = getByteFromValidHexChars(textChars[textOffset], textChars[textOffset + 1]);
-        if (parsedTypeTag == ADBDatatype.MISSING.getTypeTag() || parsedTypeTag == ADBDatatype.NULL.getTypeTag()) {
-            parsedLength = typeTagLength;
-            return parsedTypeTag;
-        }
-        int delimiterLength = 1;
-        if (textLength < typeTagLength + delimiterLength) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        if (textChars[textOffset + typeTagLength] != ADBProtocol.TEXT_DELIMITER) {
-            throw getErrorReporter().errorInProtocol();
-        }
-        parsedLength = typeTagLength + delimiterLength;
-        return parsedTypeTag;
-    }
-
-    private byte getByteFromValidHexChars(char c0, char c1) throws SQLException {
-        return (byte) ((getValueFromValidHexChar(c0) << 4) + getValueFromValidHexChar(c1));
-    }
-
-    private int getValueFromValidHexChar(char c) throws SQLException {
-        if (c >= '0' && c <= '9') {
-            return c - '0';
-        }
-        if (c >= 'a' && c <= 'f') {
-            return 10 + c - 'a';
-        }
-        if (c >= 'A' && c <= 'F') {
-            return 10 + c - 'A';
-        }
-        throw getErrorReporter().errorInProtocol(String.valueOf(c));
-    }
-
-    private static int indexOf(char c, char[] array, int begin, int end) {
-        for (int i = begin; i < end; i++) {
-            if (array[i] == c) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    private ADBErrorReporter getErrorReporter() {
-        return resultSet.getErrorReporter();
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBStatement.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBStatement.java
deleted file mode 100644
index 94ac5a3..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBStatement.java
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.io.IOException;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.sql.Connection;
-import java.sql.Date;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalTime;
-import java.time.Period;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Queue;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Function;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.BeanDescription;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializationConfig;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
-
-class ADBStatement extends ADBWrapperSupport implements java.sql.Statement {
-
-    static final List<Class<?>> SET_OBJECT_NON_ATOMIC = Arrays.asList(Object[].class, Collection.class, Map.class);
-
-    static final Map<Class<?>, AbstractValueSerializer> SERIALIZER_MAP = createSerializerMap();
-
-    protected final ADBConnection connection;
-    protected final String catalog;
-    protected final String schema;
-
-    protected final AtomicBoolean closed = new AtomicBoolean(false);
-    protected volatile boolean closeOnCompletion;
-
-    protected int queryTimeoutSeconds;
-    protected long maxRows;
-
-    // common result fields
-    protected int updateCount = -1;
-    protected List<ADBProtocol.QueryServiceResponse.Message> warnings;
-
-    // executeQuery() result fields
-    protected final ConcurrentLinkedQueue<ADBResultSet> resultSetsWithResources;
-    protected final ConcurrentLinkedQueue<WeakReference<ADBResultSet>> resultSetsWithoutResources;
-
-    // execute() result field
-    protected ADBProtocol.QueryServiceResponse executeResponse;
-    protected ADBResultSet executeResultSet;
-
-    // Lifecycle
-
-    ADBStatement(ADBConnection connection, String catalog, String schema) {
-        this.connection = Objects.requireNonNull(connection);
-        this.catalog = catalog;
-        this.schema = schema;
-        this.resultSetsWithResources = new ConcurrentLinkedQueue<>();
-        this.resultSetsWithoutResources = new ConcurrentLinkedQueue<>();
-    }
-
-    @Override
-    public void close() throws SQLException {
-        closeImpl(true, true);
-    }
-
-    void closeImpl(boolean closeResultSets, boolean notifyConnection) throws SQLException {
-        boolean wasClosed = closed.getAndSet(true);
-        if (wasClosed) {
-            return;
-        }
-        try {
-            if (closeResultSets) {
-                closeRegisteredResultSets();
-            }
-        } finally {
-            if (notifyConnection) {
-                connection.deregisterStatement(this);
-            }
-        }
-    }
-
-    @Override
-    public void closeOnCompletion() throws SQLException {
-        checkClosed();
-        closeOnCompletion = true;
-    }
-
-    @Override
-    public boolean isCloseOnCompletion() throws SQLException {
-        checkClosed();
-        return closeOnCompletion;
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closed.get();
-    }
-
-    protected void checkClosed() throws SQLException {
-        if (isClosed()) {
-            throw getErrorReporter().errorObjectClosed(Statement.class);
-        }
-    }
-
-    // Execution
-
-    @Override
-    public ADBResultSet executeQuery(String sql) throws SQLException {
-        checkClosed();
-        return executeQueryImpl(sql, null);
-    }
-
-    protected ADBResultSet executeQueryImpl(String sql, List<?> args) throws SQLException {
-        // note: we're not assigning executeResponse field at this method
-        ADBProtocol.QueryServiceResponse response =
-                connection.protocol.submitStatement(sql, args, true, false, queryTimeoutSeconds, catalog, schema);
-        boolean isQuery = connection.protocol.isStatementCategory(response,
-                ADBProtocol.QueryServiceResponse.StatementCategory.QUERY);
-        if (!isQuery) {
-            throw getErrorReporter().errorInvalidStatementCategory();
-        }
-        warnings = connection.protocol.getWarningIfExists(response);
-        updateCount = -1;
-        return fetchResultSet(response);
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql) throws SQLException {
-        checkClosed();
-        return executeUpdateImpl(sql, null);
-    }
-
-    @Override
-    public int executeUpdate(String sql) throws SQLException {
-        checkClosed();
-        return executeUpdateImpl(sql, null);
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeLargeUpdate");
-    }
-
-    @Override
-    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeUpdate");
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeLargeUpdate");
-    }
-
-    @Override
-    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeUpdate");
-    }
-
-    @Override
-    public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeLargeUpdate");
-    }
-
-    @Override
-    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeUpdate");
-    }
-
-    protected int executeUpdateImpl(String sql, List<Object> args) throws SQLException {
-        ADBProtocol.QueryServiceResponse response =
-                connection.protocol.submitStatement(sql, args, false, false, queryTimeoutSeconds, catalog, schema);
-        boolean isQuery = connection.protocol.isStatementCategory(response,
-                ADBProtocol.QueryServiceResponse.StatementCategory.QUERY);
-        // TODO: remove result set on the server (both query and update returning cases)
-        if (isQuery) {
-            throw getErrorReporter().errorInvalidStatementCategory();
-        }
-        warnings = connection.protocol.getWarningIfExists(response);
-        updateCount = connection.protocol.getUpdateCount(response);
-        return updateCount;
-    }
-
-    @Override
-    public boolean execute(String sql) throws SQLException {
-        checkClosed();
-        return executeImpl(sql, null);
-    }
-
-    @Override
-    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "execute");
-    }
-
-    @Override
-    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "execute");
-    }
-
-    @Override
-    public boolean execute(String sql, String[] columnNames) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "execute");
-    }
-
-    protected boolean executeImpl(String sql, List<Object> args) throws SQLException {
-        ADBProtocol.QueryServiceResponse response =
-                connection.protocol.submitStatement(sql, args, false, false, queryTimeoutSeconds, catalog, schema);
-        warnings = connection.protocol.getWarningIfExists(response);
-        boolean isQuery = connection.protocol.isStatementCategory(response,
-                ADBProtocol.QueryServiceResponse.StatementCategory.QUERY);
-        if (isQuery) {
-            updateCount = -1;
-            executeResponse = response;
-            return true;
-        } else {
-            updateCount = connection.protocol.getUpdateCount(response);
-            executeResponse = null;
-            return false;
-        }
-    }
-
-    @Override
-    public void cancel() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "cancel");
-    }
-
-    @Override
-    public int getQueryTimeout() throws SQLException {
-        checkClosed();
-        return queryTimeoutSeconds;
-    }
-
-    @Override
-    public void setQueryTimeout(int timeoutSeconds) throws SQLException {
-        checkClosed();
-        if (timeoutSeconds < 0) {
-            throw getErrorReporter().errorParameterValueNotSupported("timeoutSeconds");
-        }
-        queryTimeoutSeconds = timeoutSeconds;
-    }
-
-    @Override
-    public void setEscapeProcessing(boolean enable) throws SQLException {
-        checkClosed();
-    }
-
-    // Batch execution
-
-    @Override
-    public long[] executeLargeBatch() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeLargeBatch");
-    }
-
-    @Override
-    public int[] executeBatch() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "executeBatch");
-    }
-
-    @Override
-    public void addBatch(String sql) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "addBatch");
-    }
-
-    @Override
-    public void clearBatch() throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "clearBatch");
-    }
-
-    // Result access
-
-    @Override
-    public ADBResultSet getResultSet() throws SQLException {
-        checkClosed();
-        ADBProtocol.QueryServiceResponse response = executeResponse;
-        if (response == null) {
-            return null;
-        }
-        ADBResultSet rs = fetchResultSet(response);
-        executeResultSet = rs;
-        executeResponse = null;
-        return rs;
-    }
-
-    @Override
-    public boolean getMoreResults() throws SQLException {
-        return getMoreResults(Statement.CLOSE_ALL_RESULTS);
-    }
-
-    @Override
-    public boolean getMoreResults(int current) throws SQLException {
-        checkClosed();
-        ADBResultSet rs = executeResultSet;
-        executeResultSet = null;
-        if (rs != null && current != Statement.KEEP_CURRENT_RESULT) {
-            rs.closeImpl(true);
-        }
-        return false;
-    }
-
-    @Override
-    public int getResultSetType() throws SQLException {
-        checkClosed();
-        return ResultSet.TYPE_FORWARD_ONLY;
-    }
-
-    @Override
-    public int getResultSetConcurrency() throws SQLException {
-        checkClosed();
-        return ResultSet.CONCUR_READ_ONLY;
-    }
-
-    @Override
-    public int getResultSetHoldability() throws SQLException {
-        checkClosed();
-        return ADBResultSet.RESULT_SET_HOLDABILITY;
-    }
-
-    @Override
-    public ResultSet getGeneratedKeys() throws SQLException {
-        checkClosed();
-        return createEmptyResultSet();
-    }
-
-    @Override
-    public long getLargeUpdateCount() throws SQLException {
-        checkClosed();
-        return updateCount;
-    }
-
-    @Override
-    public int getUpdateCount() throws SQLException {
-        return (int) getLargeUpdateCount();
-    }
-
-    // ResultSet lifecycle
-
-    private ADBResultSet fetchResultSet(ADBProtocol.QueryServiceResponse execResponse) throws SQLException {
-        List<ADBColumn> columns = connection.protocol.getColumns(execResponse);
-        if (getLogger().isLoggable(Level.FINER)) {
-            getLogger().log(Level.FINE, "result schema " + columns);
-        }
-        if (connection.protocol.isExplainOnly(execResponse)) {
-            AbstractValueSerializer stringSer = getADMFormatSerializer(String.class);
-            ArrayNode explainResult = connection.protocol.fetchExplainOnlyResult(execResponse, stringSer);
-            return createSystemResultSet(columns, explainResult);
-        } else {
-            JsonParser rowParser = connection.protocol.fetchResult(execResponse);
-            return createResultSetImpl(columns, rowParser, true, maxRows);
-        }
-    }
-
-    protected ADBResultSet createSystemResultSet(List<ADBColumn> columns, ArrayNode values) {
-        JsonParser rowParser = connection.protocol.createJsonParser(values);
-        return createResultSetImpl(columns, rowParser, false, 0);
-    }
-
-    protected ADBResultSet createEmptyResultSet() {
-        ArrayNode empty = (ArrayNode) connection.protocol.driverContext.genericObjectReader.createArrayNode();
-        return createSystemResultSet(Collections.emptyList(), empty);
-    }
-
-    private ADBResultSet createResultSetImpl(List<ADBColumn> columns, JsonParser rowParser,
-            boolean rowParserOwnsResources, long maxRows) {
-        ADBResultSetMetaData metadata = new ADBResultSetMetaData(this, columns);
-        ADBResultSet rs = new ADBResultSet(metadata, rowParser, rowParserOwnsResources, maxRows);
-        registerResultSet(rs);
-        return rs;
-    }
-
-    private void registerResultSet(ADBResultSet rs) {
-        if (rs.rowParserOwnsResources) {
-            resultSetsWithResources.add(rs);
-        } else {
-            resultSetsWithoutResources.removeIf(ADBStatement::isEmptyReference);
-            resultSetsWithoutResources.add(new WeakReference<>(rs));
-        }
-    }
-
-    protected void deregisterResultSet(ADBResultSet rs) {
-        if (rs.rowParserOwnsResources) {
-            resultSetsWithResources.remove(rs);
-        } else {
-            resultSetsWithoutResources.removeIf(ref -> {
-                ADBResultSet refrs = ref.get();
-                return refrs == null || refrs == rs;
-            });
-        }
-        if (closeOnCompletion && resultSetsWithResources.isEmpty() && resultSetsWithoutResources.isEmpty()) {
-            try {
-                closeImpl(false, true);
-            } catch (SQLException e) {
-                // this exception shouldn't happen because there are no result sets to close
-                if (getLogger().isLoggable(Level.FINE)) {
-                    getLogger().log(Level.FINE, e.getMessage(), e);
-                }
-            }
-        }
-    }
-
-    private void closeRegisteredResultSets() throws SQLException {
-        SQLException err = null;
-        try {
-            closedRegisteredResultSetsImpl(resultSetsWithResources, Function.identity());
-        } catch (SQLException e) {
-            err = e;
-        }
-        try {
-            closedRegisteredResultSetsImpl(resultSetsWithoutResources, Reference::get);
-        } catch (SQLException e) {
-            if (err != null) {
-                e.addSuppressed(err);
-            }
-            err = e;
-        }
-        if (err != null) {
-            throw err;
-        }
-    }
-
-    private <T> void closedRegisteredResultSetsImpl(Queue<T> queue, Function<T, ADBResultSet> rsAccessor)
-            throws SQLException {
-        SQLException err = null;
-        T item;
-        while ((item = queue.poll()) != null) {
-            ADBResultSet rs = rsAccessor.apply(item);
-            if (rs != null) {
-                try {
-                    rs.closeImpl(false);
-                } catch (SQLException e) {
-                    if (err != null) {
-                        e.addSuppressed(err);
-                    }
-                    err = e;
-                }
-            }
-        }
-        if (err != null) {
-            throw err;
-        }
-    }
-
-    private static boolean isEmptyReference(Reference<ADBResultSet> ref) {
-        return ref.get() == null;
-    }
-
-    // Result control
-
-    @Override
-    public void setLargeMaxRows(long maxRows) throws SQLException {
-        checkClosed();
-        if (maxRows < 0) {
-            throw getErrorReporter().errorParameterValueNotSupported("maxRows");
-        }
-        this.maxRows = maxRows;
-    }
-
-    @Override
-    public void setMaxRows(int maxRows) throws SQLException {
-        setLargeMaxRows(maxRows);
-    }
-
-    @Override
-    public long getLargeMaxRows() throws SQLException {
-        checkClosed();
-        return maxRows;
-    }
-
-    @Override
-    public int getMaxRows() throws SQLException {
-        return (int) getLargeMaxRows();
-    }
-
-    @Override
-    public void setCursorName(String name) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "setCursorName");
-    }
-
-    // Unsupported hints (ignored)
-
-    @Override
-    public int getFetchDirection() throws SQLException {
-        checkClosed();
-        return ResultSet.FETCH_FORWARD;
-    }
-
-    @Override
-    public void setFetchDirection(int direction) throws SQLException {
-        checkClosed();
-        switch (direction) {
-            case ResultSet.FETCH_FORWARD:
-            case ResultSet.FETCH_REVERSE:
-            case ResultSet.FETCH_UNKNOWN:
-                // ignore this hint
-                break;
-            default:
-                throw getErrorReporter().errorParameterValueNotSupported("direction");
-        }
-    }
-
-    @Override
-    public int getFetchSize() throws SQLException {
-        checkClosed();
-        return 1;
-    }
-
-    @Override
-    public void setFetchSize(int rows) throws SQLException {
-        checkClosed();
-        if (rows < 0) {
-            throw getErrorReporter().errorParameterNotSupported("rows");
-        }
-    }
-
-    @Override
-    public int getMaxFieldSize() throws SQLException {
-        checkClosed();
-        return 0;
-    }
-
-    @Override
-    public void setMaxFieldSize(int maxFieldSize) throws SQLException {
-        throw getErrorReporter().errorMethodNotSupported(Statement.class, "setMaxFieldSize");
-    }
-
-    @Override
-    public boolean isPoolable() throws SQLException {
-        checkClosed();
-        return false;
-    }
-
-    @Override
-    public void setPoolable(boolean poolable) throws SQLException {
-        checkClosed();
-    }
-
-    // Errors and warnings
-
-    @Override
-    public SQLWarning getWarnings() throws SQLException {
-        checkClosed();
-        return warnings != null ? connection.protocol.createSQLWarning(warnings) : null;
-    }
-
-    @Override
-    public void clearWarnings() throws SQLException {
-        checkClosed();
-        warnings = null;
-    }
-
-    @Override
-    protected ADBErrorReporter getErrorReporter() {
-        return connection.getErrorReporter();
-    }
-
-    protected Logger getLogger() {
-        return connection.getLogger();
-    }
-
-    // Ownership
-
-    @Override
-    public Connection getConnection() throws SQLException {
-        checkClosed();
-        return connection;
-    }
-
-    ADBStatement getResultSetStatement(ADBResultSet rs) {
-        return rs.metadata.statement;
-    }
-
-    // Serialization
-
-    static void configureSerialization(SimpleModule serdeModule) {
-        serdeModule.setSerializerModifier(createADMFormatSerializerModifier());
-    }
-
-    static AbstractValueSerializer getADMFormatSerializer(Class<?> cls) {
-        return SERIALIZER_MAP.get(cls);
-    }
-
-    private static BeanSerializerModifier createADMFormatSerializerModifier() {
-        return new BeanSerializerModifier() {
-            @Override
-            public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc,
-                    JsonSerializer<?> serializer) {
-                Class<?> cls = beanDesc.getClassInfo().getAnnotated();
-                if (isSetObjectCompatible(cls)) {
-                    AbstractValueSerializer ser = getADMFormatSerializer(cls);
-                    return ser != null ? ser : super.modifySerializer(config, beanDesc, serializer);
-                } else {
-                    return null;
-                }
-            }
-        };
-    }
-
-    static boolean isSetObjectCompatible(Class<?> cls) {
-        if (ADBRowStore.OBJECT_ACCESSORS_ATOMIC.containsKey(cls)) {
-            return true;
-        }
-        for (Class<?> aClass : SET_OBJECT_NON_ATOMIC) {
-            if (aClass.isAssignableFrom(cls)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static Map<Class<?>, AbstractValueSerializer> createSerializerMap() {
-        Map<Class<?>, AbstractValueSerializer> serializerMap = new HashMap<>();
-        registerSerializer(serializerMap, createGenericSerializer(Byte.class, ADBDatatype.TINYINT));
-        registerSerializer(serializerMap, createGenericSerializer(Short.class, ADBDatatype.SMALLINT));
-        registerSerializer(serializerMap, createGenericSerializer(Integer.class, ADBDatatype.INTEGER));
-        registerSerializer(serializerMap, createGenericSerializer(UUID.class, ADBDatatype.UUID));
-        // Long is serialized as JSON number by Jackson
-        registerSerializer(serializerMap, createFloatSerializer());
-        registerSerializer(serializerMap, createDoubleSerializer());
-        registerSerializer(serializerMap, createStringSerializer());
-        registerSerializer(serializerMap, createSqlDateSerializer());
-        registerSerializer(serializerMap, createLocalDateSerializer());
-        registerSerializer(serializerMap, createSqlTimeSerializer());
-        registerSerializer(serializerMap, createLocalTimeSerializer());
-        registerSerializer(serializerMap, createSqlTimestampSerializer());
-        registerSerializer(serializerMap, createInstantSerializer());
-        registerSerializer(serializerMap, createPeriodSerializer());
-        registerSerializer(serializerMap, createDurationSerializer());
-        return serializerMap;
-    }
-
-    private static void registerSerializer(Map<Class<?>, AbstractValueSerializer> map,
-            AbstractValueSerializer serializer) {
-        map.put(serializer.getJavaType(), serializer);
-    }
-
-    private static ATaggedValueSerializer createGenericSerializer(Class<?> javaType, ADBDatatype ADBDatatype) {
-        return new ATaggedValueSerializer(javaType, ADBDatatype) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                out.append(value);
-            }
-        };
-    }
-
-    private static AbstractValueSerializer createStringSerializer() {
-        return new AbstractValueSerializer(java.lang.String.class) {
-            @Override
-            public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
-                gen.writeString(serializeToString(value));
-            }
-
-            @Override
-            protected String serializeToString(Object value) {
-                return ADBProtocol.TEXT_DELIMITER + String.valueOf(value);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createFloatSerializer() {
-        return new ATaggedValueSerializer(Float.class, ADBDatatype.FLOAT) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                int bits = Float.floatToIntBits((Float) value);
-                out.append((long) bits);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createDoubleSerializer() {
-        return new ATaggedValueSerializer(Double.class, ADBDatatype.DOUBLE) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long bits = Double.doubleToLongBits((Double) value);
-                out.append(bits);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createSqlDateSerializer() {
-        return new ATaggedValueSerializer(java.sql.Date.class, ADBDatatype.DATE) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long millis = ((Date) value).getTime();
-                out.append(millis);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createLocalDateSerializer() {
-        return new ATaggedValueSerializer(java.time.LocalDate.class, ADBDatatype.DATE) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long millis = TimeUnit.DAYS.toMillis(((LocalDate) value).toEpochDay());
-                out.append(millis);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createSqlTimeSerializer() {
-        return new ATaggedValueSerializer(java.sql.Time.class, ADBDatatype.TIME) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long millis = ((Time) value).getTime();
-                out.append(millis);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createLocalTimeSerializer() {
-        return new ATaggedValueSerializer(java.time.LocalTime.class, ADBDatatype.TIME) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long millis = TimeUnit.NANOSECONDS.toMillis(((LocalTime) value).toNanoOfDay());
-                out.append(millis);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createSqlTimestampSerializer() {
-        return new ATaggedValueSerializer(java.sql.Timestamp.class, ADBDatatype.DATETIME) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long millis = ((Timestamp) value).getTime();
-                out.append(millis);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createInstantSerializer() {
-        return new ATaggedValueSerializer(java.time.Instant.class, ADBDatatype.DATETIME) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long millis = ((Instant) value).toEpochMilli();
-                out.append(millis);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createPeriodSerializer() {
-        return new ATaggedValueSerializer(java.time.Period.class, ADBDatatype.YEARMONTHDURATION) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long months = ((Period) value).toTotalMonths();
-                out.append(months);
-            }
-        };
-    }
-
-    private static ATaggedValueSerializer createDurationSerializer() {
-        return new ATaggedValueSerializer(java.time.Duration.class, ADBDatatype.DAYTIMEDURATION) {
-            @Override
-            protected void serializeNonTaggedValue(Object value, StringBuilder out) {
-                long millis = ((Duration) value).toMillis();
-                out.append(millis);
-            }
-        };
-    }
-
-    static abstract class AbstractValueSerializer extends JsonSerializer<Object> {
-
-        protected final Class<?> javaType;
-
-        protected AbstractValueSerializer(Class<?> javaType) {
-            this.javaType = Objects.requireNonNull(javaType);
-        }
-
-        protected Class<?> getJavaType() {
-            return javaType;
-        }
-
-        abstract String serializeToString(Object value);
-    }
-
-    private static abstract class ATaggedValueSerializer extends AbstractValueSerializer {
-
-        protected final ADBDatatype adbType;
-
-        protected ATaggedValueSerializer(Class<?> javaType, ADBDatatype adbType) {
-            super(javaType);
-            this.adbType = Objects.requireNonNull(adbType);
-        }
-
-        @Override
-        public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
-            gen.writeString(serializeToString(value)); // TODO:optimize?
-        }
-
-        protected final String serializeToString(Object value) {
-            StringBuilder textBuilder = new StringBuilder(64); // TODO:optimize?
-            printByteAsHex(adbType.getTypeTag(), textBuilder);
-            textBuilder.append(ADBProtocol.TEXT_DELIMITER);
-            serializeNonTaggedValue(value, textBuilder);
-            return textBuilder.toString();
-        }
-
-        protected abstract void serializeNonTaggedValue(Object value, StringBuilder out);
-
-        private static void printByteAsHex(byte b, StringBuilder out) {
-            out.append(hex((b >>> 4) & 0x0f));
-            out.append(hex(b & 0x0f));
-        }
-
-        private static char hex(int i) {
-            return (char) (i + (i < 10 ? '0' : ('A' - 10)));
-        }
-    }
-}
diff --git a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBWrapperSupport.java b/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBWrapperSupport.java
deleted file mode 100644
index 30cbfd0..0000000
--- a/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBWrapperSupport.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc.core;
-
-import java.sql.SQLException;
-import java.sql.Wrapper;
-
-abstract class ADBWrapperSupport implements Wrapper {
-
-    @Override
-    public final boolean isWrapperFor(Class<?> iface) {
-        return iface.isInstance(this);
-    }
-
-    @Override
-    public final <T> T unwrap(Class<T> iface) throws SQLException {
-        if (!iface.isInstance(this)) {
-            throw getErrorReporter().errorUnwrapTypeMismatch(iface);
-        }
-        return iface.cast(this);
-    }
-
-    protected abstract ADBErrorReporter getErrorReporter();
-}
diff --git a/asterix-jdbc-driver/NOTICE b/asterix-jdbc-driver/NOTICE
deleted file mode 100644
index e4f823f..0000000
--- a/asterix-jdbc-driver/NOTICE
+++ /dev/null
@@ -1,4 +0,0 @@
-Couchbase asterixdb-jdbc-driver
-Copyright 2021 Couchbase, Inc.
- 
-This product includes software developed at Couchbase, Inc.
diff --git a/asterix-jdbc-driver/pom.xml b/asterix-jdbc-driver/pom.xml
deleted file mode 100644
index afac089..0000000
--- a/asterix-jdbc-driver/pom.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-<!--
- ! Licensed to the Apache Software Foundation (ASF) under one
- ! or more contributor license agreements.  See the NOTICE file
- ! distributed with this work for additional information
- ! regarding copyright ownership.  The ASF licenses this file
- ! to you under the Apache License, Version 2.0 (the
- ! "License"); you may not use this file except in compliance
- ! with the License.  You may obtain a copy of the License at
- !
- !   http://www.apache.org/licenses/LICENSE-2.0
- !
- ! Unless required by applicable law or agreed to in writing,
- ! software distributed under the License is distributed on an
- ! "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- ! KIND, either express or implied.  See the License for the
- ! specific language governing permissions and limitations
- ! under the License.
- !-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <artifactId>apache-asterixdb</artifactId>
-    <groupId>org.apache.asterix</groupId>
-    <version>0.9.7-SNAPSHOT</version>
-  </parent>
-  <artifactId>asterix-jdbc-driver</artifactId>
-
-  <licenses>
-    <license>
-      <name>Apache License, Version 2.0</name>
-      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-      <distribution>repo</distribution>
-      <comments>A business-friendly OSS license</comments>
-    </license>
-  </licenses>
-
-  <properties>
-    <root.dir>${basedir}/..</root.dir>
-    <source.jdk.version>1.8</source.jdk.version>
-    <target.jdk.version>1.8</target.jdk.version>
-    <source.java.package.path>org/apache/asterix/jdbc/</source.java.package.path>
-    <implementation.title>Apache AsterixDB JDBC Driver</implementation.title>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.asterix</groupId>
-      <artifactId>asterix-jdbc-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <configuration>
-          <archive>
-            <manifestSections>
-              <manifestSection>
-                <name>${source.java.package.path}</name>
-                <manifestEntries>
-                  <Implementation-Title>${implementation.title}</Implementation-Title>
-                  <Implementation-Version>${project.version}</Implementation-Version>
-                  <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
-                </manifestEntries>
-              </manifestSection>
-            </manifestSections>
-          </archive>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <shadedArtifactAttached>true</shadedArtifactAttached>
-              <shadedClassifierName>dist</shadedClassifierName>
-              <transformers>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"/>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer">
-                  <addHeader>false</addHeader>
-                </transformer>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.PluginXmlResourceTransformer"/>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
-              </transformers>
-              <filters>
-                <filter>
-                  <artifact>org.apache.asterix:asterix-jdbc-core</artifact>
-                  <excludes>
-                    <exclude>META-INF/MANIFEST.MF</exclude>
-                  </excludes>
-                </filter>
-                <filter>
-                  <artifact>org.apache.httpcomponents:*</artifact>
-                  <excludes>
-                    <exclude>module-info.class</exclude>
-                    <exclude>META-INF/DEPENDENCIES</exclude>
-                    <exclude>META-INF/MANIFEST.MF</exclude>
-                  </excludes>
-                </filter>
-                <filter>
-                  <artifact>commons-logging:*</artifact>
-                  <excludes>
-                    <exclude>module-info.class</exclude>
-                    <exclude>META-INF/MANIFEST.MF</exclude>
-                  </excludes>
-                </filter>
-                <filter>
-                  <artifact>commons-codec:*</artifact>
-                  <excludes>
-                    <exclude>module-info.class</exclude>
-                    <exclude>META-INF/MANIFEST.MF</exclude>
-                  </excludes>
-                </filter>
-                <filter>
-                  <artifact>com.fasterxml.jackson.core:*</artifact>
-                  <excludes>
-                    <exclude>module-info.class</exclude>
-                    <exclude>META-INF/MANIFEST.MF</exclude>
-                  </excludes>
-                </filter>
-              </filters>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/asterix-jdbc-driver/src/main/java/org/apache/asterix/jdbc/Driver.java b/asterix-jdbc-driver/src/main/java/org/apache/asterix/jdbc/Driver.java
deleted file mode 100644
index 4d175ed..0000000
--- a/asterix-jdbc-driver/src/main/java/org/apache/asterix/jdbc/Driver.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.jdbc;
-
-import org.apache.asterix.jdbc.core.ADBDriverBase;
-
-public final class Driver extends ADBDriverBase implements java.sql.Driver {
-
-    private static final String DRIVER_SCHEME = "asterixdb:";
-
-    private static final int DEFAULT_API_PORT = 19002;
-
-    static {
-        setupLogging(Driver.class);
-        registerDriver(new Driver());
-    }
-
-    public Driver() {
-        super(DRIVER_SCHEME, DEFAULT_API_PORT);
-    }
-}
diff --git a/asterix-jdbc-driver/src/main/resources/META-INF/services/java.sql.Driver b/asterix-jdbc-driver/src/main/resources/META-INF/services/java.sql.Driver
deleted file mode 100644
index 626a039..0000000
--- a/asterix-jdbc-driver/src/main/resources/META-INF/services/java.sql.Driver
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-org.apache.asterix.jdbc.Driver
\ No newline at end of file
