DRILL-2613: 2-Core: Impl. ResultSet.getXxx(...) number-to-number data conversions.
- Created tests: - integration-level unit test ResultSetGetMethodConversionsTest - unit-level unit test TypeConvertingAccessorSqlTest - Created number-converting TypeConvertingSqlAccessor. - Created conversion exceptions (SQLConversionException, SQLConversionOverflowException). - Adjusted things: - Moved InvalidAccessException out into its own file, refined ancestry. - Moved getType() up to SqlAccessor (for access by TypeConvertingSqlAccessor). - Made AbstractSqlAccessor public (for use by TypeConvertingSqlAccessor). - Documented supported ResultSet.getXxx(...) conversions (on new interface DrillResultSet). Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/fe11e86c Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/fe11e86c Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/fe11e86c Branch: refs/heads/master Commit: fe11e86c81c5a016febdcf89d790b3de2bc33ced Parents: 690ffa9 Author: dbarclay <dbarc...@maprtech.com> Authored: Sun Mar 29 14:45:33 2015 -0700 Committer: Parth Chandra <pchan...@maprtech.com> Committed: Mon Apr 13 09:36:47 2015 -0700 ---------------------------------------------------------------------- .../main/codegen/templates/SqlAccessors.java | 2 +- .../vector/accessor/AbstractSqlAccessor.java | 44 +- .../vector/accessor/BoundCheckingAccessor.java | 40 +- .../exec/vector/accessor/GenericAccessor.java | 2 +- .../vector/accessor/InvalidAccessException.java | 37 + .../drill/exec/vector/accessor/SqlAccessor.java | 12 +- .../apache/drill/jdbc/DrillAccessorList.java | 6 +- .../org/apache/drill/jdbc/DrillResultSet.java | 498 ++++++++++- .../drill/jdbc/SQLConversionException.java | 28 + .../jdbc/SQLConversionOverflowException.java | 27 + .../jdbc/impl/TypeConvertingSqlAccessor.java | 824 ++++++++++++++++++ .../jdbc/ResultSetGetMethodConversionsTest.java | 711 ++++++++++++++++ .../impl/TypeConvertingSqlAccessorTest.java | 849 +++++++++++++++++++ 13 files changed, 3032 insertions(+), 48 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/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 c0ece9b..c50a3e2 100644 --- a/exec/java-exec/src/main/codegen/templates/SqlAccessors.java +++ b/exec/java-exec/src/main/codegen/templates/SqlAccessors.java @@ -46,7 +46,7 @@ public class ${name}Accessor extends AbstractSqlAccessor { } @Override - MajorType getType() { + public MajorType getType() { return TYPE; }; http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/AbstractSqlAccessor.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/AbstractSqlAccessor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/AbstractSqlAccessor.java index f7ebfb8..ec6c67a 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/AbstractSqlAccessor.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/AbstractSqlAccessor.java @@ -21,80 +21,79 @@ import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.sql.Date; -import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import org.apache.drill.common.types.TypeProtos.MajorType; -abstract class AbstractSqlAccessor implements SqlAccessor { +public abstract class AbstractSqlAccessor implements SqlAccessor { @Override public abstract boolean isNull(int rowOffset); @Override public BigDecimal getBigDecimal(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("BigDecimal"); + throw newInvalidAccessException("BigDecimal"); } @Override public boolean getBoolean(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("boolean"); + throw newInvalidAccessException("boolean"); } @Override public byte getByte(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("byte"); + throw newInvalidAccessException("byte"); } @Override public byte[] getBytes(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("byte[]"); + throw newInvalidAccessException("byte[]"); } @Override public Date getDate(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("Date"); + throw newInvalidAccessException("Date"); } @Override public double getDouble(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("double"); + throw newInvalidAccessException("double"); } @Override public float getFloat(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("float"); + throw newInvalidAccessException("float"); } @Override public int getInt(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("int"); + throw newInvalidAccessException("int"); } @Override public long getLong(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("long"); + throw newInvalidAccessException("long"); } @Override public short getShort(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("short"); + throw newInvalidAccessException("short"); } @Override public InputStream getStream(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("InputStream"); + throw newInvalidAccessException("InputStream"); } @Override public char getChar(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("Char"); + throw newInvalidAccessException("Char"); } @Override public Reader getReader(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("Reader"); + throw newInvalidAccessException("Reader"); } @Override @@ -104,20 +103,19 @@ abstract class AbstractSqlAccessor implements SqlAccessor { @Override public Time getTime(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("Time"); + throw newInvalidAccessException("Time"); } @Override public Timestamp getTimestamp(int rowOffset) throws InvalidAccessException{ - throw new InvalidAccessException("Timestamp"); + throw newInvalidAccessException("Timestamp"); } - abstract MajorType getType(); - - public class InvalidAccessException extends SQLException{ - public InvalidAccessException(String name){ - super(String.format("Requesting class of type %s for an object of type %s:%s is not allowed.", name, getType().getMinorType().name(), getType().getMode().name())); - } + private InvalidAccessException newInvalidAccessException(String name) { + return new InvalidAccessException( + String.format( + "Requesting value of type %s for an object of type %s:%s is not allowed.", + name, getType().getMinorType().name(), getType().getMode().name())); } } http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/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 2838d3a..3d3683e 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 @@ -24,6 +24,7 @@ import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; +import org.apache.drill.common.types.TypeProtos.MajorType; import org.apache.drill.exec.vector.ValueVector; /** @@ -39,87 +40,92 @@ public class BoundCheckingAccessor implements SqlAccessor { } @Override + public MajorType getType() { + return delegate.getType(); + } + + @Override public boolean isNull(int rowOffset) { return delegate.isNull(rowOffset); } @Override - public BigDecimal getBigDecimal(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public BigDecimal getBigDecimal(int rowOffset) throws InvalidAccessException { return delegate.getBigDecimal(rowOffset); } @Override - public boolean getBoolean(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public boolean getBoolean(int rowOffset) throws InvalidAccessException { return delegate.getBoolean(rowOffset); } @Override - public byte getByte(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public byte getByte(int rowOffset) throws InvalidAccessException { return delegate.getByte(rowOffset); } @Override - public byte[] getBytes(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public byte[] getBytes(int rowOffset) throws InvalidAccessException { return delegate.getBytes(rowOffset); } @Override - public Date getDate(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public Date getDate(int rowOffset) throws InvalidAccessException { return delegate.getDate(rowOffset); } @Override - public double getDouble(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public double getDouble(int rowOffset) throws InvalidAccessException { return delegate.getDouble(rowOffset); } @Override - public float getFloat(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public float getFloat(int rowOffset) throws InvalidAccessException { return delegate.getFloat(rowOffset); } @Override - public char getChar(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public char getChar(int rowOffset) throws InvalidAccessException { return delegate.getChar(rowOffset); } @Override - public int getInt(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public int getInt(int rowOffset) throws InvalidAccessException { return delegate.getInt(rowOffset); } @Override - public long getLong(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public long getLong(int rowOffset) throws InvalidAccessException { return delegate.getLong(rowOffset); } @Override - public short getShort(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public short getShort(int rowOffset) throws InvalidAccessException { return delegate.getShort(rowOffset); } @Override - public InputStream getStream(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public InputStream getStream(int rowOffset) throws InvalidAccessException { return delegate.getStream(rowOffset); } @Override - public Reader getReader(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public Reader getReader(int rowOffset) throws InvalidAccessException { return delegate.getReader(rowOffset); } @Override - public String getString(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public String getString(int rowOffset) throws InvalidAccessException { return delegate.getString(rowOffset); } @Override - public Time getTime(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public Time getTime(int rowOffset) throws InvalidAccessException { return delegate.getTime(rowOffset); } @Override - public Timestamp getTimestamp(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public Timestamp getTimestamp(int rowOffset) throws InvalidAccessException { return delegate.getTimestamp(rowOffset); } @@ -129,7 +135,7 @@ public class BoundCheckingAccessor implements SqlAccessor { * @see org.apache.drill.exec.vector.accessor.SqlAccessor#getObject(int) */ @Override - public Object getObject(int rowOffset) throws AbstractSqlAccessor.InvalidAccessException { + public Object getObject(int rowOffset) throws InvalidAccessException { // 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(); http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/GenericAccessor.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/GenericAccessor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/GenericAccessor.java index adee171..347cf26 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/GenericAccessor.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/GenericAccessor.java @@ -39,7 +39,7 @@ public class GenericAccessor extends AbstractSqlAccessor { } @Override - TypeProtos.MajorType getType() { + public TypeProtos.MajorType getType() { return v.getMetadata().getMajorType(); } } http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/InvalidAccessException.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/InvalidAccessException.java b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/InvalidAccessException.java new file mode 100644 index 0000000..4a3b06b --- /dev/null +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/vector/accessor/InvalidAccessException.java @@ -0,0 +1,37 @@ +/** + * 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.exec.vector.accessor; + +import java.sql.SQLException; +import java.sql.SQLNonTransientException; + +// ?????? TODO clean this up: +// - determine and document conditions +// - determine place in SQLException type hierarchy +// - (Why are seemingly JDBC-specific SqlAccessor classes in +// org.apache.drill.exec.vector.accessor? Can they be in +// org.apache.drill.jdbc.impl? +// Why are they in java-exec module? Can they be in JDBC module? + +public class InvalidAccessException extends SQLNonTransientException { + private static final long serialVersionUID = 2015_04_07L; + + public InvalidAccessException( String message ) { + super(message); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/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 db10e64..19e6fcf 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 @@ -24,7 +24,7 @@ import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; -import org.apache.drill.exec.vector.accessor.AbstractSqlAccessor.InvalidAccessException; +import org.apache.drill.common.types.TypeProtos.MajorType; // TODO: Doc.: Document more of basics of pattern of contracts for getXxx(...): @@ -53,8 +53,14 @@ import org.apache.drill.exec.vector.accessor.AbstractSqlAccessor.InvalidAccessEx */ public interface SqlAccessor { - // TODO: Clean: This interface refers to type InvalidAccessException - // defined in class implementing this interface. + /** + * Reports the (native) type of data accessed by this accessor. + * <p> + * (Some implementations may support more than just the minimum + * <code>get<i>Type</i>(<i>...</i>)</code> method implied by the type. + * </p> + */ + MajorType getType(); /** * Reports whether the logical value is a SQL NULL. http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillAccessorList.java ---------------------------------------------------------------------- diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillAccessorList.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillAccessorList.java index ccf2658..b31efb1 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillAccessorList.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillAccessorList.java @@ -26,6 +26,7 @@ import org.apache.drill.exec.record.RecordBatchLoader; import org.apache.drill.exec.vector.ValueVector; import org.apache.drill.exec.vector.accessor.BoundCheckingAccessor; import org.apache.drill.exec.vector.accessor.SqlAccessor; +import org.apache.drill.jdbc.impl.TypeConvertingSqlAccessor; public class DrillAccessorList extends BasicList<Accessor>{ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillAccessorList.class); @@ -40,7 +41,10 @@ public class DrillAccessorList extends BasicList<Accessor>{ accessors = new Accessor[cnt]; for(int i =0; i < cnt; i++){ final ValueVector vector = currentBatch.getValueAccessorById(null, i).getValueVector(); - final SqlAccessor acc = new BoundCheckingAccessor(vector, TypeHelper.getSqlAccessor(vector)); + final SqlAccessor acc = + new TypeConvertingSqlAccessor( + new BoundCheckingAccessor(vector, TypeHelper.getSqlAccessor(vector)) + ); accessors[i] = new AvaticaDrillSqlAccessor(acc, cursor); } } http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java ---------------------------------------------------------------------- diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java index 36ac8cf..7a4f426 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java @@ -41,9 +41,503 @@ import java.util.Map; public interface DrillResultSet extends ResultSet { + /** + * Gets the ID the associated query (the query results this ResultSet presents). + */ String getQueryId(); + /** + * {@inheritDoc} + * <p> + * Drill's implementation accepts {@code DrillResultSet.class}. + * </p> + */ + @Override + <T> T unwrap(Class<T> iface) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * Drill's implementation returns true for {@code DrillResultSet.class}. + * </p> + */ + @Override + boolean isWrapperFor(Class<?> iface) throws SQLException; + + // Note: The commented-out methods are left in to make it easier to match + // the method order from ResultSet when adding method declarations at this + // level (e.g., to document Drill-specific behavior for more) in the future + // (so the resulting documentation page matches the order in + // java.sql.ResultSet's page). + + // (Temporary, re matching ResultSet's method order: + // next() + // close() + // wasNull() + // ) + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from all types. + * </p> + */ + @Override + String getString(int columnIndex) throws SQLException; + + // (Temporary, re matching ResultSet's method order:) + // getBoolean(int) + // ) + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from types: + * </p> + * <ul> + * <li>{@code SMALLINT} ({@code short}), + * {@code INTEGER} ({@code int}), and + * {@code BIGINT} ({@code long}) + * </li> + * <li>{@code REAL} ({@code float}), + * {@code DOUBLE PRECISION} ({@code double}), and + * {@code FLOAT} ({@code float} or {@code double}) + * </li> + * <li>{@code DECIMAL} ({@code BigDecimal}) + * </li> + * </ul> + * <p> + * Conversion throws {@link SQLConversionOverflowException} for a source + * value whose magnitude is outside the range of {@code short} values. + * </p> + * @throws SQLConversionOverflowException if a source value was too large + * to convert + */ + @Override + byte getByte(int columnIndex) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from types: + * </p> + * <ul> + * <li>{@code TINYINT} ({@code byte}), + * {@code INTEGER} ({@code int}), and + * {@code BIGINT} ({@code long}) + * </li> + * <li>{@code REAL} ({@code float}), + * {@code DOUBLE PRECISION} ({@code double}), and + * {@code FLOAT} ({@code float} or {@code double}) + * </li> + * <li>{@code DECIMAL} ({@code BigDecimal}) + * </li> + * </ul> + * <p> + * Conversion throws {@link SQLConversionOverflowException} for a source + * value whose magnitude is outside the range of {@code int} values. + * </p> + * @throws SQLConversionOverflowException if a source value was too large + * to convert + */ + @Override + short getShort(int columnIndex) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from types: + * </p> + * <ul> + * <li>{@code TINYINT} ({@code byte}), + * {@code SMALLINT} ({@code short}), and + * {@code BIGINT} ({@code long}) + * </li> + * <li>{@code REAL} ({@code float}), + * {@code DOUBLE PRECISION} ({@code double}), and + * {@code FLOAT} ({@code float} or {@code double}) + * </li> + * <li>{@code DECIMAL} ({@code BigDecimal}) + * </li> + * </ul> + * <p> + * Conversion throws {@link SQLConversionOverflowException} for a source + * value whose magnitude is outside the range of {@code int} values. + * </p> + * @throws SQLConversionOverflowException if a source value was too large + * to convert to int + */ + @Override + int getInt(int columnIndex) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from types: + * </p> + * <ul> + * <li>{@code TINYINT} ({@code byte}), + * {@code SMALLINT} ({@code short}), and + * {@code INTEGER} ({@code int}) + * </li> + * <li>{@code REAL} ({@code float}), + * {@code DOUBLE PRECISION} ({@code double}), and + * {@code FLOAT} ({@code float} or {@code double}) + * </li> + * <li>{@code DECIMAL} ({@code BigDecimal}) + * </li> + * </ul> + * <p> + * Conversion throws {@link SQLConversionOverflowException} for a source + * value whose magnitude is outside the range of {@code long} values. + * </p> + * @throws SQLConversionOverflowException if a source value was too large + * to convert + */ + @Override + long getLong(int columnIndex) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from types: + * </p> + * <ul> + * <li>{@code TINYINT} ({@code byte}), + * {@code SMALLINT} ({@code short}), and + * {@code INTEGER} ({@code int}), + * {@code BIGINT} ({@code long}) + * </li> + * <li>{@code DOUBLE PRECISION} ({@code double}) and + * {@code FLOAT} (when {@code double}) + * </li> + * <li>{@code DECIMAL} ({@code BigDecimal}) + * </li> + * </ul> + * <p> + * Conversion throws {@link SQLConversionOverflowException} for a source + * value whose magnitude is outside the range of {@code float} values. + * </p> + * @throws SQLConversionOverflowException if a source value was too large + * to convert + */ + @Override + float getFloat(int columnIndex) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from types: + * </p> + * <ul> + * <li>{@code TINYINT} ({@code byte}), + * {@code SMALLINT} ({@code short}), + * {@code INTEGER} ({@code int}), and + * {@code BIGINT} ({@code long}) + * </li> + * <li>{@code REAL} ({@code float}), + * {@code FLOAT} (when {@code float}) + * </li> + * <li>{@code DECIMAL} ({@code BigDecimal}) + * </li> + * </ul> + * <p> + * Conversion throws {@link SQLConversionOverflowException} for a source + * value whose magnitude is outside the range of {@code double} values. + * </p> + * @throws SQLConversionOverflowException if a source value was too large + * to convert + */ + @Override + double getDouble(int columnIndex) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from types: + * </p> + * <ul> + * <li>{@code TINYINT} ({@code byte}), + * {@code SMALLINT} ({@code short}), + * {@code INTEGER} ({@code int}), and + * {@code BIGINT} ({@code long}) + * </li> + * <li>{@code REAL} ({@code float}), + * {@code DOUBLE PRECISION} ({@code double}), and + * {@code FLOAT} ({@code float} or {@code double}) + * </li> + * </ul> + */ + @Override + BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException; + + // (Temporary, re matching ResultSet's method order:) + // getBytes(int) + // getDate(int) + // getTime(int) + // getTimestamp(int) + // getAsciiStream(int) + // getUnicodeStream(int) + // getBinaryStream(int) + // ) + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getString(int)}. + * </p> + */ + @Override + String getString(String columnLabel) throws SQLException; + + // (Temporary, re matching ResultSet's method order:) + // getBoolean(String) + // ) + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getByte(int)}. + * </p> + */ + @Override + byte getByte(String columnLabel) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getShort(int)}. + * </p> + */ + @Override + short getShort(String columnLabel) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getInt(int)}. + * </p> + */ + @Override + int getInt(String columnLabel) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getLong(int)}. + * </p> + */ + @Override + long getLong(String columnLabel) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getFloat(int)}. + * </p> + */ + @Override + float getFloat(String columnLabel) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getDouble(int)}. + * </p> + */ + @Override + double getDouble(String columnLabel) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getBigDecimal(int)}. + * </p> + */ + @Override + BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException; + + // (Temporary, re matching ResultSet's method order:) + // getBytes(String) + // getDate(String) + // getTime(String) + // getTimestamp(String) + // getAsciiStream(String) + // getUnicodeStream(String) + // getBinaryStream(String) + // getWarnings() + // clearWarnings() + // getCursorName() + // getMetaData() + // ) + + /** + * {@inheritDoc} + * <p> + * <strong>Conversions</strong>: Supports conversion from all types. + * </p> + */ + @Override + Object getObject(int columnIndex) throws SQLException; + + /** + * {@inheritDoc} + * <p> + * For conversions, see {@link DrillResultSet#getObject(int)}. + * </p> + */ + @Override + Object getObject(String columnLabel) throws SQLException; + + // (Temporary, re matching ResultSet's method order:) + // findColumn(String) + // getCharacterStream(int) + // getCharacterStream(String) + // getBigDecimal(int) + // getBigDecimal(String) + // isBeforeFirst() + // isAfterLast() + // isFirst() + // isLast() + // beforeFirst() + // afterLast() + // first() + // last() + // getRow() + // absolute(int) + // relative(int) + // previous() + // setFetchDirection(int) + // getFetchDirection() + // setFetchSize(int) + // getFetchSize() + // getType() + // getConcurrency() + // rowUpdated() + // rowInserted() + // rowDeleted() + // updateNull(int) + // updateBoolean(int, boolean) + // updateByte(int, byte) + // updateShort(int, short) + // updateInt(int, int) + // updateLong(int, long) + // updateFloat(int, float) + // updateDouble(int, double) + // updateBigDecimal(int, BigDecimal) + // updateString(int, String) + // updateBytes(int, byte[]) + // updateDate(int, Date) + // updateTime(int, Time) + // updateTimestamp(int, Timestamp) + // updateAsciiStream(int, InputStream, int) + // updateBinaryStream(int, InputStream, int) + // updateCharacterStream(int, Reader, int) + // updateObject(int, Object, int) + // updateObject(int, Object) + // updateNull(String) + // updateBoolean(String, boolean) + // updateByte(String, byte) + // updateShort(String, short) + // updateInt(String, int) + // updateLong(String, long) + // updateFloat(String, float) + // updateDouble(String, double) + // updateBigDecimal(String, BigDecimal) + // updateString(String, String) + // updateBytes(String, byte[]) + // updateDate(String, Date) + // updateTime(String, Time) + // updateTimestamp(String, Timestamp) + // updateAsciiStream(String, InputStream, int) + // updateBinaryStream(String, InputStream, int) + // updateCharacterStream(String, Reader, int) + // updateObject(String, Object, int) + // updateObject(String, Object) + // insertRow() + // updateRow() + // deleteRow() + // refreshRow() + // cancelRowUpdates() + // moveToInsertRow() + // moveToCurrentRow() + // getStatement() + // getObject(int, Map<String, Class<?>>) + // getRef(int) + // getBlob(int) + // getClob(int) + // getArray(int) + // getObject(String, Map<String, Class<?>>) + // getRef(String) + // getBlob(String) + // getClob(String) + // getArray(String) + // getDate(int, Calendar) + // getDate(String, Calendar) + // getTime(int, Calendar) + // getTime(String, Calendar) + // getTimestamp(int, Calendar) + // getTimestamp(String, Calendar) + // getURL(int) + // getURL(String) + // updateRef(int, Ref) + // updateRef(String, Ref) + // updateBlob(int, Blob) + // updateBlob(String, Blob) + // updateClob(int, Clob) + // updateClob(String, Clob) + // updateArray(int, Array) + // updateArray(String, Array) + // getRowId(int) + // getRowId(String) + // updateRowId(int, RowId) + // updateRowId(String, RowId) + // getHoldability() + // isClosed() + // updateNString(int, String) + // updateNString(String, String) + // updateNClob(int, NClob) + // updateNClob(String, NClob) + // getNClob(int) + // getNClob(String) + // getSQLXML(int) + // getSQLXML(String) + // updateSQLXML(int, SQLXML) + // updateSQLXML(String, SQLXML) + // getNString(int) + // getNString(String) + // getNCharacterStream(int) + // getNCharacterStream(String) + // updateNCharacterStream(int, Reader, long) + // updateNCharacterStream(String, Reader, long) + // updateAsciiStream(int, InputStream, long) + // updateBinaryStream(int, InputStream, long) + // updateCharacterStream(int, Reader, long) + // updateAsciiStream(String, InputStream, long) + // updateBinaryStream(String, InputStream, long) + // updateCharacterStream(String, Reader, long) + // updateBlob(int, InputStream, long) + // updateBlob(String, InputStream, long) + // updateClob(int, Reader, long) + // updateClob(String, Reader, long) + // updateNClob(int, Reader, long) + // updateNClob(String, Reader, long) + // updateNCharacterStream(int, Reader) + // updateNCharacterStream(String, Reader) + // updateAsciiStream(int, InputStream) + // updateBinaryStream(int, InputStream) + // updateCharacterStream(int, Reader) + // updateAsciiStream(String, InputStream) + // updateBinaryStream(String, InputStream) + // updateCharacterStream(String, Reader) + // updateBlob(int, InputStream) + // updateBlob(String, InputStream) + // updateClob(int, Reader) + // updateClob(String, Reader) + // updateNClob(int, Reader) + // updateNClob(String, Reader) + // getObject(int, Class<T>) + // getObject(String, Class<T>) + // ) } - - \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionException.java ---------------------------------------------------------------------- diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionException.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionException.java new file mode 100644 index 0000000..55ff901 --- /dev/null +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionException.java @@ -0,0 +1,28 @@ +/** + * 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 org.apache.drill.exec.vector.accessor.InvalidAccessException; + +public class SQLConversionException extends InvalidAccessException { + private static final long serialVersionUID = 2015_04-07L; + + SQLConversionException( String message ) { + super( message ); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionOverflowException.java ---------------------------------------------------------------------- diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionOverflowException.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionOverflowException.java new file mode 100644 index 0000000..a7d99fd --- /dev/null +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/SQLConversionOverflowException.java @@ -0,0 +1,27 @@ +/** + * 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; + + +public class SQLConversionOverflowException extends SQLConversionException { + private static final long serialVersionUID = 2015_04-07L; + + public SQLConversionOverflowException( String message ) { + super( message ); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/TypeConvertingSqlAccessor.java ---------------------------------------------------------------------- diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/TypeConvertingSqlAccessor.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/TypeConvertingSqlAccessor.java new file mode 100644 index 0000000..e095c42 --- /dev/null +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/TypeConvertingSqlAccessor.java @@ -0,0 +1,824 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package org.apache.drill.jdbc.impl; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; + +import org.apache.drill.common.types.TypeProtos.MajorType; +import org.apache.drill.exec.vector.accessor.InvalidAccessException; +import org.apache.drill.exec.vector.accessor.SqlAccessor; +import org.apache.drill.jdbc.SQLConversionOverflowException; + +// (Public until JDBC impl. classes moved out of published-intf. package. (DRILL-2089).) +/** + * SQL accessor implementing data type conversion for JDBC + * {@link ResultSet}.get<i>Type</i>(<i><column ID></i>) column accessor methods. + */ +public class TypeConvertingSqlAccessor implements SqlAccessor { + private final SqlAccessor innerAccessor; + + public TypeConvertingSqlAccessor( SqlAccessor innerAccessor ) { + this.innerAccessor = innerAccessor; + } + + @Override + public MajorType getType() { + return innerAccessor.getType(); + } + + @Override + public boolean isNull( int rowOffset ) { + return innerAccessor.isNull( rowOffset ); + } + + ////////////////////////////////////////////////////////////////////// + // PER JDBC specification: + // + // Column accessor (getXx(...)) methods and allowed source types, from + // JDBC 4.2 specification's TABLE B-6 ("Use of ResultSet getter Methods to + // Retrieve JDBC Data Types"; methods listed in same order as in spec (types + // reordered for consistency): + // + // - getByte: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - ROWID; + // + // - getShort: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + // - getInt: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + // - getLong: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + // - getFloat: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + // - getDouble: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + // - getBigDecimal: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + // - getBoolean: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + // - getString: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - DATE, TIME, TIMESTAMP; + // - DATALINK; + // + // - getNString: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - DATE, TIME, TIMESTAMP; + // - DATALINK; + // + // - getBytes: + // - BINARY, VARBINARY, LONGVARBINARY; + // + // - getDate: + // - CHAR, VARCHAR, LONGVARCHAR; + // - DATE, TIMESTAMP; + // + // - getTime: + // - CHAR, VARCHAR, LONGVARCHAR; + // - TIME, TIMESTAMP; + // + // - getTimestamp: + // - CHAR, VARCHAR, LONGVARCHAR; + // - DATE, TIME, TIMESTAMP; + // + // - getAsciiStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // + // - getBinaryStream: + // - BINARY, VARBINARY, LONGVARBINARY; + // + // - getCharacterStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - SQLXML; + // + // - getNCharacterStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - SQLXML; + // + // - getClob: + // - CLOB, NCLOB; + // + // - getNClob: + // - CLOB, NCLOB; + // + // - getBlob: + // - BLOB; + // + // - getArray: + // - ARRAY; + // + // - getRef: + // - REF; + // + // - getURL: + // - DATALINK; + // + // - getObject: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - BLOB; + // - DATE, TIME, TIMESTAMP; + // - TIME_WITH_TIMEZONE; + // - TIMESTAMP_WITH_TIMEZONE; + // - DATALINK; + // - ROWID; + // - SQLXML; + // - ARRAY; + // - REF; + // - STRUCT; + // - JAVA_OBJECT; + // + // - getRowId: + // - ROWID; + // + // - getSQLXML: + // - SQLXML SQLXML + + + /** + * Creates SQLConversionOverflowException using given parameters to form + * exception message text. + * + * @param methodLabel label for (string to use to identify) method that + * couldn't convert source value to target type + * (e.g., "getInt(...)") + * @param valueTypeLabel label for type of source value that couldn't be + * converted (e.g., "Java long / SQL BIGINT") + * @param value representation of source value that couldn't be converted; + * object whose toString() shows (part of) value; not null + * @return the created exception + */ + private static SQLConversionOverflowException newOverflowException( + String methodLabel, String valueTypeLabel, Object value ) { + return new SQLConversionOverflowException( + methodLabel + " can't return " + valueTypeLabel + " value " + value + + " (too large) "); + } + + + ////////////////////////////////////////////////////////////////////// + // Column accessor (getXxx(...)) methods, in same order as in JDBC 4.2 spec. + // TABLE B-6: + + //////////////////////////////////////// + // - getByte: + // - TINYINT, SMALLINT, INTEGER, BIGINT - supported/implemented (here) + // - REAL, FLOAT, DOUBLE - supported/implemented (here) + // - DECIMAL, NUMERIC- supported/implemented (here) + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - ROWID; + + /** + * Returns byte-sized integer value or throws SQLConversionOverflowException + * if given value doesn't fit in byte. + */ + private static byte getByteValueOrThrow( long value, String typeLabel ) + throws SQLConversionOverflowException { + if ( Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE ) { + return (byte) value; + } else { + throw newOverflowException( "getByte(...)", typeLabel, value ); + } + } + + /** + * Returns byte-sized integer version of floating-point value or throws + * SQLConversionOverflowException if given value doesn't fit in byte. + */ + private static byte getByteValueOrThrow( double value, String typeLabel ) + throws SQLConversionOverflowException { + if ( Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE ) { + return (byte) value; + } else { + throw newOverflowException( "getByte(...)", typeLabel, value ); + } + } + + /** + * {@inheritDoc} + * <p> + * This implementation implements type conversions for + * {@link ResultSet#getByte(String)}/{@link ResultSet#getByte(int)}. + * </p> + */ + @Override + public byte getByte( int rowOffset ) throws InvalidAccessException { + final byte result; + switch ( getType().getMinorType() ) { + // 1. Regular type: + case TINYINT: + result = innerAccessor.getByte( rowOffset ); + break; + + // 2. Converted-from types: + case SMALLINT: + result = getByteValueOrThrow( innerAccessor.getShort( rowOffset ), + "Java short / SQL SMALLINT" ); + break; + case INT: + result = getByteValueOrThrow( innerAccessor.getInt( rowOffset ), + "Java int / SQL INTEGER" ); + break; + case BIGINT: + result = getByteValueOrThrow( innerAccessor.getLong( rowOffset ), + "Java long / SQL BIGINT" ); + break; + case FLOAT4: + result = getByteValueOrThrow( innerAccessor.getFloat( rowOffset ), + "Java float / SQL REAL/FLOAT" ); + break; + case FLOAT8: + result = getByteValueOrThrow( innerAccessor.getDouble( rowOffset ), + "Java double / SQL DOUBLE PRECISION" ); + break; + + // 3. Not-yet-converted and unconvertible types: + default: + result = innerAccessor.getByte( rowOffset ); + break; + } + return result; + } + + //////////////////////////////////////// + // - getShort: + // - TINYINT, SMALLINT, INTEGER, BIGINT - supported/implemented (here) + // - REAL, FLOAT, DOUBLE - supported/implemented (here) + // - DECIMAL, NUMERIC- supported/implemented (here) + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + + private static short getShortValueOrThrow( long value, String typeLabel ) + throws SQLConversionOverflowException { + if ( Short.MIN_VALUE <= value && value <= Short.MAX_VALUE ) { + return (short) value; + } else { + throw newOverflowException( "getShort(...)", typeLabel, value ); + } + } + + private static short getShortValueOrThrow( double value, String typeLabel ) + throws SQLConversionOverflowException { + if ( Short.MIN_VALUE <= value && value <= Short.MAX_VALUE ) { + return (short) value; + } else { + throw newOverflowException( "getShort(...)", typeLabel, value ); + } + } + + @Override + public short getShort( int rowOffset ) throws InvalidAccessException { + final short result; + switch ( getType().getMinorType() ) { + // 1. Regular type: + case SMALLINT: + result = innerAccessor.getShort( rowOffset ); + break; + + // 2. Converted-from types: + case TINYINT: + result = innerAccessor.getByte( rowOffset ); + break; + case INT: + result = getShortValueOrThrow( innerAccessor.getInt( rowOffset ), + "Java int / SQL INTEGER" ); + break; + case BIGINT: + result = getShortValueOrThrow( innerAccessor.getLong( rowOffset ), + "Java long / SQL BIGINT" ); + break; + case FLOAT4: + result = getShortValueOrThrow( innerAccessor.getFloat( rowOffset ), + "Java float / SQL REAL/FLOAT" ); + break; + case FLOAT8: + result = getShortValueOrThrow( innerAccessor.getDouble( rowOffset ), + "Java double / SQL DOUBLE PRECISION" ); + break; + + // 3. Not-yet-converted and unconvertible types: + default: + result = innerAccessor.getByte( rowOffset ); + break; + } + return result; + } + + //////////////////////////////////////// + // - getInt: + // - TINYINT, SMALLINT, INTEGER, BIGINT - supported/implemented (here) + // - REAL, FLOAT, DOUBLE - supported/implemented (here) + // - DECIMAL, NUMERIC- supported/implemented (here) + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + + private static int getIntValueOrThrow( long value, String typeLabel ) + throws SQLConversionOverflowException { + if ( Integer.MIN_VALUE <= value && value <= Integer.MAX_VALUE ) { + return (int) value; + } else { + throw newOverflowException( "getInt(...)", typeLabel, value ); + } + } + + private static int getIntValueOrThrow( double value, String typeLabel ) + throws SQLConversionOverflowException { + if ( Integer.MIN_VALUE <= value && value <= Integer.MAX_VALUE ) { + return (int) value; + } else { + throw newOverflowException( "getInt(...)", typeLabel, value ); + } + } + + @Override + public int getInt( int rowOffset ) throws InvalidAccessException { + final int result; + switch ( getType().getMinorType() ) { + // 1. Regular type: + case INT: + result = innerAccessor.getInt( rowOffset ); + break; + + // 2. Converted-from types: + case TINYINT: + result = innerAccessor.getByte( rowOffset ); + break; + case SMALLINT: + result = innerAccessor.getShort( rowOffset ); + break; + case BIGINT: + result = getIntValueOrThrow( innerAccessor.getLong( rowOffset ), + "Java long / SQL BIGINT" ); + break; + case FLOAT4: + result = getIntValueOrThrow( innerAccessor.getFloat( rowOffset ), + "Java float / SQL REAL/FLOAT" ); + break; + case FLOAT8: + result = getIntValueOrThrow( innerAccessor.getDouble( rowOffset ), + "Java double / SQL DOUBLE PRECISION" ); + break; + + // 3. Not-yet-converted and unconvertible types: + default: + result = innerAccessor.getInt( rowOffset ); + break; + } + return result; + } + + //////////////////////////////////////// + // - getLong: + // - TINYINT, SMALLINT, INTEGER, BIGINT - supported/implemented (here) + // - REAL, FLOAT, DOUBLE - supported/implemented (here) + // - DECIMAL, NUMERIC- supported/implemented (here) + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + + private static long getLongValueOrThrow( double value, String typeLabel ) + throws SQLConversionOverflowException { + if ( Long.MIN_VALUE <= value && value <= Long.MAX_VALUE ) { + return (long) value; + } else { + throw newOverflowException( "getLong(...)", typeLabel, value ); + } + } + + @Override + public long getLong( int rowOffset ) throws InvalidAccessException { + final long result; + switch ( getType().getMinorType() ) { + // 1. Regular type: + case BIGINT: + result = innerAccessor.getLong( rowOffset ); + break; + + // 2. Converted-from types: + case TINYINT: + result = innerAccessor.getByte( rowOffset ); + break; + case SMALLINT: + result = innerAccessor.getShort( rowOffset ); + break; + case INT: + result = innerAccessor.getInt( rowOffset ); + break; + case FLOAT4: + result = getLongValueOrThrow( innerAccessor.getFloat( rowOffset ), + "Java float / SQL REAL/FLOAT" ); + break; + case FLOAT8: + result = getLongValueOrThrow( innerAccessor.getDouble( rowOffset ), + "Java double / SQL DOUBLE PRECISION" ); + break; + + // 3. Not-yet-converted and unconvertible types: + default: + result = innerAccessor.getLong( rowOffset ); + break; + } + return result; + } + + + //////////////////////////////////////// + // - getFloat: + // - TINYINT, SMALLINT, INTEGER, BIGINT - supported/implemented (here) + // - REAL, FLOAT, DOUBLE - supported/implemented (here) + // - DECIMAL, NUMERIC- supported/implemented (here) + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + + @Override + public float getFloat( int rowOffset ) throws InvalidAccessException { + final float result; + switch ( getType().getMinorType() ) { + // 1. Regular type: + case FLOAT4: + result = innerAccessor.getFloat( rowOffset ); + break; + + // 2. Converted-from types: + case INT: + result = innerAccessor.getInt( rowOffset ); + break; + case BIGINT: + result = innerAccessor.getLong( rowOffset ); + break; + case FLOAT8: + final double value = innerAccessor.getDouble( rowOffset ); + if ( Float.MIN_VALUE <= value && value <= Float.MAX_VALUE ) { + result = (float) value; + } else { + throw newOverflowException( "getFloat(...)", + "Java double / SQL DOUBLE PRECISION", + value ); + } + break; + + // 3. Not-yet-converted and unconvertible types: + default: + result = innerAccessor.getInt( rowOffset ); + break; + } + return result; + } + + //////////////////////////////////////// + // - getDouble: + // - TINYINT, SMALLINT, INTEGER, BIGINT - supported/implemented (here) + // - REAL, FLOAT, DOUBLE - supported/implemented (here) + // - DECIMAL, NUMERIC- supported/implemented (here) + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + + @Override + public double getDouble( int rowOffset ) throws InvalidAccessException { + final double result; + switch ( getType().getMinorType() ) { + // 1. Regular type: + case FLOAT8: + result = innerAccessor.getDouble( rowOffset ); + break; + + // 2. Converted-from types: + case INT: + result = innerAccessor.getInt( rowOffset ); + break; + case BIGINT: + result = innerAccessor.getLong( rowOffset ); + break; + case FLOAT4: + result = innerAccessor.getFloat( rowOffset ); + break; + + // 3. Not-yet-converted and unconvertible types: + default: + result = innerAccessor.getLong( rowOffset ); + //break; + } + return result; + } + + + //////////////////////////////////////// + // - getBigDecimal: + // - TINYINT, SMALLINT, INTEGER, BIGINT - supported/implemented (here) + // - REAL, FLOAT, DOUBLE - supported/implemented (here) + // - DECIMAL, NUMERIC- supported/implemented (here) + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + + @Override + public BigDecimal getBigDecimal( int rowOffset ) throws InvalidAccessException { + final BigDecimal result; + switch ( getType().getMinorType() ) { + // 1. Regular type: + case DECIMAL9: + case DECIMAL18: + case DECIMAL28SPARSE: + case DECIMAL38SPARSE: + result = innerAccessor.getBigDecimal( rowOffset ); + break; + + // 2. Converted-from types: + case TINYINT: + result = new BigDecimal( innerAccessor.getByte( rowOffset ) ); + break; + case SMALLINT: + result = new BigDecimal( innerAccessor.getShort( rowOffset ) ); + break; + case INT: + result = new BigDecimal( innerAccessor.getInt( rowOffset ) ); + break; + case BIGINT: + result = new BigDecimal( innerAccessor.getLong( rowOffset ) ); + break; + case FLOAT4: + result = new BigDecimal( innerAccessor.getFloat( rowOffset ) ); + break; + case FLOAT8: + result = new BigDecimal( innerAccessor.getDouble( rowOffset ) ); + break; + + // 3. Not-yet-converted and unconvertible types: + default: + result = innerAccessor.getBigDecimal( rowOffset ); + //break; + } + return result; + } + + //////////////////////////////////////// + // - getBoolean: + // - TINYINT, SMALLINT, INTEGER, BIGINT; + // - REAL, FLOAT, DOUBLE; + // - DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + + @Override + public boolean getBoolean( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getBoolean( rowOffset ); + } + + //////////////////////////////////////// + // - getString: + // - TINYINT, SMALLINT, INTEGER, BIGINT; + // - REAL, FLOAT, DOUBLE; + // - DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - DATE, TIME, TIMESTAMP; + // - DATALINK; + + @Override + public String getString( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getString( rowOffset ); + } + + //////////////////////////////////////// + // - getNString: + // - TINYINT, SMALLINT, INTEGER, BIGINT; + // - REAL, FLOAT, DOUBLE; + // - DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - DATE, TIME, TIMESTAMP; + // - DATALINK; + + //////////////////////////////////////// + // - getBytes: + // - BINARY, VARBINARY, LONGVARBINARY; + + @Override + public byte[] getBytes( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getBytes( rowOffset ); + } + + //////////////////////////////////////// + // - getDate: + // - CHAR, VARCHAR, LONGVARCHAR; + // - DATE, TIMESTAMP; + + @Override + public Date getDate( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getDate( rowOffset ); + } + + //////////////////////////////////////// + // - getTime: + // - CHAR, VARCHAR, LONGVARCHAR; + // - TIME, TIMESTAMP; + + @Override + public Time getTime( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getTime( rowOffset ); + } + + //////////////////////////////////////// + // - getTimestamp: + // - CHAR, VARCHAR, LONGVARCHAR; + // - DATE, TIME, TIMESTAMP; + + @Override + public Timestamp getTimestamp( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getTimestamp( rowOffset ); + } + + //////////////////////////////////////// + // - getAsciiStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getBinaryStream: + // - BINARY, VARBINARY, LONGVARBINARY; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getCharacterStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - SQLXML; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getNCharacterStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - SQLXML; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getClob: + // - CLOB, NCLOB; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getNClob: + // - CLOB, NCLOB; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getBlob: + // - BLOB; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getArray: + // - ARRAY; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getRef: + // - REF; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getURL: + // - DATALINK; + + //////////////////////////////////////// + // - getObject: + // - TINYINT, SMALLINT, INTEGER, BIGINT; + // - REAL, FLOAT, DOUBLE; + // - DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - BLOB; + // - DATE, TIME, TIMESTAMP; + // - TIME_WITH_TIMEZONE; + // - TIMESTAMP_WITH_TIMEZONE; + // - DATALINK; + // - ROWID; + // - SQLXML; + // - ARRAY; + // - REF; + // - STRUCT; + // - JAVA_OBJECT; + + @Override + public Object getObject( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getObject( rowOffset ); + } + + + //////////////////////////////////////// + // - getRowId: + // - ROWID; + + // Not supported or not supported via SqlAccessor(?). + + //////////////////////////////////////// + // - getSQLXML: + // - SQLXML SQLXML + + // Not supported or not supported via SqlAccessor(?). + + + // SqlAccessor getXxx(...) methods not corresponding by name with ResultSet methods: + + @Override + public char getChar( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getChar( rowOffset ); + } + + @Override + public InputStream getStream( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getStream( rowOffset ); + } + + @Override + public Reader getReader( int rowOffset ) throws InvalidAccessException { + return innerAccessor.getReader( rowOffset ); + } + +} http://git-wip-us.apache.org/repos/asf/drill/blob/fe11e86c/exec/jdbc/src/test/java/org/apache/drill/jdbc/ResultSetGetMethodConversionsTest.java ---------------------------------------------------------------------- diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/ResultSetGetMethodConversionsTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/ResultSetGetMethodConversionsTest.java new file mode 100644 index 0000000..eced72b --- /dev/null +++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/ResultSetGetMethodConversionsTest.java @@ -0,0 +1,711 @@ +/** + * 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.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +// TODO: Resolve requirements: +// - For SMALLINT retrieved with getObject(), is result required (by user +// expectations, from behavior of other JDBC drivers) to be a Short? Can +// it be a smaller type (e.g., Byte, if the value fits)? Can it be a larger +// type (e.g., Long)? +// - For INTEGER retrieved by getShort(...): +// - Is that always an error, or is it allowed as least sometimes? +// - For INTEGER, does getShort(...) return value if value fits in short? +// - For INTEGER, if value does not fit in short, does getShort(...) throw +// exception, or return something. If it returns: +// - Does it return maximum short value or does it use modulus? +// - Does it set warning status (on ResultSet)? +// - Should getString(...) on BOOLEAN return "TRUE"/"FALSE" or "true"/"false"? +// (TODO: Check SQL spec for general canonical form and results of +// CAST( TRUE AS VARCHAR ).) + + +/** + * Integration-level unit test for ResultSet's <code>get<i>Type</i>(<i>column ID</i>)</code> + * methods' type conversions. + * <p> + * This test class is intended for higher-level type-vs.-type coverage tests. + * Detailed-case tests (e.g., boundary conditions) are intended to be in + * {@link org.apache.drill.jdbc.impl.TypeConvertingAccessor}). + * </p> + */ +public class ResultSetGetMethodConversionsTest extends JdbcTest { + + private static Connection connection; + private static ResultSet testDataRow; + + @BeforeClass + public static void setUpConnectionAndMetadataToCheck() throws SQLException { + // Get JDBC connection to Drill: + // (Note: Can't use JdbcTest's connect(...) because JdbcTest closes + // connection on test method failure, but we use ResultSet across methods.) + connection = new Driver().connect( "jdbc:drill:zk=local", null ); + + // Set up result row with values of various types. + Statement stmt = connection.createStatement(); + testDataRow = stmt.executeQuery( + "" + + "SELECT " + + "\n" + + "\n TRUE AS C_BOOLEAN_TRUE, " + // Disabled until TINYINT/SMALLINT are implemented (DRILL-2470): + //+ "\n CAST( 1 AS TINYINT ) AS C_TINYINT_1, " + //+ "\n CAST( 2 AS SMALLINT ) AS C_SMALLINT_2, " + + "\n CAST( 3 AS INTEGER ) AS C_INTEGER_3, " + + "\n CAST( 4 AS BIGINT ) AS C_BIGINT_4, " + // Disabled until REAL is implemented (DRILL-2683): + //+ "\n CAST( 5.5 AS REAL ) AS `C_REAL_5.5`, " + + "\n CAST( 6.6 AS DOUBLE PRECISION ) AS `C_DOUBLE_PREC._6.6`, " + + "\n CAST( 7.7 AS FLOAT ) AS `C_FLOAT_7.7`, " + + "\n CAST( 10.10 AS DECIMAL ) AS `C_DECIMAL_10.10`, " + + "\n CAST( 10.5 AS DECIMAL ) AS `C_DECIMAL_10.5`, " + + "\n CAST( 11.11 AS DECIMAL(9,2) ) AS `C_DECIMAL(9,2)_11.11`, " + + "\n CAST( 12.12 AS DECIMAL(18,2) ) AS `C_DECIMAL(18,2)_12.12`, " + + "\n CAST( 13.13 AS DECIMAL(28,2) ) AS `C_DECIMAL(28,2)_13.13`, " + + "\n CAST( 14.14 AS DECIMAL(38,2) ) AS `C_DECIMAL(38,2)_14.14`, " + + "\n '' " + + "\nFROM INFORMATION_SCHEMA.CATALOGS " + + "\nLIMIT 1 " ); + // Note: Assertions must be enabled (as they have been so far in tests). + assert testDataRow.next(); + } + + @AfterClass + public static void tearDownConnection() throws SQLException { + connection.close(); + } + + + //////////////////////////////////////// + // - getByte: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - ROWID; + + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getByte_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getByte( "C_TINYINT_1" ), equalTo( (byte) 1 ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getByte_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getByte( "C_SMALLINT_2" ), equalTo( (byte) 2 ) ); + } + + @Test + public void test_getByte_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getByte( "C_INTEGER_3" ), equalTo( (byte) 3 ) ); + } + + @Test + public void test_getByte_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getByte( "C_BIGINT_4" ), equalTo( (byte) 4 ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getByte_handles_REAL() throws SQLException { + assertThat( testDataRow.getByte( "C_REAL_5.5" ), equalTo( (byte) 5 ) ); + } + + @Test + public void test_getByte_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getByte( "C_DOUBLE_PREC._6.6" ), equalTo( (byte) 6 ) ); + } + + @Test + public void test_getByte_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getByte( "C_FLOAT_7.7" ), equalTo( (byte) 7 ) ); + } + + @Test + public void test_getByte_handles_DECIMAL() throws SQLException { + assertThat( testDataRow.getByte( "C_DECIMAL_10.10" ), equalTo( (byte) 10 ) ); + } + + + //////////////////////////////////////// + // - getShort: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getShort_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getShort( "C_TINYINT_1" ), equalTo( (short) 1 ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getShort_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getShort( "C_SMALLINT_2" ), equalTo( (short) 2 ) ); + } + + @Test + public void test_getShort_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getShort( "C_INTEGER_3" ), equalTo( (short) 3 ) ); + } + + @Test + public void test_getShort_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getShort( "C_BIGINT_4" ), equalTo( (short) 4 ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getShort_handles_REAL() throws SQLException { + assertThat( testDataRow.getShort( "C_REAL_5.5" ), equalTo( (short) 5 ) ); + } + + @Test + public void test_getShort_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getShort( "C_DOUBLE_PREC._6.6" ), equalTo( (short) 6 ) ); + } + + @Test + public void test_getShort_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getShort( "C_FLOAT_7.7" ), equalTo( (short) 7 ) ); + } + + @Test + public void test_getShort_handles_DECIMAL() throws SQLException { + assertThat( testDataRow.getShort( "C_DECIMAL_10.10" ), equalTo( (short) 10 ) ); + } + + + + //////////////////////////////////////// + // - getInt: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getInt_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getInt( "C_TINYINT_1" ), equalTo( 1 ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getInt_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getInt( "C_SMALLINT_2" ), equalTo( 2 ) ); + } + + @Test + public void test_getInt_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getInt( "C_INTEGER_3" ), equalTo( 3 ) ); + } + + @Test + public void test_getInt_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getInt( "C_BIGINT_4" ), equalTo( 4 ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getInt_handles_REAL() throws SQLException { + assertThat( testDataRow.getInt( "C_REAL_5.5" ), equalTo( 5 ) ); + } + + @Test + public void test_getInt_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getInt( "C_DOUBLE_PREC._6.6" ), equalTo( 6 ) ); + } + + @Test + public void test_getInt_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getInt( "C_FLOAT_7.7" ), equalTo( 7 ) ); + } + + @Test + public void test_getInt_handles_DECIMAL() throws SQLException { + assertThat( testDataRow.getInt( "C_DECIMAL_10.10" ), equalTo( 10 ) ); + } + + + //////////////////////////////////////// + // - getLong: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getLong_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getLong( "C_TINYINT_1" ), equalTo( 1L ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getLong_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getLong( "C_SMALLINT_2" ), equalTo( 2L ) ); + } + + @Test + public void test_getLong_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getLong( "C_INTEGER_3" ), equalTo( 3L ) ); + } + + @Test + public void test_getLong_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getLong( "C_BIGINT_4" ), equalTo( 4L ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getLong_handles_REAL() throws SQLException { + assertThat( testDataRow.getLong( "C_REAL_5.5" ), equalTo( 5L ) ); + } + + @Test + public void test_getLong_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getLong( "C_DOUBLE_PREC._6.6" ), equalTo( 6L ) ); + } + + @Test + public void test_getLong_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getLong( "C_FLOAT_7.7" ), equalTo( 7L ) ); + } + + @Test + public void test_getLong_handles_DECIMAL() throws SQLException { + assertThat( testDataRow.getLong( "C_DECIMAL_10.10" ), equalTo( 10L ) ); + } + + + //////////////////////////////////////// + // - getFloat: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getFloat_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getFloat( "C_TINYINT_1" ), equalTo( 1f ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getFloat_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getFloat( "C_SMALLINT_2" ), equalTo( 2f ) ); + } + + @Test + public void test_getFloat_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getFloat( "C_INTEGER_3" ), equalTo( 3f ) ); + } + + @Test + public void test_getFloat_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getFloat( "C_BIGINT_4" ), equalTo( 4f ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getFloat_handles_REAL() throws SQLException { + assertThat( testDataRow.getFloat( "C_REAL_5.5" ), equalTo( 5.5f ) ); + } + + @Test + public void test_getFloat_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getFloat( "C_DOUBLE_PREC._6.6" ), equalTo( 6.6f ) ); + } + + @Test + public void test_getFloat_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getFloat( "C_FLOAT_7.7" ), equalTo( 7.7f ) ); + } + + @Test + public void test_getFloat_handles_DECIMAL() throws SQLException { + assertThat( testDataRow.getFloat( "C_DECIMAL_10.10" ), equalTo( 10.10f ) ); //????? + } + + //////////////////////////////////////// + // - getDouble: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getDouble_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getDouble( "C_TINYINT_1" ), equalTo( 1D ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getDouble_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getDouble( "C_SMALLINT_2" ), equalTo( 2D ) ); + } + + @Test + public void test_getDouble_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getDouble( "C_INTEGER_3" ), equalTo( 3D ) ); + } + + @Test + public void test_getDouble_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getDouble( "C_BIGINT_4" ), equalTo( 4D ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getDouble_handles_REAL() throws SQLException { + assertThat( testDataRow.getDouble( "C_REAL_5.5" ), equalTo( (double) 5.5f ) ); + } + + @Test + public void test_getDouble_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getDouble( "C_DOUBLE_PREC._6.6" ), equalTo( 6.6d ) ); + } + + @Test + public void test_getDouble_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getDouble( "C_FLOAT_7.7" ), equalTo( (double) 7.7f ) ); + } + + @Test + public void test_getDouble_handles_DECIMAL() throws SQLException { + assertThat( testDataRow.getDouble( "C_DECIMAL_10.10" ), equalTo( 10.10d ) ); //??? + } + + //////////////////////////////////////// + // - getBigDecimal: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getBigDecimal_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_TINYINT_1" ), equalTo( new BigDecimal( 1 ) ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getBigDecimal_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_SMALLINT_2" ), equalTo( new BigDecimal( 2 ) ) ); + } + + @Test + public void test_getBigDecimal_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_INTEGER_3" ), equalTo( new BigDecimal( 3 ) ) ); + } + + @Test + public void test_getBigDecimal_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_BIGINT_4" ), equalTo( new BigDecimal( 4 ) ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getBigDecimal_handles_REAL() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_REAL_5.5" ), equalTo( new BigDecimal( 5.5f ) ) ); + } + + @Test + public void test_getBigDecimal_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_DOUBLE_PREC._6.6" ), equalTo( new BigDecimal( 6.6d ) ) ); + } + + @Test + public void test_getBigDecimal_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_FLOAT_7.7" ), equalTo( new BigDecimal( 7.7f ) ) ); + } + + @Test + public void test_getBigDecimal_handles_DECIMAL_1() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_DECIMAL_10.5" ), equalTo( new BigDecimal( "10.5") ) ); + } + + @Ignore( "until DECIMAL is supported (no longer maps to double) (DRILL-????)" ) + @Test + public void test_getBigDecimal_handles_DECIMAL_2() throws SQLException { + assertThat( testDataRow.getBigDecimal( "C_DECIMAL_10.10" ), equalTo( new BigDecimal( "10.10") ) ); //??????resolve + } + + + //////////////////////////////////////// + // - getBoolean: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // + + //////////////////////////////////////// + // - getString: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - DATE, TIME, TIMESTAMP; + // - DATALINK; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getString_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getString( "C_TINYINT_1" ), equalTo( "1" ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getString_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getString( "C_SMALLINT_2" ), equalTo( "2" ) ); + } + + @Test + public void test_getString_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getString( "C_INTEGER_3" ), equalTo( "3" ) ); + } + + @Test + public void test_getString_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getString( "C_BIGINT_4" ), equalTo( "4" ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getString_handles_REAL() throws SQLException { + assertThat( testDataRow.getString( "C_REAL_5.5" ), equalTo( "5.5????" ) ); + } + + @Test + public void test_getString_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getString( "C_DOUBLE_PREC._6.6" ), equalTo( "6.6" ) ); + } + + @Test + public void test_getString_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getString( "C_FLOAT_7.7" ), equalTo( "7.7" ) ); + } + + @Test + public void test_getString_handles_DECIMAL() throws SQLException { + assertThat( testDataRow.getString( "C_DECIMAL_10.10" ), equalTo( "10.1" ) ); + } + + + //////////////////////////////////////// + // - getNString: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - DATE, TIME, TIMESTAMP; + // - DATALINK; + // + + //////////////////////////////////////// + // - getBytes: + // - BINARY, VARBINARY, LONGVARBINARY; + // + + //////////////////////////////////////// + // - getDate: + // - CHAR, VARCHAR, LONGVARCHAR; + // - DATE, TIMESTAMP; + // + + //////////////////////////////////////// + // - getTime: + // - CHAR, VARCHAR, LONGVARCHAR; + // - TIME, TIMESTAMP; + // + + //////////////////////////////////////// + // - getTimestamp: + // - CHAR, VARCHAR, LONGVARCHAR; + // - DATE, TIME, TIMESTAMP; + // + + //////////////////////////////////////// + // - getAsciiStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // + + //////////////////////////////////////// + // - getBinaryStream: + // - BINARY, VARBINARY, LONGVARBINARY; + // + + //////////////////////////////////////// + // - getCharacterStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - SQLXML; + // + + //////////////////////////////////////// + // - getNCharacterStream: + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - SQLXML; + // + + //////////////////////////////////////// + // - getClob: + // - CLOB, NCLOB; + // + + //////////////////////////////////////// + // - getNClob: + // - CLOB, NCLOB; + // + + //////////////////////////////////////// + // - getBlob: + // - BLOB; + // + + //////////////////////////////////////// + // - getArray: + // - ARRAY; + // + + //////////////////////////////////////// + // - getRef: + // - REF; + // + + //////////////////////////////////////// + // - getURL: + // - DATALINK; + // + + //////////////////////////////////////// + // - getObject: + // - TINYINT, SMALLINT, INTEGER, BIGINT; REAL, FLOAT, DOUBLE; DECIMAL, NUMERIC; + // - BIT, BOOLEAN; + // - CHAR, VARCHAR, LONGVARCHAR; + // - NCHAR, NVARCHAR, LONGNVARCHAR; + // - BINARY, VARBINARY, LONGVARBINARY; + // - CLOB, NCLOB; + // - BLOB; + // - DATE, TIME, TIMESTAMP; + // - TIME_WITH_TIMEZONE; + // - TIMESTAMP_WITH_TIMEZONE; + // - DATALINK; + // - ROWID; + // - SQLXML; + // - ARRAY; + // - REF; + // - STRUCT; + // - JAVA_OBJECT; + // + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getObject_handles_TINYINT() throws SQLException { + assertThat( testDataRow.getObject( "C_TINYINT_1" ), equalTo( (Object) 1 ) ); + } + + @Ignore( "until TINYINT/SMALLINT implemented (DRILL-2470)" ) + @Test + public void test_getObject_handles_SMALLINT() throws SQLException { + assertThat( testDataRow.getObject( "C_SMALLINT_2" ), equalTo( (Object) 2 ) ); + } + + @Test + public void test_getObject_handles_INTEGER() throws SQLException { + assertThat( testDataRow.getObject( "C_INTEGER_3" ), equalTo( (Object) 3 ) ); + } + + @Test + public void test_getObject_handles_BIGINT() throws SQLException { + assertThat( testDataRow.getObject( "C_BIGINT_4" ), equalTo( (Object) 4L ) ); + } + + @Ignore( "until REAL is implemented (DRILL-2683)" ) + @Test + public void test_getObject_handles_REAL() throws SQLException { + assertThat( testDataRow.getObject( "C_REAL_5.5" ), equalTo( (Object) 5.5f ) ); + } + + @Test + public void test_getObject_handles_DOUBLE() throws SQLException { + assertThat( testDataRow.getObject( "C_DOUBLE_PREC._6.6" ), equalTo( (Object) 6.6d ) ); + } + + @Test + public void test_getObject_handles_FLOAT() throws SQLException { + assertThat( testDataRow.getObject( "C_FLOAT_7.7" ), equalTo( (Object) 7.7f ) ); + } + + @Ignore( "until DECIMAL is supported (no longer maps to double) (DRILL-????)" ) + @Test + public void test_getObject_handles_DECIMAL_1() throws SQLException { + assertThat( testDataRow.getObject( "C_DECIMAL_10.5" ), + equalTo( (Object) new BigDecimal( "10.5" ) ) ); + } + + @Ignore( "until DECIMAL is supported (no longer maps to double) (DRILL-????)" ) + @Test + public void test_getObject_handles_DECIMAL_2() throws SQLException { + assertThat( testDataRow.getObject( "C_DECIMAL_10.10" ), + equalTo( (Object) new BigDecimal( "10.10" ) ) ); + } + + + //////////////////////////////////////// + // - getRowId: + // - ROWID; + // + + //////////////////////////////////////// + // - getSQLXML: + // - SQLXML SQLXML + +}