All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aliyun.odps.jdbc.OdpsDatabaseMetaData Maven / Gradle / Ivy

/*
 * 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 com.aliyun.odps.jdbc;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.RowIdLifetime;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import com.aliyun.odps.Column;
import com.aliyun.odps.Function;
import com.aliyun.odps.OdpsException;
import com.aliyun.odps.Table;
import com.aliyun.odps.account.AliyunAccount;
import com.aliyun.odps.jdbc.utils.JdbcColumn;
import com.aliyun.odps.jdbc.utils.OdpsLogger;
import com.aliyun.odps.jdbc.utils.Utils;
import com.aliyun.odps.type.TypeInfo;
import com.aliyun.odps.type.TypeInfoFactory;
import com.aliyun.odps.utils.StringUtils;

public class OdpsDatabaseMetaData extends WrapperAdapter implements DatabaseMetaData {

  private final OdpsLogger log;
  private static final String PRODUCT_NAME = "MaxCompute/ODPS";
  private static final String DRIVER_NAME = "odps-jdbc";

  private static final String SCHEMA_TERM = "project";
  private static final String CATALOG_TERM = "project";
  private static final String PROCEDURE_TERM = "N/A";

  // Table types
  public static final String TABLE_TYPE_TABLE = "TABLE";
  public static final String TABLE_TYPE_VIEW = "VIEW";

  // Column names
  public static final String COL_NAME_TABLE_CAT = "TABLE_CAT";
  public static final String COL_NAME_TABLE_CATALOG = "TABLE_CATALOG";
  public static final String COL_NAME_TABLE_SCHEM = "TABLE_SCHEM";
  public static final String COL_NAME_TABLE_NAME = "TABLE_NAME";
  public static final String COL_NAME_TABLE_TYPE = "TABLE_TYPE";
  public static final String COL_NAME_REMARKS = "REMARKS";
  public static final String COL_NAME_TYPE_CAT = "TYPE_CAT";
  public static final String COL_NAME_TYPE_SCHEM = "TYPE_SCHEM";
  public static final String COL_NAME_TYPE_NAME = "TYPE_NAME";
  public static final String COL_NAME_SELF_REFERENCING_COL_NAME = "SELF_REFERENCING_COL_NAME";
  public static final String COL_NAME_REF_GENERATION = "REF_GENERATION";

  // MaxCompute public data set project
  public static final String PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA = "MAXCOMPUTE_PUBLIC_DATA";

  private static final int TABLE_NAME_LENGTH = 128;

  private OdpsConnection conn;


  OdpsDatabaseMetaData(OdpsConnection conn) {
    this.conn = conn;
    this.log = conn.log;
  }

  @Override
  public boolean allProceduresAreCallable() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean allTablesAreSelectable() throws SQLException {
    return true;
  }

  @Override
  public String getURL() throws SQLException {
    return conn.getOdps().getEndpoint();
  }

  @Override
  public String getUserName() throws SQLException {
    AliyunAccount account = (AliyunAccount) conn.getOdps().getAccount();
    return account.getAccessId();
  }

  @Override
  public boolean isReadOnly() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean nullsAreSortedHigh() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean nullsAreSortedLow() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean nullsAreSortedAtStart() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean nullsAreSortedAtEnd() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public String getDatabaseProductName() throws SQLException {
    return PRODUCT_NAME;
  }

  @Override
  public String getDatabaseProductVersion() throws SQLException {
    return Utils.retrieveVersion("sdk.version");
  }

  @Override
  public String getDriverName() throws SQLException {
    return DRIVER_NAME;
  }

  @Override
  public String getDriverVersion() throws SQLException {
    return Utils.retrieveVersion("driver.version");
  }

  @Override
  public int getDriverMajorVersion() {
    try {
      return Integer.parseInt(Utils.retrieveVersion("driver.version").split("\\.")[0]);
    } catch (Exception e) {
      e.printStackTrace();
      return 1;
    }
  }

  @Override
  public int getDriverMinorVersion() {
    try {
      return Integer.parseInt(Utils.retrieveVersion("driver.version").split("\\.")[1]);
    } catch (Exception e) {
      e.printStackTrace();
      return 0;
    }
  }

  @Override
  public boolean usesLocalFiles() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean usesLocalFilePerTable() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsMixedCaseIdentifiers() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean storesUpperCaseIdentifiers() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean storesLowerCaseIdentifiers() throws SQLException {
    return true;
  }

  @Override
  public boolean storesMixedCaseIdentifiers() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public String getIdentifierQuoteString() throws SQLException {
    return "`";
  }

  @Override
  public String getSQLKeywords() throws SQLException {
    return "overwrite ";
  }

  @Override
  public String getNumericFunctions() throws SQLException {
    return " ";
  }

  @Override
  public String getStringFunctions() throws SQLException {
    return " ";
  }

  @Override
  public String getSystemFunctions() throws SQLException {
    return " ";
  }

  @Override
  public String getTimeDateFunctions() throws SQLException {
    return "  ";
  }

  @Override
  public String getSearchStringEscape() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public String getExtraNameCharacters() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsAlterTableWithAddColumn() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsAlterTableWithDropColumn() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsColumnAliasing() throws SQLException {
    return true;
  }

  @Override
  public boolean nullPlusNonNullIsNull() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsConvert() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsConvert(int fromType, int toType) throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsTableCorrelationNames() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsDifferentTableCorrelationNames() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsExpressionsInOrderBy() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsOrderByUnrelated() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsGroupBy() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsGroupByUnrelated() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsGroupByBeyondSelect() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsLikeEscapeClause() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsMultipleResultSets() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsMultipleTransactions() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsNonNullableColumns() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsMinimumSQLGrammar() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsCoreSQLGrammar() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsExtendedSQLGrammar() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsANSI92EntryLevelSQL() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsANSI92IntermediateSQL() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsANSI92FullSQL() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsIntegrityEnhancementFacility() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsOuterJoins() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsFullOuterJoins() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsLimitedOuterJoins() throws SQLException {
    return true;
  }

  @Override
  public String getSchemaTerm() throws SQLException {
    return SCHEMA_TERM;
  }

  @Override
  public String getProcedureTerm() throws SQLException {
    return PROCEDURE_TERM;
  }

  @Override
  public String getCatalogTerm() throws SQLException {
    return CATALOG_TERM;
  }

  @Override
  public boolean isCatalogAtStart() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public String getCatalogSeparator() throws SQLException {
    return ".";
  }

  @Override
  public boolean supportsSchemasInDataManipulation() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsSchemasInProcedureCalls() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsSchemasInTableDefinitions() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsSchemasInIndexDefinitions() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsCatalogsInDataManipulation() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsCatalogsInProcedureCalls() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsCatalogsInTableDefinitions() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsPositionedDelete() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsPositionedUpdate() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsSelectForUpdate() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsStoredProcedures() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsSubqueriesInComparisons() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsSubqueriesInExists() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsSubqueriesInIns() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsSubqueriesInQuantifieds() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsCorrelatedSubqueries() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsUnion() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsUnionAll() throws SQLException {
    return true;
  }

  @Override
  public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxBinaryLiteralLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxCharLiteralLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxColumnNameLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxColumnsInGroupBy() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxColumnsInIndex() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxColumnsInOrderBy() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxColumnsInSelect() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxColumnsInTable() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxConnections() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxCursorNameLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxIndexLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxSchemaNameLength() throws SQLException {
    return 32;
  }

  @Override
  public int getMaxProcedureNameLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxCatalogNameLength() throws SQLException {
    return 32;
  }

  @Override
  public int getMaxRowSize() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxStatementLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxStatements() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxTableNameLength() throws SQLException {
    return TABLE_NAME_LENGTH;
  }

  @Override
  public int getMaxTablesInSelect() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getMaxUserNameLength() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public int getDefaultTransactionIsolation() throws SQLException {
    log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!");
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public boolean supportsTransactions() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
    return false;
  }

  @Override
  public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
    return false;
  }

  @Override
  public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
    return false;
  }

  @Override
  public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
    return false;
  }

  @Override
  public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
    return false;
  }

  @Override
  public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
      throws SQLException {
    // Return an empty result set
    OdpsResultSetMetaData meta =
        new OdpsResultSetMetaData(Arrays.asList("PROCEDURE_CAT", "PROCEDURE_SCHEM",
                                                "PROCEDURE_NAME", "RESERVERD", "RESERVERD",
                                                "RESERVERD", "REMARKS", "PROCEDURE_TYPE",
                                                "SPECIFIC_NAME"),
                                  Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.STRING,
                                                TypeInfoFactory.STRING, TypeInfoFactory.STRING,
                                                TypeInfoFactory.STRING,
                                                TypeInfoFactory.STRING, TypeInfoFactory.STRING,
                                                TypeInfoFactory.BIGINT,
                                                TypeInfoFactory.STRING));

    return new OdpsStaticResultSet(getConnection(), meta);
  }

  @Override
  public ResultSet getProcedureColumns(String catalog, String schemaPattern,
                                       String procedureNamePattern, String columnNamePattern)
      throws SQLException {
    // Return an empty result set
    OdpsResultSetMetaData meta =
        new OdpsResultSetMetaData(Arrays.asList("STUPID_PLACEHOLDERS", "USELESS_PLACEHOLDER"),
                                  Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.STRING));

    return new OdpsStaticResultSet(getConnection(), meta);
  }

  @Override
  public ResultSet getTables(
      String catalog,
      String schemaPattern,
      String tableNamePattern,
      String[] types) throws SQLException {
    long begin = System.currentTimeMillis();
    List rows = new ArrayList<>();

    try {
      if (!conn.getTables().isEmpty()) {
        for (Entry>> entry: conn.getTables().entrySet()) {
          String projectName = entry.getKey();
          if (!catalogMatches(catalog, projectName)) {
            continue;
          }
          for (Entry> tableEntry: entry.getValue().entrySet()) {
            LinkedList tables = new LinkedList<>();
            String schemaName = tableEntry.getKey();
            if (!schemaMatches(schemaPattern, schemaName)) {
              continue;
            }
            for (String tableName : tableEntry.getValue()) {
              if (Utils.matchPattern(tableName, tableNamePattern)
                  && conn.getOdps().tables().exists(projectName, tableName)) {
                tables.add(tableName);
              }
            }
            if (tables.size() > 0) {
              convertTableNamesToRows(types, rows, projectName, schemaName, tables);
            }
          }
        }
      } else {
        ResultSet schemas = getSchemas(catalog, schemaPattern);
        List tables = new LinkedList<>();

        // Iterate through all the available catalog & schemas
        while (schemas.next()) {
          if (catalogMatches(catalog, schemas.getString(COL_NAME_TABLE_CATALOG))
              && schemaMatches(schemaPattern, schemas.getString(COL_NAME_TABLE_SCHEM))) {
            // Enable the argument 'extended' so that the returned table objects contains all the
            // information needed by JDBC, like comment and type.
            Iterator
iter = conn.getOdps().tables().iterator( schemas.getString(COL_NAME_TABLE_CATALOG), schemas.getString(COL_NAME_TABLE_SCHEM), null, true); while (iter.hasNext()) { Table t = iter.next(); String tableName = t.getName(); if (!Utils.matchPattern(tableName, tableNamePattern)) { continue; } tables.add(t); if (tables.size() == 100) { convertTablesToRows(types, rows, tables); } } } } if (tables.size() > 0) { convertTablesToRows(types, rows, tables); } schemas.close(); } } catch (Exception e) { throw new SQLException(e.getMessage(), e); } long end = System.currentTimeMillis(); log.info("It took me " + (end - begin) + " ms to get " + rows.size() + " Tables"); OdpsResultSetMetaData meta = new OdpsResultSetMetaData( Arrays.asList( COL_NAME_TABLE_CAT, COL_NAME_TABLE_SCHEM, COL_NAME_TABLE_NAME, COL_NAME_TABLE_TYPE, COL_NAME_REMARKS, COL_NAME_TYPE_CAT, COL_NAME_TYPE_SCHEM, COL_NAME_TYPE_NAME, COL_NAME_SELF_REFERENCING_COL_NAME, COL_NAME_REF_GENERATION), Arrays.asList( TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING)); sortRows(rows, new int[]{3, 0, 1, 2}); return new OdpsStaticResultSet(getConnection(), meta, rows.iterator()); } private boolean catalogMatches(String catalog, String actual) { return catalog == null || catalog.equalsIgnoreCase(actual); } private boolean schemaMatches(String schemaPattern, String actual) { return Utils.matchPattern(actual, schemaPattern); } private void convertTableNamesToRows( String[] types, List rows, String projectName, String schemaName, List names) throws OdpsException { LinkedList
tables = new LinkedList<>(); tables.addAll(conn.getOdps().tables().loadTables(projectName, schemaName, names)); convertTablesToRows(types, rows, tables); } private void convertTablesToRows(String[] types, List rows, List
tables) { for (Table t : tables) { String tableType = t.isVirtualView() ? TABLE_TYPE_VIEW : TABLE_TYPE_TABLE; if (types != null && types.length != 0) { if (!Arrays.asList(types).contains(tableType)) { continue; } } String schemaName = t.getProject(); if (conn.isOdpsNamespaceSchema()) { schemaName = t.getSchemaName(); } Object[] rowVals = { t.getProject(), schemaName, t.getName(), tableType, t.getComment(), null, null, null, null, null}; rows.add(rowVals); } tables.clear(); } @Override public ResultSet getSchemas() throws SQLException { return getSchemas(null, null); } @Override public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { /** ResultSet Format: * odpsnamespace=true * TABLE_SCHEM TABLE_CATALOG * ----------- ----------- * schemaName projectName * * odpsnamespace=false * TABLE_SCHEM TABLE_CATALOG * ----------- ----------- * projectName projectName */ OdpsResultSetMetaData meta = new OdpsResultSetMetaData( Arrays.asList(COL_NAME_TABLE_SCHEM, COL_NAME_TABLE_CATALOG), Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.STRING)); List rows = new ArrayList<>(); // In MaxCompute, catalog == schema == project. String schema = catalog; // Project MAXCOMPUTE_PUBLIC_DATA includes MaxCompute public data sets. It is available in // almost all the regions of every public MaxCompute service, but may not be available in // private services. try { if (catalogMatches(catalog, PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA) && schemaMatches(schemaPattern, PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA) && conn.getOdps().projects().exists(PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA)) { rows.add(new String[]{PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA, PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA}); } } catch (OdpsException e) { String errMsg = "Failed to access project: " + e.getMessage(); conn.log.debug(errMsg); } try { if (!conn.isOdpsNamespaceSchema()) { if (catalog == null) { // The follow code block implements the actual interface DatabaseMetaData#getCatalogs. But // since list projects is quite slow right now, this impl is commented out. // for (Project p : conn.getOdps().projects().iterable(null)) { // if (!PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA.equals(p.getName()) // && Utils.matchPattern(p.getName(), schemaPattern)) { // rows.add(new String[]{p.getName(), p.getName()}); // } // } if (!PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA.equalsIgnoreCase(conn.getOdps().getDefaultProject())) { rows.add( new String[]{conn.getOdps().getDefaultProject(), conn.getOdps().getDefaultProject()}); } } else { if (!PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA.equalsIgnoreCase(schema) && Utils.matchPattern(schema, schemaPattern) && conn.getOdps().projects().exists(schema)) { rows.add(new String[]{schema, schema}); } } } else { List schemaList; if (catalog == null) { catalog = conn.getOdps().getDefaultProject(); } schemaList = Utils.getSchemaList(conn.getOdps(), "show schemas in " + catalog + ";"); for (String schemaName: schemaList) { if (schemaMatches(schemaPattern, schemaName)) { rows.add(new String[]{schemaName, catalog}); } } } } catch (OdpsException | RuntimeException e) { throw new SQLException(e.getMessage(), e); } sortRows(rows, new int[]{1, 0}); return new OdpsStaticResultSet(getConnection(), meta, rows.iterator()); } @Override public ResultSet getCatalogs() throws SQLException { OdpsResultSetMetaData meta = new OdpsResultSetMetaData( Collections.singletonList(COL_NAME_TABLE_CAT), Collections.singletonList(TypeInfoFactory.STRING)); List rows = new ArrayList<>(); // Project MAXCOMPUTE_PUBLIC_DATA includes MaxCompute public data sets. It is available in // almost all the regions of every public MaxCompute service, but may not be available in // private services. try { if (conn.getOdps().projects().exists(PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA)) { rows.add(new String[]{PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA}); } } catch (OdpsException e) { String errMsg = "Failed to access project: " + e.getMessage(); conn.log.debug(errMsg); } // The follow code block implements the actual interface DatabaseMetaData#getCatalogs. But since // list projects is quite slow right now, this impl is commented out. // try { // for (Project p : conn.getOdps().projects().iterable(null)) { // rows.add(new String[] {p.getName()}); // } // } catch (RuntimeException e) { // throw new SQLException(e); // } if (!PRJ_NAME_MAXCOMPUTE_PUBLIC_DATA.equalsIgnoreCase(conn.getOdps().getDefaultProject())) { rows.add(new String[]{conn.getOdps().getDefaultProject()}); } sortRows(rows, new int[]{0}); return new OdpsStaticResultSet(getConnection(), meta, rows.iterator()); } /** * Sort rows by specified columns. * * @param rows Rows. Elements in the list cannot be null and must have the same length. * @param columnsToSort Indexes of columns to sort. */ private void sortRows(List rows, int[] columnsToSort) { rows.sort((row1, row2) -> { Objects.requireNonNull(row1); Objects.requireNonNull(row2); if (row1.length != row2.length) { throw new IllegalArgumentException("Rows have different length"); } for (int i = 0; i < row1.length; i++) { for (int idx : columnsToSort) { if (row1[idx] != null && row2[idx] != null) { int ret = ((String) row1[idx]).compareTo((String) row2[idx]); if (ret == 0) { continue; } return ret; } else if (row1[idx] != null && row2[idx] == null) { return 1; } else if (row1[idx] == null && row2[idx] != null) { return -1; } } } return 0; }); } @Override public ResultSet getTableTypes() throws SQLException { List rows = new ArrayList<>(); OdpsResultSetMetaData meta = new OdpsResultSetMetaData( Arrays.asList(COL_NAME_TABLE_TYPE), Arrays.asList(TypeInfoFactory.STRING)); rows.add(new String[]{TABLE_TYPE_TABLE}); rows.add(new String[]{TABLE_TYPE_VIEW}); return new OdpsStaticResultSet(getConnection(), meta, rows.iterator()); } @Override public ResultSet getColumns( String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { long begin = System.currentTimeMillis(); if (tableNamePattern == null) { throw new SQLException("Table name must be given when getColumns"); } List rows = new ArrayList(); if (!tableNamePattern.trim().isEmpty() && !"%".equals(tableNamePattern.trim()) && !"*".equals(tableNamePattern.trim())) { try { Table table; if (conn.isOdpsNamespaceSchema()) { table = conn.getOdps().tables().get(conn.getOdps().getDefaultProject(), schemaPattern, tableNamePattern); } else { if (StringUtils.isNullOrEmpty(catalog)) { table = conn.getOdps().tables().get(tableNamePattern); } else { table = conn.getOdps().tables().get(catalog, tableNamePattern); } } table.reload(); // Read column & partition column information from table schema List columns = new LinkedList<>(); columns.addAll(table.getSchema().getColumns()); columns.addAll(table.getSchema().getPartitionColumns()); for (int i = 0; i < columns.size(); i++) { Column col = columns.get(i); JdbcColumn jdbcCol = new JdbcColumn(col.getName(), tableNamePattern, table.getProject(), col.getTypeInfo().getOdpsType(), col.getTypeInfo(), col.getComment(), i + 1); Object[] rowVals = {catalog, // table catalog (odps project) jdbcCol.getTableSchema(), // table schema (odps project) jdbcCol.getTableName(), // table name jdbcCol.getColumnName(), // column name (long) jdbcCol.getType(), // SQL type from java.sql.Types jdbcCol.getTypeName(), // Data source dependent type name, actually odps typeInfo name null, // column size null, // not used (long) jdbcCol.getDecimalDigits(), // the number of fractional digits. (long) jdbcCol.getNumPercRaidx(), // Radix (typically either 10 or 2) (long) jdbcCol.getIsNullable(), // is NULL allowed. jdbcCol.getComment(), // comment describing column (may be null) null, // default value for the column null, // unused null, // unused null, // for char types the maximum number of bytes in the column (long) jdbcCol.getOrdinalPos(), // index of column in table (start at 1) jdbcCol.getIsNullableString(), // ISO rules are used to determine the nullability for a column. null, // SCOPE_CATALOG null, // SCOPE_SCHEMA null, // SCOPE_TABLE null, // SOURCE_DATA_TYPE "NO", // IS_AUTOINCREMENT "NO", // IS_GENERATEDCOLUMN }; rows.add(rowVals); } } catch (OdpsException e) { throw new SQLException("catalog=" + catalog + ",schemaPattern=" + schemaPattern + ",tableNamePattern=" + tableNamePattern + ",columnNamePattern" + columnNamePattern, e); } } long end = System.currentTimeMillis(); log.info("It took me " + (end - begin) + " ms to get " + rows.size() + " columns"); // Build result set meta data OdpsResultSetMetaData meta = new OdpsResultSetMetaData(Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "NUM_PERC_RADIX", "NULLABLE", "REMARKS", "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE", "SCOPE_CATALOG", "SCOPE_SCHEMA", "SCOPE_TABLE", "SOURCE_DATA_TYPE", "IS_AUTOINCREMENT", "IS_GENERATEDCOLUMN"), Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING, TypeInfoFactory.STRING)); return new OdpsStaticResultSet(getConnection(), meta, rows.iterator()); } @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { // Return an empty result set OdpsResultSetMetaData meta = new OdpsResultSetMetaData(Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "KEY_SEQ", "PK_NAME"), Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING)); return new OdpsStaticResultSet(getConnection(), meta); } @Override public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { // Return an empty result set OdpsResultSetMetaData meta = new OdpsResultSetMetaData(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(TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING)); return new OdpsStaticResultSet(getConnection(), meta); } @Override public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getTypeInfo() throws SQLException { List columnNames = Arrays.asList("TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS", "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX"); List columnTypes = Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.INT, TypeInfoFactory.INT, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.SMALLINT, TypeInfoFactory.BOOLEAN, TypeInfoFactory.SMALLINT, TypeInfoFactory.BOOLEAN, TypeInfoFactory.BOOLEAN, TypeInfoFactory.BOOLEAN, TypeInfoFactory.STRING, TypeInfoFactory.SMALLINT, TypeInfoFactory.SMALLINT, TypeInfoFactory.INT, TypeInfoFactory.INT, TypeInfoFactory.INT); OdpsResultSetMetaData meta = new OdpsResultSetMetaData(columnNames, columnTypes); List rows = new ArrayList<>(); rows.add(new Object[]{TypeInfoFactory.TINYINT.getTypeName(), Types.TINYINT, 3, null, "Y", null, typeNullable, null, typePredBasic, false, false, false, null, 0, 0, null, null, 10}); rows.add(new Object[]{TypeInfoFactory.SMALLINT.getTypeName(), Types.SMALLINT, 5, null, "S", null, typeNullable, null, typePredBasic, false, false, false, null, 0, 0, null, null, 10}); rows.add(new Object[]{TypeInfoFactory.INT.getTypeName(), Types.INTEGER, 10, null, null, null, typeNullable, null, typePredBasic, false, false, false, null, 0, 0, null, null, 10}); rows.add(new Object[]{TypeInfoFactory.BIGINT.getTypeName(), Types.BIGINT, 19, null, "L", null, typeNullable, null, typePredBasic, false, false, false, null, 0, 0, null, null, 10}); rows.add(new Object[]{TypeInfoFactory.BINARY.getTypeName(), Types.BINARY, 8 * 1024 * 1024, null, null, null, typeNullable, null, typePredNone, false, false, false, null, 0, 0, null, null, null}); rows.add(new Object[]{TypeInfoFactory.FLOAT.getTypeName(), Types.FLOAT, null, null, null, null, typeNullable, null, typePredBasic, false, false, false, null, null, null, null, null, 2}); rows.add(new Object[]{TypeInfoFactory.DOUBLE.getTypeName(), Types.DOUBLE, null, null, null, null, typeNullable, null, typePredBasic, false, false, false, null, null, null, null, null, 2}); rows.add(new Object[]{TypeInfoFactory.DECIMAL.getTypeName(), Types.DECIMAL, 38, null, "BD", null, typeNullable, null, typePredBasic, false, true, false, null, 18, 18, null, null, 10}); rows.add(new Object[]{"VARCHAR", Types.VARCHAR, null, null, null, "PRECISION", typeNullable, true, typePredChar, false, false, false, null, null, null, null, null, null}); rows.add(new Object[]{"CHAR", Types.CHAR, null, null, null, "PRECISION", typeNullable, true, typePredChar, false, false, false, null, null, null, null, null, null}); rows.add(new Object[]{TypeInfoFactory.STRING, Types.VARCHAR, 8 * 1024 * 1024, "\"", "\"", null, typeNullable, true, typePredChar, false, false, false, null, null, null, null, null, null}); // yyyy-mm-dd rows.add(new Object[]{TypeInfoFactory.DATE, Types.DATE, 10, "DATE'", "'", null, typeNullable, null, typePredBasic, false, false, false, null, null, null, null, null, null}); // yyyy-mm-dd hh:MM:ss.SSS rows.add(new Object[]{TypeInfoFactory.DATETIME, Types.TIMESTAMP, 23, "DATETIME'", "'", null, typeNullable, null, typePredBasic, false, false, false, null, null, null, null, null, null}); // yyyy-mm-dd hh:MM:ss.SSSSSSSSS rows.add(new Object[]{TypeInfoFactory.TIMESTAMP, Types.TIMESTAMP, 29, "TIMESTAMP'", "'", null, typeNullable, null, typePredBasic, false, false, false, null, null, null, null, null, null}); rows.add(new Object[]{TypeInfoFactory.BOOLEAN, Types.BOOLEAN, null, null, null, null, typeNullable, null, typePredBasic, false, false, false, null, null, null, null, null, null}); return new OdpsStaticResultSet(getConnection(), meta, rows.iterator()); } @Override public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { OdpsResultSetMetaData meta = new OdpsResultSetMetaData( Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME", "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", "ASC_OR_DESC", "CARDINALITY", "PAGES", "FILTER_CONDITION"), Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BOOLEAN, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.SMALLINT, TypeInfoFactory.SMALLINT, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING)); // Return an empty result set since index is unsupported in MaxCompute return new OdpsStaticResultSet(getConnection(), meta, Collections.emptyIterator()); } @Override public boolean supportsResultSetType(int type) throws SQLException { if (type == ResultSet.TYPE_FORWARD_ONLY || type == ResultSet.TYPE_SCROLL_INSENSITIVE) { return true; } else { return false; } } @Override public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException { return false; } @Override public boolean ownUpdatesAreVisible(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean ownDeletesAreVisible(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean ownInsertsAreVisible(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean othersUpdatesAreVisible(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean othersDeletesAreVisible(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean othersInsertsAreVisible(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean updatesAreDetected(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean deletesAreDetected(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean insertsAreDetected(int type) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean supportsBatchUpdates() throws SQLException { return false; } @Override public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { // Return an empty result set OdpsResultSetMetaData meta = new OdpsResultSetMetaData(Arrays.asList("TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", "CLASS_NAME", "DATA_TYPE", "REMARKS", "BASE_TYPE"), Arrays.asList( TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT)); return new OdpsStaticResultSet(getConnection(), meta); } @Override public OdpsConnection getConnection() throws SQLException { return conn; } @Override public boolean supportsSavepoints() throws SQLException { return false; } @Override public boolean supportsNamedParameters() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean supportsMultipleOpenResults() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean supportsGetGeneratedKeys() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException { return null; } @Override public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { return null; } @Override public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { return null; } @Override public boolean supportsResultSetHoldability(int holdability) throws SQLException { return false; } @Override public int getResultSetHoldability() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public int getDatabaseMajorVersion() throws SQLException { try { return Integer.parseInt(Utils.retrieveVersion("sdk.version").split("\\.")[0]); } catch (Exception e) { e.printStackTrace(); return 1; } } @Override public int getDatabaseMinorVersion() throws SQLException { try { return Integer.parseInt(Utils.retrieveVersion("sdk.version").split("\\.")[1]); } catch (Exception e) { e.printStackTrace(); return 0; } } @Override public int getJDBCMajorVersion() throws SQLException { // TODO: risky return 4; } @Override public int getJDBCMinorVersion() throws SQLException { return 0; } @Override public int getSQLStateType() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean locatorsUpdateCopy() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean supportsStatementPooling() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public RowIdLifetime getRowIdLifetime() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean autoCommitFailureClosesAllResultSets() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getClientInfoProperties() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { long begin = System.currentTimeMillis(); List rows = new ArrayList(); for (Function f : conn.getOdps().functions()) { Object[] rowVals = {null, null, f.getName(), 0, (long) functionResultUnknown, null}; rows.add(rowVals); } long end = System.currentTimeMillis(); log.info("It took me " + (end - begin) + " ms to get " + rows.size() + " functions"); OdpsResultSetMetaData meta = new OdpsResultSetMetaData(Arrays.asList("FUNCTION_CAT", "FUNCTION_SCHEM", "FUNCTION_NAME", "REMARKS", "FUNCTION_TYPE", "SPECIFIC_NAME"), Arrays.asList(TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.STRING, TypeInfoFactory.BIGINT, TypeInfoFactory.STRING)); return new OdpsStaticResultSet(getConnection(), meta, rows.iterator()); } @Override public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } @Override public boolean generatedKeyAlwaysReturned() throws SQLException { log.error(Thread.currentThread().getStackTrace()[1].getMethodName() + " is not supported!!!"); throw new SQLFeatureNotSupportedException(); } }