You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by mo...@apache.org on 2015/04/25 01:36:02 UTC

[1/2] incubator-zeppelin git commit: ZEPPELIN-45: Integrate Tajo with Zeppelin

Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master b3b9c93d9 -> 3a4ab1ad2


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/test/java/org/apache/zeppelin/tajo/TesterStatement.java
----------------------------------------------------------------------
diff --git a/tajo/src/test/java/org/apache/zeppelin/tajo/TesterStatement.java b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterStatement.java
new file mode 100644
index 0000000..22be68d
--- /dev/null
+++ b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterStatement.java
@@ -0,0 +1,344 @@
+/**
+ * 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.zeppelin.tajo;
+
+
+import java.sql.*;
+
+/**
+ * This is borrowed from Apache Commons DBCP2.
+ *
+ * A dummy {@link java.sql.Statement}, for testing purposes.
+ */
+public class TesterStatement implements Statement {
+  public TesterStatement(Connection conn) {
+    _connection = conn;
+  }
+
+  public TesterStatement(Connection conn, int resultSetType, int resultSetConcurrency) {
+    _connection = conn;
+    _resultSetType = resultSetType;
+    _resultSetConcurrency = resultSetConcurrency;
+  }
+
+  protected Connection _connection = null;
+  protected boolean _open = true;
+  protected int _rowsUpdated = 1;
+  protected boolean _executeResponse = true;
+  protected int _maxFieldSize = 1024;
+  protected int _maxRows = 1024;
+  protected boolean _escapeProcessing = false;
+  protected int _queryTimeout = 1000;
+  protected String _cursorName = null;
+  protected int _fetchDirection = 1;
+  protected int _fetchSize = 1;
+  protected int _resultSetConcurrency = 1;
+  protected int _resultSetType = 1;
+  protected ResultSet _resultSet = null;
+
+  @Override
+  public ResultSet executeQuery(String sql) throws SQLException {
+    checkOpen();
+    if("null".equals(sql)) {
+      return null;
+    }
+    if("invalid".equals(sql)) {
+      throw new SQLException("invalid query");
+    }
+    if ("broken".equals(sql)) {
+      throw new SQLException("broken connection");
+    }
+    if("select username".equals(sql)) {
+      String username = ((TesterConnection) _connection).getUsername();
+      Object[][] data = {{username}};
+      return new TesterResultSet(this, data);
+    } else {
+      // Simulate timeout if queryTimout is set to less than 5 seconds
+      if (_queryTimeout > 0 && _queryTimeout < 5) {
+        throw new SQLException("query timeout");
+      }
+      return new TesterResultSet(this);
+    }
+  }
+
+  @Override
+  public int executeUpdate(String sql) throws SQLException {
+    checkOpen();
+    return _rowsUpdated;
+  }
+
+  @Override
+  public void close() throws SQLException {
+    // calling close twice has no effect
+    if (!_open) {
+      return;
+    }
+
+    _open = false;
+    if (_resultSet != null) {
+      _resultSet.close();
+      _resultSet = null;
+    }
+  }
+
+  @Override
+  public int getMaxFieldSize() throws SQLException {
+    checkOpen();
+    return _maxFieldSize;
+  }
+
+  @Override
+  public void setMaxFieldSize(int max) throws SQLException {
+    checkOpen();
+    _maxFieldSize = max;
+  }
+
+  @Override
+  public int getMaxRows() throws SQLException {
+    checkOpen();
+    return _maxRows;
+  }
+
+  @Override
+  public void setMaxRows(int max) throws SQLException {
+    checkOpen();
+    _maxRows = max;
+  }
+
+  @Override
+  public void setEscapeProcessing(boolean enable) throws SQLException {
+    checkOpen();
+    _escapeProcessing = enable;
+  }
+
+  @Override
+  public int getQueryTimeout() throws SQLException {
+    checkOpen();
+    return _queryTimeout;
+  }
+
+  @Override
+  public void setQueryTimeout(int seconds) throws SQLException {
+    checkOpen();
+    _queryTimeout = seconds;
+  }
+
+  @Override
+  public void cancel() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public void clearWarnings() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void setCursorName(String name) throws SQLException {
+    checkOpen();
+    _cursorName = name;
+  }
+
+  @Override
+  public boolean execute(String sql) throws SQLException {
+    checkOpen();
+    if("invalid".equals(sql)) {
+      throw new SQLException("invalid query");
+    }
+    return _executeResponse;
+  }
+
+  @Override
+  public ResultSet getResultSet() throws SQLException {
+    checkOpen();
+    if (_resultSet == null) {
+      _resultSet = new TesterResultSet(this);
+    }
+    return _resultSet;
+  }
+
+  @Override
+  public int getUpdateCount() throws SQLException {
+    checkOpen();
+    return _rowsUpdated;
+  }
+
+  @Override
+  public boolean getMoreResults() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public void setFetchDirection(int direction) throws SQLException {
+    checkOpen();
+    _fetchDirection = direction;
+  }
+
+  @Override
+  public int getFetchDirection() throws SQLException {
+    checkOpen();
+    return _fetchDirection;
+  }
+
+  @Override
+  public void setFetchSize(int rows) throws SQLException {
+    checkOpen();
+    _fetchSize = rows;
+  }
+
+  @Override
+  public int getFetchSize() throws SQLException {
+    checkOpen();
+    return _fetchSize;
+  }
+
+  @Override
+  public int getResultSetConcurrency() throws SQLException {
+    checkOpen();
+    return _resultSetConcurrency;
+  }
+
+  @Override
+  public int getResultSetType() throws SQLException {
+    checkOpen();
+    return _resultSetType;
+  }
+
+  @Override
+  public void addBatch(String sql) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void clearBatch() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public int[] executeBatch() throws SQLException {
+    checkOpen();
+    return new int[0];
+  }
+
+  @Override
+  public Connection getConnection() throws SQLException {
+    checkOpen();
+    return _connection;
+  }
+
+  protected void checkOpen() throws SQLException {
+    if(!_open) {
+      throw new SQLException("Connection is closed.");
+    }
+  }
+
+  @Override
+  public boolean getMoreResults(int current) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public ResultSet getGeneratedKeys() throws SQLException {
+    return new TesterResultSet(this);
+  }
+
+  @Override
+  public int executeUpdate(String sql, int autoGeneratedKeys)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public int executeUpdate(String sql, int columnIndexes[])
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public int executeUpdate(String sql, String columnNames[])
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean execute(String sql, int autoGeneratedKeys)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean execute(String sql, int columnIndexes[])
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean execute(String sql, String columnNames[])
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public int getResultSetHoldability() throws SQLException {
+    checkOpen();
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean isClosed() throws SQLException {
+    return !_open;
+  }
+
+  @Override
+  public void setPoolable(boolean poolable) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean isPoolable() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void closeOnCompletion() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not implemented.");
+  }
+
+  @Override
+  public boolean isCloseOnCompletion() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not implemented.");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/test/java/org/apache/zeppelin/tajo/TesterTajoInterpreter.java
----------------------------------------------------------------------
diff --git a/tajo/src/test/java/org/apache/zeppelin/tajo/TesterTajoInterpreter.java b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterTajoInterpreter.java
new file mode 100644
index 0000000..f0eacee
--- /dev/null
+++ b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterTajoInterpreter.java
@@ -0,0 +1,36 @@
+/**
+ * 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.zeppelin.tajo;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class TesterTajoInterpreter extends TajoInterpreter {
+
+  public TesterTajoInterpreter(Properties property) {
+    super(property);
+  }
+
+  @Override
+  public Connection getJdbcConnection()
+    throws SQLException {
+    return new TesterConnection();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
index f5c816f..580860a 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
@@ -387,7 +387,8 @@ public class ZeppelinConfiguration extends XMLConfiguration {
         + "org.apache.zeppelin.markdown.Markdown,"
         + "org.apache.zeppelin.angular.AngularInterpreter,"
         + "org.apache.zeppelin.shell.ShellInterpreter,"
-        + "org.apache.zeppelin.hive.HiveInterpreter"),
+        + "org.apache.zeppelin.hive.HiveInterpreter,"
+        + "org.apache.zeppelin.tajo.TajoInterpreter"),
         ZEPPELIN_INTERPRETER_DIR("zeppelin.interpreter.dir", "interpreter"),
         ZEPPELIN_ENCODING("zeppelin.encoding", "UTF-8"),
         ZEPPELIN_NOTEBOOK_DIR("zeppelin.notebook.dir", "notebook"),


[2/2] incubator-zeppelin git commit: ZEPPELIN-45: Integrate Tajo with Zeppelin

Posted by mo...@apache.org.
ZEPPELIN-45: Integrate Tajo with Zeppelin

I succeed to test on local tajo cluster and distributed tajo cluster and I borrowed some classes from apache commons dbcp2 for unit test implementation.

Please see following site.
https://issues.apache.org/jira/browse/ZEPPELIN-45

Author: JaeHwa Jung <bl...@apache.org>

This patch had conflicts when merged, resolved by
Committer: Lee moon soo <mo...@apache.org>

Closes #39 from blrunner/ZEPPELIN-45 and squashes the following commits:

50979c5 [JaeHwa Jung] Add protocol buffer version to properties.
328c233 [JaeHwa Jung] Merge branch 'master' of https://github.com/apache/incubator-zeppelin into ZEPPELIN-45
929fd4c [JaeHwa Jung] Clean up pom.xml
0d6ce05 [JaeHwa Jung] Update Tajo build order.
6a6506b [JaeHwa Jung] Update ZeppelinRestApiTest::getAvailableInterpreters
8f3de47 [JaeHwa Jung] ProtocolBuffer dependency failed occasionally.
44fe61f [JaeHwa Jung] Merge branch 'master' of https://github.com/apache/incubator-zeppelin into ZEPPELIN-45
fccb2d4 [JaeHwa Jung] Add TajoInterpreter to ZeppelinConfiguration
35d2d87 [JaeHwa Jung] Remove unnecessary properties.
3a71896 [JaeHwa Jung] ZEPPELIN-45: Integrate Tajo with Zeppelin


Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/3a4ab1ad
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/3a4ab1ad
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/3a4ab1ad

Branch: refs/heads/master
Commit: 3a4ab1ad216b443b3bb77a8aa26c7b5d57ca6caa
Parents: b3b9c93
Author: JaeHwa Jung <bl...@apache.org>
Authored: Mon Apr 20 15:45:03 2015 +0900
Committer: Lee moon soo <mo...@apache.org>
Committed: Sat Apr 25 08:35:38 2015 +0900

----------------------------------------------------------------------
 conf/zeppelin-site.xml.template                 |    2 +-
 pom.xml                                         |    2 +
 tajo/pom.xml                                    |  138 +++
 .../apache/zeppelin/tajo/TajoInterpreter.java   |  195 +++
 .../zeppelin/tajo/TajoInterpreterTest.java      |   72 ++
 .../apache/zeppelin/tajo/TesterConnection.java  |  379 ++++++
 .../zeppelin/tajo/TesterDatabaseMetaData.java   |  950 ++++++++++++++
 .../apache/zeppelin/tajo/TesterResultSet.java   | 1163 ++++++++++++++++++
 .../zeppelin/tajo/TesterResultSetMetaData.java  |  157 +++
 .../apache/zeppelin/tajo/TesterStatement.java   |  344 ++++++
 .../zeppelin/tajo/TesterTajoInterpreter.java    |   36 +
 .../zeppelin/conf/ZeppelinConfiguration.java    |    3 +-
 12 files changed, 3439 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/conf/zeppelin-site.xml.template
----------------------------------------------------------------------
diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template
index 13d794c..fae1104 100644
--- a/conf/zeppelin-site.xml.template
+++ b/conf/zeppelin-site.xml.template
@@ -60,7 +60,7 @@
 
 <property>
   <name>zeppelin.interpreters</name>
-  <value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter</value>
+  <value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter</value>
   <description>Comma separated interpreter configurations. First interpreter become a default</description>
 </property>
 

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 27ad467..343cbf9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,7 @@
     <module>angular</module>
     <module>shell</module>
     <module>hive</module>
+    <module>tajo</module>
     <module>zeppelin-web</module>
     <module>zeppelin-server</module>
     <module>zeppelin-distribution</module>
@@ -113,6 +114,7 @@
     <hbase.version>0.94.6</hbase.version>
     <zookeeper.version>3.4.5</zookeeper.version>
     <hive.version>0.12.0</hive.version>
+    <tajo.version>0.10.0</tajo.version>
     <derby.version>10.4.2.0</derby.version>
     <parquet.version>1.4.3</parquet.version>
     <jblas.version>1.2.3</jblas.version>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/pom.xml
----------------------------------------------------------------------
diff --git a/tajo/pom.xml b/tajo/pom.xml
new file mode 100644
index 0000000..e7030f9
--- /dev/null
+++ b/tajo/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <artifactId>zeppelin</artifactId>
+    <groupId>org.apache.zeppelin</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.apache.zeppelin</groupId>
+  <artifactId>zeppelin-tajo</artifactId>
+  <packaging>jar</packaging>
+  <version>0.5.0-SNAPSHOT</version>
+  <name>Zeppelin: Tajo interpreter</name>
+  <url>http://www.apache.org</url>
+
+  <properties>
+    <protobuf.version>2.5.0</protobuf.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.zeppelin</groupId>
+      <artifactId>zeppelin-interpreter</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tajo</groupId>
+      <artifactId>tajo-jdbc</artifactId>
+      <version>${tajo.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <version>2.7</version>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <version>1.3.1</version>
+        <executions>
+          <execution>
+            <id>enforce</id>
+            <phase>none</phase>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.8</version>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/../../interpreter/tajo</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>false</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+              <includeScope>runtime</includeScope>
+            </configuration>
+          </execution>
+          <execution>
+            <id>copy-artifact</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/../../interpreter/tajo</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>false</overWriteSnapshots>
+              <overWriteIfNewer>true</overWriteIfNewer>
+              <includeScope>runtime</includeScope>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>${project.groupId}</groupId>
+                  <artifactId>${project.artifactId}</artifactId>
+                  <version>${project.version}</version>
+                  <type>${project.packaging}</type>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/main/java/org/apache/zeppelin/tajo/TajoInterpreter.java
----------------------------------------------------------------------
diff --git a/tajo/src/main/java/org/apache/zeppelin/tajo/TajoInterpreter.java b/tajo/src/main/java/org/apache/zeppelin/tajo/TajoInterpreter.java
new file mode 100644
index 0000000..d197903
--- /dev/null
+++ b/tajo/src/main/java/org/apache/zeppelin/tajo/TajoInterpreter.java
@@ -0,0 +1,195 @@
+/**
+ * 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.zeppelin.tajo;
+
+import java.sql.*;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.zeppelin.interpreter.*;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.zeppelin.interpreter.InterpreterResult.Code;
+import org.apache.zeppelin.scheduler.Scheduler;
+import org.apache.zeppelin.scheduler.SchedulerFactory;
+
+/**
+ * Tajo interpreter for Zeppelin.
+ */
+public class TajoInterpreter extends Interpreter {
+  private Logger logger = LoggerFactory.getLogger(TajoInterpreter.class);
+
+  private Connection connection;
+  private Statement statement;
+  private Exception exceptionOnConnect;
+
+  public static final String TAJO_JDBC_URI = "tajo.jdbc.uri";
+  public static final String TAJO_DRIVER_NAME = "org.apache.tajo.jdbc.TajoDriver";
+
+  static {
+    Interpreter.register(
+      "tajo",
+      "tajo",
+      TajoInterpreter.class.getName(),
+      new InterpreterPropertyBuilder()
+        .add(TAJO_JDBC_URI, "jdbc:tajo://localhost:26002/default", "The URL for TajoServer.")
+        .build());
+  }
+
+  public TajoInterpreter(Properties property) {
+    super(property);
+  }
+
+  public Connection getJdbcConnection() throws SQLException {
+    return DriverManager.getConnection(getProperty(TAJO_JDBC_URI));
+  }
+
+  @Override
+  public void open() {
+    logger.info("Jdbc open connection called!");
+    try {
+      Class.forName(TAJO_DRIVER_NAME);
+    } catch (ClassNotFoundException e) {
+      logger.error("Can not open connection", e);
+      exceptionOnConnect = e;
+      return;
+    }
+    try {
+      connection = getJdbcConnection();
+      exceptionOnConnect = null;
+      logger.info("Successfully created connection");
+    }
+    catch (SQLException e) {
+      logger.error("Cannot open connection", e);
+      exceptionOnConnect = e;
+    }
+  }
+
+  @Override
+  public void close() {
+    try {
+      if (connection != null) {
+        connection.close();
+      }
+    }
+    catch (SQLException e) {
+      logger.error("Cannot close connection", e);
+    }
+    finally {
+      connection = null;
+      exceptionOnConnect = null;
+    }
+  }
+
+  private InterpreterResult executeSql(String sql) {
+    try {
+      if (exceptionOnConnect != null) {
+        return new InterpreterResult(Code.ERROR, exceptionOnConnect.getMessage());
+      }
+      statement = connection.createStatement();
+      StringBuilder msg = null;
+      if (StringUtils.containsIgnoreCase(sql, "EXPLAIN ")) {
+        //return the explain as text, make this visual explain later
+        msg = new StringBuilder();
+      }
+      else {
+        msg = new StringBuilder("%table ");
+      }
+
+      ResultSet res = statement.executeQuery(sql);
+      try {
+        ResultSetMetaData md = res.getMetaData();
+        for (int i = 1; i < md.getColumnCount() + 1; i++) {
+          if (i == 1) {
+            msg.append(md.getColumnName(i));
+          } else {
+            msg.append("\t" + md.getColumnName(i));
+          }
+        }
+        msg.append("\n");
+        while (res.next()) {
+          for (int i = 1; i < md.getColumnCount() + 1; i++) {
+            msg.append(res.getString(i) + "\t");
+          }
+          msg.append("\n");
+        }
+      }
+      finally {
+        try {
+          res.close();
+          statement.close();
+        }
+        finally {
+          statement = null;
+        }
+      }
+
+      InterpreterResult interpreterResult = new InterpreterResult(Code.SUCCESS, msg.toString());
+      return interpreterResult;
+    }
+    catch (SQLException ex) {
+      logger.error("Can not run " + sql, ex);
+      return new InterpreterResult(Code.ERROR, ex.getMessage());
+    }
+  }
+
+  @Override
+  public InterpreterResult interpret(String cmd, InterpreterContext contextInterpreter) {
+    logger.info("Run SQL command '" + cmd + "'");
+    return executeSql(cmd);
+  }
+
+  @Override
+  public void cancel(InterpreterContext context) {
+    // Currently, Tajo doesn't provide JDBC cancel method. It will be implemented in
+    // Tajo 0.11.0 version. You can find related issue progress at TAJO-751.
+//    if (statement != null) {
+//      try {
+//        statement.cancel();
+//      }
+//      catch (SQLException ex) {
+//      }
+//      finally {
+//        statement = null;
+//      }
+//    }
+  }
+
+  @Override
+  public FormType getFormType() {
+    return FormType.SIMPLE;
+  }
+
+  @Override
+  public int getProgress(InterpreterContext context) {
+    return 0;
+  }
+
+  @Override
+  public Scheduler getScheduler() {
+    return SchedulerFactory.singleton().createOrGetFIFOScheduler(
+      TajoInterpreter.class.getName() + this.hashCode());
+  }
+
+  @Override
+  public List<String> completion(String buf, int cursor) {
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/test/java/org/apache/zeppelin/tajo/TajoInterpreterTest.java
----------------------------------------------------------------------
diff --git a/tajo/src/test/java/org/apache/zeppelin/tajo/TajoInterpreterTest.java b/tajo/src/test/java/org/apache/zeppelin/tajo/TajoInterpreterTest.java
new file mode 100644
index 0000000..abe1ca6
--- /dev/null
+++ b/tajo/src/test/java/org/apache/zeppelin/tajo/TajoInterpreterTest.java
@@ -0,0 +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.zeppelin.tajo;
+
+import com.google.gson.JsonParseException;
+import org.apache.tajo.jdbc.TajoDriver;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Tajo interpreter unit tests
+ */
+public class TajoInterpreterTest {
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void test() {
+    TajoInterpreter t = new TesterTajoInterpreter(new Properties());
+    t.open();
+
+    Class clazz;
+    try {
+      clazz = Class.forName(t.TAJO_DRIVER_NAME);
+    } catch (ClassNotFoundException e) {
+      e.printStackTrace();
+      throw new JsonParseException(e);
+    }
+
+    // check tajo jdbc driver
+    assertNotNull(clazz);
+
+    // simple select test
+    InterpreterResult result = t.interpret("select * from t", null);
+    assertEquals(result.type(), InterpreterResult.Type.TABLE);
+
+    // explain test
+    result = t.interpret("explain select * from t", null);
+    assertEquals(result.type(), InterpreterResult.Type.TEXT);
+    t.close();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/test/java/org/apache/zeppelin/tajo/TesterConnection.java
----------------------------------------------------------------------
diff --git a/tajo/src/test/java/org/apache/zeppelin/tajo/TesterConnection.java b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterConnection.java
new file mode 100644
index 0000000..e0a68e2
--- /dev/null
+++ b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterConnection.java
@@ -0,0 +1,379 @@
+/**
+ * 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.zeppelin.tajo;
+
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * This is borrowed from Apache Commons DBCP2.
+ *
+ * A dummy {@link java.sql.Connection}, for testing purposes.
+ */
+public class TesterConnection implements Connection {
+  protected boolean _open = true;
+  protected boolean _autoCommit = true;
+  protected int _transactionIsolation = 1;
+  protected DatabaseMetaData _metaData = new TesterDatabaseMetaData();
+  protected String _catalog = null;
+  protected Map<String,Class<?>> _typeMap = null;
+  protected boolean _readOnly = false;
+  protected SQLWarning warnings = null;
+  protected String username = null;
+  protected Exception failure;
+
+  public String getUsername() {
+    return this.username;
+  }
+
+  public void setWarnings(SQLWarning warning) {
+    this.warnings = warning;
+  }
+
+  @Override
+  public void clearWarnings() throws SQLException {
+    checkOpen();
+    warnings = null;
+  }
+
+  @Override
+  public void close() throws SQLException {
+    checkFailure();
+    _open = false;
+  }
+
+  @Override
+  public void commit() throws SQLException {
+    checkOpen();
+    if (isReadOnly()) {
+      throw new SQLException("Cannot commit a readonly connection");
+    }
+  }
+
+  @Override
+  public Statement createStatement() throws SQLException {
+    checkOpen();
+    return new TesterStatement(this);
+  }
+
+  @Override
+  public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+    checkOpen();
+    return new TesterStatement(this);
+  }
+
+  @Override
+  public boolean getAutoCommit() throws SQLException {
+    checkOpen();
+    return _autoCommit;
+  }
+
+  @Override
+  public String getCatalog() throws SQLException {
+    checkOpen();
+    return _catalog;
+  }
+
+  @Override
+  public DatabaseMetaData getMetaData() throws SQLException {
+    checkOpen();
+    return _metaData;
+  }
+
+  @Override
+  public int getTransactionIsolation() throws SQLException {
+    checkOpen();
+    return _transactionIsolation;
+  }
+
+  @Override
+  public Map<String,Class<?>> getTypeMap() throws SQLException {
+    checkOpen();
+    return _typeMap;
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    checkOpen();
+    return warnings;
+  }
+
+  @Override
+  public boolean isClosed() throws SQLException {
+    checkFailure();
+    return !_open;
+  }
+
+  @Override
+  public boolean isReadOnly() throws SQLException {
+    checkOpen();
+    return _readOnly;
+  }
+
+  @Override
+  public String nativeSQL(String sql) throws SQLException {
+    checkOpen();
+    return sql;
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void rollback() throws SQLException {
+    checkOpen();
+    if (isReadOnly()) {
+      throw new SQLException("Cannot rollback a readonly connection");
+    }
+  }
+
+  @Override
+  public void setAutoCommit(boolean autoCommit) throws SQLException {
+    checkOpen();
+    _autoCommit = autoCommit;
+  }
+
+  @Override
+  public void setCatalog(String catalog) throws SQLException {
+    checkOpen();
+    _catalog = catalog;
+  }
+
+  @Override
+  public void setReadOnly(boolean readOnly) throws SQLException {
+    checkOpen();
+    _readOnly = readOnly;
+  }
+
+  @Override
+  public void setTransactionIsolation(int level) throws SQLException {
+    checkOpen();
+    _transactionIsolation = level;
+  }
+
+  @Override
+  public void setTypeMap(Map<String,Class<?>> map) throws SQLException {
+    checkOpen();
+    _typeMap = map;
+  }
+
+  protected void checkOpen() throws SQLException {
+    if(!_open) {
+      throw new SQLException("Connection is closed.");
+    }
+    checkFailure();
+  }
+
+  protected void checkFailure() throws SQLException {
+    if (failure != null) {
+      if(failure instanceof SQLException) {
+        throw (SQLException)failure;
+      } else {
+        throw new SQLException("TesterConnection failure", failure);
+      }
+    }
+  }
+
+  public void setFailure(Exception failure) {
+    this.failure = failure;
+  }
+
+  @Override
+  public int getHoldability() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void setHoldability(int holdability) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public java.sql.Savepoint setSavepoint() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public java.sql.Savepoint setSavepoint(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void rollback(java.sql.Savepoint savepoint) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public Statement createStatement(int resultSetType,
+                                   int resultSetConcurrency,
+                                   int resultSetHoldability)
+    throws SQLException {
+    return createStatement();
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int resultSetType,
+                                            int resultSetConcurrency,
+                                            int resultSetHoldability)
+    throws SQLException {
+    return prepareStatement(sql);
+  }
+
+  @Override
+  public CallableStatement prepareCall(String sql, int resultSetType,
+                                       int resultSetConcurrency,
+                                       int resultSetHoldability)
+    throws SQLException {
+    return prepareCall(sql);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+    throws SQLException {
+    return prepareStatement(sql);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, int columnIndexes[])
+    throws SQLException {
+    return prepareStatement(sql);
+  }
+
+  @Override
+  public PreparedStatement prepareStatement(String sql, String columnNames[])
+    throws SQLException {
+    return prepareStatement(sql);
+  }
+
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public Blob createBlob() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public Clob createClob() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public NClob createNClob() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public SQLXML createSQLXML() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean isValid(int timeout) throws SQLException {
+    return _open;
+  }
+
+  @Override
+  public void setClientInfo(String name, String value) throws SQLClientInfoException {
+    throw new SQLClientInfoException();
+  }
+
+  @Override
+  public void setClientInfo(Properties properties) throws SQLClientInfoException {
+    throw new SQLClientInfoException();
+  }
+
+  @Override
+  public Properties getClientInfo() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public String getClientInfo(String name) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void setSchema(String schema) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public String getSchema() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void abort(Executor executor) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void setNetworkTimeout(Executor executor, int milliseconds)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public int getNetworkTimeout() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/test/java/org/apache/zeppelin/tajo/TesterDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/tajo/src/test/java/org/apache/zeppelin/tajo/TesterDatabaseMetaData.java b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterDatabaseMetaData.java
new file mode 100644
index 0000000..b293991
--- /dev/null
+++ b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterDatabaseMetaData.java
@@ -0,0 +1,950 @@
+/**
+ * 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.zeppelin.tajo;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+
+/**
+ * This is borrowed from Apache Commons DBCP2.
+ *
+ * Dummy {@link DatabaseMetaData} for testing purposes. Implements only those
+ * methods required by the test cases.
+ */
+public class TesterDatabaseMetaData implements DatabaseMetaData {
+
+  @Override
+  public boolean allProceduresAreCallable() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean allTablesAreSelectable() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean deletesAreDetected(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public ResultSet getAttributes(String catalog, String schemaPattern,
+                                 String typeNamePattern, String attributeNamePattern)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getBestRowIdentifier(String catalog, String schema,
+                                        String table, int scope, boolean nullable) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getCatalogSeparator() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getCatalogTerm() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getCatalogs() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getColumnPrivileges(String catalog, String schema,
+                                       String table, String columnNamePattern) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getColumns(String catalog, String schemaPattern,
+                              String tableNamePattern, String columnNamePattern)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public Connection getConnection() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getCrossReference(String parentCatalog,
+                                     String parentSchema, String parentTable, String foreignCatalog,
+                                     String foreignSchema, String foreignTable) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public int getDatabaseMajorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getDatabaseMinorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public String getDatabaseProductName() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getDatabaseProductVersion() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public int getDefaultTransactionIsolation() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getDriverMajorVersion() {
+    return 0;
+  }
+
+  @Override
+  public int getDriverMinorVersion() {
+    return 0;
+  }
+
+  @Override
+  public String getDriverName() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getDriverVersion() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getExportedKeys(String catalog, String schema, String table)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getExtraNameCharacters() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getIdentifierQuoteString() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getImportedKeys(String catalog, String schema, String table)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getIndexInfo(String catalog, String schema, String table,
+                                boolean unique, boolean approximate) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public int getJDBCMajorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getJDBCMinorVersion() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxBinaryLiteralLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxCatalogNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxCharLiteralLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxColumnNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxColumnsInGroupBy() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxColumnsInIndex() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxColumnsInOrderBy() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxColumnsInSelect() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxColumnsInTable() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxConnections() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxCursorNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxIndexLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxProcedureNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxRowSize() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxSchemaNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxStatementLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxStatements() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxTableNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxTablesInSelect() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getMaxUserNameLength() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public String getNumericFunctions() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getPrimaryKeys(String catalog, String schema, String table)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getProcedureColumns(String catalog, String schemaPattern,
+                                       String procedureNamePattern, String columnNamePattern)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getProcedureTerm() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getProcedures(String catalog, String schemaPattern,
+                                 String procedureNamePattern) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public int getResultSetHoldability() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public String getSQLKeywords() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public int getSQLStateType() throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public String getSchemaTerm() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getSchemas() throws SQLException {
+    return new TesterResultSet(null);
+  }
+
+  @Override
+  public String getSearchStringEscape() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getStringFunctions() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getSuperTables(String catalog, String schemaPattern,
+                                  String tableNamePattern) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getSuperTypes(String catalog, String schemaPattern,
+                                 String typeNamePattern) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getSystemFunctions() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getTablePrivileges(String catalog, String schemaPattern,
+                                      String tableNamePattern) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getTableTypes() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getTables(String catalog, String schemaPattern,
+                             String tableNamePattern, String[] types) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getTimeDateFunctions() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getTypeInfo() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getUDTs(String catalog, String schemaPattern,
+                           String typeNamePattern, int[] types) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getURL() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getUserName() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getVersionColumns(String catalog, String schema,
+                                     String table) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public boolean insertsAreDetected(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isCatalogAtStart() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isReadOnly() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean locatorsUpdateCopy() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullPlusNonNullIsNull() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedAtEnd() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedAtStart() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedHigh() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedLow() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean othersDeletesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean othersInsertsAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean othersUpdatesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean ownDeletesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean ownInsertsAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean ownUpdatesAreVisible(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesLowerCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesMixedCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesUpperCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsANSI92FullSQL() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsANSI92IntermediateSQL() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsAlterTableWithAddColumn() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsAlterTableWithDropColumn() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsBatchUpdates() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsColumnAliasing() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsConvert() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsConvert(int fromType, int toType)
+    throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCoreSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsCorrelatedSubqueries() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsDataDefinitionAndDataManipulationTransactions()
+    throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsDataManipulationTransactionsOnly()
+    throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsExpressionsInOrderBy() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsExtendedSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsFullOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsGetGeneratedKeys() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsGroupBy() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsGroupByBeyondSelect() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsGroupByUnrelated() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsLikeEscapeClause() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsLimitedOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMinimumSQLGrammar() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMultipleOpenResults() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMultipleResultSets() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMultipleTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsNamedParameters() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsNonNullableColumns() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOrderByUnrelated() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsOuterJoins() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsPositionedDelete() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsPositionedUpdate() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsResultSetConcurrency(int type, int concurrency)
+    throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsResultSetHoldability(int holdability)
+    throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsResultSetType(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSavepoints() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSchemasInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSelectForUpdate() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsStatementPooling() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsStoredProcedures() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInComparisons() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInExists() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInIns() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsTableCorrelationNames() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsTransactionIsolationLevel(int level)
+    throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsTransactions() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsUnion() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsUnionAll() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean updatesAreDetected(int type) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean usesLocalFilePerTable() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean usesLocalFiles() throws SQLException {
+    return false;
+  }
+
+    /* JDBC_4_ANT_KEY_BEGIN */
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public RowIdLifetime getRowIdLifetime() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getSchemas(String catalog, String schemaPattern)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public ResultSet getClientInfoProperties() throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getFunctionColumns(String catalog, String schemaPattern,
+                                      String functionNamePattern, String columnNamePattern)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public ResultSet getFunctions(String catalog, String schemaPattern,
+                                String functionNamePattern) throws SQLException {
+    return null;
+  }
+
+    /* JDBC_4_ANT_KEY_END */
+
+  @Override
+  public ResultSet getPseudoColumns(String catalog, String schemaPattern,
+                                    String tableNamePattern, String columnNamePattern)
+    throws SQLException {
+    return null;
+  }
+
+  @Override
+  public boolean generatedKeyAlwaysReturned() throws SQLException {
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSet.java
----------------------------------------------------------------------
diff --git a/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSet.java b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSet.java
new file mode 100644
index 0000000..dc174be
--- /dev/null
+++ b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSet.java
@@ -0,0 +1,1163 @@
+/**
+ * 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.zeppelin.tajo;
+
+import java.math.BigDecimal;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.Map;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * This is borrowed from Apache Commons DBCP2.
+ *
+ * A dummy {@link java.sql.ResultSet}, for testing purposes.
+ */
+public class TesterResultSet implements ResultSet {
+  public TesterResultSet(Statement stmt) {
+    _statement = stmt;
+  }
+
+  public TesterResultSet(Statement stmt, Object[][] data) {
+    _statement = stmt;
+    _data = data;
+  }
+
+  public TesterResultSet(Statement stmt, int type, int concurrency) {
+    _statement = stmt;
+    _data = null;
+    _type = type;
+    _concurrency = concurrency;
+  }
+
+  protected int _type = ResultSet.TYPE_FORWARD_ONLY;
+  protected int _concurrency = ResultSet.CONCUR_READ_ONLY;
+
+  protected Object[][] _data = null;
+  protected int _currentRow = -1;
+
+  protected Statement _statement = null;
+  protected int _rowsLeft = 2;
+  protected boolean _open = true;
+
+  @Override
+  public boolean next() throws SQLException {
+    checkOpen();
+    if (_data != null) {
+      _currentRow++;
+      return _currentRow < _data.length;
+    }
+    else {
+      if(--_rowsLeft > 0) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+
+  @Override
+  public void close() throws SQLException {
+    if (!_open) {
+      return;
+    }
+
+    // Not all result sets are generated from statements eg DatabaseMetaData
+    if (_statement != null) {
+      ((TesterStatement)_statement)._resultSet = null;
+    }
+
+    _open = false;
+  }
+
+  @Override
+  public boolean wasNull() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public String getString(int columnIndex) throws SQLException {
+    checkOpen();
+    if (columnIndex == -1) {
+      throw new SQLException("broken connection");
+    }
+    if (_data != null) {
+      return (String) getObject(columnIndex);
+    }
+    return "String" + columnIndex;
+  }
+
+  @Override
+  public boolean getBoolean(int columnIndex) throws SQLException {
+    checkOpen();
+    return true;
+  }
+
+  @Override
+  public byte getByte(int columnIndex) throws SQLException {
+    checkOpen();
+    return (byte)columnIndex;
+  }
+
+  @Override
+  public short getShort(int columnIndex) throws SQLException {
+    checkOpen();
+    return (short)columnIndex;
+  }
+
+  @Override
+  public int getInt(int columnIndex) throws SQLException {
+    checkOpen();
+    return (short)columnIndex;
+  }
+
+  @Override
+  public long getLong(int columnIndex) throws SQLException {
+    checkOpen();
+    return columnIndex;
+  }
+
+  @Override
+  public float getFloat(int columnIndex) throws SQLException {
+    checkOpen();
+    return columnIndex;
+  }
+
+  @Override
+  public double getDouble(int columnIndex) throws SQLException {
+    checkOpen();
+    return columnIndex;
+  }
+
+  /** @deprecated */
+  @Deprecated
+  @Override
+  public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
+    checkOpen();
+    return new BigDecimal(columnIndex);
+  }
+
+  @Override
+  public byte[] getBytes(int columnIndex) throws SQLException {
+    checkOpen();
+    return new byte[] { (byte)columnIndex };
+  }
+
+  @Override
+  public java.sql.Date getDate(int columnIndex) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Time getTime(int columnIndex) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  /** @deprecated */
+  @Deprecated
+  @Override
+  public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public String getString(String columnName) throws SQLException {
+    checkOpen();
+    return columnName;
+  }
+
+  @Override
+  public boolean getBoolean(String columnName) throws SQLException {
+    checkOpen();
+    return true;
+  }
+
+  @Override
+  public byte getByte(String columnName) throws SQLException {
+    checkOpen();
+    return (byte)columnName.hashCode();
+  }
+
+  @Override
+  public short getShort(String columnName) throws SQLException {
+    checkOpen();
+    return (short)columnName.hashCode();
+  }
+
+  @Override
+  public int getInt(String columnName) throws SQLException {
+    checkOpen();
+    return columnName.hashCode();
+  }
+
+  @Override
+  public long getLong(String columnName) throws SQLException {
+    checkOpen();
+    return columnName.hashCode();
+  }
+
+  @Override
+  public float getFloat(String columnName) throws SQLException {
+    checkOpen();
+    return columnName.hashCode();
+  }
+
+  @Override
+  public double getDouble(String columnName) throws SQLException {
+    checkOpen();
+    return columnName.hashCode();
+  }
+
+  /** @deprecated */
+  @Deprecated
+  @Override
+  public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
+    checkOpen();
+    return new BigDecimal(columnName.hashCode());
+  }
+
+  @Override
+  public byte[] getBytes(String columnName) throws SQLException {
+    checkOpen();
+    try {
+      return columnName.getBytes("UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      // Impossible. JVMs are required to support UTF-8
+      return null;
+    }
+  }
+
+  @Override
+  public java.sql.Date getDate(String columnName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Time getTime(String columnName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.io.InputStream getAsciiStream(String columnName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  /** @deprecated */
+  @Deprecated
+  @Override
+  public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.io.InputStream getBinaryStream(String columnName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public void clearWarnings() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public String getCursorName() throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public ResultSetMetaData getMetaData() throws SQLException {
+    checkOpen();
+    return new TesterResultSetMetaData();
+  }
+
+  @Override
+  public Object getObject(int columnIndex) throws SQLException {
+    checkOpen();
+    if (_data != null) {
+      return _data[_currentRow][columnIndex-1];
+    }
+    return new Object();
+  }
+
+  @Override
+  public Object getObject(String columnName) throws SQLException {
+    checkOpen();
+    return columnName;
+  }
+
+  @Override
+  public int findColumn(String columnName) throws SQLException {
+    checkOpen();
+    return 1;
+  }
+
+
+  @Override
+  public java.io.Reader getCharacterStream(int columnIndex) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.io.Reader getCharacterStream(String columnName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+    checkOpen();
+    return new BigDecimal(columnIndex);
+  }
+
+  @Override
+  public BigDecimal getBigDecimal(String columnName) throws SQLException {
+    checkOpen();
+    return new BigDecimal(columnName.hashCode());
+  }
+
+  @Override
+  public boolean isBeforeFirst() throws SQLException {
+    checkOpen();
+    return _rowsLeft == 2;
+  }
+
+  @Override
+  public boolean isAfterLast() throws SQLException {
+    checkOpen();
+    return _rowsLeft < 0;
+  }
+
+  @Override
+  public boolean isFirst() throws SQLException {
+    checkOpen();
+    return _rowsLeft == 1;
+  }
+
+  @Override
+  public boolean isLast() throws SQLException {
+    checkOpen();
+    return _rowsLeft == 0;
+  }
+
+  @Override
+  public void beforeFirst() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void afterLast() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public boolean first() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public boolean last() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public int getRow() throws SQLException {
+    checkOpen();
+    return 3 - _rowsLeft;
+  }
+
+  @Override
+  public boolean absolute( int row ) throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public boolean relative( int rows ) throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public boolean previous() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public void setFetchDirection(int direction) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public int getFetchDirection() throws SQLException {
+    checkOpen();
+    return 1;
+  }
+
+  @Override
+  public void setFetchSize(int rows) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public int getFetchSize() throws SQLException {
+    checkOpen();
+    return 2;
+  }
+
+  @Override
+  public int getType() throws SQLException {
+    return this._type;
+  }
+
+  @Override
+  public int getConcurrency() throws SQLException {
+    return this._concurrency;
+  }
+
+  @Override
+  public boolean rowUpdated() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public boolean rowInserted() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public boolean rowDeleted() throws SQLException {
+    checkOpen();
+    return false;
+  }
+
+  @Override
+  public void updateNull(int columnIndex) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateByte(int columnIndex, byte x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateShort(int columnIndex, short x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateInt(int columnIndex, int x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateLong(int columnIndex, long x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateFloat(int columnIndex, float x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateDouble(int columnIndex, double x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateString(int columnIndex, String x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBytes(int columnIndex, byte x[]) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateDate(int columnIndex, java.sql.Date x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateTime(int columnIndex, java.sql.Time x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException {
+    checkOpen();
+  }
+
+
+  @Override
+  public void updateAsciiStream(int columnIndex,
+                                java.io.InputStream x,
+                                int length) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex,
+                                 java.io.InputStream x,
+                                 int length) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex,
+                                    java.io.Reader x,
+                                    int length) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x, int scale)
+    throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateObject(int columnIndex, Object x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateNull(String columnName) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBoolean(String columnName, boolean x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateByte(String columnName, byte x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateShort(String columnName, short x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateInt(String columnName, int x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateLong(String columnName, long x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateFloat(String columnName, float x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateDouble(String columnName, double x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateString(String columnName, String x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBytes(String columnName, byte x[]) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateDate(String columnName, java.sql.Date x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateTime(String columnName, java.sql.Time x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateTimestamp(String columnName, java.sql.Timestamp x)
+    throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateAsciiStream(String columnName,
+                                java.io.InputStream x,
+                                int length) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateBinaryStream(String columnName,
+                                 java.io.InputStream x,
+                                 int length) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateCharacterStream(String columnName,
+                                    java.io.Reader reader,
+                                    int length) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateObject(String columnName, Object x, int scale)
+    throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateObject(String columnName, Object x) throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void insertRow() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void updateRow() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void deleteRow() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void refreshRow() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void cancelRowUpdates() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void moveToInsertRow() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public void moveToCurrentRow() throws SQLException {
+    checkOpen();
+  }
+
+  @Override
+  public Statement getStatement() throws SQLException {
+    checkOpen();
+    return _statement;
+  }
+
+
+  @Override
+  public Object getObject(int i, Map<String,Class<?>> map) throws SQLException {
+    checkOpen();
+    return new Object();
+  }
+
+  @Override
+  public Ref getRef(int i) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public Blob getBlob(int i) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public Clob getClob(int i) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public Array getArray(int i) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public Object getObject(String colName, Map<String,Class<?>> map) throws SQLException {
+    checkOpen();
+    return colName;
+  }
+
+  @Override
+  public Ref getRef(String colName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public Blob getBlob(String colName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public Clob getClob(String colName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public Array getArray(String colName) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  @Override
+  public java.sql.Timestamp getTimestamp(String columnName, Calendar cal)
+    throws SQLException {
+    checkOpen();
+    return null;
+  }
+
+  protected void checkOpen() throws SQLException {
+    if(!_open) {
+      throw new SQLException("ResultSet is closed.");
+    }
+  }
+
+  @Override
+  public java.net.URL getURL(int columnIndex) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public java.net.URL getURL(String columnName) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateRef(int columnIndex, java.sql.Ref x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateRef(String columnName, java.sql.Ref x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, java.sql.Blob x) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBlob(String columnName, java.sql.Blob x)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateClob(int columnIndex, java.sql.Clob x)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateClob(String columnName, java.sql.Clob x)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateArray(int columnIndex, java.sql.Array x)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateArray(String columnName, java.sql.Array x)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public RowId getRowId(int columnIndex) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public RowId getRowId(String columnLabel) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateRowId(int columnIndex, RowId value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateRowId(String columnLabel, RowId value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public int getHoldability() throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean isClosed() throws SQLException {
+    return !_open;
+  }
+
+  @Override
+  public void updateNString(int columnIndex, String value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNString(String columnLabel, String value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, NClob value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, NClob value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public NClob getNClob(int columnIndex) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public NClob getNClob(String columnLabel) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public SQLXML getSQLXML(int columnIndex) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public SQLXML getSQLXML(String columnLabel) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateSQLXML(int columnIndex, SQLXML value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateSQLXML(String columnLabel, SQLXML value) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public String getNString(int columnIndex) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public String getNString(String columnLabel) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public Reader getNCharacterStream(int columnIndex) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public Reader getNCharacterStream(String columnLabel) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNCharacterStream(int columnIndex, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream inputStream, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream inputStream, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream inputStream, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream inputStream, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNCharacterStream(int columnIndex, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateAsciiStream(int columnIndex, InputStream inputStream) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBinaryStream(int columnIndex, InputStream inputStream) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateCharacterStream(int columnIndex, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateAsciiStream(String columnLabel, InputStream inputStream) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBinaryStream(String columnLabel, InputStream inputStream) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateClob(int columnIndex, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateClob(String columnLabel, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public void updateNClob(String columnLabel, Reader reader) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public <T> T getObject(String columnLabel, Class<T> type)
+    throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/3a4ab1ad/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSetMetaData.java
----------------------------------------------------------------------
diff --git a/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSetMetaData.java b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSetMetaData.java
new file mode 100644
index 0000000..d11e22f
--- /dev/null
+++ b/tajo/src/test/java/org/apache/zeppelin/tajo/TesterResultSetMetaData.java
@@ -0,0 +1,157 @@
+/**
+ * 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.zeppelin.tajo;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A dummy {@link java.sql.ResultSetMetaData}, for testing purposes.
+ */
+public class TesterResultSetMetaData implements ResultSetMetaData {
+
+  // Dummy columns
+  private List<String> columns = null;
+
+  public TesterResultSetMetaData() {
+    columns = new ArrayList<String>();
+    columns.add("id");
+    columns.add("name");
+    columns.add("score");
+    columns.add("type");
+  }
+
+  @Override
+  public int getColumnCount() throws SQLException {
+    return columns.size();
+  }
+
+  @Override
+  public boolean isAutoIncrement(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isCaseSensitive(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isSearchable(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isCurrency(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public int isNullable(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public boolean isSigned(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public int getColumnDisplaySize(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public String getColumnLabel(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public String getColumnName(int column) throws SQLException {
+    return columns.get(column - 1);
+  }
+
+  @Override
+  public String getSchemaName(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public int getPrecision(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public int getScale(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public String getTableName(int column) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public String getCatalogName(int column) throws SQLException {
+    return null;
+  }
+
+  @Override
+  public int getColumnType(int column) throws SQLException {
+    return 0;
+  }
+
+  @Override
+  public String getColumnTypeName(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean isReadOnly(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isWritable(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean isDefinitelyWritable(int column) throws SQLException {
+    return false;
+  }
+
+  @Override
+  public String getColumnClassName(int column) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw new SQLFeatureNotSupportedException("Not supported.");
+  }
+
+  @Override
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    return false;
+  }
+}