You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ha...@apache.org on 2013/03/12 19:22:03 UTC

svn commit: r1455659 [5/11] - in /hive/trunk: ./ ant/src/org/apache/hadoop/hive/ant/ bin/ bin/ext/ cli/ common/ common/src/gen/ common/src/gen/org/ common/src/gen/org/apache/ common/src/gen/org/apache/hive/ common/src/gen/org/apache/hive/common/ common...

Added: hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDatabaseMetaData.java
URL: http://svn.apache.org/viewvc/hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDatabaseMetaData.java?rev=1455659&view=auto
==============================================================================
--- hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDatabaseMetaData.java (added)
+++ hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDatabaseMetaData.java Tue Mar 12 18:22:00 2013
@@ -0,0 +1,1097 @@
+/**
+ * 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.hive.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.jar.Attributes;
+
+import org.apache.hadoop.hive.metastore.TableType;
+import org.apache.hive.service.cli.thrift.TGetCatalogsReq;
+import org.apache.hive.service.cli.thrift.TGetCatalogsResp;
+import org.apache.hive.service.cli.thrift.TGetColumnsReq;
+import org.apache.hive.service.cli.thrift.TGetColumnsResp;
+import org.apache.hive.service.cli.thrift.TGetFunctionsReq;
+import org.apache.hive.service.cli.thrift.TGetFunctionsResp;
+import org.apache.hive.service.cli.thrift.TGetSchemasReq;
+import org.apache.hive.service.cli.thrift.TGetSchemasResp;
+import org.apache.hive.service.cli.thrift.TGetTableTypesReq;
+import org.apache.hive.service.cli.thrift.TGetTableTypesResp;
+import org.apache.hive.service.cli.thrift.TGetTablesReq;
+import org.apache.hive.service.cli.thrift.TGetTablesResp;
+import org.apache.hive.service.cli.thrift.TGetTypeInfoReq;
+import org.apache.hive.service.cli.thrift.TGetTypeInfoResp;
+import org.apache.hive.service.cli.thrift.TCLIService;
+import org.apache.hive.service.cli.thrift.TSessionHandle;
+import org.apache.thrift.TException;
+
+/**
+ * HiveDatabaseMetaData.
+ *
+ */
+public class HiveDatabaseMetaData implements DatabaseMetaData {
+
+  private final TCLIService.Iface client;
+  private final TSessionHandle sessHandle;
+  private static final String CATALOG_SEPARATOR = ".";
+
+  private static final char SEARCH_STRING_ESCAPE = '\\';
+
+  //  The maximum column length = MFieldSchema.FNAME in metastore/src/model/package.jdo
+  private static final int maxColumnNameLength = 128;
+
+  /**
+   *
+   */
+  public HiveDatabaseMetaData(TCLIService.Iface client, TSessionHandle sessHandle) {
+    this.client = client;
+    this.sessHandle = sessHandle;
+  }
+
+  public boolean allProceduresAreCallable() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean allTablesAreSelectable() throws SQLException {
+    return true;
+  }
+
+  public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean deletesAreDetected(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getAttributes(String catalog, String schemaPattern,
+      String typeNamePattern, String attributeNamePattern) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getBestRowIdentifier(String catalog, String schema,
+      String table, int scope, boolean nullable) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public String getCatalogSeparator() throws SQLException {
+    return CATALOG_SEPARATOR;
+  }
+
+  public String getCatalogTerm() throws SQLException {
+    return "instance";
+  }
+
+  public ResultSet getCatalogs() throws SQLException {
+    TGetCatalogsResp catalogResp;
+
+    try {
+      catalogResp = client.GetCatalogs(new TGetCatalogsReq(sessHandle));
+    } catch (TException e) {
+      throw new SQLException(e.getMessage(), "08S01");
+    }
+    Utils.verifySuccess(catalogResp.getStatus());
+
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setSessionHandle(sessHandle)
+    .setStmtHandle(catalogResp.getOperationHandle())
+    .build();
+  }
+
+  public ResultSet getClientInfoProperties() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getColumnPrivileges(String catalog, String schema,
+      String table, String columnNamePattern) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  /**
+   * Convert a pattern containing JDBC catalog search wildcards into
+   * Java regex patterns.
+   *
+   * @param pattern input which may contain '%' or '_' wildcard characters, or
+   * these characters escaped using {@link #getSearchStringEscape()}.
+   * @return replace %/_ with regex search characters, also handle escaped
+   * characters.
+   */
+  private String convertPattern(final String pattern) {
+    if (pattern==null) {
+      return ".*";
+    } else {
+      StringBuilder result = new StringBuilder(pattern.length());
+
+      boolean escaped = false;
+      for (int i = 0, len = pattern.length(); i < len; i++) {
+        char c = pattern.charAt(i);
+        if (escaped) {
+          if (c != SEARCH_STRING_ESCAPE) {
+            escaped = false;
+          }
+          result.append(c);
+        } else {
+          if (c == SEARCH_STRING_ESCAPE) {
+            escaped = true;
+            continue;
+          } else if (c == '%') {
+            result.append(".*");
+          } else if (c == '_') {
+            result.append('.');
+          } else {
+            result.append(Character.toLowerCase(c));
+          }
+        }
+      }
+
+      return result.toString();
+    }
+  }
+
+  public ResultSet getColumns(String catalog, String schemaPattern,
+      String tableNamePattern, String columnNamePattern) throws SQLException {
+    TGetColumnsResp colResp;
+    TGetColumnsReq colReq = new TGetColumnsReq();
+    colReq.setSessionHandle(sessHandle);
+    colReq.setCatalogName(catalog);
+    colReq.setSchemaName(schemaPattern);
+    colReq.setTableName(tableNamePattern);
+    colReq.setColumnName(columnNamePattern);
+    try {
+      colResp = client.GetColumns(colReq);
+    } catch (TException e) {
+      throw new SQLException(e.getMessage(), "08S01");
+    }
+    Utils.verifySuccess(colResp.getStatus());
+    // build the resultset from response
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setSessionHandle(sessHandle)
+    .setStmtHandle(colResp.getOperationHandle())
+    .build();
+  }
+
+  /**
+   * We sort the output of getColumns to guarantee jdbc compliance.
+   * First check by table name then by ordinal position
+   */
+  private class GetColumnsComparator implements Comparator<JdbcColumn> {
+
+    public int compare(JdbcColumn o1, JdbcColumn o2) {
+      int compareName = o1.getTableName().compareTo(o2.getTableName());
+      if (compareName==0) {
+        if (o1.getOrdinalPos() > o2.getOrdinalPos()) {
+          return 1;
+        } else if (o1.getOrdinalPos() < o2.getOrdinalPos()) {
+          return -1;
+        }
+        return 0;
+      } else {
+        return compareName;
+      }
+    }
+  }
+
+  public Connection getConnection() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getCrossReference(String primaryCatalog,
+      String primarySchema, String primaryTable, String foreignCatalog,
+      String foreignSchema, String foreignTable) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getDatabaseMajorVersion() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getDatabaseMinorVersion() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public String getDatabaseProductName() throws SQLException {
+    return "Hive";
+  }
+
+  public String getDatabaseProductVersion() throws SQLException {
+    // TODO: Fetch this from the server side
+    return "0.10.0";
+  }
+
+  public int getDefaultTransactionIsolation() throws SQLException {
+    return Connection.TRANSACTION_NONE;
+  }
+
+  public int getDriverMajorVersion() {
+    return HiveDriver.getMajorDriverVersion();
+  }
+
+  public int getDriverMinorVersion() {
+    return HiveDriver.getMinorDriverVersion();
+  }
+
+  public String getDriverName() throws SQLException {
+    return HiveDriver.fetchManifestAttribute(Attributes.Name.IMPLEMENTATION_TITLE);
+  }
+
+  public String getDriverVersion() throws SQLException {
+    return HiveDriver.fetchManifestAttribute(Attributes.Name.IMPLEMENTATION_VERSION);
+  }
+
+  public ResultSet getExportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public String getExtraNameCharacters() throws SQLException {
+    // TODO: verify that this is correct
+    return "";
+  }
+
+  public ResultSet getFunctionColumns(String arg0, String arg1, String arg2,
+      String arg3) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getFunctions(String catalogName, String schemaPattern, String functionNamePattern)
+      throws SQLException {
+    TGetFunctionsResp funcResp;
+    TGetFunctionsReq getFunctionsReq = new TGetFunctionsReq();
+    getFunctionsReq.setSessionHandle(sessHandle);
+    getFunctionsReq.setCatalogName(catalogName);
+    getFunctionsReq.setSchemaName(schemaPattern);
+    getFunctionsReq.setFunctionName(functionNamePattern);
+
+    try {
+      funcResp = client.GetFunctions(getFunctionsReq);
+    } catch (TException e) {
+      throw new SQLException(e.getMessage(), "08S01");
+    }
+    Utils.verifySuccess(funcResp.getStatus());
+
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setSessionHandle(sessHandle)
+    .setStmtHandle(funcResp.getOperationHandle())
+    .build();
+  }
+
+  public String getIdentifierQuoteString() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getImportedKeys(String catalog, String schema, String table)
+      throws SQLException {
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setEmptyResultSet(true)
+    .setSchema(
+        Arrays.asList(
+            "PKTABLE_CAT",
+            "PKTABLE_SCHEM",
+            "PKTABLE_NAME",
+            "PKCOLUMN_NAME",
+            "FKTABLE_CAT",
+            "FKTABLE_SCHEM",
+            "FKTABLE_NAME",
+            "FKCOLUMN_NAME",
+            "KEY_SEQ",
+            "UPDATE_RULE",
+            "DELETE_RULE",
+            "FK_NAME",
+            "PK_NAME",
+            "DEFERRABILITY"),
+        Arrays.asList(
+            "STRING",
+            "STRING",
+            "STRING",
+            "STRING",
+            "STRING",
+            "STRING",
+            "STRING",
+            "STRING",
+            "SMALLINT",
+            "SMALLINT",
+            "SMALLINT",
+            "STRING",
+            "STRING",
+            "STRING"))
+            .build();
+  }
+
+  public ResultSet getIndexInfo(String catalog, String schema, String table,
+      boolean unique, boolean approximate) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getJDBCMajorVersion() throws SQLException {
+    return 3;
+  }
+
+  public int getJDBCMinorVersion() throws SQLException {
+    return 0;
+  }
+
+  public int getMaxBinaryLiteralLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxCatalogNameLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxCharLiteralLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  /**
+   *  Returns the value of maxColumnNameLength.
+   *
+   */
+  public int getMaxColumnNameLength() throws SQLException {
+    return maxColumnNameLength;
+  }
+
+  public int getMaxColumnsInGroupBy() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxColumnsInIndex() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxColumnsInOrderBy() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxColumnsInSelect() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxColumnsInTable() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxConnections() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxCursorNameLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxIndexLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxProcedureNameLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxRowSize() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxSchemaNameLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxStatementLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxStatements() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxTableNameLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxTablesInSelect() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getMaxUserNameLength() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public String getNumericFunctions() throws SQLException {
+    return "";
+  }
+
+  public ResultSet getPrimaryKeys(String catalog, String schema, String table)
+      throws SQLException {
+    // Hive doesn't support primary keys
+    // using local schema with empty resultset
+    return new HiveQueryResultSet.Builder().setClient(client).setEmptyResultSet(true).
+        setSchema(Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "KEY_SEQ", "PK_NAME" ),
+            Arrays.asList("STRING",    "STRING",      "STRING",     "STRING",       "INT",  "STRING"))
+            .build();
+  }
+
+  public ResultSet getProcedureColumns(String catalog, String schemaPattern,
+      String procedureNamePattern, String columnNamePattern)
+      throws SQLException {
+    // Hive doesn't support primary keys
+    // using local schema with empty resultset
+    return new HiveQueryResultSet.Builder().setClient(client).setEmptyResultSet(true).
+                  setSchema(
+                    Arrays.asList("PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME", "COLUMN_NAME", "COLUMN_TYPE",
+                              "DATA_TYPE", "TYPE_NAME", "PRECISION", "LENGTH", "SCALE", "RADIX", "NULLABLE", "REMARKS",
+                              "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION",
+                              "IS_NULLABLE", "SPECIFIC_NAME"),
+                    Arrays.asList("STRING", "STRING", "STRING", "STRING", "SMALLINT", "INT",
+                              "STRING", "INT", "INT", "SMALLINT", "SMALLINT", "SMALLINT", "STRING", "STRING",
+                              "INT", "INT", "INT", "INT",
+                              "STRING", "STRING"))
+                  .build();
+  }
+
+  public String getProcedureTerm() throws SQLException {
+    return new String("UDF");
+  }
+
+  public ResultSet getProcedures(String catalog, String schemaPattern,
+      String procedureNamePattern) throws SQLException {
+    // Hive doesn't support primary keys
+    // using local schema with empty resultset
+    return new HiveQueryResultSet.Builder().setClient(client).setEmptyResultSet(true).
+                  setSchema(
+                    Arrays.asList("PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME", "RESERVERD", "RESERVERD",
+                                  "RESERVERD", "REMARKS", "PROCEDURE_TYPE", "SPECIFIC_NAME"),
+                    Arrays.asList("STRING", "STRING", "STRING", "STRING", "STRING",
+                                  "STRING", "STRING", "SMALLINT", "STRING"))
+                  .build();
+  }
+
+  public int getResultSetHoldability() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public RowIdLifetime getRowIdLifetime() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public String getSQLKeywords() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public int getSQLStateType() throws SQLException {
+    return DatabaseMetaData.sqlStateSQL99;
+  }
+
+  public String getSchemaTerm() throws SQLException {
+    return "database";
+  }
+
+  public ResultSet getSchemas() throws SQLException {
+    return getSchemas(null, null);
+  }
+
+  public ResultSet getSchemas(String catalog, String schemaPattern)
+      throws SQLException {
+    TGetSchemasResp schemaResp;
+
+    TGetSchemasReq schemaReq = new TGetSchemasReq();
+    schemaReq.setSessionHandle(sessHandle);
+    if (catalog != null) {
+      schemaReq.setCatalogName(catalog);
+    }
+    if (schemaPattern == null) {
+      schemaPattern = "%";
+    }
+    schemaReq.setSchemaName(schemaPattern);
+
+    try {
+      schemaResp = client.GetSchemas(schemaReq);
+    } catch (TException e) {
+      throw new SQLException(e.getMessage(), "08S01");
+    }
+    Utils.verifySuccess(schemaResp.getStatus());
+
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setSessionHandle(sessHandle)
+    .setStmtHandle(schemaResp.getOperationHandle())
+    .build();
+  }
+
+  public String getSearchStringEscape() throws SQLException {
+    return String.valueOf(SEARCH_STRING_ESCAPE);
+  }
+
+  public String getStringFunctions() throws SQLException {
+    return "";
+  }
+
+  public ResultSet getSuperTables(String catalog, String schemaPattern,
+      String tableNamePattern) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getSuperTypes(String catalog, String schemaPattern,
+      String typeNamePattern) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public String getSystemFunctions() throws SQLException {
+    return "";
+  }
+
+  public ResultSet getTablePrivileges(String catalog, String schemaPattern,
+      String tableNamePattern) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getTableTypes() throws SQLException {
+    TGetTableTypesResp tableTypeResp;
+
+    try {
+      tableTypeResp = client.GetTableTypes(new TGetTableTypesReq(sessHandle));
+    } catch (TException e) {
+      throw new SQLException(e.getMessage(), "08S01");
+    }
+    Utils.verifySuccess(tableTypeResp.getStatus());
+
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setSessionHandle(sessHandle)
+    .setStmtHandle(tableTypeResp.getOperationHandle())
+    .build();
+  }
+
+  public ResultSet getTables(String catalog, String schemaPattern,
+                             String tableNamePattern, String[] types) throws SQLException {
+    TGetTablesResp getTableResp;
+    if (schemaPattern == null) {
+      // if schemaPattern is null it means that the schemaPattern value should not be used to narrow the search
+      schemaPattern = "%";
+    }
+    TGetTablesReq getTableReq = new TGetTablesReq(sessHandle);
+    getTableReq.setTableName(tableNamePattern);
+
+    // TODO: need to set catalog parameter
+
+    if (types != null) {
+      getTableReq.setTableTypes(Arrays.asList(types));
+    }
+    if (schemaPattern != null) {
+      getTableReq.setSchemaName(schemaPattern);
+    }
+
+    try {
+      getTableResp = client.GetTables(getTableReq);
+    } catch (TException e) {
+      throw new SQLException(e.getMessage(), "08S01");
+    }
+    Utils.verifySuccess(getTableResp.getStatus());
+
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setSessionHandle(sessHandle)
+    .setStmtHandle(getTableResp.getOperationHandle())
+    .build();
+  }
+
+  /**
+   * We sort the output of getTables to guarantee jdbc compliance.
+   * First check by table type then by table name
+   */
+  private class GetTablesComparator implements Comparator<JdbcTable> {
+
+    public int compare(JdbcTable o1, JdbcTable o2) {
+      int compareType = o1.getType().compareTo(o2.getType());
+      if (compareType==0) {
+        return o1.getTableName().compareTo(o2.getTableName());
+      } else {
+        return compareType;
+      }
+    }
+  }
+
+  /**
+   * Translate hive table types into jdbc table types.
+   * @param hivetabletype
+   * @return the type of the table
+   */
+  public static String toJdbcTableType(String hivetabletype) {
+    if (hivetabletype==null) {
+      return null;
+    } else if (hivetabletype.equals(TableType.MANAGED_TABLE.toString())) {
+      return "TABLE";
+    } else if (hivetabletype.equals(TableType.VIRTUAL_VIEW.toString())) {
+      return "VIEW";
+    } else if (hivetabletype.equals(TableType.EXTERNAL_TABLE.toString())) {
+      return "EXTERNAL TABLE";
+    } else {
+      return hivetabletype;
+    }
+  }
+
+  public String getTimeDateFunctions() throws SQLException {
+    return "";
+  }
+
+  public ResultSet getTypeInfo() throws SQLException {
+    TGetTypeInfoResp getTypeInfoResp;
+    TGetTypeInfoReq getTypeInfoReq = new TGetTypeInfoReq();
+    getTypeInfoReq.setSessionHandle(sessHandle);
+    try {
+      getTypeInfoResp = client.GetTypeInfo(getTypeInfoReq);
+    } catch (TException e) {
+      throw new SQLException(e.getMessage(), "08S01");
+    }
+    Utils.verifySuccess(getTypeInfoResp.getStatus());
+    return new HiveQueryResultSet.Builder()
+    .setClient(client)
+    .setSessionHandle(sessHandle)
+    .setStmtHandle(getTypeInfoResp.getOperationHandle())
+    .build();
+  }
+
+  public ResultSet getUDTs(String catalog, String schemaPattern,
+      String typeNamePattern, int[] types) throws SQLException {
+
+    return new HiveMetaDataResultSet(
+            Arrays.asList("TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", "CLASS_NAME", "DATA_TYPE"
+                    , "REMARKS", "BASE_TYPE")
+            , Arrays.asList("STRING", "STRING", "STRING", "STRING", "INT", "STRING", "INT")
+            , null) {
+
+      public boolean next() throws SQLException {
+        return false;
+      }
+    };
+  }
+
+  public String getURL() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public String getUserName() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public ResultSet getVersionColumns(String catalog, String schema, String table)
+      throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean insertsAreDetected(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean isCatalogAtStart() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean isReadOnly() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean locatorsUpdateCopy() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean nullPlusNonNullIsNull() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean nullsAreSortedAtEnd() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean nullsAreSortedAtStart() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean nullsAreSortedHigh() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean nullsAreSortedLow() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean othersDeletesAreVisible(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean othersInsertsAreVisible(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean othersUpdatesAreVisible(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean ownDeletesAreVisible(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean ownInsertsAreVisible(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean ownUpdatesAreVisible(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean storesLowerCaseIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean storesMixedCaseIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean storesUpperCaseIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsANSI92FullSQL() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsANSI92IntermediateSQL() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsAlterTableWithAddColumn() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsAlterTableWithDropColumn() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsBatchUpdates() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsCatalogsInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsColumnAliasing() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsConvert() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsConvert(int fromType, int toType) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsCoreSQLGrammar() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsCorrelatedSubqueries() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsDataDefinitionAndDataManipulationTransactions()
+      throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsExpressionsInOrderBy() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsExtendedSQLGrammar() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsFullOuterJoins() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsGetGeneratedKeys() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsGroupBy() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsGroupByBeyondSelect() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsGroupByUnrelated() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsLikeEscapeClause() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsLimitedOuterJoins() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsMinimumSQLGrammar() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsMultipleOpenResults() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsMultipleResultSets() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsMultipleTransactions() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsNamedParameters() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsNonNullableColumns() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsOrderByUnrelated() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsOuterJoins() throws SQLException {
+    return true;
+  }
+
+  public boolean supportsPositionedDelete() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsPositionedUpdate() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsResultSetConcurrency(int type, int concurrency)
+      throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsResultSetHoldability(int holdability)
+      throws SQLException {
+    return false;
+  }
+
+  public boolean supportsResultSetType(int type) throws SQLException {
+    return true;
+  }
+
+  public boolean supportsSavepoints() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSchemasInDataManipulation() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSchemasInProcedureCalls() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSchemasInTableDefinitions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSelectForUpdate() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsStatementPooling() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsStoredProcedures() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsSubqueriesInComparisons() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsSubqueriesInExists() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsSubqueriesInIns() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsTableCorrelationNames() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsTransactionIsolationLevel(int level)
+      throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsTransactions() throws SQLException {
+    return false;
+  }
+
+  public boolean supportsUnion() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean supportsUnionAll() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean updatesAreDetected(int type) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean usesLocalFilePerTable() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean usesLocalFiles() throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw new SQLException("Method not supported");
+  }
+
+  public static void main(String[] args) throws SQLException {
+    HiveDatabaseMetaData meta = new HiveDatabaseMetaData(null, null);
+    System.out.println("DriverName: " + meta.getDriverName());
+    System.out.println("DriverVersion: " + meta.getDriverVersion());
+  }
+}

Added: hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDriver.java
URL: http://svn.apache.org/viewvc/hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDriver.java?rev=1455659&view=auto
==============================================================================
--- hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDriver.java (added)
+++ hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveDriver.java Tue Mar 12 18:22:00 2013
@@ -0,0 +1,297 @@
+/**
+ * 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.hive.jdbc;
+
+import java.io.IOException;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.regex.Pattern;
+/**
+ * HiveDriver.
+ *
+ */
+public class HiveDriver implements Driver {
+  static {
+    try {
+      java.sql.DriverManager.registerDriver(new HiveDriver());
+    } catch (SQLException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * Is this driver JDBC compliant?
+   */
+  private static final boolean JDBC_COMPLIANT = false;
+
+  /**
+   * The required prefix for the connection URL.
+   */
+  private static final String URL_PREFIX = "jdbc:hive2://";
+
+  /**
+   * If host is provided, without a port.
+   */
+  private static final String DEFAULT_PORT = "10000";
+
+  /**
+   * Property key for the database name.
+   */
+  private static final String DBNAME_PROPERTY_KEY = "DBNAME";
+
+  /**
+   * Property key for the Hive Server2 host.
+   */
+  private static final String HOST_PROPERTY_KEY = "HOST";
+
+  /**
+   * Property key for the Hive Server2 port.
+   */
+  private static final String PORT_PROPERTY_KEY = "PORT";
+
+
+  /**
+   *
+   */
+  public HiveDriver() {
+    // TODO Auto-generated constructor stub
+    SecurityManager security = System.getSecurityManager();
+    if (security != null) {
+      security.checkWrite("foobah");
+    }
+  }
+
+  /**
+   * Checks whether a given url is in a valid format.
+   *
+   * The current uri format is: jdbc:hive://[host[:port]]
+   *
+   * jdbc:hive:// - run in embedded mode jdbc:hive://localhost - connect to
+   * localhost default port (10000) jdbc:hive://localhost:5050 - connect to
+   * localhost port 5050
+   *
+   * TODO: - write a better regex. - decide on uri format
+   */
+
+  public boolean acceptsURL(String url) throws SQLException {
+    return Pattern.matches(URL_PREFIX + ".*", url);
+  }
+
+  public Connection connect(String url, Properties info) throws SQLException {
+    return new HiveConnection(url, info);
+  }
+
+  /**
+   * Package scoped access to the Driver's Major Version
+   * @return The Major version number of the driver. -1 if it cannot be determined from the
+   * manifest.mf file.
+   */
+  static int getMajorDriverVersion() {
+    int version = -1;
+    try {
+      String fullVersion = HiveDriver.fetchManifestAttribute(
+          Attributes.Name.IMPLEMENTATION_VERSION);
+      String[] tokens = fullVersion.split("\\."); //$NON-NLS-1$
+
+      if(tokens != null && tokens.length > 0 && tokens[0] != null) {
+        version = Integer.parseInt(tokens[0]);
+      }
+    } catch (Exception e) {
+      // Possible reasons to end up here:
+      // - Unable to read version from manifest.mf
+      // - Version string is not in the proper X.x.xxx format
+      version = -1;
+    }
+    return version;
+  }
+
+  /**
+   * Package scoped access to the Driver's Minor Version
+   * @return The Minor version number of the driver. -1 if it cannot be determined from the
+   * manifest.mf file.
+   */
+  static int getMinorDriverVersion() {
+    int version = -1;
+    try {
+      String fullVersion = HiveDriver.fetchManifestAttribute(
+          Attributes.Name.IMPLEMENTATION_VERSION);
+      String[] tokens = fullVersion.split("\\."); //$NON-NLS-1$
+
+      if(tokens != null && tokens.length > 1 && tokens[1] != null) {
+        version = Integer.parseInt(tokens[1]);
+      }
+    } catch (Exception e) {
+      // Possible reasons to end up here:
+      // - Unable to read version from manifest.mf
+      // - Version string is not in the proper X.x.xxx format
+      version = -1;
+    }
+    return version;
+  }
+
+  /**
+   * Returns the major version of this driver.
+   */
+  public int getMajorVersion() {
+    return HiveDriver.getMajorDriverVersion();
+  }
+
+  /**
+   * Returns the minor version of this driver.
+   */
+  public int getMinorVersion() {
+    return HiveDriver.getMinorDriverVersion();
+  }
+
+  public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+    if (info == null) {
+      info = new Properties();
+    }
+
+    if ((url != null) && url.startsWith(URL_PREFIX)) {
+      info = parseURL(url, info);
+    }
+
+    DriverPropertyInfo hostProp = new DriverPropertyInfo(HOST_PROPERTY_KEY,
+        info.getProperty(HOST_PROPERTY_KEY, ""));
+    hostProp.required = false;
+    hostProp.description = "Hostname of Hive Server2";
+
+    DriverPropertyInfo portProp = new DriverPropertyInfo(PORT_PROPERTY_KEY,
+        info.getProperty(PORT_PROPERTY_KEY, ""));
+    portProp.required = false;
+    portProp.description = "Port number of Hive Server2";
+
+    DriverPropertyInfo dbProp = new DriverPropertyInfo(DBNAME_PROPERTY_KEY,
+        info.getProperty(DBNAME_PROPERTY_KEY, "default"));
+    dbProp.required = false;
+    dbProp.description = "Database name";
+
+    DriverPropertyInfo[] dpi = new DriverPropertyInfo[3];
+
+    dpi[0] = hostProp;
+    dpi[1] = portProp;
+    dpi[2] = dbProp;
+
+    return dpi;
+  }
+
+  /**
+   * Returns whether the driver is JDBC compliant.
+   */
+
+  public boolean jdbcCompliant() {
+    return JDBC_COMPLIANT;
+  }
+
+  /**
+   * Takes a url in the form of jdbc:hive://[hostname]:[port]/[db_name] and
+   * parses it. Everything after jdbc:hive// is optional.
+   *
+   * @param url
+   * @param defaults
+   * @return
+   * @throws java.sql.SQLException
+   */
+  private Properties parseURL(String url, Properties defaults) throws SQLException {
+    Properties urlProps = (defaults != null) ? new Properties(defaults)
+        : new Properties();
+
+    if (url == null || !url.startsWith(URL_PREFIX)) {
+      throw new SQLException("Invalid connection url: " + url);
+    }
+
+    if (url.length() <= URL_PREFIX.length()) {
+      return urlProps;
+    }
+
+    // [hostname]:[port]/[db_name]
+    String connectionInfo = url.substring(URL_PREFIX.length());
+
+    // [hostname]:[port] [db_name]
+    String[] hostPortAndDatabase = connectionInfo.split("/", 2);
+
+    // [hostname]:[port]
+    if (hostPortAndDatabase[0].length() > 0) {
+      String[] hostAndPort = hostPortAndDatabase[0].split(":", 2);
+      urlProps.put(HOST_PROPERTY_KEY, hostAndPort[0]);
+      if (hostAndPort.length > 1) {
+        urlProps.put(PORT_PROPERTY_KEY, hostAndPort[1]);
+      } else {
+        urlProps.put(PORT_PROPERTY_KEY, DEFAULT_PORT);
+      }
+    }
+
+    // [db_name]
+    if (hostPortAndDatabase.length > 1) {
+      urlProps.put(DBNAME_PROPERTY_KEY, hostPortAndDatabase[1]);
+    }
+
+    return urlProps;
+  }
+
+  /**
+   * Lazy-load manifest attributes as needed.
+   */
+  private static Attributes manifestAttributes = null;
+
+  /**
+   * Loads the manifest attributes from the jar.
+   *
+   * @throws java.net.MalformedURLException
+   * @throws IOException
+   */
+  private static synchronized void loadManifestAttributes() throws IOException {
+    if (manifestAttributes != null) {
+      return;
+    }
+    Class<?> clazz = HiveDriver.class;
+    String classContainer = clazz.getProtectionDomain().getCodeSource()
+        .getLocation().toString();
+    URL manifestUrl = new URL("jar:" + classContainer
+        + "!/META-INF/MANIFEST.MF");
+    Manifest manifest = new Manifest(manifestUrl.openStream());
+    manifestAttributes = manifest.getMainAttributes();
+  }
+
+  /**
+   * Package scoped to allow manifest fetching from other HiveDriver classes
+   * Helper to initialize attributes and return one.
+   *
+   * @param attributeName
+   * @return
+   * @throws SQLException
+   */
+  static String fetchManifestAttribute(Attributes.Name attributeName)
+      throws SQLException {
+    try {
+      loadManifestAttributes();
+    } catch (IOException e) {
+      throw new SQLException("Couldn't load manifest attributes.", e);
+    }
+    return manifestAttributes.getValue(attributeName);
+  }
+}

Added: hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveMetaDataResultSet.java
URL: http://svn.apache.org/viewvc/hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveMetaDataResultSet.java?rev=1455659&view=auto
==============================================================================
--- hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveMetaDataResultSet.java (added)
+++ hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveMetaDataResultSet.java Tue Mar 12 18:22:00 2013
@@ -0,0 +1,53 @@
+/**
+ * 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.hive.jdbc;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class HiveMetaDataResultSet<M> extends HiveBaseResultSet {
+  protected final List<M> data;
+
+  @SuppressWarnings("unchecked")
+  public HiveMetaDataResultSet(final List<String> columnNames
+          , final List<String> columnTypes
+          , final List<M> data) throws SQLException {
+    if (data!=null) {
+      this.data = new ArrayList<M>(data);
+    } else {
+      this.data =  new ArrayList<M>();
+    }
+    if (columnNames!=null) {
+      this.columnNames = new ArrayList<String>(columnNames);
+    } else {
+      this.columnNames =  new ArrayList<String>();
+    }
+    if (columnTypes!=null) {
+      this.columnTypes = new ArrayList<String>(columnTypes);
+    } else {
+      this.columnTypes =  new ArrayList<String>();
+    }
+  }
+
+  @Override
+  public void close() throws SQLException {
+  }
+
+}

Added: hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java
URL: http://svn.apache.org/viewvc/hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java?rev=1455659&view=auto
==============================================================================
--- hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java (added)
+++ hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java Tue Mar 12 18:22:00 2013
@@ -0,0 +1,1280 @@
+/**
+ * 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.hive.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hive.service.cli.thrift.TExecuteStatementReq;
+import org.apache.hive.service.cli.thrift.TExecuteStatementResp;
+import org.apache.hive.service.cli.thrift.TOperationHandle;
+import org.apache.hive.service.cli.thrift.TCLIService;
+import org.apache.hive.service.cli.thrift.TSessionHandle;
+
+/**
+ * HivePreparedStatement.
+ *
+ */
+public class HivePreparedStatement implements PreparedStatement {
+  private final String sql;
+  private TCLIService.Iface client;
+  private final TSessionHandle sessHandle;
+  private TOperationHandle stmtHandle;
+  Map<String,String> sessConf = new HashMap<String,String>();
+
+  /**
+   * save the SQL parameters {paramLoc:paramValue}
+   */
+  private final HashMap<Integer, String> parameters=new HashMap<Integer, String>();
+
+  /**
+   * We need to keep a reference to the result set to support the following:
+   * <code>
+   * statement.execute(String sql);
+   * statement.getResultSet();
+   * </code>.
+   */
+  private ResultSet resultSet = null;
+  /**
+   * The maximum number of rows this statement should return (0 => all rows).
+   */
+  private  int maxRows = 0;
+
+  /**
+   * Add SQLWarnings to the warningChain if needed.
+   */
+  private  SQLWarning warningChain = null;
+
+  /**
+   * Keep state so we can fail certain calls made after close().
+   */
+  private boolean isClosed = false;
+
+  /**
+   * keep the current ResultRet update count
+   */
+  private final int updateCount=0;
+
+  /**
+   *
+   */
+  public HivePreparedStatement(TCLIService.Iface client, TSessionHandle sessHandle,
+      String sql) {
+    this.client = client;
+    this.sessHandle = sessHandle;
+    this.sql = sql;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#addBatch()
+   */
+
+  public void addBatch() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#clearParameters()
+   */
+
+  public void clearParameters() throws SQLException {
+    this.parameters.clear();
+  }
+
+  /**
+   *  Invokes executeQuery(sql) using the sql provided to the constructor.
+   *
+   *  @return boolean Returns true if a resultSet is created, false if not.
+   *                  Note: If the result set is empty a true is returned.
+   *
+   *  @throws SQLException
+   */
+
+  public boolean execute() throws SQLException {
+    ResultSet rs = executeImmediate(sql);
+    return rs != null;
+  }
+
+  /**
+   *  Invokes executeQuery(sql) using the sql provided to the constructor.
+   *
+   *  @return ResultSet
+   *  @throws SQLException
+   */
+
+  public ResultSet executeQuery() throws SQLException {
+    return executeImmediate(sql);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#executeUpdate()
+   */
+
+  public int executeUpdate() throws SQLException {
+    executeImmediate(sql);
+    return updateCount;
+  }
+
+  /**
+   *  Executes the SQL statement.
+   *
+   *  @param sql The sql, as a string, to execute
+   *  @return ResultSet
+   *  @throws SQLException if the prepared statement is closed or there is a database error.
+   *                       caught Exceptions are thrown as SQLExceptions with the description
+   *                       "08S01".
+   */
+
+  protected ResultSet executeImmediate(String sql) throws SQLException {
+    if (isClosed) {
+      throw new SQLException("Can't execute after statement has been closed");
+    }
+
+    try {
+      clearWarnings();
+      resultSet = null;
+      if (sql.contains("?")) {
+        sql = updateSql(sql, parameters);
+      }
+      TExecuteStatementReq execReq = new TExecuteStatementReq(sessHandle, sql);
+      execReq.setConfOverlay(sessConf);
+      TExecuteStatementResp execResp = client.ExecuteStatement(execReq);
+      Utils.verifySuccessWithInfo(execResp.getStatus());
+      stmtHandle = execResp.getOperationHandle();
+    } catch (SQLException es) {
+      throw es;
+    } catch (Exception ex) {
+      throw new SQLException(ex.toString(), "08S01", ex);
+    }
+    resultSet = new HiveQueryResultSet.Builder().setClient(client).setSessionHandle(sessHandle)
+                      .setStmtHandle(stmtHandle).setMaxRows(maxRows)
+                      .build();
+    return resultSet;
+  }
+
+  /**
+   * update the SQL string with parameters set by setXXX methods of {@link PreparedStatement}
+   *
+   * @param sql
+   * @param parameters
+   * @return updated SQL string
+   */
+  private String updateSql(final String sql, HashMap<Integer, String> parameters) {
+
+    StringBuffer newSql = new StringBuffer(sql);
+
+    int paramLoc = 1;
+    while (getCharIndexFromSqlByParamLocation(sql, '?', paramLoc) > 0) {
+      // check the user has set the needs parameters
+      if (parameters.containsKey(paramLoc)) {
+        int tt = getCharIndexFromSqlByParamLocation(newSql.toString(), '?', 1);
+        newSql.deleteCharAt(tt);
+        newSql.insert(tt, parameters.get(paramLoc));
+      }
+      paramLoc++;
+    }
+
+    return newSql.toString();
+
+  }
+
+  /**
+   * Get the index of given char from the SQL string by parameter location
+   * </br> The -1 will be return, if nothing found
+   *
+   * @param sql
+   * @param cchar
+   * @param paramLoc
+   * @return
+   */
+  private int getCharIndexFromSqlByParamLocation(final String sql, final char cchar, final int paramLoc) {
+    int signalCount = 0;
+    int charIndex = -1;
+    int num = 0;
+    for (int i = 0; i < sql.length(); i++) {
+      char c = sql.charAt(i);
+      if (c == '\'' || c == '\\')// record the count of char "'" and char "\"
+      {
+        signalCount++;
+      } else if (c == cchar && signalCount % 2 == 0) {// check if the ? is really the parameter
+        num++;
+        if (num == paramLoc) {
+          charIndex = i;
+          break;
+        }
+      }
+    }
+    return charIndex;
+  }
+
+
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#getMetaData()
+   */
+
+  public ResultSetMetaData getMetaData() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#getParameterMetaData()
+   */
+
+  public ParameterMetaData getParameterMetaData() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setArray(int, java.sql.Array)
+   */
+
+  public void setArray(int i, Array x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream)
+   */
+
+  public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream,
+   * int)
+   */
+
+  public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream,
+   * long)
+   */
+
+  public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBigDecimal(int, java.math.BigDecimal)
+   */
+
+  public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream)
+   */
+
+  public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream,
+   * int)
+   */
+
+  public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream,
+   * long)
+   */
+
+  public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBlob(int, java.sql.Blob)
+   */
+
+  public void setBlob(int i, Blob x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBlob(int, java.io.InputStream)
+   */
+
+  public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBlob(int, java.io.InputStream, long)
+   */
+
+  public void setBlob(int parameterIndex, InputStream inputStream, long length)
+          throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBoolean(int, boolean)
+   */
+
+  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+    this.parameters.put(parameterIndex, ""+x);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setByte(int, byte)
+   */
+
+  public void setByte(int parameterIndex, byte x) throws SQLException {
+    this.parameters.put(parameterIndex, ""+x);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setBytes(int, byte[])
+   */
+
+  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader)
+   */
+
+  public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader,
+   * int)
+   */
+
+  public void setCharacterStream(int parameterIndex, Reader reader, int length)
+      throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader,
+   * long)
+   */
+
+  public void setCharacterStream(int parameterIndex, Reader reader, long length)
+      throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setClob(int, java.sql.Clob)
+   */
+
+  public void setClob(int i, Clob x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setClob(int, java.io.Reader)
+   */
+
+  public void setClob(int parameterIndex, Reader reader) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setClob(int, java.io.Reader, long)
+   */
+
+  public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setDate(int, java.sql.Date)
+   */
+
+  public void setDate(int parameterIndex, Date x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setDate(int, java.sql.Date,
+   * java.util.Calendar)
+   */
+
+  public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setDouble(int, double)
+   */
+
+  public void setDouble(int parameterIndex, double x) throws SQLException {
+    this.parameters.put(parameterIndex,""+x);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setFloat(int, float)
+   */
+
+  public void setFloat(int parameterIndex, float x) throws SQLException {
+    this.parameters.put(parameterIndex,""+x);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setInt(int, int)
+   */
+
+  public void setInt(int parameterIndex, int x) throws SQLException {
+    this.parameters.put(parameterIndex,""+x);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setLong(int, long)
+   */
+
+  public void setLong(int parameterIndex, long x) throws SQLException {
+    this.parameters.put(parameterIndex,""+x);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNCharacterStream(int, java.io.Reader)
+   */
+
+  public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNCharacterStream(int, java.io.Reader,
+   * long)
+   */
+
+  public void setNCharacterStream(int parameterIndex, Reader value, long length)
+      throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNClob(int, java.sql.NClob)
+   */
+
+  public void setNClob(int parameterIndex, NClob value) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNClob(int, java.io.Reader)
+   */
+
+  public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNClob(int, java.io.Reader, long)
+   */
+
+  public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNString(int, java.lang.String)
+   */
+
+  public void setNString(int parameterIndex, String value) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNull(int, int)
+   */
+
+  public void setNull(int parameterIndex, int sqlType) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setNull(int, int, java.lang.String)
+   */
+
+  public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setObject(int, java.lang.Object)
+   */
+
+  public void setObject(int parameterIndex, Object x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int)
+   */
+
+  public void setObject(int parameterIndex, Object x, int targetSqlType)
+      throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int, int)
+   */
+
+  public void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
+      throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setRef(int, java.sql.Ref)
+   */
+
+  public void setRef(int i, Ref x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setRowId(int, java.sql.RowId)
+   */
+
+  public void setRowId(int parameterIndex, RowId x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setSQLXML(int, java.sql.SQLXML)
+   */
+
+  public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setShort(int, short)
+   */
+
+  public void setShort(int parameterIndex, short x) throws SQLException {
+    this.parameters.put(parameterIndex,""+x);
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setString(int, java.lang.String)
+   */
+
+  public void setString(int parameterIndex, String x) throws SQLException {
+     x=x.replace("'", "\\'");
+     this.parameters.put(parameterIndex,"'"+x+"'");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setTime(int, java.sql.Time)
+   */
+
+  public void setTime(int parameterIndex, Time x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setTime(int, java.sql.Time,
+   * java.util.Calendar)
+   */
+
+  public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp)
+   */
+
+  public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+    this.parameters.put(parameterIndex, x.toString());
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp,
+   * java.util.Calendar)
+   */
+
+  public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+      throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setURL(int, java.net.URL)
+   */
+
+  public void setURL(int parameterIndex, URL x) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.PreparedStatement#setUnicodeStream(int, java.io.InputStream,
+   * int)
+   */
+
+  public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+      throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#addBatch(java.lang.String)
+   */
+
+  public void addBatch(String sql) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#cancel()
+   */
+
+  public void cancel() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#clearBatch()
+   */
+
+  public void clearBatch() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#clearWarnings()
+   */
+
+  public void clearWarnings() throws SQLException {
+     warningChain=null;
+  }
+
+  /**
+   *  Closes the prepared statement.
+   *
+   *  @throws SQLException
+   */
+
+  public void close() throws SQLException {
+    client = null;
+    if (resultSet!=null) {
+      resultSet.close();
+      resultSet = null;
+    }
+    isClosed = true;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#execute(java.lang.String)
+   */
+
+  public boolean execute(String sql) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#execute(java.lang.String, int)
+   */
+
+  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#execute(java.lang.String, int[])
+   */
+
+  public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#execute(java.lang.String, java.lang.String[])
+   */
+
+  public boolean execute(String sql, String[] columnNames) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#executeBatch()
+   */
+
+  public int[] executeBatch() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#executeQuery(java.lang.String)
+   */
+
+  public ResultSet executeQuery(String sql) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#executeUpdate(java.lang.String)
+   */
+
+  public int executeUpdate(String sql) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#executeUpdate(java.lang.String, int)
+   */
+
+  public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#executeUpdate(java.lang.String, int[])
+   */
+
+  public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#executeUpdate(java.lang.String, java.lang.String[])
+   */
+
+  public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getConnection()
+   */
+
+  public Connection getConnection() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getFetchDirection()
+   */
+
+  public int getFetchDirection() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getFetchSize()
+   */
+
+  public int getFetchSize() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getGeneratedKeys()
+   */
+
+  public ResultSet getGeneratedKeys() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getMaxFieldSize()
+   */
+
+  public int getMaxFieldSize() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getMaxRows()
+   */
+
+  public int getMaxRows() throws SQLException {
+    return this.maxRows;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getMoreResults()
+   */
+
+  public boolean getMoreResults() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getMoreResults(int)
+   */
+
+  public boolean getMoreResults(int current) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getQueryTimeout()
+   */
+
+  public int getQueryTimeout() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getResultSet()
+   */
+
+  public ResultSet getResultSet() throws SQLException {
+    return this.resultSet;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getResultSetConcurrency()
+   */
+
+  public int getResultSetConcurrency() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getResultSetHoldability()
+   */
+
+  public int getResultSetHoldability() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getResultSetType()
+   */
+
+  public int getResultSetType() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getUpdateCount()
+   */
+
+  public int getUpdateCount() throws SQLException {
+    return updateCount;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#getWarnings()
+   */
+
+  public SQLWarning getWarnings() throws SQLException {
+    return warningChain;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#isClosed()
+   */
+
+  public boolean isClosed() throws SQLException {
+    return isClosed;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#isPoolable()
+   */
+
+  public boolean isPoolable() throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setCursorName(java.lang.String)
+   */
+
+  public void setCursorName(String name) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setEscapeProcessing(boolean)
+   */
+
+  public void setEscapeProcessing(boolean enable) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setFetchDirection(int)
+   */
+
+  public void setFetchDirection(int direction) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setFetchSize(int)
+   */
+
+  public void setFetchSize(int rows) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setMaxFieldSize(int)
+   */
+
+  public void setMaxFieldSize(int max) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setMaxRows(int)
+   */
+
+  public void setMaxRows(int max) throws SQLException {
+    if (max < 0) {
+      throw new SQLException("max must be >= 0");
+    }
+    this.maxRows = max;
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setPoolable(boolean)
+   */
+
+  public void setPoolable(boolean poolable) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Statement#setQueryTimeout(int)
+   */
+
+  public void setQueryTimeout(int seconds) throws SQLException {
+    // TODO Auto-generated method stub
+    // throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
+   */
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+  /*
+   * (non-Javadoc)
+   *
+   * @see java.sql.Wrapper#unwrap(java.lang.Class)
+   */
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    // TODO Auto-generated method stub
+    throw new SQLException("Method not supported");
+  }
+
+}

Added: hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveQueryResultSet.java
URL: http://svn.apache.org/viewvc/hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveQueryResultSet.java?rev=1455659&view=auto
==============================================================================
--- hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveQueryResultSet.java (added)
+++ hive/trunk/jdbc/src/java/org/apache/hive/jdbc/HiveQueryResultSet.java Tue Mar 12 18:22:00 2013
@@ -0,0 +1,277 @@
+/**
+ * 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.hive.jdbc;
+
+import static org.apache.hive.service.cli.thrift.TCLIServiceConstants.TYPE_NAMES;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hive.service.cli.TableSchema;
+import org.apache.hive.service.cli.thrift.TCLIService;
+import org.apache.hive.service.cli.thrift.TColumnDesc;
+import org.apache.hive.service.cli.thrift.TFetchOrientation;
+import org.apache.hive.service.cli.thrift.TFetchResultsReq;
+import org.apache.hive.service.cli.thrift.TFetchResultsResp;
+import org.apache.hive.service.cli.thrift.TGetResultSetMetadataReq;
+import org.apache.hive.service.cli.thrift.TGetResultSetMetadataResp;
+import org.apache.hive.service.cli.thrift.TOperationHandle;
+import org.apache.hive.service.cli.thrift.TRow;
+import org.apache.hive.service.cli.thrift.TSessionHandle;
+import org.apache.hive.service.cli.thrift.TTableSchema;
+
+/**
+ * HiveQueryResultSet.
+ *
+ */
+public class HiveQueryResultSet extends HiveBaseResultSet {
+
+  public static final Log LOG = LogFactory.getLog(HiveQueryResultSet.class);
+
+  private TCLIService.Iface client;
+  private TOperationHandle stmtHandle;
+  private TSessionHandle sessHandle;
+  private int maxRows;
+  private int fetchSize;
+  private int rowsFetched = 0;
+
+  private List<TRow> fetchedRows;
+  private Iterator<TRow> fetchedRowsItr;
+  private boolean isClosed = false;
+  private boolean emptyResultSet = false;
+
+  public static class Builder {
+
+    private TCLIService.Iface client = null;
+    private TOperationHandle stmtHandle = null;
+    private TSessionHandle sessHandle  = null;
+
+    /**
+     * Sets the limit for the maximum number of rows that any ResultSet object produced by this
+     * Statement can contain to the given number. If the limit is exceeded, the excess rows
+     * are silently dropped. The value must be >= 0, and 0 means there is not limit.
+     */
+    private int maxRows = 0;
+    private boolean retrieveSchema = true;
+    private List<String> colNames;
+    private List<String> colTypes;
+    private int fetchSize = 50;
+    private boolean emptyResultSet = false;
+
+    public Builder setClient(TCLIService.Iface client) {
+      this.client = client;
+      return this;
+    }
+
+    public Builder setStmtHandle(TOperationHandle stmtHandle) {
+      this.stmtHandle = stmtHandle;
+      return this;
+    }
+
+    public Builder setSessionHandle(TSessionHandle sessHandle) {
+      this.sessHandle = sessHandle;
+      return this;
+    }
+
+    public Builder setMaxRows(int maxRows) {
+      this.maxRows = maxRows;
+      return this;
+    }
+
+    public Builder setSchema(List<String> colNames, List<String> colTypes) {
+      this.colNames = new ArrayList<String>();
+      this.colNames.addAll(colNames);
+      this.colTypes = new ArrayList<String>();
+      this.colTypes.addAll(colTypes);
+      this.retrieveSchema = false;
+      return this;
+    }
+
+    public Builder setFetchSize(int fetchSize) {
+      this.fetchSize = fetchSize;
+      return this;
+    }
+
+    public Builder setEmptyResultSet(boolean emptyResultSet) {
+      this.emptyResultSet = emptyResultSet;
+      return this;
+    }
+
+    public HiveQueryResultSet build() throws SQLException {
+      return new HiveQueryResultSet(this);
+    }
+  }
+
+  protected HiveQueryResultSet(Builder builder) throws SQLException {
+    this.client = builder.client;
+    this.stmtHandle = builder.stmtHandle;
+    this.sessHandle = builder.sessHandle;
+    this.fetchSize = builder.fetchSize;
+    columnNames = new ArrayList<String>();
+    columnTypes = new ArrayList<String>();
+    if (builder.retrieveSchema) {
+      retrieveSchema();
+    } else {
+      this.columnNames.addAll(builder.colNames);
+      this.columnTypes.addAll(builder.colTypes);
+    }
+    this.emptyResultSet = builder.emptyResultSet;
+    if (builder.emptyResultSet) {
+      this.maxRows = 0;
+    } else {
+      this.maxRows = builder.maxRows;
+    }
+  }
+
+  /**
+   * Retrieve schema from the server
+   */
+  private void retrieveSchema() throws SQLException {
+    try {
+      TGetResultSetMetadataReq metadataReq = new TGetResultSetMetadataReq(stmtHandle);
+      // TODO need session handle
+      TGetResultSetMetadataResp  metadataResp = client.GetResultSetMetadata(metadataReq);
+      Utils.verifySuccess(metadataResp.getStatus());
+
+      StringBuilder namesSb = new StringBuilder();
+      StringBuilder typesSb = new StringBuilder();
+
+      TTableSchema schema = metadataResp.getSchema();
+      if (schema == null || !schema.isSetColumns()) {
+        // TODO: should probably throw an exception here.
+        return;
+      }
+      setSchema(new TableSchema(schema));
+
+      List<TColumnDesc> columns = schema.getColumns();
+      for (int pos = 0; pos < schema.getColumnsSize(); pos++) {
+        if (pos != 0) {
+          namesSb.append(",");
+          typesSb.append(",");
+        }
+        String columnName = columns.get(pos).getColumnName();
+        columnNames.add(columnName);
+        String columnTypeName = TYPE_NAMES.get(
+            columns.get(pos).getTypeDesc().getTypes().get(0).getPrimitiveEntry().getType());
+        columnTypes.add(columnTypeName);
+      }
+    } catch (SQLException eS) {
+      throw eS; // rethrow the SQLException as is
+    } catch (Exception ex) {
+      ex.printStackTrace();
+      throw new SQLException("Could not create ResultSet: " + ex.getMessage(), ex);
+    }
+  }
+
+  /**
+   * Set the specified schema to the resultset
+   * @param colNames
+   * @param colTypes
+   */
+  public void setSchema(List<String> colNames, List<String> colTypes) {
+    columnNames.addAll(colNames);
+    columnTypes.addAll(colTypes);
+  }
+
+  @Override
+  public void close() throws SQLException {
+    // Need reset during re-open when needed
+    client = null;
+    stmtHandle = null;
+    sessHandle = null;
+    isClosed = true;
+  }
+
+  /**
+   * Moves the cursor down one row from its current position.
+   *
+   * @see java.sql.ResultSet#next()
+   * @throws SQLException
+   *           if a database access error occurs.
+   */
+  public boolean next() throws SQLException {
+    if (isClosed) {
+      throw new SQLException("Resultset is closed");
+    }
+    if (emptyResultSet || (maxRows > 0 && rowsFetched >= maxRows)) {
+      return false;
+    }
+
+    try {
+      if (fetchedRows == null || !fetchedRowsItr.hasNext()) {
+        TFetchResultsReq fetchReq = new TFetchResultsReq(stmtHandle,
+            TFetchOrientation.FETCH_NEXT, fetchSize);
+        TFetchResultsResp fetchResp = client.FetchResults(fetchReq);
+        Utils.verifySuccessWithInfo(fetchResp.getStatus());
+        fetchedRows = fetchResp.getResults().getRows();
+        fetchedRowsItr = fetchedRows.iterator();
+      }
+
+      String rowStr = "";
+      if (fetchedRowsItr.hasNext()) {
+        row = fetchedRowsItr.next();
+      } else {
+        return false;
+      }
+
+      rowsFetched++;
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Fetched row string: " + rowStr);
+      }
+
+    } catch (SQLException eS) {
+      throw eS;
+    } catch (Exception ex) {
+      ex.printStackTrace();
+      throw new SQLException("Error retrieving next row", ex);
+    }
+    // NOTE: fetchOne dosn't throw new SQLException("Method not supported").
+    return true;
+  }
+
+  @Override
+  public ResultSetMetaData getMetaData() throws SQLException {
+    if (isClosed) {
+      throw new SQLException("Resultset is closed");
+    }
+    return super.getMetaData();
+  }
+
+  @Override
+  public void setFetchSize(int rows) throws SQLException {
+    if (isClosed) {
+      throw new SQLException("Resultset is closed");
+    }
+    fetchSize = rows;
+  }
+
+  @Override
+  public int getFetchSize() throws SQLException {
+    if (isClosed) {
+      throw new SQLException("Resultset is closed");
+    }
+    return fetchSize;
+  }
+
+}