You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2015/07/06 07:51:22 UTC

[08/10] incubator-kylin git commit: KYLIN-780 JDBC upgrade, test pass

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMetaImpl.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMetaImpl.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMetaImpl.java
deleted file mode 100644
index 17e8ed4..0000000
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinMetaImpl.java
+++ /dev/null
@@ -1,821 +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.kylin.jdbc;
-
-import java.lang.reflect.Field;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.apache.calcite.avatica.AvaticaResultSet;
-import org.apache.calcite.avatica.AvaticaStatement;
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.avatica.ColumnMetaData.Rep;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.linq4j.Enumerator;
-import org.apache.calcite.sql.SqlJdbcFunctionCall;
-import org.apache.calcite.sql.parser.SqlParser;
-import org.apache.kylin.jdbc.stub.DataSet;
-import org.apache.kylin.jdbc.stub.KylinColumnMetaData;
-import org.apache.kylin.jdbc.stub.RemoteClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.kylin.jdbc.util.SQLTypeMap;
-
-/**
- * Implementation of avatica interface
- *
- * @author xduo
- */
-public class KylinMetaImpl implements Meta {
-
-    private static final Logger logger = LoggerFactory.getLogger(KylinMetaImpl.class);
-
-    private final KylinConnectionImpl conn;
-
-    private final KylinJdbc41Factory factory;
-
-    /**
-     * @param conn
-     */
-    public KylinMetaImpl(KylinConnectionImpl conn, KylinJdbc41Factory factory) {
-        super();
-        this.conn = conn;
-        this.factory = factory;
-    }
-
-    private ResultSet mockEmptyResultSet() {
-        AvaticaResultSet resultSet = null;
-        try {
-            List<ColumnMetaData> columnMetas = new ArrayList<ColumnMetaData>();
-            List<Object[]> data = new ArrayList<Object[]>();
-            resultSet = this.conn.getFactory().newResultSet(this.conn.createStatement(), new KylinPrepare.PrepareResult(null, null, new KylinEnumerator<Object[]>(data), ColumnMetaData.struct(columnMetas)), this.conn.getTimeZone());
-            KylinConnectionImpl.TROJAN.execute(resultSet);
-        } catch (SQLException e) {
-            logger.error(e.getLocalizedMessage(), e);
-        }
-
-        return resultSet;
-    }
-
-    public String getSqlKeywords() {
-        return SqlParser.create("").getMetadata().getJdbcKeywords();
-    }
-
-    public String getNumericFunctions() {
-        return SqlJdbcFunctionCall.getNumericFunctions();
-    }
-
-    public String getStringFunctions() {
-        return SqlJdbcFunctionCall.getStringFunctions();
-    }
-
-    public String getSystemFunctions() {
-        return SqlJdbcFunctionCall.getSystemFunctions();
-    }
-
-    public String getTimeDateFunctions() {
-        return SqlJdbcFunctionCall.getTimeDateFunctions();
-    }
-
-    public ResultSet getTables(String catalog, Pat schemaPattern, Pat tableNamePattern, List<String> typeList) {
-        logger.debug("Get tables with conn " + conn);
-        MetaProject metaProject = conn.getMetaProject();
-
-        if (null != metaProject) {
-            final DataSet<MetaTable> tables = metaProject.getMetaTables(catalog, schemaPattern, tableNamePattern);
-            final NamedFieldGetter<MetaTable> tableGetter = new NamedFieldGetter<MetaTable>(MetaTable.class, tables.getMeta(), "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE", "REMARKS", "TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", "SELF_REFERENCING_COL_NAME", "REF_GENERATION");
-
-            AvaticaResultSet resultSet = null;
-            try {
-                resultSet = this.conn.getFactory().newResultSet(this.conn.createStatement(), new KylinPrepare.PrepareResult(null, null, null, tableGetter.structType) {
-                    @Override
-                    public Cursor createCursor() {
-                        return tableGetter.cursor(tables.getEnumerator());
-                    }
-                }, this.conn.getTimeZone());
-                KylinConnectionImpl.TROJAN.execute(resultSet);
-            } catch (SQLException e) {
-                logger.error(e.getLocalizedMessage(), e);
-            }
-
-            return resultSet;
-        } else {
-            return mockEmptyResultSet();
-        }
-    }
-
-    public ResultSet getColumns(String catalog, Pat schemaPattern, Pat tableNamePattern, Pat columnNamePattern) {
-        logger.debug("Get columns with conn " + conn);
-        MetaProject metaProject = conn.getMetaProject();
-
-        if (null != metaProject) {
-            final DataSet<MetaColumn> columns = metaProject.getMetaColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
-            final NamedFieldGetter<MetaColumn> columnGetter = new NamedFieldGetter<MetaColumn>(MetaColumn.class, columns.getMeta(), "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "NUM_PREC_RADIX", "NULLABLE", "REMARKS", "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE", "SCOPE_CATALOG", "SCOPE_TABLE", "SOURCE_DATA_TYPE", "IS_AUTOINCREMENT", "IS_GENERATEDCOLUMN");
-
-            AvaticaResultSet resultSet = null;
-            try {
-                resultSet = this.conn.getFactory().newResultSet(this.conn.createStatement(), new KylinPrepare.PrepareResult(null, null, null, columnGetter.structType) {
-                    @Override
-                    public Cursor createCursor() {
-                        return columnGetter.cursor(columns.getEnumerator());
-                    }
-                }, this.conn.getTimeZone());
-
-                KylinConnectionImpl.TROJAN.execute(resultSet);
-            } catch (SQLException e) {
-                logger.error(e.getLocalizedMessage(), e);
-            }
-
-            return resultSet;
-        } else {
-            return mockEmptyResultSet();
-        }
-    }
-
-    public ResultSet getSchemas(String catalog, Pat schemaPattern) {
-        logger.debug("Get schemas with conn " + conn);
-        MetaProject metaProject = conn.getMetaProject();
-
-        if (null != metaProject) {
-            final DataSet<MetaSchema> schemas = metaProject.getMetaSchemas(catalog, schemaPattern);
-            final NamedFieldGetter<MetaSchema> schemaGetter = new NamedFieldGetter<MetaSchema>(MetaSchema.class, schemas.getMeta(), "TABLE_SCHEM", "TABLE_CATALOG");
-
-            AvaticaResultSet resultSet = null;
-            try {
-                resultSet = this.conn.getFactory().newResultSet(this.conn.createStatement(), new KylinPrepare.PrepareResult(null, null, null, schemaGetter.structType) {
-                    @Override
-                    public Cursor createCursor() {
-                        return schemaGetter.cursor(schemas.getEnumerator());
-                    }
-                }, this.conn.getTimeZone());
-
-                KylinConnectionImpl.TROJAN.execute(resultSet);
-            } catch (SQLException e) {
-                logger.error(e.getLocalizedMessage(), e);
-            }
-
-            return resultSet;
-        } else {
-            return mockEmptyResultSet();
-        }
-    }
-
-    public ResultSet getCatalogs() {
-        MetaProject metaProject = conn.getMetaProject();
-
-        if (null != metaProject) {
-            final DataSet<MetaCatalog> catalogs = metaProject.getMetaCatalogs();
-            final NamedFieldGetter<MetaCatalog> catalogGetter = new NamedFieldGetter<MetaCatalog>(MetaCatalog.class, catalogs.getMeta(), "TABLE_CATALOG");
-
-            AvaticaResultSet resultSet = null;
-            try {
-                resultSet = this.conn.getFactory().newResultSet(this.conn.createStatement(), new KylinPrepare.PrepareResult(null, null, null, catalogGetter.structType) {
-                    @Override
-                    public Cursor createCursor() {
-                        return catalogGetter.cursor(catalogs.getEnumerator());
-                    }
-                }, this.conn.getTimeZone());
-
-                KylinConnectionImpl.TROJAN.execute(resultSet);
-            } catch (SQLException e) {
-                logger.error(e.getLocalizedMessage(), e);
-            }
-
-            return resultSet;
-        } else {
-            return mockEmptyResultSet();
-        }
-    }
-
-    public ResultSet getTableTypes() {
-        List<ColumnMetaData> tableTypeMeta = new ArrayList<ColumnMetaData>();
-        tableTypeMeta.add(ColumnMetaData.dummy(ColumnMetaData.scalar(Types.VARCHAR, "varchar", Rep.STRING), false));
-        List<Object[]> data = new ArrayList<Object[]>();
-        Object[] row = new Object[1];
-        row[0] = "TABLE";
-        data.add(row);
-
-        AvaticaResultSet resultSet = null;
-        try {
-            resultSet = this.conn.getFactory().newResultSet(this.conn.createStatement(), new KylinPrepare.PrepareResult(null, null, new KylinEnumerator<Object[]>(data), ColumnMetaData.struct(tableTypeMeta)), this.conn.getTimeZone());
-            KylinConnectionImpl.TROJAN.execute(resultSet);
-        } catch (SQLException e) {
-            logger.error(e.getLocalizedMessage(), e);
-        }
-
-        return resultSet;
-    }
-
-    public ResultSet getProcedures(String catalog, Pat schemaPattern, Pat procedureNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getProcedureColumns(String catalog, Pat schemaPattern, Pat procedureNamePattern, Pat columnNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getColumnPrivileges(String catalog, String schema, String table, Pat columnNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getTablePrivileges(String catalog, Pat schemaPattern, Pat tableNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getVersionColumns(String catalog, String schema, String table) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getPrimaryKeys(String catalog, String schema, String table) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getImportedKeys(String catalog, String schema, String table) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getExportedKeys(String catalog, String schema, String table) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getTypeInfo() {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getUDTs(String catalog, Pat schemaPattern, Pat typeNamePattern, int[] types) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getSuperTypes(String catalog, Pat schemaPattern, Pat typeNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getSuperTables(String catalog, Pat schemaPattern, Pat tableNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getAttributes(String catalog, Pat schemaPattern, Pat typeNamePattern, Pat attributeNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getClientInfoProperties() {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getFunctions(String catalog, Pat schemaPattern, Pat functionNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getFunctionColumns(String catalog, Pat schemaPattern, Pat functionNamePattern, Pat columnNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public ResultSet getPseudoColumns(String catalog, Pat schemaPattern, Pat tableNamePattern, Pat columnNamePattern) {
-        return mockEmptyResultSet();
-    }
-
-    public Cursor createCursor(AvaticaResultSet resultSet) {
-
-        if (!(resultSet instanceof KylinResultSet))
-            throw new IllegalStateException("resultSet is not KylinResultSet");
-
-        KylinPrepare.PrepareResult result = ((KylinResultSet) resultSet).getPrepareResult();
-
-        return result.createCursor();
-    }
-
-    /* 
-     * Client could request metadata after prepare
-     * 
-     * (non-Javadoc)
-     * @see org.apache.calcite.avatica.Meta#prepare(org.apache.calcite.avatica.AvaticaStatement, java.lang.String)
-     */
-    public AvaticaPrepareResult prepare(AvaticaStatement statement, String sql) {
-        RemoteClient client = factory.newRemoteClient(conn);
-        DataSet<Object[]> result = null;
-
-        try {
-            result = (DataSet<Object[]>) client.query(statement, sql);
-        } catch (Exception e) {
-            logger.error(e.getLocalizedMessage(), e);
-            throw new RuntimeException("Failed to query kylin server with exception " + e.getLocalizedMessage());
-        }
-
-        return new KylinPrepare.PrepareResult(sql, null, (Enumerator<Object[]>) result.getEnumerator(), ColumnMetaData.struct(result.getMeta()));
-    }
-
-    /**
-     * Tree node used by project tree-like structure
-     *
-     * @author xduo
-     */
-    interface Node {
-        /**
-         * Get the node name
-         *
-         * @return
-         */
-        public String getName();
-
-        /**
-         * Get direct children of the node.
-         *
-         * @return
-         */
-        public List<? extends Node> getChildren();
-
-        /**
-         * Search the subtree of the node with patterns. One pattern, one level.
-         *
-         * @param patterns
-         * @return
-         */
-        public List<? extends Node> searchByPatterns(Pat... patterns);
-    }
-
-    /**
-     * Abstract of the tree-like structure
-     *
-     * @author xduo
-     */
-    public static abstract class AbstractNode implements Node {
-
-        public List<? extends Node> searchByPatterns(Pat... patterns) {
-            if (patterns.length == 1) {
-                return findChildren(patterns[0]);
-            } else {
-                List<Node> children = new ArrayList<Node>();
-
-                for (Node child : this.findChildren(patterns[0])) {
-                    children.addAll(child.searchByPatterns(Arrays.copyOfRange(patterns, 1, patterns.length)));
-                }
-
-                return children;
-            }
-        }
-
-        private List<? extends Node> findChildren(Pat pattern) {
-            if (null == pattern.s || pattern.s.equals("%")) {
-                return this.getChildren();
-            }
-
-            List<Node> list = new ArrayList<Node>();
-
-            for (Node c : this.getChildren()) {
-                if (likeToRegex(pattern).matcher(c.getName()).matches()) {
-                    list.add(c);
-                }
-            }
-
-            return list;
-        }
-
-        ;
-
-        /**
-         * Converts a LIKE-style pattern (where '%' represents a wild-card,
-         * escaped using '\') to a Java regex.
-         */
-        private Pattern likeToRegex(Pat pattern) {
-            StringBuilder buf = new StringBuilder("^");
-            char[] charArray = pattern.s.toCharArray();
-            int slash = -2;
-            for (int i = 0; i < charArray.length; i++) {
-                char c = charArray[i];
-                if (slash == i - 1) {
-                    buf.append('[').append(c).append(']');
-                } else {
-                    switch (c) {
-                    case '\\':
-                        slash = i;
-                        break;
-                    case '%':
-                        buf.append(".*");
-                        break;
-                    case '[':
-                        buf.append("\\[");
-                        break;
-                    case ']':
-                        buf.append("\\]");
-                        break;
-                    default:
-                        buf.append('[').append(c).append(']');
-                    }
-                }
-            }
-            buf.append("$");
-
-            return Pattern.compile(buf.toString());
-        }
-    }
-
-    public static class MetaProject extends AbstractNode {
-        public final String project;
-        public final List<MetaCatalog> catalogs;
-
-        public MetaProject(String project, List<MetaCatalog> catalogs) {
-            super();
-            this.project = project;
-            this.catalogs = catalogs;
-        }
-
-        public DataSet<MetaCatalog> getMetaCatalogs() {
-            return new DataSet<MetaCatalog>(MetaCatalog.meta, new KylinEnumerator<MetaCatalog>(catalogs));
-        }
-
-        /**
-         * facade method to search schemas in current project.
-         *
-         * @param catalog
-         * @param schemaPattern
-         * @return
-         */
-        @SuppressWarnings("unchecked")
-        public DataSet<MetaSchema> getMetaSchemas(String catalog, Pat schemaPattern) {
-            List<? extends Node> metaSchemas = this.searchByPatterns(Pat.of(catalog), schemaPattern);
-
-            return new DataSet<MetaSchema>(MetaSchema.meta, new KylinEnumerator<MetaSchema>((Collection<MetaSchema>) metaSchemas));
-        }
-
-        /**
-         * facade method to search tables in current project
-         *
-         * @param catalog
-         * @param schemaPattern
-         * @param tableNamePattern
-         * @return
-         */
-        @SuppressWarnings("unchecked")
-        public DataSet<MetaTable> getMetaTables(String catalog, Pat schemaPattern, Pat tableNamePattern) {
-            logger.debug("getMetaTables with catalog:" + catalog + ", schema:" + schemaPattern.s + ", table:" + tableNamePattern.s);
-            List<? extends Node> tables = this.searchByPatterns(Pat.of(catalog), schemaPattern, tableNamePattern);
-
-            return new DataSet<MetaTable>(MetaTable.meta, new KylinEnumerator<MetaTable>((Collection<MetaTable>) tables));
-        }
-
-        /**
-         * facade method to search columns in current project
-         *
-         * @param catalog
-         * @param schemaPattern
-         * @param tableNamePattern
-         * @param columnNamePattern
-         * @return
-         */
-        @SuppressWarnings("unchecked")
-        public DataSet<MetaColumn> getMetaColumns(String catalog, Pat schemaPattern, Pat tableNamePattern, Pat columnNamePattern) {
-            logger.debug("getMetaColumns with catalog:" + catalog + ", schema:" + schemaPattern.s + ", table:" + tableNamePattern.s + ", column:" + columnNamePattern.s);
-            List<? extends Node> columns = this.searchByPatterns(Pat.of(catalog), schemaPattern, tableNamePattern, columnNamePattern);
-
-            return new DataSet<MetaColumn>(MetaColumn.meta, new KylinEnumerator<MetaColumn>((Collection<MetaColumn>) columns));
-        }
-
-        @Override
-        public String getName() {
-            return project;
-        }
-
-        @Override
-        public List<? extends Node> getChildren() {
-            return this.catalogs;
-        }
-    }
-
-    /**
-     * Metadata describing a catalog.
-     */
-    public static class MetaCatalog extends AbstractNode {
-        public static final List<ColumnMetaData> meta = new ArrayList<ColumnMetaData>();
-        public final String tableCatalog;
-        public final List<MetaSchema> schemas;
-
-        static {
-            meta.add(KylinColumnMetaData.dummy(0, "TABLE_CAT", "TABLE_CAT", ColumnMetaData.scalar(Types.VARCHAR, "varchar", Rep.STRING), true));
-        }
-
-        public MetaCatalog(String tableCatalog, List<MetaSchema> schemas) {
-            this.tableCatalog = tableCatalog;
-            this.schemas = schemas;
-        }
-
-        public String getName() {
-            return tableCatalog;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((tableCatalog == null) ? 0 : tableCatalog.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (obj == null)
-                return false;
-            if (getClass() != obj.getClass())
-                return false;
-            MetaCatalog other = (MetaCatalog) obj;
-            if (tableCatalog == null) {
-                if (other.tableCatalog != null)
-                    return false;
-            } else if (!tableCatalog.equals(other.tableCatalog))
-                return false;
-            return true;
-        }
-
-        @Override
-        public List<? extends Node> getChildren() {
-            return schemas;
-        }
-
-    }
-
-    /**
-     * Metadata describing a schema.
-     */
-    public static class MetaSchema extends AbstractNode {
-        public static final List<ColumnMetaData> meta = new ArrayList<ColumnMetaData>();
-        public final String tableCatalog;
-        public final String tableSchem;
-        public final List<MetaTable> tables;
-
-        static {
-            for (ColumnMetaData cmd : SQLTypeMap.schemaMetaTypeMapping.values()) {
-                meta.add(cmd);
-            }
-        }
-
-        public MetaSchema(String tableCatalog, String tableSchem, List<MetaTable> tables) {
-            this.tableCatalog = tableCatalog;
-            this.tableSchem = tableSchem;
-            this.tables = tables;
-        }
-
-        public String getName() {
-            return tableSchem;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((tableCatalog == null) ? 0 : tableCatalog.hashCode());
-            result = prime * result + ((tableSchem == null) ? 0 : tableSchem.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (obj == null)
-                return false;
-            if (getClass() != obj.getClass())
-                return false;
-            MetaSchema other = (MetaSchema) obj;
-            if (tableCatalog == null) {
-                if (other.tableCatalog != null)
-                    return false;
-            } else if (!tableCatalog.equals(other.tableCatalog))
-                return false;
-            if (tableSchem == null) {
-                if (other.tableSchem != null)
-                    return false;
-            } else if (!tableSchem.equals(other.tableSchem))
-                return false;
-            return true;
-        }
-
-        @Override
-        public List<MetaTable> getChildren() {
-            return this.tables;
-        }
-    }
-
-    /**
-     * Metadata describing a table type.
-     */
-    public static class MetaTableType {
-        public final String tableType;
-
-        public MetaTableType(String tableType) {
-            this.tableType = tableType;
-        }
-    }
-
-    /**
-     * Metadata describing a table.
-     */
-    public static class MetaTable extends AbstractNode {
-        public static final List<ColumnMetaData> meta = new ArrayList<ColumnMetaData>();
-        public final String tableCat;
-        public final String tableSchem;
-        public final String tableName;
-        public final String tableType;
-        public final String remarks;
-        public final String typeCat;
-        public final String typeSchem;
-        public final String typeName;
-        public final String selfReferencingColName;
-        public final String refGeneration;
-        public final List<MetaColumn> columns;
-
-        static {
-            for (ColumnMetaData cmd : SQLTypeMap.tableMetaTypeMapping.values()) {
-                meta.add(cmd);
-            }
-        }
-
-        public MetaTable(String tableCat, String tableSchem, String tableName, String tableType, String remarks, String typeCat, String typeSchem, String typeName, String selfReferencingColName, String refGeneration, List<MetaColumn> columns) {
-            this.tableCat = tableCat;
-            this.tableSchem = tableSchem;
-            this.tableName = tableName;
-            this.tableType = tableType;
-            this.remarks = remarks;
-            this.typeCat = typeCat;
-            this.typeSchem = typeSchem;
-            this.typeName = typeName;
-            this.selfReferencingColName = selfReferencingColName;
-            this.refGeneration = refGeneration;
-            this.columns = columns;
-        }
-
-        public String getName() {
-            return tableName;
-        }
-
-        @Override
-        public List<? extends Node> getChildren() {
-            return this.columns;
-        }
-    }
-
-    /**
-     * Metadata describing a column.
-     */
-    public static class MetaColumn implements Node {
-        public static final List<ColumnMetaData> meta = new ArrayList<ColumnMetaData>();
-        public final String tableCat;
-        public final String tableSchem;
-        public final String tableName;
-        public final String columnName;
-        public final int dataType;
-        public final String typeName;
-        public final int columnSize;
-        public final int bufferLength;
-        public final int decimalDigits;
-        public final int numPrecRadix;
-        public final int nullable;
-        public final String remarks;
-        public final String columnDef;
-        public final int sqlDataType;
-        public final int sqlDatetimeSub;
-        public final int charOctetLength;
-        public final int ordinalPosition;
-        public final String isNullable;
-        public final String scopeCatalog;
-        public final String scopeTable;
-        public final int sourceDataType;
-        public final String isAutoincrement;
-        public final String isGeneratedcolumn;
-
-        static {
-            for (ColumnMetaData cmd : SQLTypeMap.columnMetaTypeMapping.values()) {
-                meta.add(cmd);
-            }
-        }
-
-        public MetaColumn(String tableCat, String tableSchem, String tableName, String columnName, int dataType, String typeName, int columnSize, int bufferLength, int decimalDigits, int numPrecRadix, int nullable, String remarks, String columnDef, int sqlDataType, int sqlDatetimeSub, int charOctetLength, int ordinalPosition, String isNullable, String scopeCatalog, String scopeTable, int sourceDataType, String isAutoincrement, String isGeneratedcolumn) {
-            super();
-            this.tableCat = tableCat;
-            this.tableSchem = tableSchem;
-            this.tableName = tableName;
-            this.columnName = columnName;
-            this.dataType = dataType;
-            this.typeName = typeName;
-            this.columnSize = columnSize;
-            this.bufferLength = bufferLength;
-            this.decimalDigits = decimalDigits;
-            this.numPrecRadix = numPrecRadix;
-            this.nullable = nullable;
-            this.remarks = remarks;
-            this.columnDef = columnDef;
-            this.sqlDataType = sqlDataType;
-            this.sqlDatetimeSub = sqlDatetimeSub;
-            this.charOctetLength = charOctetLength;
-            this.ordinalPosition = ordinalPosition;
-            this.isNullable = isNullable;
-            this.scopeCatalog = scopeCatalog;
-            this.scopeTable = scopeTable;
-            this.sourceDataType = sourceDataType;
-            this.isAutoincrement = isAutoincrement;
-            this.isGeneratedcolumn = isGeneratedcolumn;
-        }
-
-        public String getName() {
-            return columnName;
-        }
-
-        @Override
-        public List<? extends Node> getChildren() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        public List<? extends Node> searchByPatterns(Pat... patterns) {
-            return Collections.emptyList();
-        }
-    }
-
-    /**
-     * Accesses fields by name.
-     */
-    private static class NamedFieldGetter<T> {
-        private final List<Field> fields = new ArrayList<Field>();
-        private final ColumnMetaData.StructType structType;
-
-        public NamedFieldGetter(Class<T> clazz, List<ColumnMetaData> columns, String... names) {
-            init(clazz, names, fields);
-            structType = ColumnMetaData.struct(columns);
-        }
-
-        private void init(Class<T> clazz, String[] names, List<Field> fields) {
-            for (String name : names) {
-                final String fieldName = Util.toCamelCase(name);
-                final Field field;
-                try {
-                    field = clazz.getField(fieldName);
-                } catch (NoSuchFieldException e) {
-                    throw new RuntimeException(e);
-                }
-                fields.add(field);
-            }
-        }
-
-        Object get(Object o, int columnIndex) {
-            try {
-                return fields.get(columnIndex).get(o);
-            } catch (IllegalArgumentException e) {
-                throw new RuntimeException(e);
-            } catch (IllegalAccessException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        public Cursor cursor(Enumerator<T> enumerator) {
-            // noinspection unchecked
-            return new EnumeratorCursor<T>(enumerator) {
-                protected Getter createGetter(final int ordinal) {
-                    return new Getter() {
-                        public Object getObject() {
-                            return get(current(), ordinal);
-                        }
-
-                        public boolean wasNull() {
-                            return getObject() == null;
-                        }
-                    };
-                }
-            };
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepare.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepare.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepare.java
deleted file mode 100644
index 686e948..0000000
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepare.java
+++ /dev/null
@@ -1,101 +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.kylin.jdbc;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.calcite.avatica.AvaticaParameter;
-import org.apache.calcite.avatica.AvaticaPrepareResult;
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.avatica.Cursor;
-
-/**
- * Interface of kylin prepare statement implementation
- * 
- * @author xduo
- * 
- */
-public interface KylinPrepare {
-
-    PrepareResult prepare(String sql);
-
-    /**
-     * The result of preparing a query. It gives the Avatica driver framework
-     * the information it needs to create a prepared statement, or to execute a
-     * statement directly, without an explicit prepare step.
-     */
-    public static class PrepareResult implements AvaticaPrepareResult {
-        public final String sql; // for debug
-        public final ColumnMetaData.StructType structType;
-        public final Enumerator<Object[]> enumerator;
-        public final List<AvaticaParameter> parameterList;
-
-        public PrepareResult(String sql, List<AvaticaParameter> parameterList, Enumerator<Object[]> enumerator, ColumnMetaData.StructType structType) {
-            super();
-            this.sql = sql;
-            this.parameterList = parameterList;
-            this.enumerator = enumerator;
-            this.structType = structType;
-        }
-
-        public Cursor createCursor() {
-            return new EnumeratorCursor<Object[]>(enumerator) {
-                @Override
-                protected Getter createGetter(int ordinal) {
-                    return new ArrayEnumeratorGetter(ordinal);
-                }
-
-                /**
-                 * Row field accessor via index
-                 */
-                class ArrayEnumeratorGetter extends AbstractGetter {
-                    protected final int field;
-
-                    public ArrayEnumeratorGetter(int field) {
-                        this.field = field;
-                    }
-
-                    public Object getObject() {
-                        Object o = current()[field];
-                        wasNull[0] = o == null;
-                        return o;
-                    }
-                }
-            };
-        }
-
-        public List<ColumnMetaData> getColumnList() {
-            return structType.columns;
-        }
-
-        public List<AvaticaParameter> getParameterList() {
-            return parameterList;
-        }
-
-        public Map<String, Object> getInternalParameters() {
-            return null;
-        }
-
-        public String getSql() {
-            return sql;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareImpl.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareImpl.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareImpl.java
deleted file mode 100644
index 5aeeb42..0000000
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareImpl.java
+++ /dev/null
@@ -1,47 +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.kylin.jdbc;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.hydromatic.avatica.AvaticaParameter;
-import net.hydromatic.avatica.ColumnMetaData;
-
-/**
- * @author xduo
- * 
- */
-public class KylinPrepareImpl implements KylinPrepare {
-
-    @Override
-    public PrepareResult prepare(String sql) {
-        List<AvaticaParameter> aps = new ArrayList<AvaticaParameter>();
-
-        int startIndex = 0;
-        while (sql.indexOf("?", startIndex) >= 0) {
-            AvaticaParameter ap = new AvaticaParameter(false, 0, 0, 0, null, null, null);
-            aps.add(ap);
-            startIndex = sql.indexOf("?", startIndex) + 1;
-        }
-
-        return new KylinPrepare.PrepareResult(sql, aps, null, ColumnMetaData.struct(new ArrayList<ColumnMetaData>()));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareStatementImpl.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareStatementImpl.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareStatementImpl.java
deleted file mode 100644
index a2818d8..0000000
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPrepareStatementImpl.java
+++ /dev/null
@@ -1,170 +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.kylin.jdbc;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.sql.NClob;
-import java.sql.ResultSet;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-import java.util.Collections;
-import java.util.List;
-
-import net.hydromatic.avatica.AvaticaConnection;
-import net.hydromatic.avatica.AvaticaPrepareResult;
-import net.hydromatic.avatica.AvaticaPreparedStatement;
-import net.hydromatic.avatica.AvaticaResultSet;
-
-/**
- * Kylin prepare statement. <br>
- * Supported operations:
- * <ul>
- * <li>setString</li>
- * <li>setInt</li>
- * <li>setShort</li>
- * <li>setLong</li>
- * <li>setFloat</li>
- * <li>setDouble</li>
- * <li>setBoolean</li>
- * <li>setByte</li>
- * <li>setDate</li>
- * <li>setTime</li>
- * <li>setTimestamp</li>
- * </ul>
- * 
- * @author xduo
- * 
- */
-public abstract class KylinPrepareStatementImpl extends AvaticaPreparedStatement {
-
-    /**
-     * Before real query,
-     */
-    protected AvaticaPrepareResult prequeryResult;
-
-    protected KylinPrepareStatementImpl(AvaticaConnection connection, AvaticaPrepareResult prepareResult, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-        super(connection, prepareResult, resultSetType, resultSetConcurrency, resultSetHoldability);
-
-        this.prequeryResult = prepareResult;
-    }
-
-    @Override
-    public ResultSet executeQuery() throws SQLException {
-        AvaticaPrepareResult queriedResult = ((KylinConnectionImpl) this.connection).getMeta().prepare(this, this.prequeryResult.getSql());
-
-        return executeQueryInternal(queriedResult);
-    }
-
-    @Override
-    protected void close_() {
-        if (!closed) {
-            closed = true;
-            final KylinConnectionImpl connection_ = (KylinConnectionImpl) connection;
-            connection_.statements.remove(this);
-            if (openResultSet != null) {
-                AvaticaResultSet c = openResultSet;
-                openResultSet = null;
-                c.close();
-            }
-            // If onStatementClose throws, this method will throw an
-            // exception (later
-            // converted to SQLException), but this statement still gets
-            // closed.
-            connection_.getDriver().handler.onStatementClose(this);
-        }
-    }
-
-    public List<Object> getParameterValues() {
-        return (List<Object>) Collections.unmodifiableList(super.getParameterValues());
-    }
-
-    public void setRowId(int parameterIndex, RowId x) throws SQLException {
-        getParameter(parameterIndex).setRowId(x);
-    }
-
-    public void setNString(int parameterIndex, String value) throws SQLException {
-        getParameter(parameterIndex).setNString(value);
-    }
-
-    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
-        getParameter(parameterIndex).setNCharacterStream(value, length);
-    }
-
-    public void setNClob(int parameterIndex, NClob value) throws SQLException {
-        getParameter(parameterIndex).setNClob(value);
-    }
-
-    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
-        getParameter(parameterIndex).setClob(reader, length);
-    }
-
-    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
-        getParameter(parameterIndex).setBlob(inputStream, length);
-    }
-
-    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
-        getParameter(parameterIndex).setNClob(reader, length);
-    }
-
-    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
-        getParameter(parameterIndex).setSQLXML(xmlObject);
-    }
-
-    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
-        getParameter(parameterIndex).setAsciiStream(x, length);
-    }
-
-    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
-        getParameter(parameterIndex).setBinaryStream(x, length);
-    }
-
-    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
-        getParameter(parameterIndex).setCharacterStream(reader, length);
-    }
-
-    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
-        getParameter(parameterIndex).setAsciiStream(x);
-    }
-
-    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
-        getParameter(parameterIndex).setBinaryStream(x);
-    }
-
-    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
-        getParameter(parameterIndex).setCharacterStream(reader);
-    }
-
-    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
-        getParameter(parameterIndex).setNCharacterStream(value);
-    }
-
-    public void setClob(int parameterIndex, Reader reader) throws SQLException {
-        getParameter(parameterIndex).setClob(reader);
-    }
-
-    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
-        getParameter(parameterIndex).setBlob(inputStream);
-    }
-
-    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
-        getParameter(parameterIndex).setNClob(reader);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java
new file mode 100644
index 0000000..21cb162
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinPreparedStatement.java
@@ -0,0 +1,100 @@
+package org.apache.kylin.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.AvaticaPreparedStatement;
+import org.apache.calcite.avatica.Meta.Signature;
+import org.apache.calcite.avatica.Meta.StatementHandle;
+
+public class KylinPreparedStatement extends AvaticaPreparedStatement {
+
+    protected KylinPreparedStatement(AvaticaConnection connection, StatementHandle h, Signature signature, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        super(connection, h, signature, resultSetType, resultSetConcurrency, resultSetHoldability);
+    }
+    
+    protected List<Object> getParameterValues() {
+        return Arrays.asList(slots);
+    }
+    
+    // ============================================================================
+
+    public void setRowId(int parameterIndex, RowId x) throws SQLException {
+        getParameter(parameterIndex).setRowId(slots, parameterIndex, x);
+    }
+
+    public void setNString(int parameterIndex, String value) throws SQLException {
+        getParameter(parameterIndex).setNString(slots, parameterIndex, value);
+    }
+
+    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+        getParameter(parameterIndex).setNCharacterStream(slots, parameterIndex, value, length);
+    }
+
+    public void setNClob(int parameterIndex, NClob value) throws SQLException {
+        getParameter(parameterIndex).setNClob(slots, parameterIndex, value);
+    }
+
+    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        getParameter(parameterIndex).setClob(slots, parameterIndex, reader, length);
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        getParameter(parameterIndex).setBlob(slots, parameterIndex, inputStream, length);
+    }
+
+    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        getParameter(parameterIndex).setNClob(slots, parameterIndex, reader, length);
+    }
+
+    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+        getParameter(parameterIndex).setSQLXML(slots, parameterIndex, xmlObject);
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+        getParameter(parameterIndex).setAsciiStream(slots, parameterIndex, x, length);
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+        getParameter(parameterIndex).setBinaryStream(slots, parameterIndex, x, length);
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+        getParameter(parameterIndex).setCharacterStream(slots, parameterIndex, reader, length);
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+        getParameter(parameterIndex).setAsciiStream(slots, parameterIndex, x);
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+        getParameter(parameterIndex).setBinaryStream(slots, parameterIndex, x);
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+        getParameter(parameterIndex).setCharacterStream(slots, parameterIndex, reader);
+    }
+
+    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+        getParameter(parameterIndex).setNCharacterStream(slots, parameterIndex, value);
+    }
+
+    public void setClob(int parameterIndex, Reader reader) throws SQLException {
+        getParameter(parameterIndex).setClob(slots, parameterIndex, reader);
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+        getParameter(parameterIndex).setBlob(slots, parameterIndex, inputStream);
+    }
+
+    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+        getParameter(parameterIndex).setNClob(slots, parameterIndex, reader);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
index 7cb9b25..1229d10 100644
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinResultSet.java
@@ -1,45 +1,72 @@
-/*
- * 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.kylin.jdbc;
-
-import java.sql.ResultSetMetaData;
-import java.util.TimeZone;
-
-import org.apache.calcite.avatica.AvaticaPrepareResult;
-import org.apache.calcite.avatica.AvaticaResultSet;
-import org.apache.calcite.avatica.AvaticaStatement;
-
-import org.apache.kylin.jdbc.KylinPrepare.PrepareResult;
-
-/**
- * Kylin query result set
- * 
- * @author xduo
- * 
- */
-public class KylinResultSet extends AvaticaResultSet {
-
-    public KylinResultSet(AvaticaStatement statement, AvaticaPrepareResult prepareResult, ResultSetMetaData resultSetMetaData, TimeZone timeZone) {
-        super(statement, prepareResult, resultSetMetaData, timeZone);
-    }
-
-    public KylinPrepare.PrepareResult getPrepareResult() {
-        return (PrepareResult) prepareResult;
-    }
-}
+/*
+ * 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.kylin.jdbc;
+
+import java.io.IOException;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.AvaticaResultSet;
+import org.apache.calcite.avatica.AvaticaStatement;
+import org.apache.calcite.avatica.Meta.Signature;
+import org.apache.calcite.avatica.MetaImpl;
+import org.apache.kylin.jdbc.IRemoteClient.QueryResult;
+
+public class KylinResultSet extends AvaticaResultSet {
+
+    public KylinResultSet(AvaticaStatement statement, Signature signature, ResultSetMetaData resultSetMetaData, TimeZone timeZone, Iterable<Object> iterable) {
+        super(statement, signature, resultSetMetaData, timeZone, iterable);
+    }
+
+    @Override
+    protected AvaticaResultSet execute() throws SQLException {
+        
+        // skip execution if result is already there (case of meta data lookup)
+        if (this.iterable != null) {
+            return super.execute();
+        }
+        
+        String sql = signature.sql;
+        List<AvaticaParameter> params = signature.parameters;
+        List<Object> paramValues = null;
+        if (params != null && params.size() > 0) {
+            paramValues = ((KylinPreparedStatement) statement).getParameterValues();
+        }
+        
+        IRemoteClient client = ((KylinConnection) statement.connection).getRemoteClient();
+        QueryResult result;
+        try {
+            result = client.executeQuery(sql, params, paramValues);
+        } catch (IOException e) {
+            throw new SQLException(e);
+        }
+        
+        columnMetaDataList.clear();
+        columnMetaDataList.addAll(result.columnMeta);
+        
+        cursor = MetaImpl.createCursor(signature.cursorFactory, result.iterable);
+        return super.execute2(cursor, columnMetaDataList);
+    }
+    
+    
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatement.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatement.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatement.java
new file mode 100644
index 0000000..6596389
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatement.java
@@ -0,0 +1,31 @@
+/*
+ * 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.kylin.jdbc;
+
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.AvaticaStatement;
+import org.apache.calcite.avatica.Meta.StatementHandle;
+
+public class KylinStatement extends AvaticaStatement {
+
+    protected KylinStatement(AvaticaConnection connection, StatementHandle h, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
+        super(connection, h, resultSetType, resultSetConcurrency, resultSetHoldability);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatementImpl.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatementImpl.java b/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatementImpl.java
deleted file mode 100644
index 0d7605d..0000000
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/KylinStatementImpl.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.kylin.jdbc;
-
-import org.apache.calcite.avatica.AvaticaConnection;
-import org.apache.calcite.avatica.AvaticaResultSet;
-import org.apache.calcite.avatica.AvaticaStatement;
-
-/**
- * Kylin statement implementation
- * 
- * @author xduo
- * 
- */
-public abstract class KylinStatementImpl extends AvaticaStatement {
-
-    protected KylinStatementImpl(AvaticaConnection connection, int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
-        super(connection, resultSetType, resultSetConcurrency, resultSetHoldability);
-    }
-
-    @Override
-    protected void close_() {
-        if (!closed) {
-            closed = true;
-            final KylinConnectionImpl connection_ = (KylinConnectionImpl) connection;
-            connection_.statements.remove(this);
-            if (openResultSet != null) {
-                AvaticaResultSet c = openResultSet;
-                openResultSet = null;
-                c.close();
-            }
-            // If onStatementClose throws, this method will throw an exception
-            // (later
-            // converted to SQLException), but this statement still gets closed.
-            connection_.getDriver().handler.onStatementClose(this);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/json/PreparedQueryRequest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/json/PreparedQueryRequest.java b/jdbc/src/main/java/org/apache/kylin/jdbc/json/PreparedQueryRequest.java
new file mode 100644
index 0000000..1f37bfd
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/json/PreparedQueryRequest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.kylin.jdbc.json;
+
+import java.util.List;
+
+public class PreparedQueryRequest extends QueryRequest {
+    private List<StatementParameter> params;
+
+    public List<StatementParameter> getParams() {
+        return params;
+    }
+
+    public void setParams(List<StatementParameter> params) {
+        this.params = params;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/json/QueryRequest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/json/QueryRequest.java b/jdbc/src/main/java/org/apache/kylin/jdbc/json/QueryRequest.java
new file mode 100644
index 0000000..4878aba
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/json/QueryRequest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.kylin.jdbc.json;
+
+public class QueryRequest {
+    private String sql;
+    private String project;
+
+    public String getSql() {
+        return sql;
+    }
+
+    public void setSql(String sql) {
+        this.sql = sql;
+    }
+
+    public String getProject() {
+        return project;
+    }
+
+    public void setProject(String project) {
+        this.project = project;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/json/SQLResponseStub.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/json/SQLResponseStub.java b/jdbc/src/main/java/org/apache/kylin/jdbc/json/SQLResponseStub.java
new file mode 100644
index 0000000..f34e48c
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/json/SQLResponseStub.java
@@ -0,0 +1,321 @@
+/*
+ * 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.kylin.jdbc.json;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ */
+public class SQLResponseStub implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // private static final Logger logger =
+    // LoggerFactory.getLogger(SQLResponse.class);
+
+    // the data type for each column
+    private List<ColumnMetaStub> columnMetas;
+
+    // the results rows, each row contains several columns
+    private List<String[]> results;
+
+    private String cube;
+
+    // if not select query, only return affected row count
+    private int affectedRowCount;
+
+    // if isException, the detailed exception message
+    private String exceptionMessage;
+
+    private boolean isException;
+
+    private long duration;
+
+    private boolean isPartial = false;
+
+    private long totalScanCount;
+
+    private boolean hitCache = false;
+
+    public SQLResponseStub() {
+    }
+
+    public List<ColumnMetaStub> getColumnMetas() {
+        return columnMetas;
+    }
+
+    public void setColumnMetas(List<ColumnMetaStub> columnMetas) {
+        this.columnMetas = columnMetas;
+    }
+
+    public List<String[]> getResults() {
+        return results;
+    }
+
+    public void setResults(List<String[]> results) {
+        this.results = results;
+    }
+
+    public String getCube() {
+        return cube;
+    }
+
+    public void setCube(String cube) {
+        this.cube = cube;
+    }
+
+    public int getAffectedRowCount() {
+        return affectedRowCount;
+    }
+
+    public void setAffectedRowCount(int affectedRowCount) {
+        this.affectedRowCount = affectedRowCount;
+    }
+
+    public boolean getIsException() {
+        return isException;
+    }
+
+    public void setIsException(boolean isException) {
+        this.isException = isException;
+    }
+
+    public String getExceptionMessage() {
+        return exceptionMessage;
+    }
+
+    public void setExceptionMessage(String exceptionMessage) {
+        this.exceptionMessage = exceptionMessage;
+    }
+
+    public long getDuration() {
+        return duration;
+    }
+
+    public void setDuration(long duration) {
+        this.duration = duration;
+    }
+
+    public boolean isPartial() {
+        return isPartial;
+    }
+
+    public void setPartial(boolean isPartial) {
+        this.isPartial = isPartial;
+    }
+
+    public long getTotalScanCount() {
+        return totalScanCount;
+    }
+
+    public void setTotalScanCount(long totalScanCount) {
+        this.totalScanCount = totalScanCount;
+    }
+
+    public boolean isHitCache() {
+        return hitCache;
+    }
+
+    public void setHitCache(boolean hitCache) {
+        this.hitCache = hitCache;
+    }
+
+    public static long getSerialversionuid() {
+        return serialVersionUID;
+    }
+
+    public static class ColumnMetaStub {
+
+        private boolean isAutoIncrement;
+        private boolean isCaseSensitive;
+        private boolean isSearchable;
+        private boolean isCurrency;
+        private int isNullable;// 0:nonull, 1:nullable, 2: nullableunknown
+        private boolean isSigned;
+        private int displaySize;
+        private String label;// AS keyword
+        private String name;
+        private String schemaName;
+        private String catelogName;
+        private String tableName;
+        private int precision;
+        private int scale;
+        private int columnType;// as defined in java.sql.Types
+        private String columnTypeName;
+        private boolean isReadOnly;
+        private boolean isWritable;
+        private boolean isDefinitelyWritable;
+
+        public ColumnMetaStub() {
+        }
+
+        public boolean isAutoIncrement() {
+            return isAutoIncrement;
+        }
+
+        public void setAutoIncrement(boolean isAutoIncrement) {
+            this.isAutoIncrement = isAutoIncrement;
+        }
+
+        public boolean isCaseSensitive() {
+            return isCaseSensitive;
+        }
+
+        public void setCaseSensitive(boolean isCaseSensitive) {
+            this.isCaseSensitive = isCaseSensitive;
+        }
+
+        public boolean isSearchable() {
+            return isSearchable;
+        }
+
+        public void setSearchable(boolean isSearchable) {
+            this.isSearchable = isSearchable;
+        }
+
+        public boolean isCurrency() {
+            return isCurrency;
+        }
+
+        public void setCurrency(boolean isCurrency) {
+            this.isCurrency = isCurrency;
+        }
+
+        public int getIsNullable() {
+            return isNullable;
+        }
+
+        public void setIsNullable(int isNullable) {
+            this.isNullable = isNullable;
+        }
+
+        public boolean isSigned() {
+            return isSigned;
+        }
+
+        public void setSigned(boolean isSigned) {
+            this.isSigned = isSigned;
+        }
+
+        public int getDisplaySize() {
+            return displaySize;
+        }
+
+        public void setDisplaySize(int displaySize) {
+            this.displaySize = displaySize;
+        }
+
+        public String getLabel() {
+            return label;
+        }
+
+        public void setLabel(String label) {
+            this.label = label;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public String getSchemaName() {
+            return schemaName;
+        }
+
+        public void setSchemaName(String schemaName) {
+            this.schemaName = schemaName;
+        }
+
+        public String getCatelogName() {
+            return catelogName;
+        }
+
+        public void setCatelogName(String catelogName) {
+            this.catelogName = catelogName;
+        }
+
+        public String getTableName() {
+            return tableName;
+        }
+
+        public void setTableName(String tableName) {
+            this.tableName = tableName;
+        }
+
+        public int getPrecision() {
+            return precision;
+        }
+
+        public void setPrecision(int precision) {
+            this.precision = precision;
+        }
+
+        public int getScale() {
+            return scale;
+        }
+
+        public void setScale(int scale) {
+            this.scale = scale;
+        }
+
+        public int getColumnType() {
+            return columnType;
+        }
+
+        public void setColumnType(int columnType) {
+            this.columnType = columnType;
+        }
+
+        public String getColumnTypeName() {
+            return columnTypeName;
+        }
+
+        public void setColumnTypeName(String columnTypeName) {
+            this.columnTypeName = columnTypeName;
+        }
+
+        public boolean isReadOnly() {
+            return isReadOnly;
+        }
+
+        public void setReadOnly(boolean isReadOnly) {
+            this.isReadOnly = isReadOnly;
+        }
+
+        public boolean isWritable() {
+            return isWritable;
+        }
+
+        public void setWritable(boolean isWritable) {
+            this.isWritable = isWritable;
+        }
+
+        public boolean isDefinitelyWritable() {
+            return isDefinitelyWritable;
+        }
+
+        public void setDefinitelyWritable(boolean isDefinitelyWritable) {
+            this.isDefinitelyWritable = isDefinitelyWritable;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/json/StatementParameter.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/json/StatementParameter.java b/jdbc/src/main/java/org/apache/kylin/jdbc/json/StatementParameter.java
new file mode 100644
index 0000000..75cf422
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/json/StatementParameter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.kylin.jdbc.json;
+
+public class StatementParameter {
+
+    private String className;
+    private String value;
+
+    public StatementParameter(String className, String value) {
+        this.className = className;
+        this.value = value;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClazz(String className) {
+        this.className = className;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/json/TableMetaStub.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/json/TableMetaStub.java b/jdbc/src/main/java/org/apache/kylin/jdbc/json/TableMetaStub.java
new file mode 100644
index 0000000..3d4b115
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/kylin/jdbc/json/TableMetaStub.java
@@ -0,0 +1,345 @@
+/*
+ * 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.kylin.jdbc.json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ */
+public class TableMetaStub {
+
+    private static final long serialVersionUID = 1L;
+    private String TABLE_CAT;
+    private String TABLE_SCHEM;
+    private String TABLE_NAME;
+    private String TABLE_TYPE;
+    private String REMARKS;
+    private String TYPE_CAT;
+    private String TYPE_SCHEM;
+    private String TYPE_NAME;
+    private String SELF_REFERENCING_COL_NAME;
+    private String REF_GENERATION;
+    @JsonProperty("columns")
+    private List<ColumnMetaStub> columns = new ArrayList<ColumnMetaStub>();
+
+    public String getTABLE_CAT() {
+        return TABLE_CAT;
+    }
+
+    public void setTABLE_CAT(String tABLE_CAT) {
+        TABLE_CAT = tABLE_CAT;
+    }
+
+    public String getTABLE_SCHEM() {
+        return TABLE_SCHEM;
+    }
+
+    public void setTABLE_SCHEM(String tABLE_SCHEM) {
+        TABLE_SCHEM = tABLE_SCHEM;
+    }
+
+    public String getTABLE_NAME() {
+        return TABLE_NAME;
+    }
+
+    public void setTABLE_NAME(String tABLE_NAME) {
+        TABLE_NAME = tABLE_NAME;
+    }
+
+    public String getTABLE_TYPE() {
+        return TABLE_TYPE;
+    }
+
+    public void setTABLE_TYPE(String tABLE_TYPE) {
+        TABLE_TYPE = tABLE_TYPE;
+    }
+
+    public String getREMARKS() {
+        return REMARKS;
+    }
+
+    public void setREMARKS(String rEMARKS) {
+        REMARKS = rEMARKS;
+    }
+
+    public String getTYPE_CAT() {
+        return TYPE_CAT;
+    }
+
+    public void setTYPE_CAT(String tYPE_CAT) {
+        TYPE_CAT = tYPE_CAT;
+    }
+
+    public String getTYPE_SCHEM() {
+        return TYPE_SCHEM;
+    }
+
+    public void setTYPE_SCHEM(String tYPE_SCHEM) {
+        TYPE_SCHEM = tYPE_SCHEM;
+    }
+
+    public String getTYPE_NAME() {
+        return TYPE_NAME;
+    }
+
+    public void setTYPE_NAME(String tYPE_NAME) {
+        TYPE_NAME = tYPE_NAME;
+    }
+
+    public String getSELF_REFERENCING_COL_NAME() {
+        return SELF_REFERENCING_COL_NAME;
+    }
+
+    public void setSELF_REFERENCING_COL_NAME(String sELF_REFERENCING_COL_NAME) {
+        SELF_REFERENCING_COL_NAME = sELF_REFERENCING_COL_NAME;
+    }
+
+    public String getREF_GENERATION() {
+        return REF_GENERATION;
+    }
+
+    public void setREF_GENERATION(String rEF_GENERATION) {
+        REF_GENERATION = rEF_GENERATION;
+    }
+
+    public List<ColumnMetaStub> getColumns() {
+        return columns;
+    }
+
+    public void setColumns(List<ColumnMetaStub> columns) {
+        this.columns = columns;
+    }
+
+    public static long getSerialversionuid() {
+        return serialVersionUID;
+    }
+
+    public static class ColumnMetaStub {
+        private String TABLE_CAT;
+        private String TABLE_SCHEM;
+        private String TABLE_NAME;
+        private String COLUMN_NAME;
+        private int DATA_TYPE;
+        private String TYPE_NAME;
+        private int COLUMN_SIZE;
+        private int BUFFER_LENGTH;
+        private int DECIMAL_DIGITS;
+        private int NUM_PREC_RADIX;
+        private int NULLABLE;
+        private String REMARKS;
+        private String COLUMN_DEF;
+        private int SQL_DATA_TYPE;
+        private int SQL_DATETIME_SUB;
+        private int CHAR_OCTET_LENGTH;
+        private int ORDINAL_POSITION;
+        private String IS_NULLABLE;
+        private String SCOPE_CATLOG;
+        private String SCOPE_SCHEMA;
+        private String SCOPE_TABLE;
+        private short SOURCE_DATA_TYPE;
+        private String IS_AUTOINCREMENT;
+
+        public String getTABLE_CAT() {
+            return TABLE_CAT;
+        }
+
+        public void setTABLE_CAT(String tABLE_CAT) {
+            TABLE_CAT = tABLE_CAT;
+        }
+
+        public String getTABLE_SCHEM() {
+            return TABLE_SCHEM;
+        }
+
+        public void setTABLE_SCHEM(String tABLE_SCHEM) {
+            TABLE_SCHEM = tABLE_SCHEM;
+        }
+
+        public String getTABLE_NAME() {
+            return TABLE_NAME;
+        }
+
+        public void setTABLE_NAME(String tABLE_NAME) {
+            TABLE_NAME = tABLE_NAME;
+        }
+
+        public String getCOLUMN_NAME() {
+            return COLUMN_NAME;
+        }
+
+        public void setCOLUMN_NAME(String cOLUMN_NAME) {
+            COLUMN_NAME = cOLUMN_NAME;
+        }
+
+        public int getDATA_TYPE() {
+            return DATA_TYPE;
+        }
+
+        public void setDATA_TYPE(int dATA_TYPE) {
+            DATA_TYPE = dATA_TYPE;
+        }
+
+        public String getTYPE_NAME() {
+            return TYPE_NAME;
+        }
+
+        public void setTYPE_NAME(String tYPE_NAME) {
+            TYPE_NAME = tYPE_NAME;
+        }
+
+        public int getCOLUMN_SIZE() {
+            return COLUMN_SIZE;
+        }
+
+        public void setCOLUMN_SIZE(int cOLUMN_SIZE) {
+            COLUMN_SIZE = cOLUMN_SIZE;
+        }
+
+        public int getBUFFER_LENGTH() {
+            return BUFFER_LENGTH;
+        }
+
+        public void setBUFFER_LENGTH(int bUFFER_LENGTH) {
+            BUFFER_LENGTH = bUFFER_LENGTH;
+        }
+
+        public int getDECIMAL_DIGITS() {
+            return DECIMAL_DIGITS;
+        }
+
+        public void setDECIMAL_DIGITS(int dECIMAL_DIGITS) {
+            DECIMAL_DIGITS = dECIMAL_DIGITS;
+        }
+
+        public int getNUM_PREC_RADIX() {
+            return NUM_PREC_RADIX;
+        }
+
+        public void setNUM_PREC_RADIX(int nUM_PREC_RADIX) {
+            NUM_PREC_RADIX = nUM_PREC_RADIX;
+        }
+
+        public int getNULLABLE() {
+            return NULLABLE;
+        }
+
+        public void setNULLABLE(int nULLABLE) {
+            NULLABLE = nULLABLE;
+        }
+
+        public String getREMARKS() {
+            return REMARKS;
+        }
+
+        public void setREMARKS(String rEMARKS) {
+            REMARKS = rEMARKS;
+        }
+
+        public String getCOLUMN_DEF() {
+            return COLUMN_DEF;
+        }
+
+        public void setCOLUMN_DEF(String cOLUMN_DEF) {
+            COLUMN_DEF = cOLUMN_DEF;
+        }
+
+        public int getSQL_DATA_TYPE() {
+            return SQL_DATA_TYPE;
+        }
+
+        public void setSQL_DATA_TYPE(int sQL_DATA_TYPE) {
+            SQL_DATA_TYPE = sQL_DATA_TYPE;
+        }
+
+        public int getSQL_DATETIME_SUB() {
+            return SQL_DATETIME_SUB;
+        }
+
+        public void setSQL_DATETIME_SUB(int sQL_DATETIME_SUB) {
+            SQL_DATETIME_SUB = sQL_DATETIME_SUB;
+        }
+
+        public int getCHAR_OCTET_LENGTH() {
+            return CHAR_OCTET_LENGTH;
+        }
+
+        public void setCHAR_OCTET_LENGTH(int cHAR_OCTET_LENGTH) {
+            CHAR_OCTET_LENGTH = cHAR_OCTET_LENGTH;
+        }
+
+        public int getORDINAL_POSITION() {
+            return ORDINAL_POSITION;
+        }
+
+        public void setORDINAL_POSITION(int oRDINAL_POSITION) {
+            ORDINAL_POSITION = oRDINAL_POSITION;
+        }
+
+        public String getIS_NULLABLE() {
+            return IS_NULLABLE;
+        }
+
+        public void setIS_NULLABLE(String iS_NULLABLE) {
+            IS_NULLABLE = iS_NULLABLE;
+        }
+
+        public String getSCOPE_CATLOG() {
+            return SCOPE_CATLOG;
+        }
+
+        public void setSCOPE_CATLOG(String sCOPE_CATLOG) {
+            SCOPE_CATLOG = sCOPE_CATLOG;
+        }
+
+        public String getSCOPE_SCHEMA() {
+            return SCOPE_SCHEMA;
+        }
+
+        public void setSCOPE_SCHEMA(String sCOPE_SCHEMA) {
+            SCOPE_SCHEMA = sCOPE_SCHEMA;
+        }
+
+        public String getSCOPE_TABLE() {
+            return SCOPE_TABLE;
+        }
+
+        public void setSCOPE_TABLE(String sCOPE_TABLE) {
+            SCOPE_TABLE = sCOPE_TABLE;
+        }
+
+        public short getSOURCE_DATA_TYPE() {
+            return SOURCE_DATA_TYPE;
+        }
+
+        public void setSOURCE_DATA_TYPE(short sOURCE_DATA_TYPE) {
+            SOURCE_DATA_TYPE = sOURCE_DATA_TYPE;
+        }
+
+        public String getIS_AUTOINCREMENT() {
+            return IS_AUTOINCREMENT;
+        }
+
+        public void setIS_AUTOINCREMENT(String iS_AUTOINCREMENT) {
+            this.IS_AUTOINCREMENT = iS_AUTOINCREMENT;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/stub/ConnectionException.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/stub/ConnectionException.java b/jdbc/src/main/java/org/apache/kylin/jdbc/stub/ConnectionException.java
deleted file mode 100644
index eeeafc6..0000000
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/stub/ConnectionException.java
+++ /dev/null
@@ -1,55 +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.kylin.jdbc.stub;
-
-/**
- * @author xduo
- * 
- */
-public class ConnectionException extends Exception {
-
-    private static final long serialVersionUID = 1L;
-
-    public ConnectionException() {
-        super();
-    }
-
-    /**
-     * @param message
-     * @param cause
-     */
-    public ConnectionException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    /**
-     * @param message
-     */
-    public ConnectionException(String message) {
-        super(message);
-    }
-
-    /**
-     * @param cause
-     */
-    public ConnectionException(Throwable cause) {
-        super(cause);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/b28e9f4a/jdbc/src/main/java/org/apache/kylin/jdbc/stub/DataSet.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/kylin/jdbc/stub/DataSet.java b/jdbc/src/main/java/org/apache/kylin/jdbc/stub/DataSet.java
deleted file mode 100644
index 8b0347a..0000000
--- a/jdbc/src/main/java/org/apache/kylin/jdbc/stub/DataSet.java
+++ /dev/null
@@ -1,55 +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.kylin.jdbc.stub;
-
-import java.util.List;
-
-import org.apache.calcite.avatica.ColumnMetaData;
-import org.apache.calcite.linq4j.Enumerator;
-
-/**
- * Data set wrapper.
- * 
- * @author xduo
- * 
- */
-public class DataSet<E> {
-
-    private final List<ColumnMetaData> meta;
-
-    private final Enumerator<E> enumerator;
-
-    /**
-     * @param meta
-     * @param enumerator
-     */
-    public DataSet(List<ColumnMetaData> meta, Enumerator<E> enumerator) {
-        this.meta = meta;
-        this.enumerator = enumerator;
-    }
-
-    public List<ColumnMetaData> getMeta() {
-        return meta;
-    }
-
-    public Enumerator<E> getEnumerator() {
-        return enumerator;
-    }
-
-}