Repository: tajo Updated Branches: refs/heads/branch-0.11.0 38fa78a04 -> 6ed7c6bcb
TAJO-1776: Fix Invalid column type in JDBC. Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/6ed7c6bc Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/6ed7c6bc Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/6ed7c6bc Branch: refs/heads/branch-0.11.0 Commit: 6ed7c6bcba6b400d61c1a16904cc17b25f74e004 Parents: 38fa78a Author: Jinho Kim <[email protected]> Authored: Thu Aug 20 10:59:44 2015 +0900 Committer: Jinho Kim <[email protected]> Committed: Thu Aug 20 10:59:44 2015 +0900 ---------------------------------------------------------------------- CHANGES | 2 + .../org/apache/tajo/client/ResultSetUtil.java | 80 +++++++-- .../java/org/apache/tajo/jdbc/TestTajoJdbc.java | 3 +- .../tajo/jdbc/util/TestResultSetUtil.java | 179 +++++++++++++++++++ 4 files changed, 244 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/6ed7c6bc/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 3cb18eb..4566306 100644 --- a/CHANGES +++ b/CHANGES @@ -227,6 +227,8 @@ Release 0.11.0 - unreleased BUG FIXES + TAJO-1776: Fix Invalid column type in JDBC. (jinho) + TAJO-1781: Join condition is still not found when it exists in OR clause. (jihoon) http://git-wip-us.apache.org/repos/asf/tajo/blob/6ed7c6bc/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java ---------------------------------------------------------------------- diff --git a/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java b/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java index 7f4746c..248de76 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/ResultSetUtil.java @@ -18,7 +18,7 @@ package org.apache.tajo.client; -import org.apache.tajo.common.TajoDataTypes; +import org.apache.tajo.common.TajoDataTypes.DataType; import org.apache.tajo.exception.TajoRuntimeException; import org.apache.tajo.exception.UnsupportedException; @@ -52,8 +52,10 @@ public class ResultSetUtil { return sb.toString(); } - public static String toSqlType(TajoDataTypes.DataType type) { + public static String toSqlType(DataType type) { switch (type.getType()) { + case BIT: + return "bit"; case BOOLEAN: return "boolean"; case INT1: @@ -67,30 +69,36 @@ public class ResultSetUtil { case FLOAT4: return "float"; case FLOAT8: - return "float8"; + return "double"; case NUMERIC: return "numeric"; case VARBINARY: return "bytea"; - case CHAR: - return "character"; case DATE: return "date"; case TIMESTAMP: return "timestamp"; case TIME: return "time"; + case CHAR: case VARCHAR: - return "varchar"; case TEXT: return "varchar"; + case BLOB: + return "blob"; + case RECORD: + return "struct"; + case NULL_TYPE: + return "null"; default: throw new TajoRuntimeException(new UnsupportedException("unknown data type '" + type.getType().name() + "'")); } } - public static int tajoTypeToSqlType(TajoDataTypes.DataType type) throws SQLException { + public static int tajoTypeToSqlType(DataType type) throws SQLException { switch (type.getType()) { + case BIT: + return Types.BIT; case BOOLEAN: return Types.BOOLEAN; case INT1: @@ -113,28 +121,37 @@ public class ResultSetUtil { return Types.TIMESTAMP; case TIME: return Types.TIME; + case CHAR: case VARCHAR: - return Types.VARCHAR; case TEXT: return Types.VARCHAR; + case BLOB: + return Types.BLOB; + case RECORD: + return Types.STRUCT; + case NULL_TYPE: + return Types.NULL; default: throw new SQLException("Unrecognized column type: " + type); } } public static int columnDisplaySize(int columnType) throws SQLException { - // according to hiveTypeToSqlType possible options are: - switch(columnType) { + + switch (columnType) { + case Types.BIT: case Types.BOOLEAN: - return columnPrecision(columnType); + case Types.CHAR: case Types.VARCHAR: - return Integer.MAX_VALUE; // hive has no max limit for strings + return columnPrecision(columnType); case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: return columnPrecision(columnType) + 1; // allow +/- case Types.TIMESTAMP: + case Types.DATE: + case Types.TIME: return columnPrecision(columnType); // see http://download.oracle.com/javase/6/docs/api/constant-values.html#java.lang.Float.MAX_EXPONENT case Types.FLOAT: @@ -144,18 +161,30 @@ public class ResultSetUtil { return 25; // e.g. -(17#).e-#### case Types.DECIMAL: return Integer.MAX_VALUE; + case Types.NULL: + return 4; + case Types.BLOB: + case Types.BINARY: + case Types.ARRAY: + case Types.STRUCT: default: - throw new SQLException("Invalid column type: " + columnType); + return 0; //unknown width } } public static int columnPrecision(int columnType) throws SQLException { - // according to hiveTypeToSqlType possible options are: - switch(columnType) { + + switch (columnType) { + case Types.BIT: case Types.BOOLEAN: return 1; + case Types.CHAR: case Types.VARCHAR: - return Integer.MAX_VALUE; // hive has no max limit for strings + case Types.BLOB: + case Types.BINARY: + case Types.STRUCT: + case Types.ARRAY: + return Integer.MAX_VALUE; case Types.TINYINT: return 3; case Types.SMALLINT: @@ -168,29 +197,44 @@ public class ResultSetUtil { return 7; case Types.DOUBLE: return 15; + case Types.DATE: + return 10; + case Types.TIME: + return 18; case Types.TIMESTAMP: return 29; case Types.DECIMAL: return Integer.MAX_VALUE; + case Types.NULL: + return 0; default: throw new SQLException("Invalid column type: " + columnType); } } public static int columnScale(int columnType) throws SQLException { - // according to hiveTypeToSqlType possible options are: - switch(columnType) { + + switch (columnType) { case Types.BOOLEAN: + case Types.CHAR: case Types.VARCHAR: case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: + case Types.DATE: + case Types.BIT: + case Types.BLOB: + case Types.BINARY: + case Types.ARRAY: + case Types.STRUCT: + case Types.NULL: return 0; case Types.FLOAT: return 7; case Types.DOUBLE: return 15; + case Types.TIME: case Types.TIMESTAMP: return 9; case Types.DECIMAL: http://git-wip-us.apache.org/repos/asf/tajo/blob/6ed7c6bc/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java ---------------------------------------------------------------------- diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java index acbc1a8..e6d01fe 100644 --- a/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java +++ b/tajo-core-tests/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java @@ -23,7 +23,6 @@ import org.apache.tajo.*; import org.apache.tajo.catalog.CatalogUtil; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.TableDesc; -import org.apache.tajo.client.QueryClient; import org.apache.tajo.client.QueryStatus; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -435,7 +434,7 @@ public class TestTajoJdbc extends QueryTestCaseBase { assertEquals("integer", rsmd.getColumnTypeName(1)); assertEquals("varchar", rsmd.getColumnTypeName(2)); - assertEquals("float8", rsmd.getColumnTypeName(3)); + assertEquals("double", rsmd.getColumnTypeName(3)); assertEquals("timestamp", rsmd.getColumnTypeName(4)); assertEquals("date", rsmd.getColumnTypeName(5)); assertEquals("time", rsmd.getColumnTypeName(6)); http://git-wip-us.apache.org/repos/asf/tajo/blob/6ed7c6bc/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/util/TestResultSetUtil.java ---------------------------------------------------------------------- diff --git a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/util/TestResultSetUtil.java b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/util/TestResultSetUtil.java new file mode 100644 index 0000000..7094a24 --- /dev/null +++ b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/util/TestResultSetUtil.java @@ -0,0 +1,179 @@ +/** + * 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.jdbc.util; + +import com.google.common.collect.Lists; +import org.apache.tajo.catalog.CatalogUtil; +import org.apache.tajo.client.ResultSetUtil; +import org.apache.tajo.common.TajoDataTypes.DataType; +import org.apache.tajo.common.TajoDataTypes.Type; +import org.junit.Test; + +import java.sql.SQLException; +import java.sql.Types; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class TestResultSetUtil { + + @Test + public void testDataTypes() throws Exception { + for (DataType type : getDataTyps()) { + validate(type); + } + } + + private void validate(DataType type) throws SQLException { + int sqlType = ResultSetUtil.tajoTypeToSqlType(type); + + switch (type.getType()) { + + case BIT: + assertEquals(Types.BIT, sqlType); + assertEquals("bit", ResultSetUtil.toSqlType(type)); + assertEquals(1, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(1, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case BOOLEAN: + assertEquals(Types.BOOLEAN, sqlType); + assertEquals("boolean", ResultSetUtil.toSqlType(type)); + assertEquals(1, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(1, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case INT1: + assertEquals(Types.TINYINT, sqlType); + assertEquals("tinyint", ResultSetUtil.toSqlType(type)); + assertEquals(4, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(3, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case INT2: + assertEquals(Types.SMALLINT, sqlType); + assertEquals("smallint", ResultSetUtil.toSqlType(type)); + assertEquals(6, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(5, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case INT4: + assertEquals(Types.INTEGER, sqlType); + assertEquals("integer", ResultSetUtil.toSqlType(type)); + assertEquals(11, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(10, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case INT8: + assertEquals(Types.BIGINT, sqlType); + assertEquals("bigint", ResultSetUtil.toSqlType(type)); + assertEquals(20, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(19, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case FLOAT4: + assertEquals(Types.FLOAT, sqlType); + assertEquals("float", ResultSetUtil.toSqlType(type)); + assertEquals(24, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(7, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(7, ResultSetUtil.columnScale(sqlType)); + break; + case FLOAT8: + assertEquals(Types.DOUBLE, sqlType); + assertEquals("double", ResultSetUtil.toSqlType(type)); + assertEquals(25, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(15, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(15, ResultSetUtil.columnScale(sqlType)); + break; + case DATE: + assertEquals(Types.DATE, sqlType); + assertEquals("date", ResultSetUtil.toSqlType(type)); + assertEquals(10, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(10, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case TIMESTAMP: + assertEquals(Types.TIMESTAMP, sqlType); + assertEquals("timestamp", ResultSetUtil.toSqlType(type)); + assertEquals(29, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(29, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(9, ResultSetUtil.columnScale(sqlType)); + break; + case TIME: + assertEquals(Types.TIME, sqlType); + assertEquals("time", ResultSetUtil.toSqlType(type)); + assertEquals(18, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(18, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(9, ResultSetUtil.columnScale(sqlType)); + break; + case CHAR: + case VARCHAR: + case TEXT: + assertEquals(Types.VARCHAR, sqlType); + assertEquals("varchar", ResultSetUtil.toSqlType(type)); + assertEquals(Integer.MAX_VALUE, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(Integer.MAX_VALUE, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case BLOB: + assertEquals(Types.BLOB, sqlType); + assertEquals("blob", ResultSetUtil.toSqlType(type)); + assertEquals(0, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(Integer.MAX_VALUE, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case RECORD: + assertEquals(Types.STRUCT, sqlType); + assertEquals("struct", ResultSetUtil.toSqlType(type)); + assertEquals(0, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(Integer.MAX_VALUE, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + case NULL_TYPE: + assertEquals(Types.NULL, sqlType); + assertEquals("null", ResultSetUtil.toSqlType(type)); + assertEquals(4, ResultSetUtil.columnDisplaySize(sqlType)); + assertEquals(0, ResultSetUtil.columnPrecision(sqlType)); + assertEquals(0, ResultSetUtil.columnScale(sqlType)); + break; + default: + fail("Unrecognized column type: " + type); + break; + } + } + + private List<DataType> getDataTyps() { + List<DataType> typeList = Lists.newArrayList(); + for (Type type : getSupportDataTyps()) { + typeList.add(CatalogUtil.newSimpleDataType(type)); + } + return typeList; + } + + private Type[] getSupportDataTyps() { + return new Type[]{Type.NULL_TYPE, Type.BOOLEAN, Type.BIT, + Type.INT1, Type.INT2, Type.INT4, Type.INT8, + Type.FLOAT4, Type.FLOAT8, + Type.CHAR, Type.VARCHAR, Type.TEXT, + Type.DATE, Type.TIME, Type.TIMESTAMP, + Type.BLOB, + Type.RECORD}; + } +}
