You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by pa...@apache.org on 2015/03/27 18:49:19 UTC
[1/6] drill git commit: DRILL-2463: Implement JDBC mapping of SQL
NULL for ResultSet.getXxx() methods.
Repository: drill
Updated Branches:
refs/heads/master ee94a37e5 -> 20efb2fbc
DRILL-2463: Implement JDBC mapping of SQL NULL for ResultSet.getXxx() methods.
- Added test Drill2463GetNullsFailedWithAssertionsBugTest.
- Implemented JDBC mapping of NULL for ResultSet.getXxx() methods:
- Fixed was-always-false isNull(...) for Nullable... SqlAccessor
implementations in SqlAccessors template.
- Handled NULL mapping for primitive types in AvaticaDrillSqlAccessor.
- Handled NULL mapping for object types in Nullable... SqlAccessor
implementations in SqlAccessors template.
- Related miscellaneous changes:
- Added "rename this" TODO. [config.fmpp]
- Added documentation. [SqlAccessor]
- Edited comment. [BoundCheckingAccessor]
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/83ebf4f3
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/83ebf4f3
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/83ebf4f3
Branch: refs/heads/master
Commit: 83ebf4f3e12ae42ba771e7c1cdd833a27ecf9b35
Parents: ee94a37
Author: dbarclay <db...@maprtech.com>
Authored: Tue Mar 17 20:45:31 2015 -0700
Committer: Parth Chandra <pc...@maprtech.com>
Committed: Fri Mar 27 10:19:14 2015 -0700
----------------------------------------------------------------------
exec/java-exec/src/main/codegen/config.fmpp | 1 +
.../main/codegen/templates/SqlAccessors.java | 199 ++++++++++++++-----
.../vector/accessor/BoundCheckingAccessor.java | 4 +-
.../drill/exec/vector/accessor/SqlAccessor.java | 83 +++++---
.../drill/jdbc/AvaticaDrillSqlAccessor.java | 37 +++-
...2463GetNullsFailedWithAssertionsBugTest.java | 122 ++++++++++++
6 files changed, 360 insertions(+), 86 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/83ebf4f3/exec/java-exec/src/main/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/config.fmpp b/exec/java-exec/src/main/codegen/config.fmpp
index 5dc7360..8db120d 100644
--- a/exec/java-exec/src/main/codegen/config.fmpp
+++ b/exec/java-exec/src/main/codegen/config.fmpp
@@ -15,6 +15,7 @@
# limitations under the License.
data: {
+ # TODO: Rename to ~valueVectorModesAndTypes for clarity.
vv: tdd(../data/ValueVectorTypes.tdd),
# Most types for comparison functions (for templates/ComparisonFunctions.java).
http://git-wip-us.apache.org/repos/asf/drill/blob/83ebf4f3/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/SqlAccessors.java b/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
index 3039e5c..a838e11 100644
--- a/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
+++ b/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
@@ -32,150 +32,245 @@ package org.apache.drill.exec.vector.accessor;
<#include "/@includes/vv_imports.ftl" />
@SuppressWarnings("unused")
-public class ${name}Accessor extends AbstractSqlAccessor{
- <#if mode == "Nullable">
+public class ${name}Accessor extends AbstractSqlAccessor {
+ <#if mode == "Nullable">
private static final MajorType TYPE = Types.optional(MinorType.${minor.class?upper_case});
- <#else>
+ <#else>
private static final MajorType TYPE = Types.required(MinorType.${minor.class?upper_case});
- </#if>
-
+ </#if>
+
private final ${name}Vector.Accessor ac;
-
- public ${name}Accessor(${name}Vector vector){
+
+ public ${name}Accessor(${name}Vector vector) {
this.ac = vector.getAccessor();
}
- <#if minor.class != "TimeStamp" && minor.class != "Time" && minor.class != "Date">
- public Object getObject(int index){
+ @Override
+ MajorType getType() {
+ return TYPE;
+ };
+
+ @Override
+ public boolean isNull(int index) {
+ <#if mode == "Nullable">
+ return ac.isNull(index);
+ <#else>
+ return false;
+ </#if>
+ }
+
+ <#if minor.class != "TimeStamp" && minor.class != "Time" && minor.class != "Date">
+ public Object getObject(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return ac.getObject(index);
}
- </#if>
-
- <#if type.major == "VarLen">
+ </#if>
+
+ <#if type.major == "VarLen">
- @Override
- public InputStream getStream(int index){
+ @Override
+ public InputStream getStream(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
${name}Holder h = new ${name}Holder();
ac.get(index, h);
return new ByteBufInputStream(h.buffer.slice(h.start, h.end));
}
-
- @Override
- public byte[] getBytes(int index){
+
+ @Override
+ public byte[] getBytes(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return ac.get(index);
}
-
+
<#switch minor.class>
+
<#case "VarBinary">
public String getString(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
byte [] b = ac.get(index);
return DrillStringUtils.toBinaryString(b);
}
<#break>
+
<#case "VarChar">
- @Override
- public InputStreamReader getReader(int index){
+ @Override
+ public InputStreamReader getReader(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return new InputStreamReader(getStream(index), Charsets.UTF_8);
}
-
- @Override
- public String getString(int index){
+
+ @Override
+ public String getString(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return new String(getBytes(index), Charsets.UTF_8);
}
-
-
<#break>
+
<#case "Var16Char">
- @Override
- public InputStreamReader getReader(int index){
+ @Override
+ public InputStreamReader getReader(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return new InputStreamReader(getStream(index), Charsets.UTF_16);
}
-
- @Override
- public String getString(int index){
+
+ @Override
+ public String getString(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return new String(getBytes(index), Charsets.UTF_16);
}
-
-
<#break>
- <#default>
+
+ <#default>
This is uncompilable code
+
</#switch>
- <#else>
- <#if minor.class == "Interval" || minor.class == "IntervalDay" || minor.class == "IntervalYear">
+ <#else> <#-- VarLen -->
+
+ <#if minor.class == "TimeStampTZ">
+
+ public Object getObject(int index) {
+ return getTimestamp(index);
+ }
+
+ @Override
+ public Timestamp getTimestamp(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
+ return new Timestamp(ac.getObject(index).getMillis());
+ }
+
+ <#elseif minor.class == "Interval" || minor.class == "IntervalDay" || minor.class == "IntervalYear">
+
@Override
public String getString(int index) {
- return String.valueOf(ac.getAsStringBuilder(index));
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
+ return String.valueOf(ac.getAsStringBuilder(index));
}
+
<#elseif minor.class.startsWith("Decimal")>
+
@Override
public BigDecimal getBigDecimal(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return ac.getObject(index);
}
<#elseif minor.class == "Date">
+
public Object getObject(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return getDate(index);
}
@Override
public Date getDate(int index) {
- <#if mode == "Nullable">
+ <#if mode == "Nullable">
if (ac.isNull(index)) {
return null;
}
- </#if>
+ </#if>
org.joda.time.DateTime date = new org.joda.time.DateTime(ac.get(index), org.joda.time.DateTimeZone.UTC);
date = date.withZoneRetainFields(org.joda.time.DateTimeZone.getDefault());
return new Date(date.getMillis());
}
+
<#elseif minor.class == "TimeStamp">
+
public Object getObject(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return null;
+ }
+ </#if>
return getTimestamp(index);
}
@Override
public Timestamp getTimestamp(int index) {
- <#if mode == "Nullable">
+ <#if mode == "Nullable">
if (ac.isNull(index)) {
return null;
}
- </#if>
+ </#if>
org.joda.time.DateTime date = new org.joda.time.DateTime(ac.get(index), org.joda.time.DateTimeZone.UTC);
date = date.withZoneRetainFields(org.joda.time.DateTimeZone.getDefault());
return new Timestamp(date.getMillis());
}
+
<#elseif minor.class == "Time">
+
public Object getObject(int index) {
return getTime(index);
}
@Override
public Time getTime(int index) {
- <#if mode == "Nullable">
+ <#if mode == "Nullable">
if (ac.isNull(index)) {
return null;
}
- </#if>
+ </#if>
org.joda.time.DateTime time = new org.joda.time.DateTime(ac.get(index), org.joda.time.DateTimeZone.UTC);
time = time.withZoneRetainFields(org.joda.time.DateTimeZone.getDefault());
return new TimePrintMillis(time.getMillis());
}
+
<#else>
+
@Override
- public ${javaType} get${javaType?cap_first}(int index){
+ public ${javaType} get${javaType?cap_first}(int index) {
return ac.get(index);
}
</#if>
- </#if>
-
- @Override
- public boolean isNull(int index){
- return false;
- }
-
- @Override
- MajorType getType(){return TYPE;};
+
+ </#if> <#-- not VarLen -->
}
http://git-wip-us.apache.org/repos/asf/drill/blob/83ebf4f3/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/BoundCheckingAccessor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/BoundCheckingAccessor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/BoundCheckingAccessor.java
index 7e8da2c..c8d6cc7 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/BoundCheckingAccessor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/BoundCheckingAccessor.java
@@ -130,8 +130,8 @@ public class BoundCheckingAccessor implements SqlAccessor {
*/
@Override
public Object getObject(int index) throws AbstractSqlAccessor.InvalidAccessException {
- // in case some vectors have less values than others, callee invokes this method with index >= #getValueCount
- // this should still yield null.
+ // In case some vectors have fewer values than others, and callee invokes
+ // this method with index >= getValueCount(), this should still yield null.
final ValueVector.Accessor accessor = vector.getAccessor();
if (index < accessor.getValueCount()) {
return delegate.getObject(index);
http://git-wip-us.apache.org/repos/asf/drill/blob/83ebf4f3/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/SqlAccessor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/SqlAccessor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/SqlAccessor.java
index b69ae54..6007bf4 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/SqlAccessor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/SqlAccessor.java
@@ -26,53 +26,90 @@ import java.sql.Timestamp;
import org.apache.drill.exec.vector.accessor.AbstractSqlAccessor.InvalidAccessException;
-// TODO: Doc.
-public interface SqlAccessor {
- // TODO: Document (renamed) index.
- // TODO: Rename ambiguous "index" (JDBC (1-based) column index? other index?)
- // TODO: Doc./Spec.: What happens if index is invalid?
+// TODO: Doc.: Document more of basics of pattern of contracts for getXxx(...):
+// - What index is (especially since is not 1-based JDBC/SQL column index).
+// - What constitutes invalid access (that throws InvalidAccessException):
+// - Does it include out-of-bound index values? (The lack of "throws
+// InvalidAccessException" on isNull(...) suggests no, but ...)
- public abstract boolean isNull(int index);
+/**
+ * Column-data accessor that implements JDBC's Java-null--when--SQL-NULL mapping.
+ * <p>
+ * When the requested value is logically a SQL NULL:
+ * </p>
+ * <li>
+ * a get method that return primitive type throws an exception (callers are
+ * responsible for calling {@link isNull} to check for null before calling
+ * such methods)
+ * </li>
+ * <li>
+ * a get method that returns a non-primitive type returns Java {@code null}
+ * (the caller does not need to call {@link isNull} to check for nulls)
+ * </li>
+ */
+public interface SqlAccessor {
// TODO: Clean: This interface refers to type InvalidAccessException
// defined in class implementing this interface.
- public abstract BigDecimal getBigDecimal(int index) throws InvalidAccessException;
+ /**
+ * Reports whether the logical value is a SQL NULL.
+ */
+ boolean isNull(int index);
+
+ /** (See {@link SqlAccessor class description}.) */
+ BigDecimal getBigDecimal(int index) throws InvalidAccessException;
- public abstract boolean getBoolean(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ boolean getBoolean(int index) throws InvalidAccessException;
- public abstract byte getByte(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ byte getByte(int index) throws InvalidAccessException;
- public abstract byte[] getBytes(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ byte[] getBytes(int index) throws InvalidAccessException;
- public abstract Date getDate(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ Date getDate(int index) throws InvalidAccessException;
- public abstract double getDouble(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ double getDouble(int index) throws InvalidAccessException;
- public abstract float getFloat(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ float getFloat(int index) throws InvalidAccessException;
- public abstract char getChar(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ char getChar(int index) throws InvalidAccessException;
- public abstract int getInt(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ int getInt(int index) throws InvalidAccessException;
- public abstract long getLong(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ long getLong(int index) throws InvalidAccessException;
- public abstract short getShort(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ short getShort(int index) throws InvalidAccessException;
- public abstract InputStream getStream(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ InputStream getStream(int index) throws InvalidAccessException;
- public abstract Reader getReader(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ Reader getReader(int index) throws InvalidAccessException;
// TODO: Doc./Spec.: What should happen if called on non-string type? (Most
// are convertible to string. Does that result in error or conversion?)
// Similar question for many other methods.
- public abstract String getString(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ String getString(int index) throws InvalidAccessException;
- public abstract Time getTime(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ Time getTime(int index) throws InvalidAccessException;
- public abstract Timestamp getTimestamp(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ Timestamp getTimestamp(int index) throws InvalidAccessException;
- public abstract Object getObject(int index) throws InvalidAccessException;
+ /** (See {@link SqlAccessor class description}.) */
+ Object getObject(int index) throws InvalidAccessException;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/drill/blob/83ebf4f3/exec/jdbc/src/main/java/org/apache/drill/jdbc/AvaticaDrillSqlAccessor.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/AvaticaDrillSqlAccessor.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/AvaticaDrillSqlAccessor.java
index 3702257..2b20f23 100644
--- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/AvaticaDrillSqlAccessor.java
+++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/AvaticaDrillSqlAccessor.java
@@ -39,9 +39,14 @@ import net.hydromatic.avatica.Cursor.Accessor;
import org.apache.drill.exec.vector.accessor.SqlAccessor;
+// TODO: Revisit adding null check for non-primitive types to SqlAccessor's
+// contract and classes generated by SqlAccessor template (DRILL-xxxx).
-public class AvaticaDrillSqlAccessor implements Accessor{
- static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AvaticaDrillSqlAccessor.class);
+public class AvaticaDrillSqlAccessor implements Accessor {
+ private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AvaticaDrillSqlAccessor.class);
+
+ private final static byte PRIMITIVE_NUM_NULL_VALUE = 0;
+ private final static boolean BOOLEAN_NULL_VALUE = false;
private SqlAccessor underlyingAccessor;
private DrillCursor cursor;
@@ -78,37 +83,51 @@ public class AvaticaDrillSqlAccessor implements Accessor{
@Override
public boolean getBoolean() throws SQLException {
- return underlyingAccessor.getBoolean(getCurrentRecordNumber());
+ return underlyingAccessor.isNull(getCurrentRecordNumber())
+ ? BOOLEAN_NULL_VALUE
+ : underlyingAccessor.getBoolean(getCurrentRecordNumber());
}
@Override
public byte getByte() throws SQLException {
- return underlyingAccessor.getByte(getCurrentRecordNumber());
+ return underlyingAccessor.isNull(getCurrentRecordNumber())
+ ? PRIMITIVE_NUM_NULL_VALUE
+ : underlyingAccessor.getByte(getCurrentRecordNumber());
}
@Override
public short getShort() throws SQLException {
- return underlyingAccessor.getShort(getCurrentRecordNumber());
+ return underlyingAccessor.isNull(getCurrentRecordNumber())
+ ? PRIMITIVE_NUM_NULL_VALUE
+ : underlyingAccessor.getShort(getCurrentRecordNumber());
}
@Override
public int getInt() throws SQLException {
- return underlyingAccessor.getInt(getCurrentRecordNumber());
+ return underlyingAccessor.isNull(getCurrentRecordNumber())
+ ? PRIMITIVE_NUM_NULL_VALUE
+ : underlyingAccessor.getInt(getCurrentRecordNumber());
}
@Override
public long getLong() throws SQLException {
- return underlyingAccessor.getLong(getCurrentRecordNumber());
+ return underlyingAccessor.isNull(getCurrentRecordNumber())
+ ? PRIMITIVE_NUM_NULL_VALUE
+ : underlyingAccessor.getLong(getCurrentRecordNumber());
}
@Override
public float getFloat() throws SQLException {
- return underlyingAccessor.getFloat(getCurrentRecordNumber());
+ return underlyingAccessor.isNull(getCurrentRecordNumber())
+ ? PRIMITIVE_NUM_NULL_VALUE
+ : underlyingAccessor.getFloat(getCurrentRecordNumber());
}
@Override
public double getDouble() throws SQLException {
- return underlyingAccessor.getDouble(getCurrentRecordNumber());
+ return underlyingAccessor.isNull(getCurrentRecordNumber())
+ ? PRIMITIVE_NUM_NULL_VALUE
+ : underlyingAccessor.getDouble(getCurrentRecordNumber());
}
@Override
http://git-wip-us.apache.org/repos/asf/drill/blob/83ebf4f3/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2463GetNullsFailedWithAssertionsBugTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2463GetNullsFailedWithAssertionsBugTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2463GetNullsFailedWithAssertionsBugTest.java
new file mode 100644
index 0000000..c8346b1
--- /dev/null
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2463GetNullsFailedWithAssertionsBugTest.java
@@ -0,0 +1,122 @@
+/**
+ * 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.test;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.CoreMatchers.*;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.apache.drill.jdbc.Driver;
+import org.apache.drill.jdbc.JdbcTest;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+
+public class Drill2463GetNullsFailedWithAssertionsBugTest extends JdbcTest {
+
+ private static Connection connection;
+ private static Statement statement;
+
+ @BeforeClass
+ public static void setUpConnection() throws SQLException {
+ connection = new Driver().connect( "jdbc:drill:zk=local", null );
+ statement = connection.createStatement();
+ }
+
+ @AfterClass
+ public static void tearDownConnection() throws SQLException {
+ connection.close();
+ }
+
+ // Test primitive types vs. non-primitive types:
+
+ @Test
+ public void testGetPrimitiveTypeNullAsOwnType() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS INTEGER ) FROM INFORMATION_SCHEMA.CATALOGS" );
+ assert rs.next();
+ assertThat( "getInt(...) for NULL", rs.getInt( 1 ), equalTo( 0 ) );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+ @Test
+ public void testGetPrimitiveTypeNullAsObject() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS INTEGER ) FROM INFORMATION_SCHEMA.CATALOGS" );
+ assert rs.next();
+ assertThat( "getObject(...) for NULL", rs.getObject( 1 ), nullValue() );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+ @Test
+ public void testGetNonprimitiveTypeNullAsOwnType() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS VARCHAR) FROM INFORMATION_SCHEMA.CATALOGS" );
+ assert rs.next();
+ assertThat( "getString(...) for NULL", rs.getString( 1 ), nullValue() );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+
+ // Test a few specifics
+
+ @Test
+ public void testGetBooleanNullAsOwnType() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS BOOLEAN ) FROM INFORMATION_SCHEMA.CATALOGS" );
+ assert rs.next();
+ assertThat( "getBoolean(...) for NULL", rs.getBoolean( 1 ), equalTo( false ) );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+ @Test
+ public void testGetBooleanNullAsObject() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS BOOLEAN ) FROM INFORMATION_SCHEMA.CATALOGS" );
+ assert rs.next();
+ assertThat( "getObject(...) for NULL", rs.getObject( 1 ), nullValue() );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+ @Test
+ public void testGetIntegerNullAsOwnType() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS INTEGER ) FROM INFORMATION_SCHEMA.CATALOGS" );
+ assert rs.next();
+ assertThat( "getInt(...) for NULL", rs.getInt( 1 ), equalTo( 0 ) );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+ @Test
+ public void testGetIntegerNullAsObject() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS INTEGER ) FROM INFORMATION_SCHEMA.CATALOGS" );
+ assert rs.next();
+ assertThat( "getObject(...) for NULL", rs.getObject( 1 ), nullValue() );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+
+}
[3/6] drill git commit: DRILL-2461: Fix: INTERVAL in view makes
INFORMATION_SCHEMA.COLUMN fail.
Posted by pa...@apache.org.
DRILL-2461: Fix: INTERVAL in view makes INFORMATION_SCHEMA.COLUMN fail.
- Created test.
- Handled INTERVAL data types in View:
- Added <interval qualifier> data to FieldType.
- Switch calling of createSqlType to createSqlIntervalType for interval types
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/8796fd1e
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/8796fd1e
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/8796fd1e
Branch: refs/heads/master
Commit: 8796fd1e13f07ac84df1c466dce83456dfa22950
Parents: 9a5b50e
Author: dbarclay <db...@maprtech.com>
Authored: Sun Mar 22 13:05:38 2015 -0700
Committer: Parth Chandra <pc...@maprtech.com>
Committed: Fri Mar 27 10:19:32 2015 -0700
----------------------------------------------------------------------
.../org/apache/drill/exec/dotdrill/View.java | 160 +++++++++++++++----
...rill2461IntervalsBreakInfoSchemaBugTest.java | 91 +++++++++++
2 files changed, 222 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/8796fd1e/exec/java-exec/src/main/java/org/apache/drill/exec/dotdrill/View.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/dotdrill/View.java b/exec/java-exec/src/main/java/org/apache/drill/exec/dotdrill/View.java
index a7b496b..c5c62d8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/dotdrill/View.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/dotdrill/View.java
@@ -22,9 +22,13 @@ import java.util.List;
import org.apache.drill.exec.planner.StarColumnHelper;
import org.apache.drill.exec.planner.types.RelDataTypeDrillImpl;
import org.apache.drill.exec.planner.types.RelDataTypeHolder;
+
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;
import org.eigenbase.reltype.RelDataTypeField;
+import org.eigenbase.sql.SqlIntervalQualifier;
+import org.eigenbase.sql.parser.SqlParserPos;
+import org.eigenbase.sql.type.SqlTypeFamily;
import org.eigenbase.sql.type.SqlTypeName;
import com.fasterxml.jackson.annotation.JsonCreator;
@@ -48,36 +52,50 @@ public class View {
@JsonInclude(Include.NON_NULL)
public static class FieldType {
- public final String name;
- public final SqlTypeName type;
- public final Integer precision;
- public final Integer scale;
- public final Boolean isNullable;
+
+ private final String name;
+ private final SqlTypeName type;
+ private final Integer precision;
+ private final Integer scale;
+ private SqlIntervalQualifier intervalQualifier;
+ private final Boolean isNullable;
+
@JsonCreator
public FieldType(
- @JsonProperty("name") String name,
- @JsonProperty("type") SqlTypeName type,
- @JsonProperty("precision") Integer precision,
- @JsonProperty("scale") Integer scale,
- @JsonProperty("isNullable") Boolean isNullable){
+ @JsonProperty("name") String name,
+ @JsonProperty("type") SqlTypeName type,
+ @JsonProperty("precision") Integer precision,
+ @JsonProperty("scale") Integer scale,
+ @JsonProperty("startUnit") SqlIntervalQualifier.TimeUnit startUnit,
+ @JsonProperty("endUnit") SqlIntervalQualifier.TimeUnit endUnit,
+ @JsonProperty("fractionalSecondPrecision") Integer fractionalSecondPrecision,
+ @JsonProperty("isNullable") Boolean isNullable) {
this.name = name;
this.type = type;
this.precision = precision;
this.scale = scale;
+ this.intervalQualifier =
+ null == startUnit
+ ? null
+ : new SqlIntervalQualifier(
+ startUnit, precision, endUnit, fractionalSecondPrecision, SqlParserPos.ZERO );
- // Property "isNullable" is not part of the initial view definition and added in DRILL-2342. If the
- // default value is null, consider it as "true". It is safe to default to "nullable" than "required" type.
- this.isNullable = (isNullable == null) ? true : isNullable;
+ // Property "isNullable" is not part of the initial view definition and
+ // was added in DRILL-2342. If the default value is null, consider it as
+ // "true". It is safe to default to "nullable" than "required" type.
+ this.isNullable = isNullable == null ? true : isNullable;
}
- public FieldType(String name, RelDataType dataType){
+ public FieldType(String name, RelDataType dataType) {
this.name = name;
this.type = dataType.getSqlTypeName();
+
Integer p = null;
Integer s = null;
+ Integer fractionalSecondPrecision = null;
- switch(dataType.getSqlTypeName()){
+ switch (dataType.getSqlTypeName()) {
case CHAR:
case BINARY:
case VARBINARY:
@@ -88,19 +106,100 @@ public class View {
p = dataType.getPrecision();
s = dataType.getScale();
break;
+ case INTERVAL_YEAR_MONTH:
+ case INTERVAL_DAY_TIME:
+ p = dataType.getIntervalQualifier().getStartPrecision();
+ default:
+ break;
}
this.precision = p;
this.scale = s;
+ this.intervalQualifier = dataType.getIntervalQualifier();
this.isNullable = dataType.isNullable();
}
+
+ /**
+ * Gets the name of this field.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the data type of this field.
+ * (Data type only; not full datatype descriptor.)
+ */
+ public SqlTypeName getType() {
+ return type;
+ }
+
+ /**
+ * Gets the precision of the data type descriptor of this field.
+ * The precision is the precision for a numeric type, the length for a
+ * string type, or the start unit precision for an interval type.
+ * */
+ public Integer getPrecision() {
+ return precision;
+ }
+
+ /**
+ * Gets the numeric scale of the data type descriptor of this field,
+ * for numeric types.
+ */
+ public Integer getScale() {
+ return scale;
+ }
+
+ /**
+ * Gets the interval type qualifier of the interval data type descriptor of
+ * this field (<i>iff</i> interval type). */
+ @JsonIgnore
+ public SqlIntervalQualifier getIntervalQualifier() {
+ return intervalQualifier;
+ }
+
+ /**
+ * Gets the time range start unit of the type qualifier of the interval data
+ * type descriptor of this field (<i>iff</i> interval type).
+ */
+ public SqlIntervalQualifier.TimeUnit getStartUnit() {
+ return null == intervalQualifier ? null : intervalQualifier.getStartUnit();
+ }
+
+ /**
+ * Gets the time range end unit of the type qualifier of the interval data
+ * type descriptor of this field (<i>iff</i> interval type).
+ */
+ public SqlIntervalQualifier.TimeUnit getEndUnit() {
+ return null == intervalQualifier ? null : intervalQualifier.getEndUnit();
+ }
+
+ /**
+ * Gets the fractional second precision of the type qualifier of the interval
+ * data type descriptor of this field (<i>iff</i> interval type).
+ * Gets the interval type descriptor's fractional second precision
+ * (<i>iff</i> interval type).
+ */
+ public Integer getFractionalSecondPrecision() {
+ return null == intervalQualifier ? null : intervalQualifier.getFractionalSecondPrecision();
+ }
+
+ /**
+ * Gets the nullability of the data type desription of this field.
+ */
+ public Boolean getIsNullable() {
+ return isNullable;
+ }
+
}
- public View(String name, String sql, RelDataType rowType, List<String> workspaceSchemaPath){
+
+ public View(String name, String sql, RelDataType rowType, List<String> workspaceSchemaPath) {
this.name = name;
this.sql = sql;
fields = Lists.newArrayList();
- for(RelDataTypeField f : rowType.getFieldList()){
+ for (RelDataTypeField f : rowType.getFieldList()) {
fields.add(new FieldType(f.getName(), f.getType()));
}
this.workspaceSchemaPath =
@@ -119,28 +218,31 @@ public class View {
workspaceSchemaPath == null ? ImmutableList.<String>of() : ImmutableList.copyOf(workspaceSchemaPath);
}
- public RelDataType getRowType(RelDataTypeFactory factory){
+ public RelDataType getRowType(RelDataTypeFactory factory) {
// if there are no fields defined, this is a dynamic view.
- if(isDynamic()){
+ if (isDynamic()) {
return new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory);
}
List<RelDataType> types = Lists.newArrayList();
List<String> names = Lists.newArrayList();
- for(FieldType field : fields){
- names.add(field.name);
+ for (FieldType field : fields) {
+ names.add(field.getName());
RelDataType type;
- if(field.precision == null && field.scale == null){
- type = factory.createSqlType(field.type);
- }else if(field.precision != null && field.scale == null){
- type = factory.createSqlType(field.type, field.precision);
- }else{
- type = factory.createSqlType(field.type, field.precision, field.scale);
+ if ( SqlTypeFamily.INTERVAL_YEAR_MONTH == field.getType().getFamily()
+ || SqlTypeFamily.INTERVAL_DAY_TIME == field.getType().getFamily() ) {
+ type = factory.createSqlIntervalType( field.getIntervalQualifier() );
+ } else if (field.getPrecision() == null && field.getScale() == null) {
+ type = factory.createSqlType(field.getType());
+ } else if (field.getPrecision() != null && field.getScale() == null) {
+ type = factory.createSqlType(field.getType(), field.getPrecision());
+ } else {
+ type = factory.createSqlType(field.getType(), field.getPrecision(), field.getScale());
}
- if (field.isNullable) {
+ if (field.getIsNullable()) {
types.add(factory.createTypeWithNullability(type, true));
} else {
types.add(type);
@@ -157,7 +259,7 @@ public class View {
@JsonIgnore
public boolean hasStar() {
for (FieldType field : fields) {
- if (StarColumnHelper.isNonPrefixedStarColumn(field.name)) {
+ if (StarColumnHelper.isNonPrefixedStarColumn(field.getName())) {
return true;
}
}
http://git-wip-us.apache.org/repos/asf/drill/blob/8796fd1e/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2461IntervalsBreakInfoSchemaBugTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2461IntervalsBreakInfoSchemaBugTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2461IntervalsBreakInfoSchemaBugTest.java
new file mode 100644
index 0000000..fce7923
--- /dev/null
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2461IntervalsBreakInfoSchemaBugTest.java
@@ -0,0 +1,91 @@
+/**
+ * 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.test;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.CoreMatchers.*;
+
+import org.apache.drill.common.util.TestTools;
+import org.apache.drill.jdbc.Driver;
+import org.apache.drill.jdbc.JdbcTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.sql.SQLException;
+
+
+public class Drill2461IntervalsBreakInfoSchemaBugTest extends JdbcTest {
+
+ private static final String VIEW_NAME =
+ Drill2461IntervalsBreakInfoSchemaBugTest.class.getSimpleName() + "_View";
+
+ private static Connection connection;
+
+
+ @BeforeClass
+ public static void setUpConnection() throws Exception {
+ connection = connect( "jdbc:drill:zk=local" );
+ }
+
+ @AfterClass
+ public static void tearDownConnection() throws Exception {
+ connection.close();
+ }
+
+
+ @Test
+ public void testIntervalInViewDoesntCrashInfoSchema() throws Exception {
+ final Statement stmt = connection.createStatement();
+ ResultSet util;
+
+ // Create a view using an INTERVAL type:
+ util = stmt.executeQuery( "USE dfs.tmp" );
+ assert util.next();
+ assert util.getBoolean( 1 )
+ : "Error setting schema to dfs.tmp: " + util.getString( 2 );
+ util = stmt.executeQuery(
+ "CREATE OR REPLACE VIEW " + VIEW_NAME + " AS "
+ + "\n SELECT CAST( NULL AS INTERVAL HOUR(4) TO MINUTE ) AS optINTERVAL_HM "
+ + "\n FROM INFORMATION_SCHEMA.CATALOGS "
+ + "\n LIMIT 1 " );
+ assert util.next();
+ assert util.getBoolean( 1 )
+ : "Error creating temporary test-columns view " + VIEW_NAME + ": "
+ + util.getString( 2 );
+
+ // Test whether query INFORMATION_SCHEMA.COLUMNS works (doesn't crash):
+ util = stmt.executeQuery( "SELECT * FROM INFORMATION_SCHEMA.COLUMNS" );
+ assert util.next();
+
+ // Clean up the test view:
+ util = connection.createStatement().executeQuery( "DROP VIEW " + VIEW_NAME );
+ assert util.next();
+ assert util.getBoolean( 1 )
+ : "Error dropping temporary test-columns view " + VIEW_NAME + ": "
+ + util.getString( 2 );
+ }
+
+}
[4/6] drill git commit: DRILL-2465: Fix multiple
DatabaseMetaData.getColumns() bugs.
Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/drill/blob/20efb2fb/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsBugsTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsBugsTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsBugsTest.java
deleted file mode 100644
index 0a9104b..0000000
--- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsBugsTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * 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.test;
-
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.hamcrest.CoreMatchers.*;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.apache.drill.jdbc.JdbcTest;
-
-
-/**
- * Basic (spot-check/incomplete) tests for DRILL-2128 bugs (many
- * DatabaseMetaData.getColumns(...) result table problems).
- */
-public class Drill2128GetColumnsBugsTest extends JdbcTest {
-
- private static Connection connection;
- private static DatabaseMetaData dbMetadata;
-
- @BeforeClass
- public static void setUpConnection() throws Exception {
- connection = connect( "jdbc:drill:zk=local" );
- dbMetadata = connection.getMetaData();
- }
-
- @AfterClass
- public static void tearDownConnection() throws SQLException {
- connection.close();
- }
-
-
- /**
- * Basic test that column DATA_TYPE is integer type codes (not strings such
- * as "VARCHAR" or "INTEGER").
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testColumn_DATA_TYPE_isInteger() throws Exception {
- // Get metadata for some column(s).
- final ResultSet columns = dbMetadata.getColumns( null, null, null, null );
- final boolean hasRow = columns.next();
- assert hasRow : "DatabaseMetaData.getColumns(...) returned no rows";
-
- do {
- // DATA_TYPE should be INTEGER, so getInt( "DATA_TYPE" ) should succeed:
- final int typeCode1 = columns.getInt( "DATA_TYPE" );
-
- // DATA_TYPE should be at ordinal position 5 (seemingly):
- assertThat( "Column 5's label",
- columns.getMetaData().getColumnLabel( 5 ), equalTo( "DATA_TYPE" ) );
-
- // Also, getInt( 5 ) should succeed and return the same type code as above:
- final int typeCode2 = columns.getInt( 5 );
- assertThat( "getInt( 5 ) (expected to be same as getInt( \"DATA_TYPE\" ))",
- typeCode2, equalTo( typeCode1 ) );
-
- // Type code should be one of java.sql.Types.*:
- assertThat(
- typeCode1,
- anyOf( // List is from java.sql.Types
- equalTo( Types.ARRAY ),
- equalTo( Types.BIGINT ),
- equalTo( Types.BINARY ),
- equalTo( Types.BIT ),
- equalTo( Types.BLOB ),
- equalTo( Types.BOOLEAN ),
- equalTo( Types.CHAR ),
- equalTo( Types.CLOB ),
- equalTo( Types.DATALINK ),
- equalTo( Types.DATE ),
- equalTo( Types.DECIMAL ),
- equalTo( Types.DISTINCT ),
- equalTo( Types.DOUBLE ),
- equalTo( Types.FLOAT ),
- equalTo( Types.INTEGER ),
- equalTo( Types.JAVA_OBJECT ),
- equalTo( Types.LONGNVARCHAR ),
- equalTo( Types.LONGVARBINARY ),
- equalTo( Types.LONGVARCHAR ),
- equalTo( Types.NCHAR ),
- equalTo( Types.NCLOB ),
- // TODO: Resolve: Is it not clear whether Types.NULL can re-
- // present a type (e.g., the type of NULL), or whether a column
- // can ever have that type, and therefore whether Types.NULL
- // can appear. Currently, exclude NULL so we'll notice if it
- // does appear:
- // No equalTo( Types.NULL ).
- equalTo( Types.NUMERIC ),
- equalTo( Types.NVARCHAR ),
- equalTo( Types.OTHER ),
- equalTo( Types.REAL ),
- equalTo( Types.REF ),
- equalTo( Types.ROWID ),
- equalTo( Types.SMALLINT ),
- equalTo( Types.SQLXML ),
- equalTo( Types.STRUCT ),
- equalTo( Types.TIME ),
- equalTo( Types.TIMESTAMP ),
- equalTo( Types.TINYINT ),
- equalTo( Types.VARBINARY ),
- equalTo( Types.VARCHAR )
- ) );
- } while ( columns.next() );
- }
-
- /**
- * Basic test that column TYPE_NAME exists and is strings (such "INTEGER").
- */
- @Test
- public void testColumn_TYPE_NAME_isString() throws Exception {
- // Get metadata for some INTEGER column.
- final ResultSet columns =
- dbMetadata.getColumns( null, "INFORMATION_SCHEMA", "COLUMNS",
- "ORDINAL_POSITION" );
- final boolean hasRow = columns.next();
- assert hasRow : "DatabaseMetaData.getColumns(...) returned no rows";
-
- // TYPE_NAME should be character string for type name "INTEGER", so
- // getString( "TYPE_NAME" ) should succeed and getInt( "TYPE_NAME" ) should
- // fail:
- final String typeName1 = columns.getString( "TYPE_NAME" );
- assertThat( "getString( \"TYPE_NAME\" )", typeName1, equalTo( "INTEGER" ) );
-
- try {
- final int unexpected = columns.getInt( "TYPE_NAME" );
- fail( "getInt( \"TYPE_NAME\" ) didn't throw exception (and returned "
- + unexpected + ")" );
- }
- catch ( SQLException e ) {
- // Expected.
- }
-
- // TYPE_NAME should be at ordinal position 6 (seemingly):
- assertThat( "Column 6's label",
- columns.getMetaData().getColumnLabel( 6 ), equalTo( "TYPE_NAME" ) );
-
- // Also, getString( 6 ) should succeed and return the same type name as above:
- final String typeName2 = columns.getString( 6 );
- assertThat( "getString( 6 ) (expected to be same as getString( \"TYPE_NAME\" ))",
- typeName2, equalTo( typeName1 ) );
- }
-
-}
http://git-wip-us.apache.org/repos/asf/drill/blob/20efb2fb/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsDataTypeNotTypeCodeIntBugsTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsDataTypeNotTypeCodeIntBugsTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsDataTypeNotTypeCodeIntBugsTest.java
new file mode 100644
index 0000000..faca543
--- /dev/null
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2128GetColumnsDataTypeNotTypeCodeIntBugsTest.java
@@ -0,0 +1,169 @@
+/**
+ * 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.test;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.hamcrest.CoreMatchers.*;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.apache.drill.jdbc.JdbcTest;
+
+
+/**
+ * Basic (spot-check/incomplete) tests for DRILL-2128 bugs (many
+ * DatabaseMetaData.getColumns(...) result table problems).
+ */
+public class Drill2128GetColumnsDataTypeNotTypeCodeIntBugsTest extends JdbcTest {
+
+ private static Connection connection;
+ private static DatabaseMetaData dbMetadata;
+
+ @BeforeClass
+ public static void setUpConnection() throws Exception {
+ connection = connect( "jdbc:drill:zk=local" );
+ dbMetadata = connection.getMetaData();
+ }
+
+ @AfterClass
+ public static void tearDownConnection() throws SQLException {
+ connection.close();
+ }
+
+
+ /**
+ * Basic test that column DATA_TYPE is integer type codes (not strings such
+ * as "VARCHAR" or "INTEGER").
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testColumn_DATA_TYPE_isInteger() throws Exception {
+ // Get metadata for some column(s).
+ final ResultSet columns = dbMetadata.getColumns( null, null, null, null );
+ final boolean hasRow = columns.next();
+ assert hasRow : "DatabaseMetaData.getColumns(...) returned no rows";
+
+ do {
+ // DATA_TYPE should be INTEGER, so getInt( "DATA_TYPE" ) should succeed:
+ final int typeCode1 = columns.getInt( "DATA_TYPE" );
+
+ // DATA_TYPE should be at ordinal position 5 (seemingly):
+ assertThat( "Column 5's label",
+ columns.getMetaData().getColumnLabel( 5 ), equalTo( "DATA_TYPE" ) );
+
+ // Also, getInt( 5 ) should succeed and return the same type code as above:
+ final int typeCode2 = columns.getInt( 5 );
+ assertThat( "getInt( 5 ) (expected to be same as getInt( \"DATA_TYPE\" ))",
+ typeCode2, equalTo( typeCode1 ) );
+
+ // Type code should be one of java.sql.Types.*:
+ assertThat(
+ typeCode1,
+ anyOf( // List is from java.sql.Types
+ equalTo( Types.ARRAY ),
+ equalTo( Types.BIGINT ),
+ equalTo( Types.BINARY ),
+ equalTo( Types.BIT ),
+ equalTo( Types.BLOB ),
+ equalTo( Types.BOOLEAN ),
+ equalTo( Types.CHAR ),
+ equalTo( Types.CLOB ),
+ equalTo( Types.DATALINK ),
+ equalTo( Types.DATE ),
+ equalTo( Types.DECIMAL ),
+ equalTo( Types.DISTINCT ),
+ equalTo( Types.DOUBLE ),
+ equalTo( Types.FLOAT ),
+ equalTo( Types.INTEGER ),
+ equalTo( Types.JAVA_OBJECT ),
+ equalTo( Types.LONGNVARCHAR ),
+ equalTo( Types.LONGVARBINARY ),
+ equalTo( Types.LONGVARCHAR ),
+ equalTo( Types.NCHAR ),
+ equalTo( Types.NCLOB ),
+ // TODO: Resolve: Is it not clear whether Types.NULL can re-
+ // present a type (e.g., the type of NULL), or whether a column
+ // can ever have that type, and therefore whether Types.NULL
+ // can appear. Currently, exclude NULL so we'll notice if it
+ // does appear:
+ // No equalTo( Types.NULL ).
+ equalTo( Types.NUMERIC ),
+ equalTo( Types.NVARCHAR ),
+ equalTo( Types.OTHER ),
+ equalTo( Types.REAL ),
+ equalTo( Types.REF ),
+ equalTo( Types.ROWID ),
+ equalTo( Types.SMALLINT ),
+ equalTo( Types.SQLXML ),
+ equalTo( Types.STRUCT ),
+ equalTo( Types.TIME ),
+ equalTo( Types.TIMESTAMP ),
+ equalTo( Types.TINYINT ),
+ equalTo( Types.VARBINARY ),
+ equalTo( Types.VARCHAR )
+ ) );
+ } while ( columns.next() );
+ }
+
+ /**
+ * Basic test that column TYPE_NAME exists and is strings (such "INTEGER").
+ */
+ @Test
+ public void testColumn_TYPE_NAME_isString() throws Exception {
+ // Get metadata for some INTEGER column.
+ final ResultSet columns =
+ dbMetadata.getColumns( null, "INFORMATION_SCHEMA", "COLUMNS",
+ "ORDINAL_POSITION" );
+ final boolean hasRow = columns.next();
+ assert hasRow : "DatabaseMetaData.getColumns(...) returned no rows";
+
+ // TYPE_NAME should be character string for type name "INTEGER", so
+ // getString( "TYPE_NAME" ) should succeed and getInt( "TYPE_NAME" ) should
+ // fail:
+ final String typeName1 = columns.getString( "TYPE_NAME" );
+ assertThat( "getString( \"TYPE_NAME\" )", typeName1, equalTo( "INTEGER" ) );
+
+ try {
+ final int unexpected = columns.getInt( "TYPE_NAME" );
+ fail( "getInt( \"TYPE_NAME\" ) didn't throw exception (and returned "
+ + unexpected + ")" );
+ }
+ catch ( SQLException e ) {
+ // Expected.
+ }
+
+ // TYPE_NAME should be at ordinal position 6 (seemingly):
+ assertThat( "Column 6's label",
+ columns.getMetaData().getColumnLabel( 6 ), equalTo( "TYPE_NAME" ) );
+
+ // Also, getString( 6 ) should succeed and return the same type name as above:
+ final String typeName2 = columns.getString( 6 );
+ assertThat( "getString( 6 ) (expected to be same as getString( \"TYPE_NAME\" ))",
+ typeName2, equalTo( typeName1 ) );
+ }
+
+}
[6/6] drill git commit: DRILL-2465: Fix multiple
DatabaseMetaData.getColumns() bugs.
Posted by pa...@apache.org.
DRILL-2465: Fix multiple DatabaseMetaData.getColumns() bugs.
- Added test DatabaseMetaDataGetColumnsTest.
- (Renamed Drill2128GetColumnsBugsTest to
Drill2128GetColumnsDataTypeNotTypeCodeIntBugsTest.)
- Fixed/implemented various columns:
- Added COLUMN_SIZE (big CASE expression handling lots of cases).
- Fixed DECIMAL_DIGITS.
- Fixed NUM_PREC_RADIX.
- ~Fixed REMARKS ('' -> NULL).
- ~Fixed COLUMN_DEF ('' -> NULL).
- Fixed CHARACTER_OCTET_LENGTH.
- Fixed ORDINAL_POSITION.
- Fixed SCOPE_CATALOG, SCOPE_SCHEMA, SCOPE_TABLE,
- Fixed SOURCE_DATA_TYPE.
- Note: INTERVAL types have only *interim* implementations.
(INFORMATION_SCHEMA.COLUMNS fixes are needed for completion.)
- Added canonical data type name strings in DATA_TYPE -> TYPE_NAME CASE
expression (for robustness for expected upcoming INFORMATION_SCHEMA.COLUMNS
standard-compliance bug fixing).
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/20efb2fb
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/20efb2fb
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/20efb2fb
Branch: refs/heads/master
Commit: 20efb2fbc8176242c94505bcaab662586d66ba4d
Parents: 8796fd1
Author: dbarclay <db...@maprtech.com>
Authored: Sat Mar 21 00:45:41 2015 -0700
Committer: Parth Chandra <pc...@maprtech.com>
Committed: Fri Mar 27 10:19:43 2015 -0700
----------------------------------------------------------------------
.../java/org/apache/drill/jdbc/MetaImpl.java | 409 ++-
.../jdbc/DatabaseMetaDataGetColumnsTest.java | 2779 ++++++++++++++++++
.../jdbc/test/Drill2128GetColumnsBugsTest.java | 169 --
...etColumnsDataTypeNotTypeCodeIntBugsTest.java | 169 ++
4 files changed, 3261 insertions(+), 265 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/20efb2fb/exec/jdbc/src/main/java/org/apache/drill/jdbc/MetaImpl.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/MetaImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/MetaImpl.java
index 99e0d22..4ff626e 100644
--- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/MetaImpl.java
+++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/MetaImpl.java
@@ -34,10 +34,51 @@ import org.apache.drill.common.util.DrillStringUtils;
public class MetaImpl implements Meta {
+ private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MetaImpl.class);
+
+ // TODO: Use more central version of these constants if availabe.
+
+ /** Radix used to report precision and scale of integral exact numeric types. */
+ private static final int RADIX_INTEGRAL = 10;
+ /** Radix used to report precision and scale of non-integral exact numeric
+ types (DECIMAL). */
+ private static final int RADIX_DECIMAL = 10;
+ /** Radix used to report precision and scale of approximate numeric types
+ (FLOAT, etc.). */
+ private static final int RADIX_APPROXIMATE = 10;
+ /** Radix used to report precisions of interval types. */
+ private static final int RADIX_INTERVAL = 10;
+
+ /** (Maximum) precision of TINYINT. */
+ private static final int PREC_TINYINT = 3;
+ /** (Maximum) precision of SMALLINT. */
+ private static final int PREC_SMALLINT = 5;
+ /** (Maximum) precision of INTEGER. */
+ private static final int PREC_INTEGER = 10;
+ /** (Maximum) precision of BIGINT. */
+ private static final int PREC_BIGINT = 19;
+
+ /** Precision of FLOAT. */
+ private static final int PREC_FLOAT = 7;
+ /** Precision of DOUBLE. */
+ private static final int PREC_DOUBLE = 15;
+ /** Precision of REAL. */
+ private static final int PREC_REAL = PREC_DOUBLE;
+
+ /** Scale of INTEGER types. */
+ private static final int SCALE_INTEGRAL = 0;
+ /** JDBC conventional(?) scale value for FLOAT. */
+ private static final int SCALE_FLOAT = 7;
+ /** JDBC conventional(?) scale value for DOUBLE. */
+ private static final int SCALE_DOUBLE = 15;
+ /** JDBC conventional(?) scale value for REAL. */
+ private static final int SCALE_REAL = SCALE_DOUBLE;
+
+ /** (Apparent) maximum precision for starting unit of INTERVAL type. */
+ private static final int PREC_INTERVAL_LEAD_MAX = 10;
+ /** (Apparent) maximum fractional seconds precision for INTERVAL type. */
+ private static final int PREC_INTERVAL_TRAIL_MAX = 9;
- static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MetaImpl.class);
-
- static final Driver DRIVER = new Driver();
final DrillConnectionImpl connection;
@@ -126,145 +167,323 @@ public class MetaImpl implements Meta {
return s(sb.toString());
}
- public ResultSet getColumns(String catalog, Pat schemaPattern, Pat tableNamePattern, Pat columnNamePattern) {
+ /**
+ * Implements @link DatabaseMetaData#getColumns()}.
+ */
+ public ResultSet getColumns(String catalog, Pat schemaPattern,
+ Pat tableNamePattern, Pat columnNamePattern) {
StringBuilder sb = new StringBuilder();
- // TODO: Fix the various remaining bugs and resolve the various questions
- // noted below.
+ // TODO: Resolve the various questions noted below.
sb.append(
- "SELECT \n"
- // getColumns INFORMATION_SCHEMA.COLUMNS getColumns()
- // column source column or column name
- // number expression
- // ------- ------------------------ -------------
- + /* 1 */ " TABLE_CATALOG as TABLE_CAT, \n"
- + /* 2 */ " TABLE_SCHEMA as TABLE_SCHEM, \n"
- + /* 3 */ " TABLE_NAME as TABLE_NAME, \n"
- + /* 4 */ " COLUMN_NAME as COLUMN_NAME, \n"
-
+ "SELECT "
+ // getColumns INFORMATION_SCHEMA.COLUMNS getColumns()
+ // column source column or column name
+ // number expression
+ // ------- ------------------------ -------------
+ + /* 1 */ "\n TABLE_CATALOG as TABLE_CAT, "
+ + /* 2 */ "\n TABLE_SCHEMA as TABLE_SCHEM, "
+ + /* 3 */ "\n TABLE_NAME as TABLE_NAME, "
+ + /* 4 */ "\n COLUMN_NAME as COLUMN_NAME, "
+
+ /* 5 DATA_TYPE */
// TODO: Resolve the various questions noted below for DATA_TYPE.
- /* 5 (DATA_TYPE) */
- + " CASE \n"
+ + "\n CASE DATA_TYPE "
// (All values in JDBC 4.0/Java 7 java.sql.Types except for types.NULL:)
- // TODO: RESOLVE: How does ARRAY appear in COLUMNS.DATA_TYPE?
- // - Only at end (with no maximum size, as "VARCHAR(65535) ARRAY")?
- // - Possibly with maximum size (as "... ARRAY[10]")?
- // (SQL source syntax:
- // <array type> ::=
- // <data type> ARRAY
- // [ <left bracket or trigraph> <maximum cardinality> <right bracket or trigraph> ]
- + " WHEN DATA_TYPE LIKE '% ARRAY' THEN " + Types.ARRAY
-
- + " WHEN DATA_TYPE = 'BIGINT' THEN " + Types.BIGINT
- + " WHEN DATA_TYPE = 'BINARY' THEN " + Types.BINARY
+ // Exact-match cases:
+ + "\n WHEN 'BIGINT' THEN " + Types.BIGINT
+ + "\n WHEN 'BINARY' THEN " + Types.BINARY
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'BIT' THEN " + Types.BIT
+ + "\n WHEN 'BIT' THEN " + Types.BIT
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'BLOB' THEN " + Types.BLOB
- + " WHEN DATA_TYPE = 'BOOLEAN' THEN " + Types.BOOLEAN
+ + "\n WHEN 'BLOB', 'BINARY LARGE OBJECT' THEN " + Types.BLOB
+ + "\n WHEN 'BOOLEAN' THEN " + Types.BOOLEAN
- + " WHEN DATA_TYPE = 'CHAR' THEN " + Types.CHAR
+ + "\n WHEN 'CHAR', 'CHARACTER' THEN " + Types.CHAR
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'CLOB' THEN " + Types.CLOB
+ + "\n WHEN 'CLOB', 'CHARACTER LARGE OBJECT' "
+ + "\n THEN " + Types.CLOB
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'DATALINK' THEN " + Types.DATALINK
- + " WHEN DATA_TYPE = 'DATE' THEN " + Types.DATE
- + " WHEN DATA_TYPE = 'DECIMAL' THEN " + Types.DECIMAL
+ + "\n WHEN 'DATALINK' THEN " + Types.DATALINK
+ + "\n WHEN 'DATE' THEN " + Types.DATE
+ + "\n WHEN 'DECIMAL' THEN " + Types.DECIMAL
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'DISTINCT' THEN " + Types.DISTINCT
- + " WHEN DATA_TYPE = 'DOUBLE' THEN " + Types.DOUBLE
+ + "\n WHEN 'DISTINCT' THEN " + Types.DISTINCT
+ + "\n WHEN 'DOUBLE', 'DOUBLE PRECISION' THEN " + Types.DOUBLE
+
+ + "\n WHEN 'FLOAT' THEN " + Types.FLOAT
- + " WHEN DATA_TYPE = 'FLOAT' THEN " + Types.FLOAT
+ + "\n WHEN 'INTEGER' THEN " + Types.INTEGER
- + " WHEN DATA_TYPE = 'INTEGER' THEN " + Types.INTEGER
+ // Drill's INFORMATION_SCHEMA's COLUMNS currently has
+ // "INTERVAL_YEAR_MONTH" and "INTERVAL_DAY_TIME" instead of SQL standard
+ // 'INTERVAL'.
+ + "\n WHEN 'INTERVAL', "
+ + "\n 'INTERVAL_YEAR_MONTH', "
+ + "\n 'INTERVAL_DAY_TIME' THEN " + Types.OTHER
// Resolve: Not seen in Drill yet. Can it ever appear?:
- + " WHEN DATA_TYPE = 'JAVA_OBJECT' THEN " + Types.JAVA_OBJECT
+ + "\n WHEN 'JAVA_OBJECT' THEN " + Types.JAVA_OBJECT
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'LONGNVARCHAR' THEN " + Types.LONGNVARCHAR
+ + "\n WHEN 'LONGNVARCHAR' THEN " + Types.LONGNVARCHAR
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'LONGVARBINARY' THEN " + Types.LONGVARBINARY
+ + "\n WHEN 'LONGVARBINARY' THEN " + Types.LONGVARBINARY
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'LONGVARCHAR' THEN " + Types.LONGVARCHAR
+ + "\n WHEN 'LONGVARCHAR' THEN " + Types.LONGVARCHAR
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'NCHAR' THEN " + Types.NCHAR
+ + "\n WHEN 'NCHAR', 'NATIONAL CHARACTER' THEN " + Types.NCHAR
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'NCLOB' THEN " + Types.NCLOB
+ + "\n WHEN 'NCLOB', 'NATIONAL CHARACTER LARGE OBJECT' "
+ + "\n THEN " + Types.NCLOB
// TODO: Resolve following about NULL (and then update comment and code):
// It is not clear whether Types.NULL can represent a type (perhaps the
// type of the literal NULL when no further type information is known?) or
// whether 'NULL' can appear in INFORMATION_SCHEMA.COLUMNS.DATA_TYPE.
// For now, since it shouldn't hurt, include 'NULL'/Types.NULL in mapping.
- + " WHEN DATA_TYPE = 'NULL' THEN " + Types.NULL
+ + "\n WHEN 'NULL' THEN " + Types.NULL
// (No NUMERIC--Drill seems to map any to DECIMAL currently.)
- + " WHEN DATA_TYPE = 'NUMERIC' THEN " + Types.NUMERIC
+ + "\n WHEN 'NUMERIC' THEN " + Types.NUMERIC
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'NVARCHAR' THEN " + Types.NVARCHAR
+ + "\n WHEN 'NVARCHAR', 'NATIONAL CHARACTER VARYING' "
+ + "\n THEN " + Types.NVARCHAR
// Resolve: Unexpectedly, has appeared in Drill. Should it?
- + " WHEN DATA_TYPE = 'OTHER' THEN " + Types.OTHER
+ + "\n WHEN 'OTHER' THEN " + Types.OTHER
- + " WHEN DATA_TYPE = 'REAL' THEN " + Types.REAL
+ + "\n WHEN 'REAL' THEN " + Types.REAL
// SQL source syntax:
// <reference type> ::=
// REF <left paren> <referenced type> <right paren> [ <scope clause> ]
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'REF' THEN " + Types.REF
+ + "\n WHEN 'REF' THEN " + Types.REF
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'ROWID' THEN " + Types.ROWID
+ + "\n WHEN 'ROWID' THEN " + Types.ROWID
- + " WHEN DATA_TYPE = 'SMALLINT' THEN " + Types.SMALLINT
+ + "\n WHEN 'SMALLINT' THEN " + Types.SMALLINT
// Resolve: Not seen in Drill yet. Can it appear?:
- + " WHEN DATA_TYPE = 'SQLXML' THEN " + Types.SQLXML
+ + "\n WHEN 'SQLXML' THEN " + Types.SQLXML
- // TODO: RESOLVE: How does "STRUCT" appear?
- // - Only at beginning (as "STRUCT(INTEGER sint, BOOLEAN sboolean")?
- // - Otherwise too?
- + " WHEN DATA_TYPE LIKE 'STRUCT(%' THEN " + Types.STRUCT
+ + "\n WHEN 'TIME' THEN " + Types.TIME
+ + "\n WHEN 'TIMESTAMP' THEN " + Types.TIMESTAMP
+ + "\n WHEN 'TINYINT' THEN " + Types.TINYINT
- + " WHEN DATA_TYPE = 'TIME' THEN " + Types.TIME
- + " WHEN DATA_TYPE = 'TIMESTAMP' THEN " + Types.TIMESTAMP
- + " WHEN DATA_TYPE = 'TINYINT' THEN " + Types.TINYINT
+ + "\n WHEN 'VARBINARY', 'BINARY VARYING' THEN " + Types.VARBINARY
+ + "\n WHEN 'VARCHAR', 'CHARACTER VARYING' "
+ + "\n THEN " + Types.VARCHAR
- + " WHEN DATA_TYPE = 'VARBINARY' THEN " + Types.VARBINARY
- + " WHEN DATA_TYPE = 'VARCHAR' THEN " + Types.VARCHAR
+ + "\n ELSE"
+ // Pattern-match cases:
+ + "\n CASE "
+
+ // TODO: RESOLVE: How does ARRAY appear in COLUMNS.DATA_TYPE?
+ // - Only at end (with no maximum size, as "VARCHAR(65535) ARRAY")?
+ // - Possibly with maximum size (as "... ARRAY[10]")?
+ // - Then, how should it appear in JDBC ("ARRAY"? "... ARRAY"?)
+ // (SQL source syntax:
+ // <array type> ::=
+ // <data type> ARRAY
+ // [ <left bracket or trigraph> <maximum cardinality>
+ // <right bracket or trigraph> ]
+ + "\n WHEN DATA_TYPE LIKE '% ARRAY' THEN " + Types.ARRAY
// TODO: RESOLVE: How does MAP appear in COLUMNS.DATA_TYPE?
// - Only at end?
// - Otherwise?
// TODO: RESOLVE: Should it map to Types.OTHER or something else?
// Has appeared in Drill. Should it?
- + " WHEN DATA_TYPE LIKE '% MAP' THEN " + Types.OTHER
-
- + " ELSE " + Types.OTHER
- + " END as DATA_TYPE, \n"
-
- + /* 6 */ " DATA_TYPE as TYPE_NAME, \n"
- ///* 7 */ FIXME: BUG: There should be: COLUMN_SIZE
- + /* 8 */ " CHARACTER_MAXIMUM_LENGTH as BUFFER_LENGTH, \n"
- // FIXME: BUG: Many of the following are wrong.
- + /* 9 */ " NUMERIC_PRECISION as DECIMAL_PRECISION, \n" // FIXME: BUG: Should be "DECIMAL_DIGITS"
- + /* 10 */ " NUMERIC_PRECISION_RADIX as NUM_PREC_RADIX, \n"
- + /* 11 */ " " + DatabaseMetaData.columnNullableUnknown
- + " as NULLABLE, \n"
- + /* 12 */ " '' as REMARKS, \n"
- + /* 13 */ " '' as COLUMN_DEF, \n"
- + /* 14 */ " 0 as SQL_DATA_TYPE, \n"
- + /* 15 */ " 0 as SQL_DATETIME_SUB, \n"
- + /* 16 */ " 4 as CHAR_OCTET_LENGTH, \n"
- + /* 17 */ " 1 as ORDINAL_POSITION, \n"
- + /* 18 */ " 'YES' as IS_NULLABLE, \n"
- + /* 19 */ " '' as SCOPE_CATALOG,"
- + /* 20 */ " '' as SCOPE_SCHEMA, \n"
- + /* 21 */ " '' as SCOPE_TABLE, \n"
- + /* 22 */ " '' as SOURCE_DATA_TYPE, \n"
- + /* 23 */ " '' as IS_AUTOINCREMENT, \n"
- + /* 24 */ " '' as IS_GENERATEDCOLUMN \n"
- + "FROM INFORMATION_SCHEMA.COLUMNS \n"
- + "WHERE 1=1 ");
+ + "\n WHEN DATA_TYPE LIKE '% MAP' THEN " + Types.OTHER
+
+ // TODO: RESOLVE: How does "STRUCT" appear?
+ // - Only at beginning (as "STRUCT(INTEGER sint, BOOLEAN sboolean")?
+ // - Otherwise too?
+ // - Then, how should it appear in JDBC ("STRUCT"? "STRUCT(...)"?)
+ + "\n WHEN DATA_TYPE LIKE 'STRUCT(%' THEN " + Types.STRUCT
+
+ + "\n ELSE " + Types.OTHER
+ + "\n END "
+ + "\n END as DATA_TYPE, "
+
+ /* 6 TYPE_NAME */
+ // Map Drill's current info. schema values to what SQL standard
+ // specifies (for DATA_TYPE)--and assume that that's what JDBC wants.
+ + "\n CASE DATA_TYPE "
+ + "\n WHEN 'INTERVAL_YEAR_MONTH', "
+ + "\n 'INTERVAL_DAY_TIME' THEN 'INTERVAL'"
+ // TODO: Resolve how non-scalar types should appear in
+ // INFORMATION_SCHEMA.COLUMNS and here in JDBC:
+ // - "ARRAY" or "... ARRAY"?
+ // - "MAP" or "... MAP"?
+ // - "STRUCT" or "STRUCT(...)"?
+ + "\n ELSE DATA_TYPE "
+ + "\n END as TYPE_NAME, "
+
+ /* 7 COLUMN_SIZE */
+ /* "... COLUMN_SIZE ....
+ * For numeric data, this is the maximum precision.
+ * For character data, this is the length in characters.
+ * For datetime datatypes, this is the length in characters of the String
+ * representation (assuming the maximum allowed precision of the
+ * fractional seconds component).
+ * For binary data, this is the length in bytes.
+ * For the ROWID datatype, this is the length in bytes.
+ * Null is returned for data types where the column size is not applicable."
+ *
+ * Note: "Maximum precision" seems to mean the maximum number of
+ * significant decimal digits that can appear (not the number of digits
+ * that can be counted on, and not the maximum number of characters
+ * needed to display a value).
+ */
+ + "\n CASE DATA_TYPE "
+
+ // "For numeric data, ... the maximum precision":
+ // TODO: Change literals to references to declared constant fields:
+ // - exact numeric types:
+ // (in decimal digits, coordinated with NUM_PREC_RADIX = 10)
+ + "\n WHEN 'TINYINT' THEN " + PREC_TINYINT
+ + "\n WHEN 'SMALLINT' THEN " + PREC_SMALLINT
+ + "\n WHEN 'INTEGER' THEN " + PREC_INTEGER
+ + "\n WHEN 'BIGINT' THEN " + PREC_BIGINT
+ + "\n WHEN 'DECIMAL', 'NUMERIC' THEN NUMERIC_PRECISION "
+ // - approximate numeric types:
+ // (in decimal digits, coordinated with NUM_PREC_RADIX = 10)
+ // TODO: REVISIT: Should these be in bits or decimal digits (with
+ // NUM_PREC_RADIX coordinated)? INFORMATION_SCHEMA.COLUMNS's value
+ // are supposed to be in bits (per the SQL spec.). What does JDBC
+ // require and allow?
+ + "\n WHEN 'FLOAT' THEN " + PREC_FLOAT
+ + "\n WHEN 'DOUBLE' THEN " + PREC_DOUBLE
+ + "\n WHEN 'REAL' THEN " + PREC_REAL
+
+ // "For character data, ... the length in characters":
+ // TODO: BUG: DRILL-2459: For CHARACTER / CHAR, length is not in
+ // CHARACTER_MAXIMUM_LENGTH but in NUMERIC_PRECISION.
+ // Workaround:
+ + "\n WHEN 'VARCHAR', 'CHARACTER VARYING' "
+ + "\n THEN CHARACTER_MAXIMUM_LENGTH "
+ + "\n WHEN 'CHAR', 'CHARACTER', "
+ + "\n 'NCHAR', 'NATIONAL CHAR', 'NATIONAL CHARACTER' "
+ + "\n THEN NUMERIC_PRECISION "
+
+ // "For datetime datatypes ... length ... String representation
+ // (assuming the maximum ... precision of ... fractional seconds ...)":
+ + "\n WHEN 'DATE' THEN 10 " // YYYY-MM-DD
+ + "\n WHEN 'TIME' THEN "
+ + "\n CASE "
+ + "\n WHEN NUMERIC_PRECISION > 0 " // HH:MM:SS.sss
+ + "\n THEN 8 + 1 + NUMERIC_PRECISION"
+ + "\n ELSE 8" // HH:MM:SS
+ + "\n END "
+ + "\n WHEN 'TIMESTAMP' THEN "
+ + "\n CASE " // date + "T" + time (above)
+ + "\n WHEN NUMERIC_PRECISION > 0 "
+ + " THEN 10 + 1 + 8 + 1 + NUMERIC_PRECISION"
+ + "\n ELSE 10 + 1 + 8"
+ + "\n END "
+
+ // TODO: DRILL-2531: When DRILL-2519 is fixed, use start and end unit
+ // and start-unit precision to implement maximum width more precisely
+ // (narrowly) than this workaround:
+ // For INTERVAL_YEAR_MONTH, maximum width is from "P1234567890Y12M"
+ // (5 + apparent maximum start unit precision of 10)
+ // unit precision):
+ + "\n WHEN 'INTERVAL_YEAR_MONTH' "
+ + "\n THEN 5 + "
+ + PREC_INTERVAL_LEAD_MAX
+ // For INTERVAL_DAY_TIME, maximum width is from
+ // "P1234567890D12H12M12.123456789S" (12 + apparent maximum start unit
+ // precision of 10 + apparent maximum seconds fractional precision of 9):
+ + "\n WHEN 'INTERVAL_DAY_TIME' "
+ + "\n THEN 12 + "
+ + ( PREC_INTERVAL_LEAD_MAX
+ + PREC_INTERVAL_TRAIL_MAX )
+
+ // "For binary data, ... the length in bytes":
+ // BUG: DRILL-2459: BINARY and BINARY VARYING / VARBINARY length is
+ // not in CHARACTER_MAXIMUM_LENGTH but in NUMERIC_PRECISION.
+ // Workaround:
+ + "\n WHEN 'VARBINARY', 'BINARY VARYING', "
+ + "\n 'BINARY' THEN NUMERIC_PRECISION "
+
+ // "For ... ROWID datatype...": Not in Drill?
+
+ // "Null ... for data types [for which] ... not applicable.":
+ + "\n ELSE NULL "
+ + "\n END as COLUMN_SIZE, "
+
+ + /* 8 */ "\n CHARACTER_MAXIMUM_LENGTH as BUFFER_LENGTH, "
+
+ /* 9 DECIMAL_DIGITS */
+ + "\n CASE DATA_TYPE"
+ + "\n WHEN 'TINYINT', "
+ + "\n 'SMALLINT', "
+ + "\n 'INTEGER', "
+ + "\n 'BIGINT' THEN " + SCALE_INTEGRAL
+ + "\n WHEN 'DECIMAL', "
+ + "\n 'NUMERIC' THEN NUMERIC_SCALE "
+ + "\n WHEN 'FLOAT' THEN " + SCALE_FLOAT
+ + "\n WHEN 'DOUBLE' THEN " + SCALE_DOUBLE
+ + "\n WHEN 'REAL' THEN " + SCALE_REAL
+ + "\n WHEN 'INTERVAL' THEN NUMERIC_SCALE "
+ + "\n WHEN 'INTERVAL_YEAR_MONTH' THEN 0 "
+ + "\n WHEN 'INTERVAL_DAY_TIME' THEN NUMERIC_SCALE "
+ + "\n END as DECIMAL_DIGITS, "
+
+ /* 10 NUM_PREC_RADIX */
+ + "\n CASE DATA_TYPE "
+ + "\n WHEN 'TINYINT', "
+ + "\n 'SMALLINT', "
+ + "\n 'INTEGER', "
+ + "\n 'BIGINT' THEN " + RADIX_INTEGRAL
+ + "\n WHEN 'DECIMAL', "
+ + "\n 'NUMERIC' THEN " + RADIX_DECIMAL
+ + "\n WHEN 'FLOAT', "
+ + "\n 'DOUBLE', "
+ + "\n 'REAL' THEN " + RADIX_APPROXIMATE
+ + "\n WHEN 'INTERVAL_YEAR_MONTH', "
+ + "\n 'INTERVAL_DAY_TIME' THEN " + RADIX_INTERVAL
+ + "\n ELSE NULL"
+ + "\n END as NUM_PREC_RADIX, "
+
+ /* 11 NULLABLE */
+ + "\n CASE IS_NULLABLE "
+ + "\n WHEN 'YES' THEN " + DatabaseMetaData.columnNullable
+ + "\n WHEN 'NO' THEN " + DatabaseMetaData.columnNoNulls
+ + "\n WHEN '' THEN " + DatabaseMetaData.columnNullableUnknown
+ + "\n ELSE -1"
+ + "\n END as NULLABLE, "
+
+ + /* 12 */ "\n CAST( NULL as VARCHAR ) as REMARKS, "
+ + /* 13 */ "\n CAST( NULL as VARCHAR ) as COLUMN_DEF, "
+ + /* 14 */ "\n 0 as SQL_DATA_TYPE, "
+ + /* 15 */ "\n 0 as SQL_DATETIME_SUB, "
+
+ /* 16 CHAR_OCTET_LENGTH */
+ + "\n CASE DATA_TYPE"
+ + "\n WHEN 'VARCHAR', 'CHARACTER VARYING' "
+ + "\n THEN 4 * CHARACTER_MAXIMUM_LENGTH "
+ + "\n WHEN 'CHAR', 'CHARACTER', "
+ + "\n 'NCHAR', 'NATIONAL CHAR', 'NATIONAL CHARACTER' "
+ // TODO: BUG: DRILL-2459: For CHARACTER / CHAR, length is not in
+ // CHARACTER_MAXIMUM_LENGTH but in NUMERIC_PRECISION. Workaround:
+ + "\n THEN 4 * NUMERIC_PRECISION "
+ + "\n ELSE NULL "
+ + "\n END as CHAR_OCTET_LENGTH, "
+
+ + /* 17 */ "\n 1 + ORDINAL_POSITION as ORDINAL_POSITION, "
+ + /* 18 */ "\n IS_NULLABLE as IS_NULLABLE, "
+ + /* 19 */ "\n CAST( NULL as VARCHAR ) as SCOPE_CATALOG, "
+ + /* 20 */ "\n CAST( NULL as VARCHAR ) as SCOPE_SCHEMA, "
+ + /* 21 */ "\n CAST( NULL as VARCHAR ) as SCOPE_TABLE, "
+ // TODO: Change to SMALLINT when it's implemented (DRILL-2470):
+ + /* 22 */ "\n CAST( NULL as INTEGER ) as SOURCE_DATA_TYPE, "
+ + /* 23 */ "\n '' as IS_AUTOINCREMENT, "
+ + /* 24 */ "\n '' as IS_GENERATEDCOLUMN "
+
+ + "\n FROM INFORMATION_SCHEMA.COLUMNS "
+ + "\n WHERE 1=1 ");
if (catalog != null) {
sb.append("\n AND TABLE_CATALOG = '" + DrillStringUtils.escapeSql(catalog) + "'");
@@ -272,16 +491,14 @@ public class MetaImpl implements Meta {
if (schemaPattern.s != null) {
sb.append("\n AND TABLE_SCHEMA like '" + DrillStringUtils.escapeSql(schemaPattern.s) + "'");
}
-
if (tableNamePattern.s != null) {
sb.append("\n AND TABLE_NAME like '" + DrillStringUtils.escapeSql(tableNamePattern.s) + "'");
}
-
if (columnNamePattern.s != null) {
sb.append("\n AND COLUMN_NAME like '" + DrillStringUtils.escapeSql(columnNamePattern.s) + "'");
}
- sb.append(" ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME");
+ sb.append("\n ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME");
return s(sb.toString());
}
[2/6] drill git commit: DRILL-2439: Fix: getBoolean() doesn't work
(for non-null values).
Posted by pa...@apache.org.
DRILL-2439: Fix: getBoolean() doesn't work (for non-null values).
- Created regression test Drill2439GetBooleanSaysWrongTypeBugTest.
- Added getBoolean(...) for SqlAccessor implementations for type Bit in
SqlAccessors template.
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/9a5b50ea
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/9a5b50ea
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/9a5b50ea
Branch: refs/heads/master
Commit: 9a5b50ea52ee60a355926ac0d52ab87fafb592c0
Parents: 83ebf4f
Author: dbarclay <db...@maprtech.com>
Authored: Fri Mar 20 22:14:56 2015 -0700
Committer: Parth Chandra <pc...@maprtech.com>
Committed: Fri Mar 27 10:19:23 2015 -0700
----------------------------------------------------------------------
.../main/codegen/templates/SqlAccessors.java | 13 ++++
...39GetBooleanFailsSayingWrongTypeBugTest.java | 80 ++++++++++++++++++++
2 files changed, 93 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/9a5b50ea/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/SqlAccessors.java b/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
index a838e11..c0ece9b 100644
--- a/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
+++ b/exec/java-exec/src/main/codegen/templates/SqlAccessors.java
@@ -270,6 +270,19 @@ public class ${name}Accessor extends AbstractSqlAccessor {
}
</#if>
+
+ <#if minor.class == "Bit" >
+ public boolean getBoolean(int index) {
+ <#if mode == "Nullable">
+ if (ac.isNull(index)) {
+ return false;
+ }
+ </#if>
+ return 1 == ac.get(index);
+ }
+ </#if>
+
+
</#if> <#-- not VarLen -->
}
http://git-wip-us.apache.org/repos/asf/drill/blob/9a5b50ea/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2439GetBooleanFailsSayingWrongTypeBugTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2439GetBooleanFailsSayingWrongTypeBugTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2439GetBooleanFailsSayingWrongTypeBugTest.java
new file mode 100644
index 0000000..69f194a
--- /dev/null
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2439GetBooleanFailsSayingWrongTypeBugTest.java
@@ -0,0 +1,80 @@
+/**
+ * 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.test;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.CoreMatchers.*;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.apache.drill.jdbc.Driver;
+import org.apache.drill.jdbc.JdbcTest;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+
+public class Drill2439GetBooleanFailsSayingWrongTypeBugTest extends JdbcTest {
+
+ private static Connection connection;
+ private static Statement statement;
+
+ @BeforeClass
+ public static void setUpConnection() throws SQLException {
+ connection = new Driver().connect( "jdbc:drill:zk=local", null );
+ statement = connection.createStatement();
+ }
+
+ @AfterClass
+ public static void tearDownConnection() throws SQLException {
+ connection.close();
+ }
+
+ @Test
+ public void testGetBooleanGetsTrue() throws Exception {
+ ResultSet rs =
+ statement.executeQuery( "SELECT TRUE FROM INFORMATION_SCHEMA.CATALOGS" );
+ rs.next();
+ assertThat( "getBoolean(...) for TRUE", rs.getBoolean( 1 ), equalTo( true ) );
+ assertThat( "wasNull", rs.wasNull(), equalTo( false ) );
+ }
+
+ @Test
+ public void testGetBooleanGetsFalse() throws Exception {
+ ResultSet rs =
+ statement.executeQuery( "SELECT FALSE FROM INFORMATION_SCHEMA.CATALOGS" );
+ rs.next();
+ assertThat( "getBoolean(...) for FALSE", rs.getBoolean( 1 ), equalTo( false ) );
+ assertThat( "wasNull", rs.wasNull(), equalTo( false ) );
+ }
+
+ @Test
+ public void testGetBooleanGetsNull() throws Exception {
+ ResultSet rs = statement.executeQuery(
+ "SELECT CAST( NULL AS BOOLEAN ) FROM INFORMATION_SCHEMA.CATALOGS" );
+ rs.next();
+ assertThat( "getBoolean(...) for BOOLEAN NULL", rs.getBoolean( 1 ), equalTo( false ) );
+ assertThat( "wasNull", rs.wasNull(), equalTo( true ) );
+ }
+
+}
[5/6] drill git commit: DRILL-2465: Fix multiple
DatabaseMetaData.getColumns() bugs.
Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/drill/blob/20efb2fb/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java
new file mode 100644
index 0000000..1a7b63d
--- /dev/null
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/DatabaseMetaDataGetColumnsTest.java
@@ -0,0 +1,2779 @@
+/**
+ * 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;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.CoreMatchers.*;
+
+import org.apache.drill.exec.store.hive.HiveTestDataGenerator;
+import org.apache.drill.jdbc.Driver;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.Statement;
+
+import static java.sql.ResultSetMetaData.columnNoNulls;
+import static java.sql.ResultSetMetaData.columnNullable;
+import static java.sql.ResultSetMetaData.columnNullableUnknown;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+// TODO: MOVE notes to implementation (have this not (just) in test).
+
+// TODO: Determine for each numeric type whether its precision is reported in
+// decimal or binary (and NUM_PREC_RADIX is 10 or 2, respectively).
+// The SQL specification for INFORMATION_SCHEMA.COLUMNS seems to specify the
+// radix for each numeric type:
+// - 2 or 10 for SMALLINT, INTEGER, and BIGINT;
+// - only 10 for NUMERIC and DECIMAL; and
+// - only 2 for REAL, DOUBLE PRECISION, and FLOAT.
+// However, it is not clear what the JDBC API intends:
+// - It has NUM_PREC_RADIX, specifying a radix or 10 or 2, but doesn't specify
+// exactly what is applies to. Apparently, it applies to COLUMN_SIZE abd
+// ResultMetaData.getPrecision() (which are defined in terms of maximum
+// precision for numeric types).
+// - Is has DECIMAL_DIGITS, which is <em>not</em> the number of decimal digits
+// of precision, but which it defines as the number of fractional digits--
+// without actually specifying that it's in decimal.
+
+// TODO: Review nullability (NULLABLE and IS_NULLABLE columns):
+// - It's not clear what JDBC's requirements are.
+// - It does seem obvious that metadata should not contradictorily say that a
+// - column cannot contain nulls when the column currently does contain nulls.
+// - It's not clear whether metadata must say that a column cannot contains
+// nulls if JDBC specifies that the column always has a non-null value.
+// - It's not clear why Drill reports that columns that will never contain nulls
+// can contain nulls.
+// - It's not clear why Drill sets INFORMATION_SCHEMA.COLUMNS.IS_NULLABLE to
+// 'NO' for some columns that contain only null (e.g., for
+// "CREATE VIEW x AS SELECT CAST(NULL AS ...) ..."
+
+
+/**
+ * Test class for Drill's java.sql.DatabaseMetaData.getColumns() implementation.
+ * <p>
+ * Based on JDBC 4.1 (Java 7).
+ * </p>
+ */
+public class DatabaseMetaDataGetColumnsTest extends JdbcTest {
+
+ private static final String VIEW_NAME =
+ DatabaseMetaDataGetColumnsTest.class.getSimpleName() + "_View";
+
+
+ /** The one shared JDBC connection to Drill. */
+ private static Connection connection;
+
+ /** Overall (connection-level) metadata. */
+ private static DatabaseMetaData dbMetadata;
+
+
+ /** getColumns result metadata. For checking columns themselves (not cell
+ * values or row order). */
+ private static ResultSetMetaData rowsMetadata;
+
+
+ ////////////////////
+ // Results from getColumns for test columns of various types.
+ // Each ResultSet is positioned at first row for, and must not be modified by,
+ // test methods.
+
+ //////////
+ // For columns in temporary test view (types accessible via casting):
+ // TODO: Determine whether any other data types are accessible via CAST
+ // and add them.
+
+ private static ResultSet mdrOptBOOLEAN;
+
+ private static ResultSet mdrReqTINYINT;
+ private static ResultSet mdrOptSMALLINT;
+ private static ResultSet mdrReqINTEGER;
+ private static ResultSet mdrOptBIGINT;
+
+ private static ResultSet mdrOptFLOAT;
+ private static ResultSet mdrReqDOUBLE;
+ private static ResultSet mdrOptREAL;
+
+ private static ResultSet mdrReqDECIMAL_5_3;
+ // No NUMERIC while Drill just maps it to DECIMAL.
+
+ private static ResultSet mdrReqVARCHAR_10;
+ private static ResultSet mdrOptVARCHAR;
+ private static ResultSet mdrReqCHAR_5;
+ // No NCHAR, etc., in Drill (?).
+ private static ResultSet mdrOptVARBINARY_16;
+ private static ResultSet mdrOptBINARY_1048576;
+
+ private static ResultSet mdrReqDATE;
+ private static ResultSet mdrOptTIME;
+ private static ResultSet mdrOptTIME_7;
+ private static ResultSet mdrOptTIMESTAMP;
+ // No "... WITH TIME ZONE" in Drill.
+ private static ResultSet mdrOptINTERVAL_H_S3;
+ private static ResultSet mdrOptINTERVAL_Y4;
+
+ //////////
+ // For columns in schema hive_test.default's infoschematest table:
+
+ // listtype column: VARCHAR(65535) ARRAY, non-null(?):
+ private static ResultSet mdrReqARRAY;
+ // maptype column: (VARCHAR(65535), INTEGER) MAP, non-null(?):
+ private static ResultSet mdrReqMAP;
+ // structtype column: STRUCT(INTEGER sint, BOOLEAN sboolean,
+ // VARCHAR(65535) sstring), non-null(?):
+ private static ResultSet testRowSTRUCT;
+ // uniontypetype column: OTHER (?), non=nullable(?):
+ private static ResultSet testRowUnion;
+
+
+ private static ResultSet setUpRow( final String schemaName,
+ final String tableOrViewName,
+ final String columnName ) throws SQLException
+ {
+ System.out.println( "(Setting up row for " + tableOrViewName + "." + columnName + ".)");
+ assert null != dbMetadata
+ : "dbMetadata is null; must be set before calling setUpRow(...)";
+ final ResultSet testRow =
+ dbMetadata.getColumns( "DRILL", schemaName, tableOrViewName, columnName );
+ if ( ! testRow.next() ) {
+ assert false
+ : "Test setup error: No row for column DRILL . `" + schemaName + "` . `"
+ + tableOrViewName + "` . `" + columnName + "`";
+ }
+ return testRow;
+ }
+
+ @BeforeClass
+ public static void setUpConnectionAndMetadataToCheck() throws Exception {
+
+ // Get JDBC connection to Drill:
+ connection = new Driver().connect( "jdbc:drill:zk=local", null );
+ dbMetadata = connection.getMetaData();
+ Statement stmt = connection.createStatement();
+
+ ResultSet util;
+
+ // Create Hive test data, only if not created already (speed optimization):
+ util = stmt.executeQuery( "SELECT * FROM INFORMATION_SCHEMA.COLUMNS "
+ + "WHERE TABLE_SCHEMA = 'hive_test.default' "
+ + " AND TABLE_NAME = 'infoschematest'" );
+
+ System.out.println( "(Hive infoschematest columns: " );
+ int hiveTestColumnRowCount = 0;
+ while ( util.next() ) {
+ hiveTestColumnRowCount++;
+ System.out.println(
+ " Hive test column: "
+ + util.getString( 1 ) + " - " + util.getString( 2 ) + " - "
+ + util.getString( 3 ) + " - " + util.getString( 4 ) );
+ }
+ System.out.println( " Hive test column count: " + hiveTestColumnRowCount + ")" );
+ if ( 0 == hiveTestColumnRowCount ) {
+ // No Hive test data--create it.
+ new HiveTestDataGenerator().generateTestData();
+ } else if ( 17 == hiveTestColumnRowCount ) {
+ // Hive data seems to exist already--skip recreating it.
+ } else {
+ assert false
+ : "Expected 17 Hive test columns see " + hiveTestColumnRowCount + "."
+ + " Test code is out of date or Hive data is corrupted.";
+ }
+
+ // Note: Assertions must be enabled (as they have been so far in tests).
+
+ // Create temporary test-columns view:
+ util = stmt.executeQuery( "USE dfs.tmp" );
+ assert util.next();
+ assert util.getBoolean( 1 )
+ : "Error setting schema for test: " + util.getString( 2 );
+ util = stmt.executeQuery(
+ ""
+ + "CREATE OR REPLACE VIEW " + VIEW_NAME + " AS SELECT "
+ + "\n CAST( NULL AS BOOLEAN ) AS optBOOLEAN, "
+ + "\n"
+ + "\n CAST( 1 AS TINYINT ) AS reqTINYINT, "
+ + "\n CAST( NULL AS SMALLINT ) AS optSMALLINT, "
+ + "\n CAST( 2 AS INTEGER ) AS reqINTEGER, "
+ + "\n CAST( NULL AS BIGINT ) AS optBIGINT, "
+ + "\n"
+ + "\n CAST( NULL AS FLOAT ) AS optFLOAT, "
+ + "\n CAST( 3.3 AS DOUBLE ) AS reqDOUBLE, "
+ + "\n CAST( NULL AS REAL ) AS optREAL, "
+ + "\n"
+ + "\n CAST( 4.4 AS DECIMAL(5,3) ) AS reqDECIMAL_5_3, "
+ + "\n"
+ + "\n CAST( 'Hi' AS VARCHAR(10) ) AS reqVARCHAR_10, "
+ + "\n CAST( NULL AS VARCHAR ) AS optVARCHAR, "
+ + "\n CAST( '55' AS CHAR(5) ) AS reqCHAR_5, "
+ + "\n CAST( NULL AS VARBINARY(16) ) AS optVARBINARY_16, "
+ + "\n CAST( NULL AS VARBINARY(1048576) ) AS optBINARY_1048576, "
+ + "\n CAST( NULL AS BINARY(8) ) AS optBINARY_8, "
+ + "\n"
+ + "\n CAST( '2015-01-01' AS DATE ) AS reqDATE, "
+ + "\n CAST( NULL AS TIME ) AS optTIME, "
+ + "\n CAST( NULL AS TIME(7) ) AS optTIME_7, "
+ + "\n CAST( NULL AS TIMESTAMP ) AS optTIMESTAMP, "
+ + "\n CAST( NULL AS INTERVAL HOUR TO SECOND(3) ) AS optINTERVAL_H_S3, "
+ + "\n CAST( NULL AS INTERVAL YEAR(4) ) AS optINTERVAL_Y4, "
+ + "\n '' "
+ + "\nFROM INFORMATION_SCHEMA.COLUMNS "
+ + "\nLIMIT 1 " );
+ assert util.next();
+ assert util.getBoolean( 1 )
+ : "Error creating temporary test-columns view " + VIEW_NAME + ": "
+ + util.getString( 2 );
+
+ // Set up result rows for temporary test view and Hivetest columns:
+
+ mdrOptBOOLEAN = setUpRow( "dfs.tmp", VIEW_NAME, "optBOOLEAN" );
+
+ mdrReqTINYINT = setUpRow( "dfs.tmp", VIEW_NAME, "reqTINYINT" );
+ mdrOptSMALLINT = setUpRow( "dfs.tmp", VIEW_NAME, "optSMALLINT" );
+ mdrReqINTEGER = setUpRow( "dfs.tmp", VIEW_NAME, "reqINTEGER" );
+ mdrOptBIGINT = setUpRow( "dfs.tmp", VIEW_NAME, "optBIGINT" );
+
+ mdrOptFLOAT = setUpRow( "dfs.tmp", VIEW_NAME, "optFLOAT" );
+ mdrReqDOUBLE = setUpRow( "dfs.tmp", VIEW_NAME, "reqDOUBLE" );
+ mdrOptREAL = setUpRow( "dfs.tmp", VIEW_NAME, "optREAL" );
+
+ mdrReqDECIMAL_5_3 = setUpRow( "dfs.tmp", VIEW_NAME, "reqDECIMAL_5_3" );
+
+ mdrReqVARCHAR_10 = setUpRow( "dfs.tmp", VIEW_NAME, "reqVARCHAR_10" );
+ mdrOptVARCHAR = setUpRow( "dfs.tmp", VIEW_NAME, "optVARCHAR" );
+ mdrReqCHAR_5 = setUpRow( "dfs.tmp", VIEW_NAME, "reqCHAR_5" );
+ mdrOptVARBINARY_16 = setUpRow( "dfs.tmp", VIEW_NAME, "optVARBINARY_16" );
+ mdrOptBINARY_1048576 = setUpRow( "dfs.tmp", VIEW_NAME, "optBINARY_1048576" );
+
+ mdrReqDATE = setUpRow( "dfs.tmp", VIEW_NAME, "reqDATE" );
+ mdrOptTIME = setUpRow( "dfs.tmp", VIEW_NAME, "optTIME" );
+ mdrOptTIME_7 = setUpRow( "dfs.tmp", VIEW_NAME, "optTIME_7" );
+ mdrOptTIMESTAMP = setUpRow( "dfs.tmp", VIEW_NAME, "optTIMESTAMP" );
+ mdrOptINTERVAL_H_S3 = setUpRow( "dfs.tmp", VIEW_NAME, "optINTERVAL_H_S3" );
+ mdrOptINTERVAL_Y4 = setUpRow( "dfs.tmp", VIEW_NAME, "optINTERVAL_Y4" );
+
+ mdrReqARRAY = setUpRow( "hive_test.default", "infoschematest", "listtype" );
+ mdrReqMAP = setUpRow( "hive_test.default", "infoschematest", "maptype" );
+ testRowSTRUCT = setUpRow( "hive_test.default", "infoschematest", "structtype" );
+ testRowUnion = setUpRow( "hive_test.default", "infoschematest", "uniontypetype" );
+
+ // Set up getColumns(...)) result set' metadata:
+
+ // Get all columns for more diversity of values (e.g., nulls and non-nulls),
+ // in case that affects metadata (e.g., nullability) (in future).
+ final ResultSet allColumns = dbMetadata.getColumns( null /* any catalog */,
+ null /* any schema */,
+ "%" /* any table */,
+ "%" /* any column */ );
+ rowsMetadata = allColumns.getMetaData();
+ }
+
+ @AfterClass
+ public static void tearDownConnection() throws SQLException {
+
+ ResultSet util =
+ connection.createStatement().executeQuery( "DROP VIEW " + VIEW_NAME + "" );
+ assert util.next();
+ // DRILL-2439: assert util.getBoolean( 1 ) : ...;
+ assert util.getBoolean( 1 )
+ : "Error dropping temporary test-columns view " + VIEW_NAME + ": "
+ + util.getString( 2 );
+ connection.close();
+ }
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Tests:
+
+ ////////////////////////////////////////////////////////////
+ // Number of columns.
+
+ @Test
+ public void testMetadataHasRightNumberOfColumns() throws SQLException {
+ // TODO: Review: Is this check valid? (Are extra columns allowed?)
+ assertThat( "column count", rowsMetadata.getColumnCount(), equalTo( 24 ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #1: TABLE_CAT:
+ // - JDBC: "1. ... String => table catalog (may be null)"
+ // - Drill: Apparently chooses always "DRILL".
+ // - (Meta): VARCHAR (NVARCHAR?); Non-nullable(?);
+
+ @Test
+ public void test_TABLE_CAT_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 1 ), equalTo( "TABLE_CAT" ) );
+ }
+
+ @Test
+ public void test_TABLE_CAT_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getString( "TABLE_CAT" ), equalTo( "DRILL" ) );
+ }
+
+ // Not bothering with other test columns for TABLE_CAT.
+
+ @Test
+ public void test_TABLE_CAT_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 1 ), equalTo( "TABLE_CAT" ) );
+ }
+
+ @Test
+ public void test_TABLE_CAT_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 1 ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_TABLE_CAT_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 1 ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_TABLE_CAT_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.String" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 1 ), equalTo( String.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_TABLE_CAT_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 1 ), equalTo( columnNullable ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #2: TABLE_SCHEM:
+ // - JDBC: "2. ... String => table schema (may be null)"
+ // - Drill: Always reports a schema name.
+ // - (Meta): VARCHAR (NVARCHAR?); Nullable?;
+
+ @Test
+ public void test_TABLE_SCHEM_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 2 ), equalTo( "TABLE_SCHEM" ) );
+ }
+
+ @Test
+ public void test_TABLE_SCHEM_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getString( "TABLE_SCHEM" ), equalTo( "dfs.tmp" ) );
+ }
+
+ // Not bothering with other _local_view_ test columns for TABLE_SCHEM.
+
+ @Test
+ public void test_TABLE_SCHEM_hasRightValue_tdbARRAY() throws SQLException {
+ assertThat( mdrReqARRAY.getString( "TABLE_SCHEM" ), equalTo( "hive_test.default" ) );
+ }
+
+ // Not bothering with other Hive test columns for TABLE_SCHEM.
+
+ @Test
+ public void test_TABLE_SCHEM_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 2 ), equalTo( "TABLE_SCHEM" ) );
+ }
+
+ @Test
+ public void test_TABLE_SCHEM_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 2 ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_TABLE_SCHEM_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 2 ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_TABLE_SCHEM_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.String" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 2 ), equalTo( String.class.getName() ) );
+ }
+
+ @Ignore( "until resolved: any requirement on nullability (DRILL-2420?)" )
+ @Test
+ public void test_TABLE_SCHEM_hasRightNullability() throws SQLException {
+ // To-do: CHECK: Why columnNullable, when seemingly known nullable?
+ // (Why not like TABLE_CAT, which does have columnNoNulls?)
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 2 ), equalTo( columnNoNulls ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #3: TABLE_NAME:
+ // - JDBC: "3. ... String => table name"
+ // - Drill:
+ // - (Meta): VARCHAR (NVARCHAR?); Non-nullable?;
+
+ @Test
+ public void test_TABLE_NAME_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 3 ), equalTo( "TABLE_NAME" ) );
+ }
+
+ @Test
+ public void test_TABLE_NAME_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getString( "TABLE_NAME" ), equalTo( VIEW_NAME ) );
+ }
+
+ // Not bothering with other _local_view_ test columns for TABLE_NAME.
+
+ @Test
+ public void test_TABLE_NAME_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 3 ), equalTo( "TABLE_NAME" ) );
+ }
+
+ @Test
+ public void test_TABLE_NAME_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 3 ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_TABLE_NAME_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 3 ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_TABLE_NAME_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.String" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 3 ), equalTo( String.class.getName() ) );
+ }
+
+ @Ignore( "until resolved: any requirement on nullability (DRILL-2420?)" )
+ @Test
+ public void test_TABLE_NAME_hasRightNullability() throws SQLException {
+ // To-do: CHECK: Why columnNullable, when seemingly known nullable?
+ // (Why not like TABLE_CAT, which does have columnNoNulls?)
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 3 ), equalTo( columnNoNulls ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #4: COLUMN_NAME:
+ // - JDBC: "4. ... String => column name"
+ // - Drill:
+ // - (Meta): VARCHAR (NVARCHAR?); Non-nullable(?);
+
+ @Test
+ public void test_COLUMN_NAME_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 4 ), equalTo( "COLUMN_NAME" ) );
+ }
+
+ @Test
+ public void test_COLUMN_NAME_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getString( "COLUMN_NAME" ), equalTo( "optBOOLEAN" ) );
+ }
+
+ // Not bothering with other _local_view_ test columns for TABLE_SCHEM.
+
+ @Test
+ public void test_COLUMN_NAME_hasRightValue_tdbARRAY() throws SQLException {
+ assertThat( mdrReqARRAY.getString( "COLUMN_NAME" ), equalTo( "listtype" ) );
+ }
+
+ // Not bothering with other Hive test columns for TABLE_SCHEM.
+
+ @Test
+ public void test_COLUMN_NAME_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 4 ), equalTo( "COLUMN_NAME" ) );
+ }
+
+ @Test
+ public void test_COLUMN_NAME_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 4 ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_COLUMN_NAME_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 4 ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_COLUMN_NAME_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.String" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 4 ), equalTo( String.class.getName() ) );
+ }
+
+ @Ignore( "until resolved: any requirement on nullability (DRILL-2420?)" )
+ @Test
+ public void test_COLUMN_NAME_hasRightNullability() throws SQLException {
+ // To-do: CHECK: Why columnNullable, when seemingly known nullable?
+ // (Why not like TABLE_CAT, which does have columnNoNulls?)
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 4 ), equalTo( columnNoNulls ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #5: DATA_TYPE:
+ // - JDBC: "5. ... int => SQL type from java.sql.Types"
+ // - Drill:
+ // - (Meta): INTEGER(?); Non-nullable(?);
+
+ @Test
+ public void test_DATA_TYPE_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 5 ), equalTo( "DATA_TYPE" ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getInt( "DATA_TYPE" ), equalTo( Types.BOOLEAN ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_reqTINYINT() throws SQLException {
+ assertThat( mdrReqTINYINT.getInt( "DATA_TYPE" ), equalTo( Types.TINYINT ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optSMALLINT() throws SQLException {
+ assertThat( mdrOptSMALLINT.getInt( "DATA_TYPE" ), equalTo( Types.SMALLINT ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_reqINTEGER() throws SQLException {
+ assertThat( mdrReqINTEGER.getInt( "DATA_TYPE" ), equalTo( Types.INTEGER ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optBIGINT() throws SQLException {
+ assertThat( mdrOptBIGINT.getInt( "DATA_TYPE" ), equalTo( Types.BIGINT ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optFLOAT() throws SQLException {
+ assertThat( mdrOptFLOAT.getInt( "DATA_TYPE" ), equalTo( Types.FLOAT ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_reqDOUBLE() throws SQLException {
+ assertThat( mdrReqDOUBLE.getInt( "DATA_TYPE" ), equalTo( Types.DOUBLE ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optREAL() throws SQLException {
+ assertThat( mdrOptREAL.getInt( "DATA_TYPE" ), equalTo( Types.REAL ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_reqDECIMAL_5_3() throws SQLException {
+ assertThat( mdrReqDECIMAL_5_3.getInt( "DATA_TYPE" ), equalTo( Types.DECIMAL ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_reqVARCHAR_10() throws SQLException {
+ assertThat( mdrReqVARCHAR_10.getInt( "DATA_TYPE" ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optVARCHAR() throws SQLException {
+ assertThat( mdrOptVARCHAR.getInt( "DATA_TYPE" ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_reqCHAR_5() throws SQLException {
+ assertThat( mdrReqCHAR_5.getInt( "DATA_TYPE" ), equalTo( Types.CHAR ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optVARBINARY_16() throws SQLException {
+ assertThat( mdrOptVARBINARY_16.getInt( "DATA_TYPE" ), equalTo( Types.VARBINARY ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optBINARY_1048576CHECK() throws SQLException {
+ assertThat( mdrOptBINARY_1048576.getInt( "DATA_TYPE" ), equalTo( Types.VARBINARY ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_reqDATE() throws SQLException {
+ assertThat( mdrReqDATE.getInt( "DATA_TYPE" ), equalTo( Types.DATE ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optTIME() throws SQLException {
+ assertThat( mdrOptTIME.getInt( "DATA_TYPE" ), equalTo( Types.TIME ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optTIME_7() throws SQLException {
+ assertThat( mdrOptTIME_7.getInt( "DATA_TYPE" ), equalTo( Types.TIME ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optTIMESTAMP() throws SQLException {
+ assertThat( mdrOptTIMESTAMP.getInt( "DATA_TYPE" ), equalTo( Types.TIMESTAMP ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optINTERVAL_HM() throws SQLException {
+ assertThat( mdrOptINTERVAL_H_S3.getInt( "DATA_TYPE" ), equalTo( Types.OTHER ) );
+ // To-do: Determine which.
+ assertThat( mdrOptINTERVAL_H_S3.getInt( "DATA_TYPE" ), equalTo( Types.JAVA_OBJECT ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_DATA_TYPE_hasRightValue_optINTERVAL_Y3() throws SQLException {
+ assertThat( mdrOptINTERVAL_Y4.getInt( "DATA_TYPE" ), equalTo( Types.OTHER ) );
+ // To-do: Determine which.
+ assertThat( mdrOptINTERVAL_Y4.getInt( "DATA_TYPE" ), equalTo( Types.JAVA_OBJECT ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_tdbARRAY() throws SQLException {
+ assertThat( mdrReqARRAY.getInt( "DATA_TYPE" ), equalTo( Types.ARRAY ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_DATA_TYPE_hasRightValue_tbdMAP() throws SQLException {
+ assertThat( "java.sql.Types.* type code",
+ mdrReqMAP.getInt( "DATA_TYPE" ), equalTo( Types.OTHER ) );
+ // To-do: Determine which.
+ assertThat( "java.sql.Types.* type code",
+ mdrReqMAP.getInt( "DATA_TYPE" ), equalTo( Types.JAVA_OBJECT ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightValue_tbdSTRUCT() throws SQLException {
+ assertThat( testRowSTRUCT.getInt( "DATA_TYPE" ), equalTo( Types.STRUCT ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_DATA_TYPE_hasRightValue_tbdUnion() throws SQLException {
+ assertThat( "java.sql.Types.* type code",
+ testRowUnion.getInt( "DATA_TYPE" ), equalTo( Types.OTHER ) );
+ // To-do: Determine which.
+ assertThat( "java.sql.Types.* type code",
+ testRowUnion.getInt( "DATA_TYPE" ), equalTo( Types.JAVA_OBJECT ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 5 ), equalTo( "DATA_TYPE" ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 5 ), equalTo( "INTEGER" ) );
+ }
+
+ @Test
+ public void test_DATA_TYPE_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 5 ), equalTo( Types.INTEGER ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_DATA_TYPE_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 5 ), equalTo( Integer.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_DATA_TYPE_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 5 ), equalTo( columnNoNulls ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #6: TYPE_NAME:
+ // - JDBC: "6. ... String => Data source dependent type name, for a UDT the
+ // type name is fully qualified"
+ // - Drill:
+ // - (Meta): VARCHAR (NVARCHAR?); Non-nullable?;
+
+ @Test
+ public void test_TYPE_NAME_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 6 ), equalTo( "TYPE_NAME" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getString( "TYPE_NAME" ), equalTo( "BOOLEAN" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_reqTINYINT() throws SQLException {
+ assertThat( mdrReqTINYINT.getString( "TYPE_NAME" ), equalTo( "TINYINT" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optSMALLINT() throws SQLException {
+ assertThat( mdrOptSMALLINT.getString( "TYPE_NAME" ), equalTo( "SMALLINT" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_reqINTEGER() throws SQLException {
+ assertThat( mdrReqINTEGER.getString( "TYPE_NAME" ), equalTo( "INTEGER" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optBIGINT() throws SQLException {
+ assertThat( mdrOptBIGINT.getString( "TYPE_NAME" ), equalTo( "BIGINT" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optFLOAT() throws SQLException {
+ assertThat( mdrOptFLOAT.getString( "TYPE_NAME" ), equalTo( "FLOAT" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_reqDOUBLE() throws SQLException {
+ assertThat( mdrReqDOUBLE.getString( "TYPE_NAME" ), equalTo( "DOUBLE" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optREAL() throws SQLException {
+ assertThat( mdrOptREAL.getString( "TYPE_NAME" ), equalTo( "REAL" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_reqDECIMAL_5_3() throws SQLException {
+ assertThat( mdrReqDECIMAL_5_3.getString( "TYPE_NAME" ), equalTo( "DECIMAL" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_reqVARCHAR_10() throws SQLException {
+ assertThat( mdrReqVARCHAR_10.getString( "TYPE_NAME" ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optVARCHAR() throws SQLException {
+ assertThat( mdrOptVARCHAR.getString( "TYPE_NAME" ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_reqCHAR_5() throws SQLException {
+ assertThat( mdrReqCHAR_5.getString( "TYPE_NAME" ), equalTo( "CHAR" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optVARBINARY_16() throws SQLException {
+ assertThat( mdrOptVARBINARY_16.getString( "TYPE_NAME" ), equalTo( "VARBINARY" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optBINARY_1048576CHECK() throws SQLException {
+ assertThat( mdrOptBINARY_1048576.getString( "TYPE_NAME" ), equalTo( "VARBINARY" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_reqDATE() throws SQLException {
+ assertThat( mdrReqDATE.getString( "TYPE_NAME" ), equalTo( "DATE" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optTIME() throws SQLException {
+ assertThat( mdrOptTIME.getString( "TYPE_NAME" ), equalTo( "TIME" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optTIME_7() throws SQLException {
+ assertThat( mdrOptTIME_7.getString( "TYPE_NAME" ), equalTo( "TIME" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optTIMESTAMP() throws SQLException {
+ assertThat( mdrOptTIMESTAMP.getString( "TYPE_NAME" ), equalTo( "TIMESTAMP" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optINTERVAL_HM() throws SQLException {
+ // (What SQL standard specifies for DATA_TYPE in INFORMATION_SCHEMA.COLUMNS:)
+ assertThat( mdrOptINTERVAL_H_S3.getString( "TYPE_NAME" ), equalTo( "INTERVAL" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightValue_optINTERVAL_Y3() throws SQLException {
+ // (What SQL standard specifies for DATA_TYPE in INFORMATION_SCHEMA.COLUMNS:)
+ assertThat( mdrOptINTERVAL_Y4.getString( "TYPE_NAME" ), equalTo( "INTERVAL" ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_TYPE_NAME_hasRightValue_tdbARRAY() throws SQLException {
+ assertThat( mdrReqARRAY.getString( "TYPE_NAME" ), equalTo( "VARCHAR(65535) ARRAY" ) );
+ // TODO: Determine which.
+ assertThat( mdrReqARRAY.getString( "TYPE_NAME" ), equalTo( "ARRAY" ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_TYPE_NAME_hasRightValue_tbdMAP() throws SQLException {
+ assertThat( mdrReqMAP.getString( "TYPE_NAME" ), equalTo( "(VARCHAR(65535), INTEGER) MAP" ) );
+ // TODO: Determine which.
+ assertThat( mdrReqMAP.getString( "TYPE_NAME" ), equalTo( "MAP" ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_TYPE_NAME_hasRightValue_tbdSTRUCT() throws SQLException {
+ assertThat( testRowSTRUCT.getString( "TYPE_NAME" ),
+ equalTo( "STRUCT(INTEGER sint, BOOLEAN sboolean, VARCHAR(65535) sstring)" ) ); // TODO: Confirm.
+ // TODO: Determine which.
+ assertThat( testRowSTRUCT.getString( "TYPE_NAME" ), equalTo( "STRUCT" ) );
+ }
+
+ @Ignore( "until resolved: expected value (DRILL-2420?)" )
+ @Test
+ public void test_TYPE_NAME_hasRightValue_tbdUnion() throws SQLException {
+ assertThat( testRowUnion.getString( "TYPE_NAME" ), equalTo( "OTHER" ) );
+ fail( "Expected value is not resolved yet." );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 6 ), equalTo( "TYPE_NAME" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 6 ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_TYPE_NAME_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 6 ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_TYPE_NAME_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.String" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 6 ), equalTo( String.class.getName() ) );
+ }
+
+ @Ignore( "until resolved: any requirement on nullability (DRILL-2420?)" )
+ @Test
+ public void test_TYPE_NAME_hasRightNullability() throws SQLException {
+ // To-do: CHECK: Why columnNullable, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 6 ), equalTo( columnNoNulls ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #7: COLUMN_SIZE:
+ // - JDBC: "7. ... int => column size."
+ // "The COLUMN_SIZE column specifies the column size for the given column.
+ // For numeric data, this is the maximum precision.
+ // For character data, this is the length in characters.
+ // For datetime datatypes, this is the length in characters of the String
+ // representation (assuming the maximum allowed precision of the
+ // fractional seconds component).
+ // For binary data, this is the length in bytes.
+ // For the ROWID datatype, this is the length in bytes.
+ // Null is returned for data types where the column size is not applicable."
+ // - "Maximum precision" seem to mean maximum number of digits that can
+ // appear.
+ // - (Meta): INTEGER(?); Nullable;
+
+ @Test
+ public void test_COLUMN_SIZE_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 7 ), equalTo( "COLUMN_SIZE" ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optBOOLEAN() throws SQLException {
+ final int value = mdrOptBOOLEAN.getInt( "COLUMN_SIZE" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBOOLEAN.wasNull(), equalTo( true ) ); // TODO: CONFIRM.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_reqTINYINT() throws SQLException {
+ assertThat( mdrReqTINYINT.getInt( "COLUMN_SIZE" ), equalTo( 3 ) ); // TODO: CONFIRM.
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optSMALLINT() throws SQLException {
+ assertThat( mdrOptSMALLINT.getInt( "COLUMN_SIZE" ), equalTo( 5 ) ); // TODO: CONFIRM
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_reqINTEGER() throws SQLException {
+ assertThat( mdrReqINTEGER.getInt( "COLUMN_SIZE" ), equalTo( 10 ) ); // TODO: CONFIRM.
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optBIGINT() throws SQLException {
+ assertThat( mdrOptBIGINT.getInt( "COLUMN_SIZE" ), equalTo( 19 ) ); // To-do: CONFIRM.
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optFLOAT() throws SQLException {
+ assertThat( mdrOptFLOAT.getInt( "COLUMN_SIZE" ), equalTo( 7 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_reqDOUBLE() throws SQLException {
+ assertThat( mdrReqDOUBLE.getInt( "COLUMN_SIZE" ), equalTo( 15 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optREAL() throws SQLException {
+ assertThat( mdrOptREAL.getInt( "COLUMN_SIZE" ), equalTo( 15 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_reqDECIMAL_5_3() throws SQLException {
+ assertThat( mdrReqDECIMAL_5_3.getInt( "COLUMN_SIZE" ), equalTo( 5 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_reqVARCHAR_10() throws SQLException {
+ assertThat( mdrReqVARCHAR_10.getInt( "COLUMN_SIZE" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optVARCHAR() throws SQLException {
+ assertThat( mdrOptVARCHAR.getInt( "COLUMN_SIZE" ), equalTo( 1 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_reqCHAR_5() throws SQLException {
+ assertThat( mdrReqCHAR_5.getInt( "COLUMN_SIZE" ), equalTo( 5 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optVARBINARY_16() throws SQLException {
+ assertThat( mdrOptVARBINARY_16.getInt( "COLUMN_SIZE" ), equalTo( 16 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optBINARY_1048576() throws SQLException {
+ assertThat( mdrOptBINARY_1048576.getInt( "COLUMN_SIZE" ), equalTo( 1048576 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_reqDATE() throws SQLException {
+ assertThat( mdrReqDATE.getInt( "COLUMN_SIZE" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optTIME() throws SQLException {
+ assertThat( mdrOptTIME.getInt( "COLUMN_SIZE" ),
+ equalTo( 8 /* HH:MM:SS */ ) );
+ }
+
+ @Ignore( "until resolved: whether to implement TIME precision or drop test" )
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optTIME_7() throws SQLException {
+ assertThat( mdrOptTIME_7.getInt( "COLUMN_SIZE" ),
+ equalTo( 8 /* HH:MM:SS */ + 1 /* '.' */ + 7 /* sssssss */ ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optTIMESTAMP() throws SQLException {
+ assertThat( mdrOptTIMESTAMP.getInt( "COLUMN_SIZE" ),
+ equalTo( 19 /* YYYY-MM-DDTHH:MM:SS */ ) );
+ }
+
+ @Ignore( "until fixed: INTERVAL metadata in INFORMATION_SCHEMA (DRILL-2531)" )
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optINTERVAL_HM() throws SQLException {
+ assertThat( mdrOptINTERVAL_H_S3.getInt( "COLUMN_SIZE" ),
+ equalTo( 14 ) ); // "P12H12M12.1234S"
+ }
+
+ // TODO: When DRILL-2531 is fixed, remove this:
+ @Test
+ public void test_COLUMN_SIZE_hasRightINTERIMValue_optINTERVAL_HM() throws SQLException {
+ assertThat( mdrOptINTERVAL_H_S3.getInt( "COLUMN_SIZE" ),
+ equalTo( 31 ) ); // from max. form "P12..90D12H12M12.12..89S"
+ }
+
+ @Ignore( "until fixed: INTERVAL metadata in INFORMATION_SCHEMA (DRILL-2531)" )
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_optINTERVAL_Y3() throws SQLException {
+ assertThat( mdrOptINTERVAL_Y4.getInt( "COLUMN_SIZE" ),
+ equalTo( 6 ) ); // "P1234Y"
+ }
+
+ // TODO: When DRILL-2531 is fixed, remove this:
+ @Test
+ public void test_COLUMN_SIZE_hasRightINTERIMValue_optINTERVAL_Y3() throws SQLException {
+ assertThat( mdrOptINTERVAL_Y4.getInt( "COLUMN_SIZE" ),
+ equalTo( 15 ) ); // from max. form "P12..90Y"
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_tdbARRAY() throws SQLException {
+ final int value = mdrReqARRAY.getInt( "COLUMN_SIZE" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqARRAY.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_tbdMAP() throws SQLException {
+ final int value = mdrReqMAP.getInt( "COLUMN_SIZE" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqMAP.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_tbdSTRUCT() throws SQLException {
+ final int value = testRowSTRUCT.getInt( "COLUMN_SIZE" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowSTRUCT.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightValue_tbdUnion() throws SQLException {
+ final int value = testRowUnion.getInt( "COLUMN_SIZE" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowUnion.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 7 ), equalTo( "COLUMN_SIZE" ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 7 ), equalTo( "INTEGER" ) );
+ }
+
+ @Test
+ public void test_COLUMN_SIZE_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 7 ), equalTo( Types.INTEGER ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_COLUMN_SIZE_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 7 ), equalTo( Integer.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_COLUMN_SIZE_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 7 ), equalTo( columnNullable ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #8: BUFFER_LENGTH:
+ // - JDBC: "8. ... is not used"
+ // - Drill:
+ // - (Meta):
+
+ // Since "unused," check only certain meta-metadata.
+
+ @Test
+ public void test_BUFFER_LENGTH_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 8 ), equalTo( "BUFFER_LENGTH" ) );
+ }
+
+ // No specific value or even type to check for.
+
+ @Test
+ public void test_BUFFER_LENGTH_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 8 ), equalTo( "BUFFER_LENGTH" ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #9: DECIMAL_DIGITS:
+ // - JDBC: "9. ... int => the number of fractional digits. Null is
+ // returned for data types where DECIMAL_DIGITS is not applicable."
+ // - Resolve: When exactly null?
+ // - Drill:
+ // - (Meta): INTEGER(?); Nullable;
+
+ @Test
+ public void test_DECIMAL_DIGITS_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 9 ), equalTo( "DECIMAL_DIGITS" ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optBOOLEAN() throws SQLException {
+ final int value = mdrOptBOOLEAN.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBOOLEAN.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_reqTINYINT() throws SQLException {
+ final int value = mdrReqTINYINT.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqTINYINT.wasNull(), equalTo( false ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optSMALLINT() throws SQLException {
+ final int value = mdrOptSMALLINT.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptSMALLINT.wasNull(), equalTo( false ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_reqINTEGER() throws SQLException {
+ final int value = mdrReqINTEGER.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqINTEGER.wasNull(), equalTo( false ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optBIGINT() throws SQLException {
+ final int value = mdrOptBIGINT.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBIGINT.wasNull(), equalTo( false ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optFLOAT() throws SQLException {
+ assertThat( mdrOptFLOAT.getInt( "DECIMAL_DIGITS" ), equalTo( 7 ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_reqDOUBLE() throws SQLException {
+ assertThat( mdrReqDOUBLE.getInt( "DECIMAL_DIGITS" ), equalTo( 15 ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optREAL() throws SQLException {
+ assertThat( mdrOptREAL.getInt( "DECIMAL_DIGITS" ), equalTo( 15 ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_reqDECIMAL_5_3() throws SQLException {
+ assertThat( mdrReqDECIMAL_5_3.getInt( "DECIMAL_DIGITS" ), equalTo( 3 ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_reqVARCHAR_10() throws SQLException {
+ final int value = mdrReqVARCHAR_10.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqVARCHAR_10.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optVARCHAR() throws SQLException {
+ final int value = mdrOptVARCHAR.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptVARCHAR.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_reqCHAR_5() throws SQLException {
+ final int value = mdrReqCHAR_5.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqCHAR_5.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optVARBINARY_16() throws SQLException {
+ final int value = mdrOptVARBINARY_16.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptVARBINARY_16.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optBINARY_1048576CHECK() throws SQLException {
+ final int value = mdrOptBINARY_1048576.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBINARY_1048576.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_reqDATE() throws SQLException {
+ final int value = mdrReqDATE.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqDATE.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optTIME() throws SQLException {
+ assertThat( mdrOptTIME.getInt( "DECIMAL_DIGITS" ), equalTo( 0 ) );
+ }
+
+ @Ignore( "until resolved: whether to implement TIME precision or drop test" )
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optTIME_7() throws SQLException {
+ assertThat( mdrOptTIME_7.getInt( "DECIMAL_DIGITS" ), equalTo( 7 ) );
+ }
+
+ @Ignore( "until resolved: whether to implement TIME precision or drop test" )
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optTIMESTAMP() throws SQLException {
+ assertThat( mdrOptTIMESTAMP.getInt( "DECIMAL_DIGITS" ), equalTo( 0 ) );
+ }
+
+ @Ignore( "until fixed: INTERVAL metadata in INFORMATION_SCHEMA (DRILL-2531)" )
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optINTERVAL_HM() throws SQLException {
+ assertThat( mdrOptINTERVAL_H_S3.getInt( "DECIMAL_DIGITS" ), equalTo( 3 ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_optINTERVAL_Y3() throws SQLException {
+ assertThat( mdrOptINTERVAL_Y4.getInt( "DECIMAL_DIGITS" ), equalTo( 0 ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_tdbARRAY() throws SQLException {
+ final int value = mdrReqARRAY.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqARRAY.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_tbdMAP() throws SQLException {
+ final int value = mdrReqMAP.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqMAP.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_tbdSTRUCT() throws SQLException {
+ final int value = testRowSTRUCT.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowSTRUCT.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightValue_tbdUnion() throws SQLException {
+ final int value = testRowUnion.getInt( "DECIMAL_DIGITS" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowUnion.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 9 ), equalTo( "DECIMAL_DIGITS" ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 9 ), equalTo( "INTEGER" ) );
+ }
+
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 9 ), equalTo( Types.INTEGER ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 9 ), equalTo( Integer.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_DECIMAL_DIGITS_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 9 ), equalTo( columnNullable ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #10: NUM_PREC_RADIX:
+ // - JDBC: "10. ... int => Radix (typically either 10 or 2)"
+ // - Seems should be null for non-numeric, but unclear.
+ // - Drill: ?
+ // - (Meta): INTEGER?; Nullable?;
+ //
+ // Note: Some MS page says NUM_PREC_RADIX specifies the units (decimal digits
+ // or binary bits COLUMN_SIZE, and is NULL for non-numeric columns.
+
+ @Test
+ public void test_NUM_PREC_RADIX_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 10 ), equalTo( "NUM_PREC_RADIX" ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optBOOLEAN() throws SQLException {
+ final int value = mdrOptBOOLEAN.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBOOLEAN.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_reqTINYINT() throws SQLException {
+ assertThat( mdrReqTINYINT.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optSMALLINT() throws SQLException {
+ assertThat( mdrOptSMALLINT.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_reqINTEGER() throws SQLException {
+ assertThat( mdrReqINTEGER.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optBIGINT() throws SQLException {
+ assertThat( mdrOptBIGINT.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optFLOAT() throws SQLException {
+ assertThat( mdrOptFLOAT.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_reqDOUBLE() throws SQLException {
+ assertThat( mdrReqDOUBLE.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optREAL() throws SQLException {
+ assertThat( mdrOptREAL.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_reqDECIMAL_5_3() throws SQLException {
+ assertThat( mdrReqDECIMAL_5_3.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_reqVARCHAR_10() throws SQLException {
+ final int value = mdrReqVARCHAR_10.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqVARCHAR_10.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optVARCHAR() throws SQLException {
+ final int value = mdrOptVARCHAR.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptVARCHAR.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_reqCHAR_5() throws SQLException {
+ final int value = mdrReqCHAR_5.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqCHAR_5.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optVARBINARY_16() throws SQLException {
+ final int value = mdrOptVARBINARY_16.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptVARBINARY_16.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optBINARY_1048576CHECK() throws SQLException {
+ final int value = mdrOptBINARY_1048576.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBINARY_1048576.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_reqDATE() throws SQLException {
+ final int value = mdrReqDATE.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqDATE.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Ignore( "until resolved: expected value" )
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optTIME() throws SQLException {
+ assertThat( mdrOptTIME.getInt( "NUM_PREC_RADIX" ), equalTo( 10 /* NULL */ ) );
+ // To-do: Determine which.
+ final int value = mdrOptTIME.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptTIME.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Ignore( "until resolved: expected value" )
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optTIME_7() throws SQLException {
+ assertThat( mdrOptTIME_7.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ // To-do: Determine which.
+ final int value = mdrOptTIME_7.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptTIME_7.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Ignore( "until resolved: expected value" )
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optTIMESTAMP() throws SQLException {
+ assertThat( mdrOptTIMESTAMP.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ // To-do: Determine which.
+ final int value = mdrOptTIMESTAMP.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptTIMESTAMP.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optINTERVAL_HM() throws SQLException {
+ assertThat( mdrOptINTERVAL_H_S3.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_optINTERVAL_Y3() throws SQLException {
+ assertThat( mdrOptINTERVAL_Y4.getInt( "NUM_PREC_RADIX" ), equalTo( 10 ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_tdbARRAY() throws SQLException {
+ final int value = mdrReqARRAY.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqARRAY.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_tbdMAP() throws SQLException {
+ final int value = mdrReqMAP.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqMAP.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_tbdSTRUCT() throws SQLException {
+ final int value = testRowSTRUCT.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowSTRUCT.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightValue_tbdUnion() throws SQLException {
+ final int value = testRowUnion.getInt( "NUM_PREC_RADIX" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowUnion.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 10 ), equalTo( "NUM_PREC_RADIX" ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 10 ), equalTo( "INTEGER" ) );
+ }
+
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 10 ), equalTo( Types.INTEGER ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 10 ), equalTo( Integer.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NUM_PREC_RADIX_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 10 ), equalTo( columnNullable ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #11: NULLABLE:
+ // - JDBC: "11. ... int => is NULL allowed.
+ // columnNoNulls - might not allow NULL values
+ // columnNullable - definitely allows NULL values
+ // columnNullableUnknown - nullability unknown"
+ // - Drill:
+ // - (Meta): INTEGER(?); Non-nullable(?).
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 11 ), equalTo( "NULLABLE" ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optBOOLEAN() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptBOOLEAN.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_reqTINYINT() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known non-nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrReqTINYINT.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optSMALLINT() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptSMALLINT.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optBIGINT() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptBIGINT.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optFLOAT() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptFLOAT.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_reqDOUBLE() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known non-nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrReqDOUBLE.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optREAL() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptREAL.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_reqINTEGER() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known non-nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrReqINTEGER.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_reqDECIMAL_5_3() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known non-nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrReqDECIMAL_5_3.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_reqVARCHAR_10() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known non-nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrReqVARCHAR_10.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optVARCHAR() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptVARCHAR.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_reqCHAR_5() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known non-nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrReqCHAR_5.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optVARBINARY_16() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptVARBINARY_16.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optBINARY_1048576CHECK() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptBINARY_1048576.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_reqDATE() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known non-nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrReqDATE.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optTIME() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptTIME.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optTIME_7() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptTIME_7.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optTIMESTAMP() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptTIMESTAMP.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optINTERVAL_HM() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptINTERVAL_H_S3.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_optINTERVAL_Y3() throws SQLException {
+ // To-do: CHECK: Why columnNullableUnknown, when seemingly known nullable?
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ mdrOptINTERVAL_Y4.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_tdbARRAY() throws SQLException {
+ assertThat( mdrReqARRAY.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightValue_tbdMAP() throws SQLException {
+ assertThat( mdrReqMAP.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ }
+
+ @Ignore( "until resolved: any requirement on nullability (DRILL-2420?)" )
+ @Test
+ public void test_NULLABLE_hasRightValue_tbdSTRUCT() throws SQLException {
+ assertThat( testRowSTRUCT.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ // To-do: Determine which.
+ assertThat( testRowSTRUCT.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ // To-do: Determine which.
+ assertThat( testRowSTRUCT.getInt( "NULLABLE" ), equalTo( columnNullableUnknown ) );
+ }
+
+ @Ignore( "until resolved: any requirement on nullability (DRILL-2420?)" )
+ @Test
+ public void test_NULLABLE_hasRightValue_tbdUnion() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ testRowUnion.getInt( "NULLABLE" ), equalTo( columnNullable ) );
+ // To-do: Determine which.
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ testRowUnion.getInt( "NULLABLE" ), equalTo( columnNoNulls ) );
+ // To-do: Determine which.
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ testRowUnion.getInt( "NULLABLE" ), equalTo( columnNullableUnknown ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 11 ), equalTo( "NULLABLE" ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 11 ), equalTo( "INTEGER" ) ); // TODO: Confirm.
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 11 ), equalTo( Types.INTEGER ) ); // TODO: Confirm.
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_NULLABLE_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 11 ), equalTo( Integer.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_NULLABLE_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 11 ), equalTo( columnNoNulls ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #12: REMARKS:
+ // - JDBC: "12. ... String => comment describing column (may be null)"
+ // - Drill: none, so always null
+ // - (Meta): VARCHAR (NVARCHAR?); Nullable;
+
+ @Test
+ public void test_REMARKS_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 12 ), equalTo( "REMARKS" ) );
+ }
+
+ @Test
+ public void test_REMARKS_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getString( "REMARKS" ), nullValue() );
+ }
+
+ @Test
+ public void test_REMARKS_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 12 ), equalTo( "REMARKS" ) );
+ }
+
+ @Test
+ public void test_REMARKS_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 12 ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_REMARKS_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 12 ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_REMARKS_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.String" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 12 ), equalTo( String.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_REMARKS_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 12 ), equalTo( columnNullable ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #13: COLUMN_DEF:
+ // - JDBC: "13. ... String => default value for the column, which should be
+ // interpreted as a string when the value is enclosed in single quotes
+ // (may be null)"
+ // - Drill: no real default values, right?
+ // - (Meta): VARCHAR (NVARCHAR?); Nullable;
+
+ @Test
+ public void test_COLUMN_DEF_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 13 ), equalTo( "COLUMN_DEF" ) );
+ }
+
+ @Test
+ public void test_COLUMN_DEF_hasRightValue_optBOOLEAN() throws SQLException {
+ assertThat( mdrOptBOOLEAN.getString( "COLUMN_DEF" ), nullValue() );
+ }
+
+ @Test
+ public void test_COLUMN_DEF_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 13 ), equalTo( "COLUMN_DEF" ) );
+ }
+
+ @Test
+ public void test_COLUMN_DEF_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 13 ), equalTo( "VARCHAR" ) );
+ }
+
+ @Test
+ public void test_COLUMN_DEF_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 13 ), equalTo( Types.VARCHAR ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_COLUMN_DEF_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.String" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 13 ), equalTo( String.class.getName() ) );
+ }
+
+ // (See to-do note near top of file about reviewing nullability.)
+ @Test
+ public void test_COLUMN_DEF_hasRightNullability() throws SQLException {
+ assertThat( "ResultSetMetaData.column...Null... nullability code",
+ rowsMetadata.isNullable( 13 ), equalTo( columnNullable ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #14: SQL_DATA_??TYPE:
+ // - JDBC: "14. ... int => unused"
+ // - Drill:
+ // - (Meta): INTEGER(?);
+
+ // Since "unused," check only certain meta-metadata.
+
+ @Test
+ public void test_SQL_DATA_TYPE_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 14 ), equalTo( "SQL_DATA_TYPE" ) );
+ }
+
+ // No specific value to check for.
+
+ @Test
+ public void test_SQL_DATA_TYPE_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 14 ), equalTo( "SQL_DATA_TYPE" ) );
+ }
+
+ @Test
+ public void test_SQL_DATA_TYPE_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 14 ), equalTo( "INTEGER" ) );
+ }
+
+ @Test
+ public void test_SQL_DATA_TYPE_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 14 ), equalTo( Types.INTEGER ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_SQL_DATA_TYPE_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 14 ), equalTo( Integer.class.getName() ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #15: SQL_DATETIME_SUB:
+ // - JDBC: "15. ... int => unused"
+ // - Drill:
+ // - (Meta): INTEGER(?);
+
+ // Since "unused," check only certain meta-metadata.
+
+ @Test
+ public void test_SQL_DATETIME_SUB_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 15 ), equalTo( "SQL_DATETIME_SUB" ) );
+ }
+
+ // No specific value to check for.
+
+ @Test
+ public void test_SQL_DATETIME_SUB_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 15 ), equalTo( "SQL_DATETIME_SUB" ) );
+ }
+
+ @Test
+ public void test_SQL_DATETIME_SUB_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 15 ), equalTo( "INTEGER" ) ); // TODO: Confirm.
+ }
+
+ @Test
+ public void test_SQL_DATETIME_SUB_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 15 ), equalTo( Types.INTEGER ) ); // TODO: Confirm.
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_SQL_DATETIME_SUB_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassName( 15 ), equalTo( Integer.class.getName() ) );
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ // #16: CHAR_OCTET_LENGTH:
+ // - JDBC: "16. ... int => for char types the maximum number of bytes
+ // in the column"
+ // - apparently should be null for non-character types
+ // - Drill:
+ // - (Meta): INTEGER(?); Nullable(?);
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_isAtRightPosition() throws SQLException {
+ assertThat( rowsMetadata.getColumnLabel( 16 ), equalTo( "CHAR_OCTET_LENGTH" ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optBOOLEAN() throws SQLException {
+ final int value = mdrOptBOOLEAN.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBOOLEAN.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_reqTINYINT() throws SQLException {
+ final int value = mdrReqTINYINT.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqTINYINT.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optSMALLINT() throws SQLException {
+ final int value = mdrOptSMALLINT.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptSMALLINT.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_reqINTEGER() throws SQLException {
+ final int value = mdrReqINTEGER.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqINTEGER.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optBIGINT() throws SQLException {
+ final int value = mdrOptREAL.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptREAL.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optFLOAT() throws SQLException {
+ final int value = mdrOptFLOAT.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptFLOAT.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_reqDOUBLE() throws SQLException {
+ final int value = mdrReqDOUBLE.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqDOUBLE.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optREAL() throws SQLException {
+ final int value = mdrOptREAL.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptREAL.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_reqDECIMAL_5_3() throws SQLException {
+ final int value = mdrReqDECIMAL_5_3.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqDECIMAL_5_3.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_reqVARCHAR_10() throws SQLException {
+ assertThat( mdrReqVARCHAR_10.getInt( "CHAR_OCTET_LENGTH" ),
+ equalTo( 10 /* chars. */
+ * 4 /* max. UTF-8 bytes per char. */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optVARCHAR() throws SQLException {
+ assertThat( mdrOptVARCHAR.getInt( "CHAR_OCTET_LENGTH" ),
+ equalTo( 1 /* chars. (default of 1) */
+ * 4 /* max. UTF-8 bytes per char. */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_reqCHAR_5() throws SQLException {
+ assertThat( mdrReqCHAR_5.getInt( "CHAR_OCTET_LENGTH" ),
+ equalTo( 5 /* chars. */
+ * 4 /* max. UTF-8 bytes per char. */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optVARBINARY_16() throws SQLException {
+ final int value = mdrOptVARBINARY_16.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptVARBINARY_16.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optBINARY_1048576CHECK() throws SQLException {
+ final int value = mdrOptBINARY_1048576.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptBINARY_1048576.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_reqDATE() throws SQLException {
+ final int value = mdrReqDATE.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqDATE.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optTIME() throws SQLException {
+ final int value = mdrOptTIME.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptTIME.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optTIME_7() throws SQLException {
+ final int value = mdrOptTIME_7.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptTIME_7.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optTIMESTAMP() throws SQLException {
+ final int value = mdrOptTIMESTAMP.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptTIMESTAMP.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optINTERVAL_HM() throws SQLException {
+ final int value = mdrOptINTERVAL_H_S3.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptINTERVAL_H_S3.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_optINTERVAL_Y3() throws SQLException {
+ final int value = mdrOptINTERVAL_Y4.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrOptINTERVAL_Y4.wasNull(), equalTo( true ) );
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_tdbARRAY() throws SQLException {
+ final int value = mdrReqARRAY.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqARRAY.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_tbdMAP() throws SQLException {
+ final int value = mdrReqMAP.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ mdrReqMAP.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_tbdSTRUCT() throws SQLException {
+ final int value = testRowSTRUCT.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowSTRUCT.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightValue_tbdUnion() throws SQLException {
+ final int value = testRowUnion.getInt( "CHAR_OCTET_LENGTH" );
+ assertThat( "wasNull() [after " + value + "]",
+ testRowUnion.wasNull(), equalTo( true ) ); // TODO: Confirm.
+ assertThat( value, equalTo( 0 /* NULL */ ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasSameNameAndLabel() throws SQLException {
+ assertThat( rowsMetadata.getColumnName( 16 ), equalTo( "CHAR_OCTET_LENGTH" ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightTypeString() throws SQLException {
+ assertThat( rowsMetadata.getColumnTypeName( 16 ), equalTo( "INTEGER" ) );
+ }
+
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightTypeCode() throws SQLException {
+ assertThat( rowsMetadata.getColumnType( 16 ), equalTo( Types.INTEGER ) );
+ }
+
+ @Ignore( "until fixed (\"none\" -> right class name) (DRILL-2137)" )
+ @Test
+ public void test_CHAR_OCTET_LENGTH_hasRightClass() throws SQLException {
+ // TODO: Confirm that this "java.lang.Integer" is correct:
+ assertThat( rowsMetadata.getColumnClassN
<TRUNCATED>