blob: 14ffe5f9f6d195c531759185b0ab650f938d9df0 [file] [log] [blame]
/**
* 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.drill.jdbc.impl;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.RowIdLifetime;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import org.apache.calcite.avatica.AvaticaDatabaseMetaData;
import org.apache.drill.common.Version;
import org.apache.drill.common.exceptions.DrillRuntimeException;
import org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.common.types.Types;
import org.apache.drill.exec.client.ServerMethod;
import org.apache.drill.exec.proto.UserBitShared.DrillPBError;
import org.apache.drill.exec.proto.UserProtos.ConvertSupport;
import org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport;
import org.apache.drill.exec.proto.UserProtos.GetServerMetaResp;
import org.apache.drill.exec.proto.UserProtos.GroupBySupport;
import org.apache.drill.exec.proto.UserProtos.IdentifierCasing;
import org.apache.drill.exec.proto.UserProtos.NullCollation;
import org.apache.drill.exec.proto.UserProtos.OrderBySupport;
import org.apache.drill.exec.proto.UserProtos.OuterJoinSupport;
import org.apache.drill.exec.proto.UserProtos.RequestStatus;
import org.apache.drill.exec.proto.UserProtos.ServerMeta;
import org.apache.drill.exec.proto.UserProtos.SubQuerySupport;
import org.apache.drill.exec.proto.UserProtos.UnionSupport;
import org.apache.drill.jdbc.AlreadyClosedSqlException;
import org.apache.drill.jdbc.DrillDatabaseMetaData;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
/**
* Drill's implementation of {@link DatabaseMetaData}.
*/
class DrillDatabaseMetaDataImpl extends AvaticaDatabaseMetaData
implements DrillDatabaseMetaData {
/**
* Holds allowed conversion between SQL types
*
*/
private static final class SQLConvertSupport {
public final int from;
public final int to;
public SQLConvertSupport(int from, int to) {
this.from = from;
this.to = to;
}
@Override
public int hashCode() {
return Objects.hash(from, to);
}
@Override public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof SQLConvertSupport)) {
return false;
}
SQLConvertSupport other = (SQLConvertSupport) obj;
return from == other.from && to == other.to;
}
public static final Set<SQLConvertSupport> toSQLConvertSupport(Iterable<ConvertSupport> convertSupportIterable) {
ImmutableSet.Builder<SQLConvertSupport> sqlConvertSupportSet = ImmutableSet.builder();
for(ConvertSupport convertSupport: convertSupportIterable) {
try {
sqlConvertSupportSet.add(new SQLConvertSupport(
toSQLType(convertSupport.getFrom()),
toSQLType(convertSupport.getTo())));
} catch(IllegalArgumentException e) {
// Ignore unknown types...
}
}
return sqlConvertSupportSet.build();
}
private static int toSQLType(MinorType minorType) {
String sqlTypeName = Types.getSqlTypeName(Types.optional(minorType));
return Types.getJdbcTypeCode(sqlTypeName);
}
}
private volatile ServerMeta serverMeta;
private volatile Set<SQLConvertSupport> convertSupport;
protected DrillDatabaseMetaDataImpl( DrillConnectionImpl connection ) {
super( connection );
}
/**
* Throws AlreadyClosedSqlException if the associated Connection is closed.
*
* @throws AlreadyClosedSqlException if Connection is closed
* @throws SQLException if error in calling {@link Connection#isClosed()}
*/
private void throwIfClosed() throws AlreadyClosedSqlException,
SQLException {
if ( getConnection().isClosed() ) {
throw new AlreadyClosedSqlException(
"DatabaseMetaData's Connection is already closed." );
}
}
private boolean getServerMetaSupported() throws SQLException {
DrillConnectionImpl connection = (DrillConnectionImpl) getConnection();
return
!connection.getConfig().isServerMetadataDisabled()
&& connection.getClient().getSupportedMethods().contains(ServerMethod.GET_SERVER_META);
}
private String getServerName() throws SQLException {
DrillConnectionImpl connection = (DrillConnectionImpl) getConnection();
return connection.getClient().getServerName();
}
private Version getServerVersion() throws SQLException {
DrillConnectionImpl connection = (DrillConnectionImpl) getConnection();
return connection.getClient().getServerVersion();
}
private ServerMeta getServerMeta() throws SQLException {
assert getServerMetaSupported();
if (serverMeta == null) {
synchronized(this) {
if (serverMeta == null) {
DrillConnectionImpl connection = (DrillConnectionImpl) getConnection();
try {
GetServerMetaResp resp = connection.getClient().getServerMeta().get();
if (resp.getStatus() != RequestStatus.OK) {
DrillPBError drillError = resp.getError();
throw new SQLException("Error when getting server meta: " + drillError.getMessage());
}
serverMeta = resp.getServerMeta();
convertSupport = SQLConvertSupport.toSQLConvertSupport(serverMeta.getConvertSupportList());
} catch (InterruptedException e) {
throw new SQLException("Interrupted when getting server meta", e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause == null) {
throw new AssertionError("Something unknown happened", e);
}
Throwables.propagateIfPossible(cause);
throw new SQLException("Error when getting server meta", cause);
}
}
}
}
return serverMeta;
}
// Note: Dynamic proxies could be used to reduce the quantity (450?) of
// method overrides by eliminating those that exist solely to check whether
// the object is closed. (Check performance before applying to frequently
// called ResultSet.)
// Note: Methods are in same order as in java.sql.DatabaseMetaData.
// No isWrapperFor(Class<?>) (it doesn't throw SQLException if already closed).
// No unwrap(Class<T>) (it doesn't throw SQLException if already closed).
@Override
public boolean allProceduresAreCallable() throws SQLException {
throwIfClosed();
return super.allProceduresAreCallable();
}
@Override
public boolean allTablesAreSelectable() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.allTablesAreSelectable();
}
return getServerMeta().getAllTablesSelectable();
}
@Override
public String getURL() throws SQLException {
throwIfClosed();
return super.getURL();
}
@Override
public String getUserName() throws SQLException {
throwIfClosed();
return super.getUserName();
}
@Override
public boolean isReadOnly() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.isReadOnly();
}
return getServerMeta().getReadOnly();
}
// For omitted NULLS FIRST/NULLS HIGH, Drill sort NULL sorts as highest value:
@Override
public boolean nullsAreSortedHigh() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return true;
}
return getServerMeta().getNullCollation() == NullCollation.NC_HIGH;
}
@Override
public boolean nullsAreSortedLow() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return false;
}
return getServerMeta().getNullCollation() == NullCollation.NC_LOW;
}
@Override
public boolean nullsAreSortedAtStart() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return false;
}
return getServerMeta().getNullCollation() == NullCollation.NC_AT_START;
}
@Override
public boolean nullsAreSortedAtEnd() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return false;
}
return getServerMeta().getNullCollation() == NullCollation.NC_AT_END;
}
@Override
public String getDatabaseProductName() throws SQLException {
throwIfClosed();
String name = getServerName();
if (name == null) {
return super.getDatabaseProductName();
}
return name;
}
@Override
public String getDatabaseProductVersion() throws SQLException {
throwIfClosed();
Version version = getServerVersion();
if (version == null) {
return super.getDatabaseProductVersion();
}
return version.getVersion();
}
@Override
public String getDriverName() throws SQLException {
throwIfClosed();
return super.getDriverName();
}
@Override
public String getDriverVersion() throws SQLException {
throwIfClosed();
return super.getDriverVersion();
}
@Override
public int getDriverMajorVersion() {
// No already-closed exception required or allowed by JDBC.
return super.getDriverMajorVersion();
}
@Override
public int getDriverMinorVersion() {
// No already-closed exception required or allowed by JDBC.
return super.getDriverMinorVersion();
}
@Override
public boolean usesLocalFiles() throws SQLException {
throwIfClosed();
return super.usesLocalFiles();
}
@Override
public boolean usesLocalFilePerTable() throws SQLException {
throwIfClosed();
return super.usesLocalFilePerTable();
}
@Override
public boolean supportsMixedCaseIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsMixedCaseIdentifiers();
}
return getServerMeta().getIdentifierCasing() == IdentifierCasing.IC_SUPPORTS_MIXED;
}
@Override
public boolean storesUpperCaseIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.storesUpperCaseIdentifiers();
}
return getServerMeta().getIdentifierCasing() == IdentifierCasing.IC_STORES_UPPER;
}
@Override
public boolean storesLowerCaseIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.storesLowerCaseIdentifiers();
}
return getServerMeta().getIdentifierCasing() == IdentifierCasing.IC_STORES_LOWER;
}
@Override
public boolean storesMixedCaseIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.storesMixedCaseIdentifiers();
}
return getServerMeta().getIdentifierCasing() == IdentifierCasing.IC_STORES_MIXED;
}
@Override
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsMixedCaseQuotedIdentifiers();
}
return getServerMeta().getQuotedIdentifierCasing() == IdentifierCasing.IC_SUPPORTS_MIXED;
}
@Override
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.storesUpperCaseQuotedIdentifiers();
}
return getServerMeta().getQuotedIdentifierCasing() == IdentifierCasing.IC_STORES_UPPER;
}
@Override
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.storesLowerCaseQuotedIdentifiers();
}
return getServerMeta().getQuotedIdentifierCasing() == IdentifierCasing.IC_STORES_LOWER;
}
@Override
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.storesMixedCaseQuotedIdentifiers();
}
return getServerMeta().getQuotedIdentifierCasing() == IdentifierCasing.IC_STORES_MIXED;
}
// TODO(DRILL-3510): Update when Drill accepts standard SQL's double quote.
@Override
public String getIdentifierQuoteString() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return "`";
}
return getServerMeta().getIdentifierQuoteString();
}
@Override
public String getSQLKeywords() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getSQLKeywords();
}
return Joiner.on(",").join(getServerMeta().getSqlKeywordsList());
}
@Override
public String getNumericFunctions() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getNumericFunctions();
}
return Joiner.on(",").join(getServerMeta().getNumericFunctionsList());
}
@Override
public String getStringFunctions() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getStringFunctions();
}
return Joiner.on(",").join(getServerMeta().getStringFunctionsList());
}
@Override
public String getSystemFunctions() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getSystemFunctions();
}
return Joiner.on(",").join(getServerMeta().getSystemFunctionsList());
}
@Override
public String getTimeDateFunctions() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getTimeDateFunctions();
}
return Joiner.on(",").join(getServerMeta().getDateTimeFunctionsList());
}
@Override
public String getSearchStringEscape() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getSearchStringEscape();
}
return getServerMeta().getSearchEscapeString();
}
@Override
public String getExtraNameCharacters() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getExtraNameCharacters();
}
return getServerMeta().getSpecialCharacters();
}
@Override
public boolean supportsAlterTableWithAddColumn() throws SQLException {
throwIfClosed();
return super.supportsAlterTableWithAddColumn();
}
@Override
public boolean supportsAlterTableWithDropColumn() throws SQLException {
throwIfClosed();
return super.supportsAlterTableWithDropColumn();
}
@Override
public boolean supportsColumnAliasing() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsColumnAliasing();
}
return getServerMeta().getColumnAliasingSupported();
}
@Override
public boolean nullPlusNonNullIsNull() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.nullPlusNonNullIsNull();
}
return getServerMeta().getNullPlusNonNullEqualsNull();
}
@Override
public boolean supportsConvert() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsConvert();
}
// Make sure the convert table is loaded
getServerMeta();
return !convertSupport.isEmpty();
}
@Override
public boolean supportsConvert(int fromType, int toType) throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsConvert(fromType, toType);
}
// Make sure the convert table is loaded
getServerMeta();
return convertSupport.contains(new SQLConvertSupport(fromType, toType));
}
@Override
public boolean supportsTableCorrelationNames() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsTableCorrelationNames();
}
return getServerMeta().getCorrelationNamesSupport() == CorrelationNamesSupport.CN_ANY
|| getServerMeta().getCorrelationNamesSupport() == CorrelationNamesSupport.CN_DIFFERENT_NAMES;
}
@Override
public boolean supportsDifferentTableCorrelationNames() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsDifferentTableCorrelationNames();
}
return getServerMeta().getCorrelationNamesSupport() == CorrelationNamesSupport.CN_DIFFERENT_NAMES;
}
@Override
public boolean supportsExpressionsInOrderBy() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsExpressionsInOrderBy();
}
return getServerMeta().getOrderBySupportList().contains(OrderBySupport.OB_EXPRESSION);
}
@Override
public boolean supportsOrderByUnrelated() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsOrderByUnrelated();
}
return getServerMeta().getOrderBySupportList().contains(OrderBySupport.OB_UNRELATED);
}
@Override
public boolean supportsGroupBy() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsGroupBy();
}
return getServerMeta().getGroupBySupport() != GroupBySupport.GB_NONE;
}
@Override
public boolean supportsGroupByUnrelated() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsGroupByUnrelated();
}
return getServerMeta().getGroupBySupport() == GroupBySupport.GB_UNRELATED;
}
@Override
public boolean supportsGroupByBeyondSelect() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsGroupByBeyondSelect();
}
return getServerMeta().getGroupBySupport() == GroupBySupport.GB_BEYOND_SELECT;
}
@Override
public boolean supportsLikeEscapeClause() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsLikeEscapeClause();
}
return getServerMeta().getLikeEscapeClauseSupported();
}
@Override
public boolean supportsMultipleResultSets() throws SQLException {
throwIfClosed();
return super.supportsMultipleResultSets();
}
@Override
public boolean supportsMultipleTransactions() throws SQLException {
throwIfClosed();
return super.supportsMultipleTransactions();
}
@Override
public boolean supportsNonNullableColumns() throws SQLException {
throwIfClosed();
return super.supportsNonNullableColumns();
}
@Override
public boolean supportsMinimumSQLGrammar() throws SQLException {
throwIfClosed();
return super.supportsMinimumSQLGrammar();
}
@Override
public boolean supportsCoreSQLGrammar() throws SQLException {
throwIfClosed();
return super.supportsCoreSQLGrammar();
}
@Override
public boolean supportsExtendedSQLGrammar() throws SQLException {
throwIfClosed();
return super.supportsExtendedSQLGrammar();
}
@Override
public boolean supportsANSI92EntryLevelSQL() throws SQLException {
throwIfClosed();
return super.supportsANSI92EntryLevelSQL();
}
@Override
public boolean supportsANSI92IntermediateSQL() throws SQLException {
throwIfClosed();
return super.supportsANSI92IntermediateSQL();
}
@Override
public boolean supportsANSI92FullSQL() throws SQLException {
throwIfClosed();
return super.supportsANSI92FullSQL();
}
@Override
public boolean supportsIntegrityEnhancementFacility() throws SQLException {
throwIfClosed();
return super.supportsIntegrityEnhancementFacility();
}
@Override
public boolean supportsOuterJoins() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsOuterJoins();
}
return getServerMeta().getOuterJoinSupportCount() > 0;
}
@Override
public boolean supportsFullOuterJoins() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsFullOuterJoins();
}
return getServerMeta().getOuterJoinSupportList().contains(OuterJoinSupport.OJ_FULL);
}
@Override
public boolean supportsLimitedOuterJoins() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsFullOuterJoins();
}
return getServerMeta().getOuterJoinSupportCount() > 0
&& !(getServerMeta().getOuterJoinSupportList().contains(OuterJoinSupport.OJ_FULL));
}
@Override
public String getSchemaTerm() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getSchemaTerm();
}
return getServerMeta().getSchemaTerm();
}
@Override
public String getProcedureTerm() throws SQLException {
throwIfClosed();
return super.getProcedureTerm();
}
@Override
public String getCatalogTerm() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getCatalogTerm();
}
return getServerMeta().getCatalogTerm();
}
@Override
public boolean isCatalogAtStart() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.isCatalogAtStart();
}
return getServerMeta().getCatalogAtStart();
}
@Override
public String getCatalogSeparator() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getCatalogSeparator();
}
return getServerMeta().getCatalogSeparator();
}
@Override
public boolean supportsSchemasInDataManipulation() throws SQLException {
throwIfClosed();
return super.supportsSchemasInDataManipulation();
}
@Override
public boolean supportsSchemasInProcedureCalls() throws SQLException {
throwIfClosed();
return super.supportsSchemasInProcedureCalls();
}
@Override
public boolean supportsSchemasInTableDefinitions() throws SQLException {
throwIfClosed();
return super.supportsSchemasInTableDefinitions();
}
@Override
public boolean supportsSchemasInIndexDefinitions() throws SQLException {
throwIfClosed();
return super.supportsSchemasInIndexDefinitions();
}
@Override
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
throwIfClosed();
return super.supportsSchemasInPrivilegeDefinitions();
}
@Override
public boolean supportsCatalogsInDataManipulation() throws SQLException {
throwIfClosed();
return super.supportsCatalogsInDataManipulation();
}
@Override
public boolean supportsCatalogsInProcedureCalls() throws SQLException {
throwIfClosed();
return super.supportsCatalogsInProcedureCalls();
}
@Override
public boolean supportsCatalogsInTableDefinitions() throws SQLException {
throwIfClosed();
return super.supportsCatalogsInTableDefinitions();
}
@Override
public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
throwIfClosed();
return super.supportsCatalogsInIndexDefinitions();
}
@Override
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
throwIfClosed();
return super.supportsCatalogsInPrivilegeDefinitions();
}
@Override
public boolean supportsPositionedDelete() throws SQLException {
throwIfClosed();
return super.supportsPositionedDelete();
}
@Override
public boolean supportsPositionedUpdate() throws SQLException {
throwIfClosed();
return super.supportsPositionedUpdate();
}
@Override
public boolean supportsSelectForUpdate() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsSelectForUpdate();
}
return getServerMeta().getSelectForUpdateSupported();
}
@Override
public boolean supportsStoredProcedures() throws SQLException {
throwIfClosed();
return super.supportsStoredProcedures();
}
@Override
public boolean supportsSubqueriesInComparisons() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsSubqueriesInComparisons();
}
return getServerMeta().getSubquerySupportList().contains(SubQuerySupport.SQ_IN_COMPARISON);
}
@Override
public boolean supportsSubqueriesInExists() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsSubqueriesInExists();
}
return getServerMeta().getSubquerySupportList().contains(SubQuerySupport.SQ_IN_EXISTS);
}
@Override
public boolean supportsSubqueriesInIns() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsSubqueriesInIns();
}
return getServerMeta().getSubquerySupportList().contains(SubQuerySupport.SQ_IN_INSERT);
}
@Override
public boolean supportsSubqueriesInQuantifieds() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsSubqueriesInQuantifieds();
}
return getServerMeta().getSubquerySupportList().contains(SubQuerySupport.SQ_IN_QUANTIFIED);
}
@Override
public boolean supportsCorrelatedSubqueries() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsCorrelatedSubqueries();
}
return getServerMeta().getSubquerySupportList().contains(SubQuerySupport.SQ_CORRELATED);
}
@Override
public boolean supportsUnion() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsUnion();
}
return getServerMeta().getUnionSupportList().contains(UnionSupport.U_UNION);
}
@Override
public boolean supportsUnionAll() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsUnionAll();
}
return getServerMeta().getUnionSupportList().contains(UnionSupport.U_UNION_ALL);
}
@Override
public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
throwIfClosed();
return super.supportsOpenCursorsAcrossCommit();
}
@Override
public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
throwIfClosed();
return super.supportsOpenCursorsAcrossRollback();
}
@Override
public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
throwIfClosed();
return super.supportsOpenStatementsAcrossCommit();
}
@Override
public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
throwIfClosed();
return super.supportsOpenStatementsAcrossRollback();
}
@Override
public int getMaxBinaryLiteralLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxBinaryLiteralLength();
}
return getServerMeta().getMaxBinaryLiteralLength();
}
@Override
public int getMaxCharLiteralLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxCharLiteralLength();
}
return getServerMeta().getMaxCharLiteralLength();
}
@Override
public int getMaxColumnNameLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxColumnNameLength();
}
return getServerMeta().getMaxColumnNameLength();
}
@Override
public int getMaxColumnsInGroupBy() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxColumnsInGroupBy();
}
return getServerMeta().getMaxColumnsInGroupBy();
}
@Override
public int getMaxColumnsInIndex() throws SQLException {
throwIfClosed();
return super.getMaxColumnsInIndex();
}
@Override
public int getMaxColumnsInOrderBy() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxColumnsInOrderBy();
}
return getServerMeta().getMaxColumnsInOrderBy();
}
@Override
public int getMaxColumnsInSelect() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxColumnsInSelect();
}
return getServerMeta().getMaxColumnsInSelect();
}
@Override
public int getMaxColumnsInTable() throws SQLException {
throwIfClosed();
return super.getMaxColumnsInTable();
}
@Override
public int getMaxConnections() throws SQLException {
throwIfClosed();
return super.getMaxConnections();
}
@Override
public int getMaxCursorNameLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxCursorNameLength();
}
return getServerMeta().getMaxCursorNameLength();
}
@Override
public int getMaxIndexLength() throws SQLException {
throwIfClosed();
return super.getMaxIndexLength();
}
@Override
public int getMaxSchemaNameLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxSchemaNameLength();
}
return getServerMeta().getMaxSchemaNameLength();
}
@Override
public int getMaxProcedureNameLength() throws SQLException {
throwIfClosed();
return super.getMaxProcedureNameLength();
}
@Override
public int getMaxCatalogNameLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxCatalogNameLength();
}
return getServerMeta().getMaxCatalogNameLength();
}
@Override
public int getMaxRowSize() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxRowSize();
}
return getServerMeta().getMaxRowSize();
}
@Override
public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.doesMaxRowSizeIncludeBlobs();
}
return getServerMeta().getBlobIncludedInMaxRowSize();
}
@Override
public int getMaxStatementLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxStatementLength();
}
return getServerMeta().getMaxStatementLength();
}
@Override
public int getMaxStatements() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxStatements();
}
return getServerMeta().getMaxStatements();
}
@Override
public int getMaxTableNameLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxTableNameLength();
}
return getServerMeta().getMaxTableNameLength();
}
@Override
public int getMaxTablesInSelect() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxTablesInSelect();
}
return getServerMeta().getMaxTablesInSelect();
}
@Override
public int getMaxUserNameLength() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.getMaxUserNameLength();
}
return getServerMeta().getMaxUserNameLength();
}
@Override
public int getDefaultTransactionIsolation() throws SQLException {
throwIfClosed();
return super.getDefaultTransactionIsolation();
}
@Override
public boolean supportsTransactions() throws SQLException {
throwIfClosed();
if (!getServerMetaSupported()) {
return super.supportsTransactions();
}
return getServerMeta().getTransactionSupported();
}
@Override
public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
throwIfClosed();
return super.supportsTransactionIsolationLevel(level);
}
@Override
public boolean supportsDataDefinitionAndDataManipulationTransactions()
throws SQLException {
throwIfClosed();
return super.supportsDataDefinitionAndDataManipulationTransactions();
}
@Override
public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
throwIfClosed();
return super.supportsDataManipulationTransactionsOnly();
}
@Override
public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
throwIfClosed();
return super.dataDefinitionCausesTransactionCommit();
}
@Override
public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
throwIfClosed();
return super.dataDefinitionIgnoredInTransactions();
}
@Override
public ResultSet getProcedures(String catalog, String schemaPattern,
String procedureNamePattern) throws SQLException {
throwIfClosed();
return super.getProcedures(catalog, schemaPattern, procedureNamePattern);
}
@Override
public ResultSet getProcedureColumns(String catalog, String schemaPattern,
String procedureNamePattern,
String columnNamePattern) throws SQLException {
throwIfClosed();
return super.getProcedureColumns(catalog, schemaPattern,
procedureNamePattern, columnNamePattern);
}
@Override
public ResultSet getTables(String catalog,
String schemaPattern,
String tableNamePattern,
String[] types) throws SQLException {
throwIfClosed();
try {
return super.getTables(catalog, schemaPattern,tableNamePattern, types);
} catch(DrillRuntimeException e) {
Throwables.propagateIfInstanceOf(e.getCause(), SQLException.class);
throw e;
}
}
@Override
public ResultSet getSchemas() throws SQLException {
throwIfClosed();
try {
return super.getSchemas();
} catch(DrillRuntimeException e) {
Throwables.propagateIfInstanceOf(e.getCause(), SQLException.class);
throw e;
}
}
@Override
public ResultSet getCatalogs() throws SQLException {
throwIfClosed();
try {
return super.getCatalogs();
} catch(DrillRuntimeException e) {
Throwables.propagateIfInstanceOf(e.getCause(), SQLException.class);
throw e;
}
}
@Override
public ResultSet getTableTypes() throws SQLException {
throwIfClosed();
return super.getTableTypes();
}
@Override
public ResultSet getColumns(String catalog, String schema, String table,
String columnNamePattern) throws SQLException {
throwIfClosed();
try {
return super.getColumns(catalog, schema, table, columnNamePattern);
} catch(DrillRuntimeException e) {
Throwables.propagateIfInstanceOf(e.getCause(), SQLException.class);
throw e;
}
}
@Override
public ResultSet getColumnPrivileges(String catalog, String schema,
String table,
String columnNamePattern) throws SQLException {
throwIfClosed();
return super.getColumnPrivileges(catalog, schema, table, columnNamePattern);
}
@Override
public ResultSet getTablePrivileges(String catalog, String schemaPattern,
String tableNamePattern) throws SQLException {
throwIfClosed();
return super.getTablePrivileges(catalog, schemaPattern, tableNamePattern);
}
@Override
public ResultSet getBestRowIdentifier(String catalog, String schema,
String table, int scope,
boolean nullable) throws SQLException {
throwIfClosed();
return super.getBestRowIdentifier(catalog, schema, table, scope, nullable);
}
@Override
public ResultSet getVersionColumns(String catalog, String schema,
String table) throws SQLException {
throwIfClosed();
return super.getVersionColumns(catalog, schema, table);
}
@Override
public ResultSet getPrimaryKeys(String catalog, String schema,
String table) throws SQLException {
throwIfClosed();
return super.getPrimaryKeys(catalog, schema, table);
}
@Override
public ResultSet getImportedKeys(String catalog, String schema,
String table) throws SQLException {
throwIfClosed();
return super.getImportedKeys(catalog, schema, table);
}
@Override
public ResultSet getExportedKeys(String catalog, String schema,
String table) throws SQLException {
throwIfClosed();
return super.getExportedKeys(catalog, schema, table);
}
@Override
public ResultSet getCrossReference(
String parentCatalog, String parentSchema, String parentTable,
String foreignCatalog, String foreignSchema,
String foreignTable ) throws SQLException {
throwIfClosed();
return super.getCrossReference(parentCatalog, parentSchema, parentTable,
foreignCatalog, foreignSchema, foreignTable );
}
@Override
public ResultSet getTypeInfo() throws SQLException {
throwIfClosed();
return super.getTypeInfo();
}
@Override
public ResultSet getIndexInfo(String catalog, String schema, String table,
boolean unique,
boolean approximate) throws SQLException {
throwIfClosed();
return super.getIndexInfo(catalog, schema, table, unique, approximate);
}
@Override
public boolean supportsResultSetType(int type) throws SQLException {
throwIfClosed();
return super.supportsResultSetType(type);
}
@Override
public boolean supportsResultSetConcurrency(int type,
int concurrency) throws SQLException {
throwIfClosed();
return super.supportsResultSetConcurrency(type, concurrency);
}
@Override
public boolean ownUpdatesAreVisible(int type) throws SQLException {
throwIfClosed();
try {
return super.ownUpdatesAreVisible(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"ownUpdatesAreVisible(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean ownDeletesAreVisible(int type) throws SQLException {
throwIfClosed();
try {
return super.ownDeletesAreVisible(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"ownDeletesAreVisible(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean ownInsertsAreVisible(int type) throws SQLException {
throwIfClosed();
try {
return super.ownInsertsAreVisible(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"ownInsertsAreVisible(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean othersUpdatesAreVisible(int type) throws SQLException {
throwIfClosed();
try {
return super.othersUpdatesAreVisible(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"othersUpdatesAreVisible(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean othersDeletesAreVisible(int type) throws SQLException {
throwIfClosed();
try {
return super.othersDeletesAreVisible(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"othersDeletesAreVisible(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean othersInsertsAreVisible(int type) throws SQLException {
throwIfClosed();
try {
return super.othersInsertsAreVisible(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"othersInsertsAreVisible(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean updatesAreDetected(int type) throws SQLException {
throwIfClosed();
try {
return super.updatesAreDetected(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"updatesAreDetected(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean deletesAreDetected(int type) throws SQLException {
throwIfClosed();
try {
return super.deletesAreDetected(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"deletesAreDetected(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean insertsAreDetected(int type) throws SQLException {
throwIfClosed();
try {
return super.insertsAreDetected(type);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"insertsAreDetected(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public boolean supportsBatchUpdates() throws SQLException {
throwIfClosed();
return super.supportsBatchUpdates();
}
@Override
public ResultSet getUDTs(String catalog, String schemaPattern,
String typeNamePattern,
int[] types) throws SQLException {
throwIfClosed();
return super.getUDTs(catalog, schemaPattern, typeNamePattern, types);
}
@Override
public Connection getConnection() throws SQLException {
// No already-closed exception required by JDBC.
return super.getConnection();
}
@Override
public boolean supportsSavepoints() throws SQLException {
throwIfClosed();
return super.supportsSavepoints();
}
@Override
public boolean supportsNamedParameters() throws SQLException {
throwIfClosed();
return super.supportsNamedParameters();
}
@Override
public boolean supportsMultipleOpenResults() throws SQLException {
throwIfClosed();
return super.supportsMultipleOpenResults();
}
@Override
public boolean supportsGetGeneratedKeys() throws SQLException {
throwIfClosed();
return super.supportsGetGeneratedKeys();
}
@Override
public ResultSet getSuperTypes(String catalog, String schemaPattern,
String typeNamePattern) throws SQLException {
throwIfClosed();
return super.getSuperTypes(catalog, schemaPattern, typeNamePattern);
}
@Override
public ResultSet getSuperTables(String catalog, String schemaPattern,
String tableNamePattern) throws SQLException {
throwIfClosed();
return super.getSuperTables(catalog, schemaPattern, tableNamePattern);
}
@Override
public ResultSet getAttributes(String catalog, String schemaPattern,
String typeNamePattern,
String attributeNamePattern) throws SQLException {
throwIfClosed();
return super.getAttributes(catalog, schemaPattern, typeNamePattern,
attributeNamePattern);
}
@Override
public boolean supportsResultSetHoldability(int holdability) throws SQLException {
throwIfClosed();
try {
return super.supportsResultSetHoldability(holdability);
}
catch (RuntimeException e) {
if ("todo: implement this method".equals(e.getMessage())) {
throw new SQLFeatureNotSupportedException(
"supportsResultSetHoldability(int) is not supported", e);
}
else {
throw new SQLException(e.getMessage(), e);
}
}
}
@Override
public int getResultSetHoldability() {
// Can't throw any SQLException because Avatica's getResultSetHoldability()
// is missing "throws SQLException".
try {
throwIfClosed();
} catch (AlreadyClosedSqlException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
return super.getResultSetHoldability();
}
@Override
public int getDatabaseMajorVersion() throws SQLException {
throwIfClosed();
Version version = getServerVersion();
if (version == null) {
return super.getDatabaseMajorVersion();
}
return version.getMajorVersion();
}
@Override
public int getDatabaseMinorVersion() throws SQLException {
throwIfClosed();
Version version = getServerVersion();
if (version == null) {
return super.getDatabaseMinorVersion();
}
return version.getMinorVersion();
}
@Override
public int getJDBCMajorVersion() throws SQLException {
throwIfClosed();
return super.getJDBCMajorVersion();
}
@Override
public int getJDBCMinorVersion() throws SQLException {
throwIfClosed();
return super.getJDBCMinorVersion();
}
@Override
public int getSQLStateType() throws SQLException {
throwIfClosed();
return super.getSQLStateType();
}
@Override
public boolean locatorsUpdateCopy() throws SQLException {
throwIfClosed();
return super.locatorsUpdateCopy();
}
@Override
public boolean supportsStatementPooling() throws SQLException {
throwIfClosed();
return super.supportsStatementPooling();
}
@Override
public RowIdLifetime getRowIdLifetime() throws SQLException {
throwIfClosed();
return super.getRowIdLifetime();
}
@Override
public ResultSet getSchemas(String catalog,
String schemaPattern) throws SQLException {
throwIfClosed();
return super.getSchemas(catalog, schemaPattern);
}
@Override
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
throwIfClosed();
return super.supportsStoredFunctionsUsingCallSyntax();
}
@Override
public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
throwIfClosed();
return super.autoCommitFailureClosesAllResultSets();
}
@Override
public ResultSet getClientInfoProperties() throws SQLException {
throwIfClosed();
return super.getClientInfoProperties();
}
@Override
public ResultSet getFunctions(String catalog, String schemaPattern,
String functionNamePattern) throws SQLException {
throwIfClosed();
return super.getFunctions(catalog, schemaPattern, functionNamePattern);
}
@Override
public ResultSet getFunctionColumns(String catalog, String schemaPattern,
String functionNamePattern,
String columnNamePattern) throws SQLException {
throwIfClosed();
return super.getFunctionColumns(catalog, schemaPattern, functionNamePattern,
columnNamePattern);
}
@Override
public ResultSet getPseudoColumns(String catalog, String schemaPattern,
String tableNamePattern,
String columnNamePattern) throws SQLException {
throwIfClosed();
return super.getPseudoColumns(catalog, schemaPattern, tableNamePattern,
columnNamePattern);
}
@Override
public boolean generatedKeyAlwaysReturned() throws SQLException {
throwIfClosed();
return super.generatedKeyAlwaysReturned();
}
}