TAJO-1030: Not supported JDBC APIs should return empty results instead of Exception. (Hyoungjun Kim via hyunsik)
Closes #145 Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/029054b4 Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/029054b4 Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/029054b4 Branch: refs/heads/block_iteration Commit: 029054b45c158159325a68ac1491256e3abe71f4 Parents: 68b44da Author: Hyunsik Choi <[email protected]> Authored: Sat Oct 4 17:56:12 2014 -0700 Committer: Hyunsik Choi <[email protected]> Committed: Sat Oct 4 17:56:12 2014 -0700 ---------------------------------------------------------------------- CHANGES | 3 + .../apache/tajo/catalog/CatalogConstants.java | 2 + .../apache/tajo/jdbc/TajoResultSetMetaData.java | 8 +- .../apache/tajo/common/type/TajoTypeUtil.java | 183 +++++++++++++++++++ .../tajo/jdbc/TestTajoDatabaseMetaData.java | 111 ++++++++++- .../apache/tajo/jdbc/TajoDatabaseMetaData.java | 101 ++++++++-- 6 files changed, 385 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/029054b4/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index d9744d1..56f267e 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,9 @@ Release 0.9.0 - unreleased IMPROVEMENT + TAJO-1030: Not supported JDBC APIs should return empty results instead of + Exception. (Hyoungjun Kim via hyunsik) + TAJO-983: Worker should directly read Intermediate data stored in localhost rather than fetching. (Mai Hai Thanh via hyunsik) http://git-wip-us.apache.org/repos/asf/tajo/blob/029054b4/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java index d823f25..6ec52b9 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogConstants.java @@ -25,6 +25,8 @@ public class CatalogConstants { public final static int MAX_IDENTIFIER_LENGTH = 128; // Linux and BSD's max username length is 32. For compatibility with other systems, we should follow it. public final static int MAX_USERNAME_LENGTH = 32; + public final static int MAX_STATEMENT_LENGTH = 128 * 1024; + public final static int MAX_CONNECTION_LENGTH = 10 * 1024; public static final String STORE_CLASS="tajo.catalog.store.class"; http://git-wip-us.apache.org/repos/asf/tajo/blob/029054b4/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java ---------------------------------------------------------------------- diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java index 5b7f822..8811c13 100644 --- a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java +++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSetMetaData.java @@ -26,6 +26,7 @@ import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.Schema; import org.apache.tajo.client.ResultSetUtil; import org.apache.tajo.common.TajoDataTypes.DataType; +import org.apache.tajo.common.type.TajoTypeUtil; import java.sql.ResultSetMetaData; import java.sql.SQLException; @@ -112,7 +113,7 @@ public class TajoResultSetMetaData implements ResultSetMetaData { @Override public String getSchemaName(int column) throws SQLException { - throw new SQLFeatureNotSupportedException("getSchemaName not supported"); + return ""; } @Override @@ -132,7 +133,7 @@ public class TajoResultSetMetaData implements ResultSetMetaData { @Override public boolean isCurrency(int column) throws SQLException { - throw new SQLFeatureNotSupportedException("isCurrency not supported"); + return false; } @Override @@ -157,7 +158,8 @@ public class TajoResultSetMetaData implements ResultSetMetaData { @Override public boolean isSigned(int column) throws SQLException { - throw new SQLFeatureNotSupportedException("isSigned not supported"); + DataType type = schema.getColumn(column - 1).getDataType(); + return TajoTypeUtil.isSigned(type.getType()); } @Override http://git-wip-us.apache.org/repos/asf/tajo/blob/029054b4/tajo-common/src/main/java/org/apache/tajo/common/type/TajoTypeUtil.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/common/type/TajoTypeUtil.java b/tajo-common/src/main/java/org/apache/tajo/common/type/TajoTypeUtil.java new file mode 100644 index 0000000..c4bfec4 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/common/type/TajoTypeUtil.java @@ -0,0 +1,183 @@ +/** + * 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.tajo.common.type; + +import org.apache.tajo.common.TajoDataTypes.Type; +import org.apache.tajo.datum.*; + +import java.sql.DatabaseMetaData; +import java.sql.Types; +import java.util.ArrayList; +import java.util.List; + +public class TajoTypeUtil { + private static List<Datum[]> typeInfos = new ArrayList<Datum[]>(); + + public static List<Datum[]> getTypeInfos() { + synchronized (typeInfos) { + if (typeInfos.isEmpty()) { + for (Type eachType : Type.values()) { + if (!isUserDataType(eachType)) { + continue; + } + Datum[] datums = new Datum[18]; + + int index = 0; + datums[index++] = new TextDatum(eachType.name()); //TYPE_NAME + datums[index++] = new Int2Datum((short) getJavaSqlType(eachType)); //DATA_TYPE + datums[index++] = new Int4Datum(getPrecision(eachType)); //PRECISION + datums[index++] = new TextDatum(getLiteralPrefix(eachType)); //LITERAL_PREFIX + datums[index++] = new TextDatum(getLiteralPrefix(eachType)); //LITERAL_SUFFIX + datums[index++] = new TextDatum(""); //CREATE_PARAMS + datums[index++] = new Int2Datum((short) DatabaseMetaData.typeNullable); //NULLABLE + datums[index++] = BooleanDatum.TRUE; //CASE_SENSITIVE + datums[index++] = new Int2Datum(getSearchable(eachType)); //SEARCHABLE + datums[index++] = BooleanDatum.FALSE; //UNSIGNED_ATTRIBUTE + datums[index++] = BooleanDatum.FALSE; //FIXED_PREC_SCALE + datums[index++] = BooleanDatum.FALSE; //AUTO_INCREMENT + datums[index++] = new TextDatum(eachType.name()); //LOCAL_TYPE_NAME + datums[index++] = new Int2Datum((short) 0); //MINIMUM_SCALE + datums[index++] = new Int2Datum((short) 0); //MAXIMUM_SCALE + datums[index++] = NullDatum.get(); //SQL_DATA_TYPE + datums[index++] = NullDatum.get(); //SQL_DATETIME_SUB + datums[index++] = new Int4Datum(getNumPrecRadix(eachType)); //NUM_PREC_RADIX + + typeInfos.add(datums); + } + } + return typeInfos; + } + } + + public static boolean isUserDataType(Type type) { + switch (type) { + case INT1: + case INT2: + case INT4: + case INT8: + case FLOAT4: + case FLOAT8: + case DATE: + case TIME: + case TIMESTAMP: + case NUMERIC: + case VARCHAR: + case TEXT: return true; + default: return false; + } + } + + public static int getJavaSqlType(Type type) { + switch (type) { + case INT1: return Types.TINYINT; + case INT2: return Types.SMALLINT; + case INT4: return Types.INTEGER; + case INT8: return Types.BIGINT; + case FLOAT4: return Types.FLOAT; + case FLOAT8: return Types.DOUBLE; + case VARCHAR: + case TEXT: return Types.VARCHAR; + case DATE: return Types.DATE; + case TIME: return Types.TIME; + case TIMESTAMP: return Types.TIMESTAMP; + case NUMERIC: return Types.DECIMAL; + default: return Types.VARCHAR; + } + } + + public static int getPrecision(Type type) { + switch (type) { + case INT1: return 3; + case INT2: return 5; + case INT4: return 10; + case INT8: return 19; + case FLOAT4: return 7; + case FLOAT8: return 15; + case DATE: + case TIME: + case TIMESTAMP: return 0; + default: return Integer.MAX_VALUE; + } + } + + public static String getLiteralPrefix(Type type) { + switch (type) { + case VARCHAR: + case TEXT: return "'"; + default: return ""; + } + } + + public static short getSearchable(Type type) { + /* + * DatabaseMetaData.typePredNone - No support + * DatabaseMetaData.typePredChar - Only support with WHERE .. LIKE + * DatabaseMetaData.typePredBasic - Supported except for WHERE .. LIKE + * DatabaseMetaData.typeSearchable - Supported for all WHERE .. + */ + switch (type) { + case INT1: + case INT2: + case INT4: + case INT8: + case FLOAT4: + case FLOAT8: + case DATE: + case TIME: + case TIMESTAMP: + case NUMERIC: return DatabaseMetaData.typePredBasic; + case VARCHAR: + case TEXT: return DatabaseMetaData.typeSearchable; + default: return DatabaseMetaData.typePredBasic; + } + } + + public static int getNumPrecRadix(Type type) { + switch (type) { + case INT1: + case INT2: + case INT4: + case INT8: + return 10; + case FLOAT4: + case FLOAT8: + return 2; + default: + return 0; + } + } + + public static boolean isSigned(Type type) { + switch (type) { + case INT1: + case INT2: + case INT4: + case INT8: + case FLOAT4: + case FLOAT8: + return true; + case DATE: + case TIME: + case TIMESTAMP: + case VARCHAR: + case TEXT: return false; + default: return true; + } + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/029054b4/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java index c23a7a1..dfb0269 100644 --- a/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java +++ b/tajo-core/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java @@ -22,6 +22,7 @@ import com.google.common.collect.Sets; import org.apache.tajo.QueryTestCaseBase; import org.apache.tajo.TajoConstants; import org.apache.tajo.catalog.CatalogUtil; +import org.apache.tajo.common.type.TajoTypeUtil; import org.apache.tajo.util.TUtil; import org.junit.BeforeClass; import org.junit.Test; @@ -30,8 +31,7 @@ import java.net.InetSocketAddress; import java.sql.*; import java.util.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public class TestTajoDatabaseMetaData extends QueryTestCaseBase { private static InetSocketAddress tajoMasterAddress; @@ -394,4 +394,111 @@ public class TestTajoDatabaseMetaData extends QueryTestCaseBase { executeString("DROP DATABASE db2"); } } + + @Test + public void testEmptyMetaInfo() throws Exception { + if (!testingCluster.isHCatalogStoreRunning()) { + String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(), + TajoConstants.DEFAULT_DATABASE_NAME); + Connection conn = DriverManager.getConnection(connUri); + + try { + DatabaseMetaData meta = conn.getMetaData(); + + ResultSet res = meta.getProcedures(null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getProcedureColumns(null, null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getUDTs(null, null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getColumnPrivileges(null, null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getTablePrivileges(null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getBestRowIdentifier(null, null, null, 0, false); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getVersionColumns(null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getPrimaryKeys(null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getImportedKeys(null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getExportedKeys(null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getCrossReference(null, null, null, null, null, null); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getIndexInfo(null, null, null, false, false); + assertNotNull(res); + assertFalse(res.next()); + + res = meta.getClientInfoProperties(); + assertNotNull(res); + assertFalse(res.next()); + } finally { + conn.close(); + } + } + } + + @Test + public void testGetTypeInfo() throws Exception { + if (!testingCluster.isHCatalogStoreRunning()) { + String connUri = TestTajoJdbc.buildConnectionUri(tajoMasterAddress.getHostName(), tajoMasterAddress.getPort(), + TajoConstants.DEFAULT_DATABASE_NAME); + Connection conn = DriverManager.getConnection(connUri); + + try { + DatabaseMetaData meta = conn.getMetaData(); + + ResultSet res = meta.getTypeInfo(); + + assertNotNull(res); + + int numTypes = 0; + + String[] columnNames = {"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"}; + + while (res.next()) { + for (int i = 0; i < columnNames.length; i++) { + Object value = res.getObject(columnNames[i]); + if (i == 15 || i == 16) { + assertNull(value); + } else { + assertNotNull(value); + } + } + numTypes++; + } + + assertEquals(numTypes, TajoTypeUtil.getTypeInfos().size()); + } finally { + conn.close(); + } + } + } } http://git-wip-us.apache.org/repos/asf/tajo/blob/029054b4/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java ---------------------------------------------------------------------- diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java index c422751..0ceb589 100644 --- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java +++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java @@ -24,8 +24,12 @@ import org.apache.tajo.catalog.*; import org.apache.tajo.client.ResultSetUtil; import org.apache.tajo.client.TajoClient; import org.apache.tajo.common.TajoDataTypes.Type; +import org.apache.tajo.common.type.TajoTypeUtil; +import org.apache.tajo.datum.Datum; import org.apache.tajo.datum.NullDatum; import org.apache.tajo.datum.TextDatum; +import org.apache.tajo.storage.Tuple; +import org.apache.tajo.storage.VTuple; import org.apache.tajo.util.VersionInfo; import java.sql.*; @@ -155,7 +159,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { @Override public String getProcedureTerm() throws SQLException { - throw new SQLFeatureNotSupportedException("getProcedureTerm not supported"); + return new String("UDF"); } @Override @@ -210,17 +214,17 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { @Override public int getMaxConnections() throws SQLException { - throw new SQLFeatureNotSupportedException("getMaxConnections not supported"); + return CatalogConstants.MAX_CONNECTION_LENGTH; } @Override public int getMaxCursorNameLength() throws SQLException { - throw new SQLFeatureNotSupportedException("getMaxCursorNameLength not supported"); + return CatalogConstants.MAX_IDENTIFIER_LENGTH; } @Override public int getMaxIndexLength() throws SQLException { - throw new SQLFeatureNotSupportedException("getMaxIndexLength not supported"); + return 0; } @Override @@ -250,12 +254,12 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { @Override public int getMaxStatementLength() throws SQLException { - throw new SQLFeatureNotSupportedException("getMaxStatementLength not supported"); + return CatalogConstants.MAX_STATEMENT_LENGTH; } @Override public int getMaxStatements() throws SQLException { - throw new SQLFeatureNotSupportedException("getMaxStatements not supported"); + return 0; } @Override @@ -281,26 +285,41 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { @Override public boolean dataDefinitionCausesTransactionCommit() throws SQLException { - throw new SQLFeatureNotSupportedException("dataDefinitionCausesTransactionCommit not supported"); + return false; } @Override public boolean dataDefinitionIgnoredInTransactions() throws SQLException { - throw new SQLFeatureNotSupportedException("dataDefinitionIgnoredInTransactions not supported"); + return false; } @Override public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { - throw new SQLFeatureNotSupportedException("stored procedures not supported"); + return new TajoMetaDataResultSet(Arrays.asList("PROCEDURE_CAT", "PROCEDURE_SCHEM", + "PROCEDURE_NAME", "NUM_INPUT_PARAMS", "NUM_OUTPUT_PARAMS", "NUM_RESULT_SETS", "REMARKS", + "PROCEDURE_TYPE"), + Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.INT4, Type.INT4, Type.INT4, + Type.VARCHAR, Type.INT2), + new ArrayList<MetaDataTuple>()); } @Override public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException { - throw new SQLFeatureNotSupportedException("stored procedures not supported"); + return new TajoMetaDataResultSet(Arrays.asList( + "PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME", "COLUMN_NAME", "COLUMN_TYPE", + "DATA_TYPE", "TYPE_NAME", "PRECISION", "LENGTH", "SCALE", + "RADIX", "NULLABLE", "REMARKS", "COLUMN_DEF", "SQL_DATA_TYPE", + "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE", "SPECIFIC_NAME"), + Arrays.asList( + Type.VARCHAR, Type.VARCHAR, Type.VARCHAR,Type.VARCHAR, Type.INT2, + Type.INT2, Type.VARCHAR, Type.INT4, Type.INT4, Type.INT2, + Type.INT2, Type.INT2, Type.VARCHAR, Type.VARCHAR, Type.INT2, + Type.INT2, Type.INT2, Type.INT1, Type.VARCHAR, Type.VARCHAR), + new ArrayList<MetaDataTuple>()); } /** @@ -550,25 +569,39 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { - throw new SQLFeatureNotSupportedException("privileges not supported"); + return new TajoMetaDataResultSet(Arrays.asList("TABLE_CAT", "TABLE_SCHEM", + "TABLE_NAME", "COLUMN_NAME", "GRANTOR", "GRANTEE", "PRIVILEGE", + "IS_GRANTABLE"), + Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, + Type.VARCHAR, Type.VARCHAR), + new ArrayList<MetaDataTuple>()); } @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { - throw new SQLFeatureNotSupportedException("privileges not supported"); + return new TajoMetaDataResultSet(Arrays.asList("TABLE_CAT", "TABLE_SCHEM", + "TABLE_NAME", "GRANTOR", "GRANTEE", "PRIVILEGE", "IS_GRANTABLE"), + Arrays.asList(Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.VARCHAR), + new ArrayList<MetaDataTuple>()); } @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { - throw new SQLFeatureNotSupportedException("row identifiers not supported"); + return new TajoMetaDataResultSet(Arrays.asList("SCOPE", "COLUMN_NAME", + "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "PSEUDO_COLUMN"), + Arrays.asList(Type.INT2, Type.VARCHAR, Type.INT2, Type.VARCHAR, Type.INT4, Type.INT4, Type.INT2, Type.INT2), + new ArrayList<MetaDataTuple>()); } @Override public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { - throw new SQLFeatureNotSupportedException("version columns not supported"); + return new TajoMetaDataResultSet(Arrays.asList("SCOPE", "COLUMN_NAME", + "DATA_TYPE", "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", "PSEUDO_COLUMN"), + Arrays.asList(Type.INT2, Type.VARCHAR, Type.INT2, Type.VARCHAR, Type.INT4, Type.INT4, Type.INT2, Type.INT2), + new ArrayList<MetaDataTuple>()); } @Override @@ -612,15 +645,45 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { return new TajoMetaDataResultSet(importedExportedSchema, new ArrayList<MetaDataTuple>()); } + @Override public ResultSet getTypeInfo() throws SQLException { - throw new UnsupportedOperationException("getTypeInfo not supported"); + List<MetaDataTuple> tuples = new ArrayList<MetaDataTuple>(); + for (Datum[] eachDatums: TajoTypeUtil.getTypeInfos()) { + MetaDataTuple tuple = new MetaDataTuple(eachDatums.length); + for (int i = 0; i < eachDatums.length; i++) { + tuple.put(i, eachDatums[i]); + } + tuples.add(tuple); + } + + return new TajoMetaDataResultSet( + 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"), + Arrays.asList( + Type.VARCHAR, Type.INT2, Type.INT4, Type.VARCHAR, Type.VARCHAR, + Type.VARCHAR, Type.INT2, Type.BOOLEAN, Type.INT2, Type.BOOLEAN, + Type.BOOLEAN, Type.BOOLEAN, Type.VARCHAR, Type.INT2, Type.INT2, + Type.INT4, Type.INT4, Type.INT4) + , tuples); } @Override public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { - throw new SQLFeatureNotSupportedException("indexes not supported"); + return new TajoMetaDataResultSet( + 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( + Type.VARCHAR, Type.VARCHAR, Type.VARCHAR, Type.BOOLEAN, Type.VARCHAR, + Type.VARCHAR, Type.INT2, Type.INT2, Type.VARCHAR, Type.VARCHAR, + Type.INT4, Type.INT4, Type.VARCHAR) + , new ArrayList<MetaDataTuple>()); } @Override @@ -727,7 +790,9 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { @Override public ResultSet getClientInfoProperties() throws SQLException { - throw new SQLFeatureNotSupportedException("getClientInfoProperties not supported"); + return new TajoMetaDataResultSet(Arrays.asList("NAME", "MAX_LEN", "DEFAULT_VALUE", "DESCRIPTION"), + Arrays.asList(Type.VARCHAR, Type.INT4, Type.VARCHAR, Type.VARCHAR), + new ArrayList<MetaDataTuple>()); } @Override @@ -1203,7 +1268,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData { public boolean generatedKeyAlwaysReturned() throws SQLException { // JDK 1.7 - throw new SQLFeatureNotSupportedException("generatedKeyAlwaysReturned not supported"); + return false; } public ResultSet getPseudoColumns(String catalog, String schemaPattern,
