diff --git a/database-commons/pom.xml b/database-commons/pom.xml
index a704d967e..29f424bd6 100644
--- a/database-commons/pom.xml
+++ b/database-commons/pom.xml
@@ -65,6 +65,12 @@
${mockrunner.version}
test
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
diff --git a/database-commons/src/main/java/io/cdap/plugin/db/CommonSchemaReader.java b/database-commons/src/main/java/io/cdap/plugin/db/CommonSchemaReader.java
index 1da471c9e..ff1284249 100644
--- a/database-commons/src/main/java/io/cdap/plugin/db/CommonSchemaReader.java
+++ b/database-commons/src/main/java/io/cdap/plugin/db/CommonSchemaReader.java
@@ -90,14 +90,10 @@ public Schema getSchema(ResultSetMetaData metadata, int index) throws SQLExcepti
case Types.DECIMAL:
int precision = metadata.getPrecision(index); // total number of digits
int scale = metadata.getScale(index); // digits after the decimal point
- // decimal type with scale 0 is not supported
- // possible cases are:
- // - scale is set to 0
- // - only precision is set - by default scale is 0
- // - precision and scale are set as dynamic - by default scale is 0
- if (scale == 0) {
- throw new SQLException(new UnsupportedTypeException(String.format("Unsupported SQL Type: %s with scale 0.",
- metadata.getColumnTypeName(index))));
+ // decimal type with precision 0 is not supported
+ if (precision == 0) {
+ throw new SQLException(new UnsupportedTypeException(
+ String.format("Unsupported SQL Type: %s with precision 0.", metadata.getColumnTypeName(index))));
}
return Schema.decimalOf(precision, scale);
diff --git a/database-commons/src/test/java/io/cdap/plugin/db/CommonSchemaReaderTest.java b/database-commons/src/test/java/io/cdap/plugin/db/CommonSchemaReaderTest.java
new file mode 100644
index 000000000..48709eaf6
--- /dev/null
+++ b/database-commons/src/test/java/io/cdap/plugin/db/CommonSchemaReaderTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * Licensed 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 io.cdap.plugin.db;
+
+import io.cdap.cdap.api.data.schema.Schema;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CommonSchemaReaderTest {
+
+ CommonSchemaReader reader;
+
+ @Mock
+ ResultSetMetaData metadata;
+
+ @Before
+ public void before() {
+ reader = new CommonSchemaReader();
+ }
+
+ @Test
+ public void testGetSchemaHandlesNull() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.NULL);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.NULL));
+ }
+
+ @Test
+ public void testGetSchemaHandlesRowID() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.ROWID);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.STRING));
+ }
+
+ @Test
+ public void testGetSchemaHandlesBoolean() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.BOOLEAN);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.BOOLEAN));
+
+ when(metadata.getColumnType(eq(2))).thenReturn(Types.BIT);
+ Assert.assertEquals(reader.getSchema(metadata, 2), Schema.of(Schema.Type.BOOLEAN));
+ }
+
+ @Test
+ public void testGetSchemaHandlesInt() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.TINYINT);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.INT));
+
+ when(metadata.getColumnType(eq(2))).thenReturn(Types.SMALLINT);
+ Assert.assertEquals(reader.getSchema(metadata, 2), Schema.of(Schema.Type.INT));
+
+ when(metadata.getColumnType(eq(3))).thenReturn(Types.INTEGER);
+ Assert.assertEquals(reader.getSchema(metadata, 3), Schema.of(Schema.Type.INT));
+ }
+
+ @Test
+ public void testGetSchemaHandlesLong() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.BIGINT);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.LONG));
+ }
+
+ @Test
+ public void testGetSchemaHandlesFloat() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.REAL);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.FLOAT));
+
+ when(metadata.getColumnType(eq(2))).thenReturn(Types.FLOAT);
+ Assert.assertEquals(reader.getSchema(metadata, 2), Schema.of(Schema.Type.FLOAT));
+ }
+
+ @Test
+ public void testGetSchemaHandlesNumeric() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.NUMERIC);
+ when(metadata.getPrecision(eq(1))).thenReturn(10);
+ when(metadata.getScale(eq(1))).thenReturn(0);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.decimalOf(10, 0));
+
+ when(metadata.getColumnType(eq(2))).thenReturn(Types.DECIMAL);
+ when(metadata.getPrecision(eq(2))).thenReturn(10);
+ when(metadata.getScale(eq(2))).thenReturn(1);
+ Assert.assertEquals(reader.getSchema(metadata, 2), Schema.decimalOf(10, 1));
+ }
+
+ @Test
+ public void testGetSchemaHandlesDouble() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.DOUBLE);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.DOUBLE));
+ }
+
+ @Test
+ public void testGetSchemaHandlesDate() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.DATE);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.LogicalType.DATE));
+ }
+
+ @Test
+ public void testGetSchemaHandlesTime() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.TIME);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.LogicalType.TIME_MICROS));
+ }
+
+ @Test
+ public void testGetSchemaHandlesTimestamp() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.TIMESTAMP);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.LogicalType.TIMESTAMP_MICROS));
+ }
+
+ @Test
+ public void testGetSchemaHandlesBytes() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.BINARY);
+ Assert.assertEquals(reader.getSchema(metadata, 1), Schema.of(Schema.Type.BYTES));
+
+ when(metadata.getColumnType(eq(2))).thenReturn(Types.VARBINARY);
+ Assert.assertEquals(reader.getSchema(metadata, 2), Schema.of(Schema.Type.BYTES));
+
+ when(metadata.getColumnType(eq(3))).thenReturn(Types.LONGVARBINARY);
+ Assert.assertEquals(reader.getSchema(metadata, 3), Schema.of(Schema.Type.BYTES));
+
+ when(metadata.getColumnType(eq(4))).thenReturn(Types.BLOB);
+ Assert.assertEquals(reader.getSchema(metadata, 4), Schema.of(Schema.Type.BYTES));
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnNumericWithZeroPrecision() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.NUMERIC);
+ when(metadata.getPrecision(eq(1))).thenReturn(0);
+ when(metadata.getScale(eq(1))).thenReturn(10);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnArray() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.ARRAY);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnDatalink() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.DATALINK);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnDistinct() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.DISTINCT);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnJavaObject() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.JAVA_OBJECT);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnOther() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.OTHER);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnRef() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.REF);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnSQLXML() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.SQLXML);
+ reader.getSchema(metadata, 1);
+ }
+
+ @Test(expected = SQLException.class)
+ public void testGetSchemaThrowsExceptionOnStruct() throws SQLException {
+ when(metadata.getColumnType(eq(1))).thenReturn(Types.STRUCT);
+ reader.getSchema(metadata, 1);
+ }
+}
diff --git a/pom.xml b/pom.xml
index 96a870d7c..719ec8428 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,7 @@
2.2.4
4.11
2.0.1
+ 3.3.3
1.7.5
0.9.0