You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/08/01 00:42:41 UTC
[04/50] [abbrv] incubator-calcite git commit: [CALCITE-677]
RemoteDriverTest.testTypeHandling fails east of Greenwich
[CALCITE-677] RemoteDriverTest.testTypeHandling fails east of Greenwich
Move logic for setting parameters into new class AvaticaSite.
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/7f8ce197
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/7f8ce197
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/7f8ce197
Branch: refs/heads/branch-release
Commit: 7f8ce1978b1792848bea127094a2ee24d52c6604
Parents: 9e272f2
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Apr 13 13:57:22 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Apr 20 01:37:25 2015 -0700
----------------------------------------------------------------------
.../apache/calcite/avatica/jdbc/JdbcMeta.java | 75 +--
.../calcite/avatica/jdbc/JdbcResultSet.java | 18 +-
.../calcite/avatica/RemoteDriverTest.java | 193 +++++--
.../calcite/avatica/AvaticaConnection.java | 5 +-
.../calcite/avatica/AvaticaJdbc41Factory.java | 54 +-
.../calcite/avatica/AvaticaParameter.java | 556 ------------------
.../avatica/AvaticaPreparedStatement.java | 130 +++--
.../calcite/avatica/AvaticaResultSet.java | 5 +-
.../org/apache/calcite/avatica/AvaticaSite.java | 578 +++++++++++++++++++
.../calcite/avatica/AvaticaStatement.java | 17 +-
.../apache/calcite/avatica/ColumnMetaData.java | 2 +-
.../java/org/apache/calcite/avatica/Meta.java | 6 +-
.../org/apache/calcite/avatica/MetaImpl.java | 13 +-
.../org/apache/calcite/avatica/SqlType.java | 87 ++-
.../calcite/avatica/remote/LocalService.java | 5 +-
.../calcite/avatica/remote/RemoteMeta.java | 7 +-
.../calcite/avatica/remote/TypedValue.java | 274 +++++++--
.../calcite/avatica/util/AbstractCursor.java | 4 +-
.../calcite/avatica/util/DateTimeUtils.java | 11 +
.../calcite/jdbc/CalciteConnectionImpl.java | 13 +-
.../calcite/jdbc/CalciteJdbc41Factory.java | 59 +-
.../apache/calcite/jdbc/CalciteMetaImpl.java | 7 +-
.../calcite/jdbc/CalciteRemoteDriverTest.java | 2 +-
23 files changed, 1239 insertions(+), 882 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
index 72274ff..2beeadf 100644
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
+++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
@@ -20,7 +20,8 @@ import org.apache.calcite.avatica.AvaticaParameter;
import org.apache.calcite.avatica.ColumnMetaData;
import org.apache.calcite.avatica.ConnectionPropertiesImpl;
import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.util.ByteString;
+import org.apache.calcite.avatica.SqlType;
+import org.apache.calcite.avatica.remote.TypedValue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -30,9 +31,6 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
-import java.lang.reflect.Array;
-import java.lang.reflect.Type;
-import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
@@ -41,12 +39,10 @@ import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
-import java.sql.Types;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.UUID;
@@ -54,43 +50,12 @@ import java.util.concurrent.TimeUnit;
/** Implementation of {@link Meta} upon an existing JDBC data source. */
public class JdbcMeta implements Meta {
-
private static final Log LOG = LogFactory.getLog(JdbcMeta.class);
- /**
- * JDBC Types Mapped to Java Types
- *
- * @see <a href="https://docs.oracle.com/javase/1.5.0/docs/guide/jdbc/getstart/mapping.html#1051555">JDBC Types Mapped to Java Types</a>
- */
- protected static final Map<Integer, Type> SQL_TYPE_TO_JAVA_TYPE =
- new HashMap<>();
- static {
- SQL_TYPE_TO_JAVA_TYPE.put(Types.CHAR, String.class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.VARCHAR, String.class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.LONGNVARCHAR, String.class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.NUMERIC, BigDecimal.class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.DECIMAL, BigDecimal.class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.BIT, Boolean.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.TINYINT, Byte.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.SMALLINT, Short.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.INTEGER, Integer.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.BIGINT, Long.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.REAL, Float.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.FLOAT, Double.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.DOUBLE, Double.TYPE);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.BINARY, byte[].class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.VARBINARY, byte[].class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.LONGVARBINARY, byte[].class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.DATE, java.sql.Date.class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.TIME, java.sql.Time.class);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.TIMESTAMP, java.sql.Timestamp.class);
- //put(Types.CLOB, Clob);
- //put(Types.BLOB, Blob);
- SQL_TYPE_TO_JAVA_TYPE.put(Types.ARRAY, Array.class);
- }
-
private static final String CONN_CACHE_KEY_BASE = "avatica.connectioncache";
+ final Calendar calendar = Calendar.getInstance();
+
/** Configurable connection cache settings. */
public enum ConnectionCacheSettings {
/** JDBC connection property for setting connection cache concurrency level. */
@@ -190,20 +155,8 @@ public class JdbcMeta implements Meta {
}
final List<ColumnMetaData> columns = new ArrayList<>();
for (int i = 1; i <= metaData.getColumnCount(); i++) {
- final Type javaType =
- SQL_TYPE_TO_JAVA_TYPE.get(metaData.getColumnType(i));
- final ColumnMetaData.Rep rep;
- switch (metaData.getColumnType(i)) {
- case Types.DATE:
- case Types.TIME:
- rep = ColumnMetaData.Rep.INTEGER;
- break;
- case Types.TIMESTAMP:
- rep = ColumnMetaData.Rep.LONG;
- break;
- default:
- rep = ColumnMetaData.Rep.of(javaType);
- }
+ final SqlType sqlType = SqlType.valueOf(metaData.getColumnType(i));
+ final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(sqlType.internal);
ColumnMetaData.AvaticaType t =
ColumnMetaData.scalar(metaData.getColumnType(i),
metaData.getColumnTypeName(i), rep);
@@ -624,7 +577,7 @@ public class JdbcMeta implements Meta {
}
public Iterable<Object> createIterable(StatementHandle handle,
- Signature signature, List<Object> parameterValues, Frame firstFrame) {
+ Signature signature, List<TypedValue> parameterValues, Frame firstFrame) {
return null;
}
@@ -788,7 +741,7 @@ public class JdbcMeta implements Meta {
}
}
- public Frame fetch(StatementHandle h, List<Object> parameterValues,
+ public Frame fetch(StatementHandle h, List<TypedValue> parameterValues,
int offset, int fetchMaxRowCount) {
if (LOG.isTraceEnabled()) {
LOG.trace("fetching " + h + " offset:" + offset + " fetchMaxRowCount:" + fetchMaxRowCount);
@@ -805,11 +758,8 @@ public class JdbcMeta implements Meta {
(PreparedStatement) statementInfo.statement;
if (parameterValues != null) {
for (int i = 0; i < parameterValues.size(); i++) {
- Object o = parameterValues.get(i);
- if (o instanceof ByteString) {
- o = ((ByteString) o).getBytes();
- }
- preparedStatement.setObject(i + 1, o);
+ TypedValue o = parameterValues.get(i);
+ preparedStatement.setObject(i + 1, o.toJdbc(calendar));
}
}
if (preparedStatement.execute()) {
@@ -819,7 +769,8 @@ public class JdbcMeta implements Meta {
if (statementInfo.resultSet == null) {
return Frame.EMPTY;
} else {
- return JdbcResultSet.frame(statementInfo.resultSet, offset, fetchMaxRowCount);
+ return JdbcResultSet.frame(statementInfo.resultSet, offset,
+ fetchMaxRowCount, calendar);
}
} catch (SQLException e) {
throw propagate(e);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
index bcc2745..b1a67ac 100644
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
+++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
@@ -27,6 +27,7 @@ import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.List;
/** Implementation of {@link org.apache.calcite.avatica.Meta.MetaResultSet}
@@ -44,7 +45,8 @@ class JdbcResultSet extends Meta.MetaResultSet {
ResultSet resultSet) {
try {
Meta.Signature sig = JdbcMeta.signature(resultSet.getMetaData());
- final Meta.Frame firstFrame = frame(resultSet, 0, -1);
+ final Calendar calendar = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
+ final Meta.Frame firstFrame = frame(resultSet, 0, -1, calendar);
resultSet.close();
return new JdbcResultSet(connectionId, statementId, true, sig,
firstFrame);
@@ -56,7 +58,7 @@ class JdbcResultSet extends Meta.MetaResultSet {
/** Creates a frame containing a given number or unlimited number of rows
* from a result set. */
static Meta.Frame frame(ResultSet resultSet, int offset,
- int fetchMaxRowCount) throws SQLException {
+ int fetchMaxRowCount, Calendar calendar) throws SQLException {
final ResultSetMetaData metaData = resultSet.getMetaData();
final int columnCount = metaData.getColumnCount();
final int[] types = new int[columnCount];
@@ -72,15 +74,15 @@ class JdbcResultSet extends Meta.MetaResultSet {
}
Object[] columns = new Object[columnCount];
for (int j = 0; j < columnCount; j++) {
- columns[j] = getValue(resultSet, types[j], j);
+ columns[j] = getValue(resultSet, types[j], j, calendar);
}
rows.add(columns);
}
return new Meta.Frame(offset, done, rows);
}
- private static Object getValue(ResultSet resultSet, int type, int j)
- throws SQLException {
+ private static Object getValue(ResultSet resultSet, int type, int j,
+ Calendar calendar) throws SQLException {
switch (type) {
case Types.BIGINT:
final long aLong = resultSet.getLong(j + 1);
@@ -102,17 +104,17 @@ class JdbcResultSet extends Meta.MetaResultSet {
final float aFloat = resultSet.getFloat(j + 1);
return aFloat == 0D && resultSet.wasNull() ? null : aFloat;
case Types.DATE:
- final Date aDate = resultSet.getDate(j + 1);
+ final Date aDate = resultSet.getDate(j + 1, calendar);
return aDate == null
? null
: (int) (aDate.getTime() / DateTimeUtils.MILLIS_PER_DAY);
case Types.TIME:
- final Time aTime = resultSet.getTime(j + 1);
+ final Time aTime = resultSet.getTime(j + 1, calendar);
return aTime == null
? null
: (int) (aTime.getTime() % DateTimeUtils.MILLIS_PER_DAY);
case Types.TIMESTAMP:
- final Timestamp aTimestamp = resultSet.getTimestamp(j + 1);
+ final Timestamp aTimestamp = resultSet.getTimestamp(j + 1, calendar);
return aTimestamp == null ? null : aTimestamp.getTime();
default:
return resultSet.getObject(j + 1);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
index b2aa2b9..204f0fa 100644
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
+++ b/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
@@ -40,6 +40,7 @@ import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
+import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Map;
@@ -352,27 +353,108 @@ public class RemoteDriverTest {
Statement s2 = underTest.createStatement()) {
assertTrue(s1.execute(query));
assertTrue(s2.execute(query));
- try (ResultSet rs1 = s1.getResultSet();
- ResultSet rs2 = s2.getResultSet()) {
- assertEquals(rs1.getMetaData().getColumnCount(), rs2.getMetaData().getColumnCount());
- int colCount = rs1.getMetaData().getColumnCount();
- while (rs1.next() && rs2.next()) {
- for (int i = 0; i < colCount; i++) {
- Object o1 = rs1.getObject(i + 1);
- Object o2 = rs2.getObject(i + 1);
- if (o1 instanceof Integer && o2 instanceof Short) {
- // Hsqldb returns Integer for short columns; we prefer Short
- o1 = ((Number) o1).shortValue();
- }
- if (o1 instanceof Integer && o2 instanceof Byte) {
- // Hsqldb returns Integer for tinyint columns; we prefer Byte
- o1 = ((Number) o1).byteValue();
- }
- assertEquals(o1, o2);
+ assertResultSetsEqual(s1, s2);
+ }
+ }
+
+ private void assertResultSetsEqual(Statement s1, Statement s2)
+ throws SQLException {
+ final TimeZone moscowTz = TimeZone.getTimeZone("Europe/Moscow");
+ final Calendar moscowCalendar = Calendar.getInstance(moscowTz);
+ final TimeZone alaskaTz = TimeZone.getTimeZone("America/Anchorage");
+ final Calendar alaskaCalendar = Calendar.getInstance(alaskaTz);
+ try (ResultSet rs1 = s1.getResultSet();
+ ResultSet rs2 = s2.getResultSet()) {
+ assertEquals(rs1.getMetaData().getColumnCount(),
+ rs2.getMetaData().getColumnCount());
+ int colCount = rs1.getMetaData().getColumnCount();
+ while (rs1.next() && rs2.next()) {
+ for (int i = 0; i < colCount; i++) {
+ Object o1 = rs1.getObject(i + 1);
+ Object o2 = rs2.getObject(i + 1);
+ if (o1 instanceof Integer && o2 instanceof Short) {
+ // Hsqldb returns Integer for short columns; we prefer Short
+ o1 = ((Number) o1).shortValue();
}
+ if (o1 instanceof Integer && o2 instanceof Byte) {
+ // Hsqldb returns Integer for tinyint columns; we prefer Byte
+ o1 = ((Number) o1).byteValue();
+ }
+ if (o1 instanceof Date) {
+ Date d1 = rs1.getDate(i + 1, moscowCalendar);
+ Date d2 = rs2.getDate(i + 1, moscowCalendar);
+ assertEquals(d1, d2);
+ d1 = rs1.getDate(i + 1, alaskaCalendar);
+ d2 = rs2.getDate(i + 1, alaskaCalendar);
+ assertEquals(d1, d2);
+ d1 = rs1.getDate(i + 1, null);
+ d2 = rs2.getDate(i + 1, null);
+ assertEquals(d1, d2);
+ d1 = rs1.getDate(i + 1);
+ d2 = rs2.getDate(i + 1);
+ assertEquals(d1, d2);
+ }
+ if (o1 instanceof Timestamp) {
+ Timestamp d1 = rs1.getTimestamp(i + 1, moscowCalendar);
+ Timestamp d2 = rs2.getTimestamp(i + 1, moscowCalendar);
+ assertEquals(d1, d2);
+ d1 = rs1.getTimestamp(i + 1, alaskaCalendar);
+ d2 = rs2.getTimestamp(i + 1, alaskaCalendar);
+ assertEquals(d1, d2);
+ d1 = rs1.getTimestamp(i + 1, null);
+ d2 = rs2.getTimestamp(i + 1, null);
+ assertEquals(d1, d2);
+ d1 = rs1.getTimestamp(i + 1);
+ d2 = rs2.getTimestamp(i + 1);
+ assertEquals(d1, d2);
+ }
+ assertEquals(o1, o2);
}
- assertEquals(rs1.next(), rs2.next());
}
+ assertEquals(rs1.next(), rs2.next());
+ }
+ }
+
+ /** Callback to set parameters on each prepared statement before
+ * each is executed and the result sets compared. */
+ interface PreparedStatementFunction {
+ void apply(PreparedStatement s1, PreparedStatement s2)
+ throws SQLException;
+ }
+
+ @Test public void testSetParameter() throws Exception {
+ checkSetParameter("select ? from (values 1)",
+ new PreparedStatementFunction() {
+ public void apply(PreparedStatement s1, PreparedStatement s2)
+ throws SQLException {
+ final Date d = new Date(1234567890);
+ s1.setDate(1, d);
+ s2.setDate(1, d);
+ }
+ });
+ checkSetParameter("select ? from (values 1)",
+ new PreparedStatementFunction() {
+ public void apply(PreparedStatement s1, PreparedStatement s2)
+ throws SQLException {
+ final Timestamp ts = new Timestamp(123456789012L);
+ s1.setTimestamp(1, ts);
+ s2.setTimestamp(1, ts);
+ }
+ });
+ }
+
+ void checkSetParameter(String query, PreparedStatementFunction fn)
+ throws SQLException {
+ try (Connection cannon =
+ DriverManager.getConnection(CONNECTION_SPEC.url,
+ CONNECTION_SPEC.username, CONNECTION_SPEC.password);
+ Connection underTest = ljs();
+ PreparedStatement s1 = cannon.prepareStatement(query);
+ PreparedStatement s2 = underTest.prepareStatement(query)) {
+ fn.apply(s1, s2);
+ assertTrue(s1.execute());
+ assertTrue(s2.execute());
+ assertResultSetsEqual(s1, s2);
}
}
@@ -497,46 +579,75 @@ public class RemoteDriverTest {
}
@Test public void testPrepareBindExecuteFetchDate() throws Exception {
- final Connection connection = ljs();
- final String sql = "select ? + interval '2' day as c from (values (1, 'a'))";
- final PreparedStatement ps =
- connection.prepareStatement(sql);
- final ParameterMetaData parameterMetaData = ps.getParameterMetaData();
- assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+ checkPrepareBindExecuteFetchDate(ljs());
+ }
+
+ @Test public void testPrepareBindExecuteFetchDate2() throws Exception {
+ try (Connection cannon =
+ DriverManager.getConnection(CONNECTION_SPEC.url,
+ CONNECTION_SPEC.username, CONNECTION_SPEC.password)) {
+ checkPrepareBindExecuteFetchDate(cannon);
+ }
+ }
+
+ private void checkPrepareBindExecuteFetchDate(Connection connection) throws Exception {
+ final String sql0 =
+ "select cast(? as varchar(20)) as c\n"
+ + "from (values (1, 'a'))";
+ final String sql1 = "select ? + interval '2' day as c from (values (1, 'a'))";
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.YEAR, 2015);
- calendar.set(Calendar.MONTH, 4);
- calendar.set(Calendar.DAY_OF_MONTH, 8);
- calendar.set(Calendar.HOUR_OF_DAY, 0);
- calendar.set(Calendar.MINUTE, 0);
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);
- final long time = calendar.getTime().getTime();
+ final Date date = Date.valueOf("2015-04-08");
+ final long time = date.getTime();
+
+ PreparedStatement ps;
+ ParameterMetaData parameterMetaData;
ResultSet resultSet;
- ps.setDate(1, new java.sql.Date(time), calendar);
+ ps = connection.prepareStatement(sql0);
+ parameterMetaData = ps.getParameterMetaData();
+ assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+ ps.setDate(1, date);
+ resultSet = ps.executeQuery();
+ assertThat(resultSet.next(), is(true));
+ assertThat(resultSet.getString(1), is("2015-04-08"));
+
+ ps.setTimestamp(1, new Timestamp(time));
+ resultSet = ps.executeQuery();
+ assertThat(resultSet.next(), is(true));
+ assertThat(resultSet.getString(1), is("2015-04-08 00:00:00.0"));
+
+ ps.setTime(1, new Time(time));
+ resultSet = ps.executeQuery();
+ assertThat(resultSet.next(), is(true));
+ assertThat(resultSet.getString(1), is("00:00:00"));
+ ps.close();
+
+ ps = connection.prepareStatement(sql1);
+ parameterMetaData = ps.getParameterMetaData();
+ assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+
+ ps.setDate(1, date);
resultSet = ps.executeQuery();
assertTrue(resultSet.next());
- assertThat(resultSet.getDate(1, calendar),
+ assertThat(resultSet.getDate(1),
equalTo(new Date(time + TimeUnit.DAYS.toMillis(2))));
- assertThat(resultSet.getTimestamp(1, calendar),
+ assertThat(resultSet.getTimestamp(1),
equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
- ps.setTimestamp(1, new Timestamp(time), calendar);
+ ps.setTimestamp(1, new Timestamp(time));
resultSet = ps.executeQuery();
assertTrue(resultSet.next());
- assertThat(resultSet.getTimestamp(1, calendar),
+ assertThat(resultSet.getTimestamp(1),
equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
- assertThat(resultSet.getTimestamp(1, calendar),
+ assertThat(resultSet.getTimestamp(1),
equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
ps.setObject(1, new java.util.Date(time));
resultSet = ps.executeQuery();
assertTrue(resultSet.next());
- assertThat(resultSet.getDate(1, calendar),
+ assertThat(resultSet.getDate(1),
equalTo(new Date(time + TimeUnit.DAYS.toMillis(2))));
- assertThat(resultSet.getTimestamp(1, calendar),
+ assertThat(resultSet.getTimestamp(1),
equalTo(new Timestamp(time + TimeUnit.DAYS.toMillis(2))));
resultSet.close();
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
index 213b42a..1a6ea44 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
@@ -16,6 +16,8 @@
*/
package org.apache.calcite.avatica;
+import org.apache.calcite.avatica.remote.TypedValue;
+
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
@@ -187,6 +189,7 @@ public abstract class AvaticaConnection implements Connection {
}
public int getTransactionIsolation() throws SQLException {
+ //noinspection MagicConstant
return meta.connectionSync(handle, new ConnectionPropertiesImpl()).getTransactionIsolation();
}
@@ -517,7 +520,7 @@ public abstract class AvaticaConnection implements Connection {
/** A means for anyone who has a trojan to call the protected method
* {@link org.apache.calcite.avatica.AvaticaStatement#getParameterValues()}.
*/
- public List<Object> getParameterValues(AvaticaStatement statement) {
+ public List<TypedValue> getParameterValues(AvaticaStatement statement) {
return statement.getParameterValues();
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
index 6a70a26..b573eab 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaJdbc41Factory.java
@@ -130,117 +130,117 @@ class AvaticaJdbc41Factory implements AvaticaFactory {
public void setRowId(
int parameterIndex,
RowId x) throws SQLException {
- getParameter(parameterIndex).setRowId(slots, parameterIndex, x);
+ getSite(parameterIndex).setRowId(x);
}
public void setNString(
int parameterIndex, String value) throws SQLException {
- getParameter(parameterIndex).setNString(slots, parameterIndex, value);
+ getSite(parameterIndex).setNString(value);
}
public void setNCharacterStream(
int parameterIndex,
Reader value,
long length) throws SQLException {
- getParameter(parameterIndex)
- .setNCharacterStream(slots, parameterIndex, value, length);
+ getSite(parameterIndex)
+ .setNCharacterStream(value, length);
}
public void setNClob(
int parameterIndex,
NClob value) throws SQLException {
- getParameter(parameterIndex).setNClob(slots, parameterIndex, value);
+ getSite(parameterIndex).setNClob(value);
}
public void setClob(
int parameterIndex,
Reader reader,
long length) throws SQLException {
- getParameter(parameterIndex)
- .setClob(slots, parameterIndex, reader, length);
+ getSite(parameterIndex)
+ .setClob(reader, length);
}
public void setBlob(
int parameterIndex,
InputStream inputStream,
long length) throws SQLException {
- getParameter(parameterIndex)
- .setBlob(slots, parameterIndex, inputStream, length);
+ getSite(parameterIndex)
+ .setBlob(inputStream, length);
}
public void setNClob(
int parameterIndex,
Reader reader,
long length) throws SQLException {
- getParameter(parameterIndex)
- .setNClob(slots, parameterIndex, reader, length);
+ getSite(parameterIndex)
+ .setNClob(reader, length);
}
public void setSQLXML(
int parameterIndex, SQLXML xmlObject) throws SQLException {
- getParameter(parameterIndex).setSQLXML(slots, parameterIndex, xmlObject);
+ getSite(parameterIndex).setSQLXML(xmlObject);
}
public void setAsciiStream(
int parameterIndex,
InputStream x,
long length) throws SQLException {
- getParameter(parameterIndex)
- .setAsciiStream(slots, parameterIndex, x, length);
+ getSite(parameterIndex)
+ .setAsciiStream(x, length);
}
public void setBinaryStream(
int parameterIndex,
InputStream x,
long length) throws SQLException {
- getParameter(parameterIndex)
- .setBinaryStream(slots, parameterIndex, x, length);
+ getSite(parameterIndex)
+ .setBinaryStream(x, length);
}
public void setCharacterStream(
int parameterIndex,
Reader reader,
long length) throws SQLException {
- getParameter(parameterIndex)
- .setCharacterStream(slots, parameterIndex, reader, length);
+ getSite(parameterIndex)
+ .setCharacterStream(reader, length);
}
public void setAsciiStream(
int parameterIndex, InputStream x) throws SQLException {
- getParameter(parameterIndex).setAsciiStream(slots, parameterIndex, x);
+ getSite(parameterIndex).setAsciiStream(x);
}
public void setBinaryStream(
int parameterIndex, InputStream x) throws SQLException {
- getParameter(parameterIndex).setBinaryStream(slots, parameterIndex, x);
+ getSite(parameterIndex).setBinaryStream(x);
}
public void setCharacterStream(
int parameterIndex, Reader reader) throws SQLException {
- getParameter(parameterIndex)
- .setCharacterStream(slots, parameterIndex, reader);
+ getSite(parameterIndex)
+ .setCharacterStream(reader);
}
public void setNCharacterStream(
int parameterIndex, Reader value) throws SQLException {
- getParameter(parameterIndex)
- .setNCharacterStream(slots, parameterIndex, value);
+ getSite(parameterIndex)
+ .setNCharacterStream(value);
}
public void setClob(
int parameterIndex,
Reader reader) throws SQLException {
- getParameter(parameterIndex).setClob(slots, parameterIndex, reader);
+ getSite(parameterIndex).setClob(reader);
}
public void setBlob(
int parameterIndex, InputStream inputStream) throws SQLException {
- getParameter(parameterIndex).setBlob(slots, parameterIndex, inputStream);
+ getSite(parameterIndex).setBlob(inputStream);
}
public void setNClob(
int parameterIndex, Reader reader) throws SQLException {
- getParameter(parameterIndex).setNClob(slots, parameterIndex, reader);
+ getSite(parameterIndex).setNClob(reader);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
index 8ec961d..ac011ed 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaParameter.java
@@ -16,31 +16,9 @@
*/
package org.apache.calcite.avatica;
-import org.apache.calcite.avatica.util.ByteString;
-import org.apache.calcite.avatica.util.Cursor;
-
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.Calendar;
-
/**
* Metadata for a parameter.
*/
@@ -53,10 +31,6 @@ public class AvaticaParameter {
public final String className;
public final String name;
- /** Value that means the parameter has been set to null.
- * If value is null, parameter has not been set. */
- public static final Object DUMMY_VALUE = Dummy.INSTANCE;
-
@JsonCreator
public AvaticaParameter(
@JsonProperty("signed") boolean signed,
@@ -75,536 +49,6 @@ public class AvaticaParameter {
this.name = name;
}
- public void setByte(Object[] slots, int index, byte o) {
- slots[index] = o;
- }
-
- public void setChar(Object[] slots, int index, char o) {
- slots[index] = o;
- }
-
- public void setShort(Object[] slots, int index, short o) {
- slots[index] = o;
- }
-
- public void setInt(Object[] slots, int index, int o) {
- slots[index] = o;
- }
-
- public void setLong(Object[] slots, int index, long o) {
- slots[index] = o;
- }
-
- public void setBoolean(Object[] slots, int index, boolean o) {
- slots[index] = o;
- }
-
- private static Object wrap(Object o) {
- if (o == null) {
- return DUMMY_VALUE;
- }
- return o;
- }
-
- public boolean isSet(Object[] slots, int index) {
- return slots[index] != null;
- }
-
- public void setRowId(Object[] slots, int index, RowId x) {
- slots[index] = wrap(x);
- }
-
- public void setNString(Object[] slots, int index, String o) {
- slots[index] = wrap(o);
- }
-
- public void setNCharacterStream(Object[] slots, int index, Reader value,
- long length) {
- }
-
- public void setNClob(Object[] slots, int index, NClob value) {
- slots[index] = wrap(value);
- }
-
- public void setClob(Object[] slots, int index, Reader reader, long length) {
- }
-
- public void setBlob(Object[] slots, int index, InputStream inputStream,
- long length) {
- }
-
- public void setNClob(Object[] slots, int index, Reader reader, long length) {
- }
-
- public void setSQLXML(Object[] slots, int index, SQLXML xmlObject) {
- slots[index] = wrap(xmlObject);
- }
-
- public void setAsciiStream(Object[] slots, int index, InputStream x,
- long length) {
- }
-
- public void setBinaryStream(Object[] slots, int index, InputStream x,
- long length) {
- }
-
- public void setCharacterStream(Object[] slots, int index, Reader reader,
- long length) {
- }
-
- public void setAsciiStream(Object[] slots, int index, InputStream x) {
- }
-
- public void setBinaryStream(Object[] slots, int index, InputStream x) {
- }
-
- public void setCharacterStream(Object[] slots, int index, Reader reader) {
- }
-
- public void setNCharacterStream(Object[] slots, int index, Reader value) {
- }
-
- public void setClob(Object[] slots, int index, Reader reader) {
- }
-
- public void setBlob(Object[] slots, int index, InputStream inputStream) {
- }
-
- public void setNClob(Object[] slots, int index, Reader reader) {
- }
-
- public void setUnicodeStream(Object[] slots, int index, InputStream x,
- int length) {
- }
-
- public void setTimestamp(Object[] slots, int index, Timestamp x) {
- slots[index] = wrap(x);
- }
-
- public void setTime(Object[] slots, int index, Time x) {
- slots[index] = wrap(x);
- }
-
- public void setFloat(Object[] slots, int index, float x) {
- slots[index] = wrap(x);
- }
-
- public void setDouble(Object[] slots, int index, double x) {
- slots[index] = wrap(x);
- }
-
- public void setBigDecimal(Object[] slots, int index, BigDecimal x) {
- slots[index] = wrap(x);
- }
-
- public void setString(Object[] slots, int index, String x) {
- slots[index] = wrap(x);
- }
-
- public void setBytes(Object[] slots, int index, byte[] x) {
- slots[index] = x == null ? DUMMY_VALUE : new ByteString(x);
- }
-
- public void setDate(Object[] slots, int index, Date x, Calendar cal) {
- setDate(slots, index, x); // TODO: use calendar
- }
-
- public void setDate(Object[] slots, int index, Date x) {
- slots[index] = wrap(x);
- }
-
- public void setObject(Object[] slots, int index, Object x,
- int targetSqlType) {
- if (x == null || Types.NULL == targetSqlType) {
- setNull(slots, index, targetSqlType);
- return;
- }
- switch (targetSqlType) {
- case Types.CLOB:
- case Types.DATALINK:
- case Types.NCLOB:
- case Types.OTHER:
- case Types.REF:
- case Types.SQLXML:
- case Types.STRUCT:
- throw notImplemented();
- case Types.ARRAY:
- setArray(slots, index, toArray(x));
- break;
- case Types.BIGINT:
- setLong(slots, index, toLong(x));
- break;
- case Types.BINARY:
- case Types.LONGVARBINARY:
- case Types.VARBINARY:
- setBytes(slots, index, toBytes(x));
- break;
- case Types.BIT:
- case Types.BOOLEAN:
- setBoolean(slots, index, toBoolean(x));
- break;
- case Types.BLOB:
- if (x instanceof Blob) {
- setBlob(slots, index, (Blob) x);
- break;
- } else if (x instanceof InputStream) {
- setBlob(slots, index, (InputStream) x);
- }
- throw unsupportedCast(x.getClass(), Blob.class);
- case Types.DATE:
- setDate(slots, index, toDate(x));
- break;
- case Types.DECIMAL:
- case Types.NUMERIC:
- setBigDecimal(slots, index, toBigDecimal(x));
- break;
- case Types.DISTINCT:
- throw notImplemented();
- case Types.DOUBLE:
- case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
- setDouble(slots, index, toDouble(x));
- break;
- case Types.INTEGER:
- setInt(slots, index, toInt(x));
- break;
- case Types.JAVA_OBJECT:
- setObject(slots, index, x);
- break;
- case Types.LONGNVARCHAR:
- case Types.LONGVARCHAR:
- case Types.NVARCHAR:
- case Types.VARCHAR:
- case Types.CHAR:
- case Types.NCHAR:
- setString(slots, index, toString(x));
- break;
- case Types.REAL:
- setFloat(slots, index, toFloat(x));
- break;
- case Types.ROWID:
- if (x instanceof RowId) {
- setRowId(slots, index, (RowId) x);
- break;
- }
- throw unsupportedCast(x.getClass(), RowId.class);
- case Types.SMALLINT:
- setShort(slots, index, toShort(x));
- break;
- case Types.TIME:
- setTime(slots, index, toTime(x));
- break;
- case Types.TIMESTAMP:
- setTimestamp(slots, index, toTimestamp(x));
- break;
- case Types.TINYINT:
- setByte(slots, index, toByte(x));
- break;
- default:
- throw notImplemented();
- }
- }
-
- /** Similar logic to {@link #setObject}. */
- public static Object get(Cursor.Accessor accessor, int targetSqlType,
- Calendar localCalendar) throws SQLException {
- switch (targetSqlType) {
- case Types.CLOB:
- case Types.DATALINK:
- case Types.NCLOB:
- case Types.REF:
- case Types.SQLXML:
- case Types.STRUCT:
- throw notImplemented();
- case Types.ARRAY:
- return accessor.getArray();
- case Types.BIGINT:
- final long aLong = accessor.getLong();
- if (aLong == 0 && accessor.wasNull()) {
- return null;
- }
- return aLong;
- case Types.BINARY:
- case Types.LONGVARBINARY:
- case Types.VARBINARY:
- return accessor.getBytes();
- case Types.BIT:
- case Types.BOOLEAN:
- final boolean aBoolean = accessor.getBoolean();
- if (!aBoolean && accessor.wasNull()) {
- return null;
- }
- return aBoolean;
- case Types.BLOB:
- return accessor.getBlob();
- case Types.DATE:
- return accessor.getDate(localCalendar);
- case Types.DECIMAL:
- case Types.NUMERIC:
- return accessor.getBigDecimal();
- case Types.DISTINCT:
- throw notImplemented();
- case Types.DOUBLE:
- case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
- final double aDouble = accessor.getDouble();
- if (aDouble == 0 && accessor.wasNull()) {
- return null;
- }
- return aDouble;
- case Types.INTEGER:
- final int anInt = accessor.getInt();
- if (anInt == 0 && accessor.wasNull()) {
- return null;
- }
- return anInt;
- case Types.JAVA_OBJECT:
- case Types.OTHER:
- return accessor.getObject();
- case Types.LONGNVARCHAR:
- case Types.LONGVARCHAR:
- case Types.NVARCHAR:
- case Types.VARCHAR:
- case Types.CHAR:
- case Types.NCHAR:
- return accessor.getString();
- case Types.REAL:
- final float aFloat = accessor.getFloat();
- if (aFloat == 0 && accessor.wasNull()) {
- return null;
- }
- return aFloat;
- case Types.ROWID:
- throw notImplemented();
- case Types.SMALLINT:
- final short aShort = accessor.getShort();
- if (aShort == 0 && accessor.wasNull()) {
- return null;
- }
- return aShort;
- case Types.TIME:
- return accessor.getTime(localCalendar);
- case Types.TIMESTAMP:
- return accessor.getTimestamp(localCalendar);
- case Types.TINYINT:
- final byte aByte = accessor.getByte();
- if (aByte == 0 && accessor.wasNull()) {
- return null;
- }
- return aByte;
- default:
- throw notImplemented();
- }
- }
-
- public void setObject(Object[] slots, int index, Object x) {
- slots[index] = wrap(x);
- }
-
- public void setNull(Object[] slots, int index, int sqlType) {
- slots[index] = DUMMY_VALUE;
- }
-
- public void setTime(Object[] slots, int index, Time x, Calendar cal) {
- }
-
- public void setRef(Object[] slots, int index, Ref x) {
- }
-
- public void setBlob(Object[] slots, int index, Blob x) {
- }
-
- public void setClob(Object[] slots, int index, Clob x) {
- }
-
- public void setArray(Object[] slots, int index, Array x) {
- }
-
- public void setTimestamp(Object[] slots, int index, Timestamp x,
- Calendar cal) {
- }
-
- public void setNull(Object[] slots, int index, int sqlType, String typeName) {
- }
-
- public void setURL(Object[] slots, int index, URL x) {
- }
-
- public void setObject(Object[] slots, int index, Object x, int targetSqlType,
- int scaleOrLength) {
- }
-
- private static RuntimeException unsupportedCast(Class<?> from, Class<?> to) {
- return new UnsupportedOperationException("Cannot convert from "
- + from.getCanonicalName() + " to " + to.getCanonicalName());
- }
-
- private static RuntimeException notImplemented() {
- return new RuntimeException("not implemented");
- }
-
- private static Array toArray(Object x) {
- if (x instanceof Array) {
- return (Array) x;
- }
- throw unsupportedCast(x.getClass(), Array.class);
- }
-
- public static BigDecimal toBigDecimal(Object x) {
- if (x instanceof BigDecimal) {
- return (BigDecimal) x;
- } else if (x instanceof BigInteger) {
- return new BigDecimal((BigInteger) x);
- } else if (x instanceof Number) {
- if (x instanceof Double || x instanceof Float) {
- return new BigDecimal(((Number) x).doubleValue());
- } else {
- return new BigDecimal(((Number) x).longValue());
- }
- } else if (x instanceof Boolean) {
- return (Boolean) x ? BigDecimal.ONE : BigDecimal.ZERO;
- } else if (x instanceof String) {
- return new BigDecimal((String) x);
- }
- throw unsupportedCast(x.getClass(), BigDecimal.class);
- }
-
- private static boolean toBoolean(Object x) {
- if (x instanceof Boolean) {
- return (Boolean) x;
- } else if (x instanceof Number) {
- return ((Number) x).intValue() != 0;
- } else if (x instanceof String) {
- String s = (String) x;
- if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) {
- return true;
- } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) {
- return false;
- }
- }
- throw unsupportedCast(x.getClass(), Boolean.TYPE);
- }
-
- private static byte toByte(Object x) {
- if (x instanceof Number) {
- return ((Number) x).byteValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? (byte) 1 : (byte) 0;
- } else if (x instanceof String) {
- return Byte.parseByte((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Byte.TYPE);
- }
- }
-
- private static byte[] toBytes(Object x) {
- if (x instanceof byte[]) {
- return (byte[]) x;
- }
- if (x instanceof String) {
- return ((String) x).getBytes();
- }
- throw unsupportedCast(x.getClass(), byte[].class);
- }
-
- private static Date toDate(Object x) {
- if (x instanceof String) {
- return Date.valueOf((String) x);
- }
- return new Date(toLong(x));
- }
-
- private static Time toTime(Object x) {
- if (x instanceof String) {
- return Time.valueOf((String) x);
- }
- return new Time(toLong(x));
- }
-
- private static Timestamp toTimestamp(Object x) {
- if (x instanceof String) {
- return Timestamp.valueOf((String) x);
- }
- return new Timestamp(toLong(x));
- }
-
- private static double toDouble(Object x) {
- if (x instanceof Number) {
- return ((Number) x).doubleValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1D : 0D;
- } else if (x instanceof String) {
- return Double.parseDouble((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Double.TYPE);
- }
- }
-
- private static float toFloat(Object x) {
- if (x instanceof Number) {
- return ((Number) x).floatValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1F : 0F;
- } else if (x instanceof String) {
- return Float.parseFloat((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Float.TYPE);
- }
- }
-
- private static int toInt(Object x) {
- if (x instanceof Number) {
- return ((Number) x).intValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1 : 0;
- } else if (x instanceof String) {
- return Integer.parseInt((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Integer.TYPE);
- }
- }
-
- private static long toLong(Object x) {
- if (x instanceof Number) {
- return ((Number) x).longValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1L : 0L;
- } else if (x instanceof String) {
- return Long.parseLong((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Long.TYPE);
- }
- }
-
- private static short toShort(Object x) {
- if (x instanceof Number) {
- return ((Number) x).shortValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? (short) 1 : (short) 0;
- } else if (x instanceof String) {
- return Short.parseShort((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Short.TYPE);
- }
- }
-
- private static String toString(Object x) {
- if (x instanceof String) {
- return (String) x;
- } else if (x instanceof Character
- || x instanceof Boolean) {
- return x.toString();
- }
- throw unsupportedCast(x.getClass(), String.class);
- }
-
- /** Singleton value to denote parameters that have been set to null (as
- * opposed to not set).
- *
- * <p>Not a valid value for a parameter.
- *
- * <p>As an enum, it is serializable by Jackson. */
- private enum Dummy {
- INSTANCE
- }
}
// End AvaticaParameter.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
index 51606c9..4656af8 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
@@ -16,6 +16,8 @@
*/
package org.apache.calcite.avatica;
+import org.apache.calcite.avatica.remote.TypedValue;
+
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
@@ -48,7 +50,8 @@ public abstract class AvaticaPreparedStatement
implements PreparedStatement, ParameterMetaData {
private final Meta.Signature signature;
private final ResultSetMetaData resultSetMetaData;
- protected final Object[] slots;
+ private Calendar calendar;
+ protected final TypedValue[] slots;
/**
* Creates an AvaticaPreparedStatement.
@@ -70,15 +73,27 @@ public abstract class AvaticaPreparedStatement
super(connection, h, resultSetType, resultSetConcurrency,
resultSetHoldability);
this.signature = signature;
- this.slots = new Object[signature.parameters.size()];
+ this.slots = new TypedValue[signature.parameters.size()];
this.resultSetMetaData =
connection.factory.newResultSetMetaData(this, signature);
}
- @Override protected List<Object> getParameterValues() {
+ @Override protected List<TypedValue> getParameterValues() {
return Arrays.asList(slots);
}
+ /** Returns a calendar in the connection's time zone, creating one the first
+ * time this method is called.
+ *
+ * <p>Uses the calendar to offset date-time values when calling methods such
+ * as {@link #setDate(int, Date)}. */
+ protected synchronized Calendar getCalendar() {
+ if (calendar == null) {
+ calendar = Calendar.getInstance(connection.getTimeZone());
+ }
+ return calendar;
+ }
+
// implement PreparedStatement
public ResultSet executeQuery() throws SQLException {
@@ -95,79 +110,66 @@ public abstract class AvaticaPreparedStatement
}
public void setNull(int parameterIndex, int sqlType) throws SQLException {
- getParameter(parameterIndex).setNull(slots, parameterIndex - 1, sqlType);
+ getSite(parameterIndex).setNull(sqlType);
}
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
- getParameter(parameterIndex).setBoolean(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setBoolean(x);
}
public void setByte(int parameterIndex, byte x) throws SQLException {
- getParameter(parameterIndex).setByte(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setByte(x);
}
public void setShort(int parameterIndex, short x) throws SQLException {
- getParameter(parameterIndex).setShort(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setShort(x);
}
public void setInt(int parameterIndex, int x) throws SQLException {
- getParameter(parameterIndex).setInt(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setInt(x);
}
public void setLong(int parameterIndex, long x) throws SQLException {
- getParameter(parameterIndex).setLong(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setLong(x);
}
public void setFloat(int parameterIndex, float x) throws SQLException {
- getParameter(parameterIndex).setFloat(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setFloat(x);
}
public void setDouble(int parameterIndex, double x) throws SQLException {
- getParameter(parameterIndex).setDouble(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setDouble(x);
}
public void setBigDecimal(int parameterIndex, BigDecimal x)
throws SQLException {
- getParameter(parameterIndex).setBigDecimal(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setBigDecimal(x);
}
public void setString(int parameterIndex, String x) throws SQLException {
- getParameter(parameterIndex).setString(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setString(x);
}
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
- getParameter(parameterIndex).setBytes(slots, parameterIndex - 1, x);
- }
-
- public void setDate(int parameterIndex, Date x) throws SQLException {
- getParameter(parameterIndex).setDate(slots, parameterIndex - 1, x);
- }
-
- public void setTime(int parameterIndex, Time x) throws SQLException {
- getParameter(parameterIndex).setTime(slots, parameterIndex - 1, x);
- }
-
- public void setTimestamp(int parameterIndex, Timestamp x)
- throws SQLException {
- getParameter(parameterIndex).setTimestamp(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setBytes(x);
}
public void setAsciiStream(int parameterIndex, InputStream x, int length)
throws SQLException {
- getParameter(parameterIndex)
- .setAsciiStream(slots, parameterIndex - 1, x, length);
+ getSite(parameterIndex)
+ .setAsciiStream(x, length);
}
public void setUnicodeStream(int parameterIndex, InputStream x, int length)
throws SQLException {
- getParameter(parameterIndex)
- .setUnicodeStream(slots, parameterIndex - 1, x, length);
+ getSite(parameterIndex)
+ .setUnicodeStream(x, length);
}
public void setBinaryStream(int parameterIndex, InputStream x, int length)
throws SQLException {
- getParameter(parameterIndex)
- .setBinaryStream(slots, parameterIndex - 1, x, length);
+ getSite(parameterIndex)
+ .setBinaryStream(x, length);
}
public void clearParameters() throws SQLException {
@@ -178,12 +180,12 @@ public abstract class AvaticaPreparedStatement
public void setObject(int parameterIndex, Object x, int targetSqlType)
throws SQLException {
- getParameter(parameterIndex)
- .setObject(slots, parameterIndex - 1, x, targetSqlType);
+ getSite(parameterIndex)
+ .setObject(x, targetSqlType, getCalendar());
}
public void setObject(int parameterIndex, Object x) throws SQLException {
- getParameter(parameterIndex).setObject(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setObject(x);
}
public boolean execute() throws SQLException {
@@ -199,60 +201,75 @@ public abstract class AvaticaPreparedStatement
public void setCharacterStream(int parameterIndex, Reader reader, int length)
throws SQLException {
- getParameter(parameterIndex)
- .setCharacterStream(slots, parameterIndex - 1, reader, length);
+ getSite(parameterIndex)
+ .setCharacterStream(reader, length);
}
public void setRef(int parameterIndex, Ref x) throws SQLException {
- getParameter(parameterIndex).setRef(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setRef(x);
}
public void setBlob(int parameterIndex, Blob x) throws SQLException {
- getParameter(parameterIndex).setBlob(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setBlob(x);
}
public void setClob(int parameterIndex, Clob x) throws SQLException {
- getParameter(parameterIndex).setClob(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setClob(x);
}
public void setArray(int parameterIndex, Array x) throws SQLException {
- getParameter(parameterIndex).setArray(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setArray(x);
}
public ResultSetMetaData getMetaData() {
return resultSetMetaData;
}
- public void setDate(int parameterIndex, Date x, Calendar cal)
+ public void setDate(int parameterIndex, Date x, Calendar calendar)
throws SQLException {
- getParameter(parameterIndex).setDate(slots, parameterIndex - 1, x, cal);
+ getSite(parameterIndex)
+ .setDate(x, calendar);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ setDate(parameterIndex, x, getCalendar());
}
- public void setTime(int parameterIndex, Time x, Calendar cal)
+ public void setTime(int parameterIndex, Time x, Calendar calendar)
throws SQLException {
- getParameter(parameterIndex).setTime(slots, parameterIndex - 1, x, cal);
+ getSite(parameterIndex)
+ .setTime(x, calendar);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ setTime(parameterIndex, x, getCalendar());
}
- public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar calendar)
throws SQLException {
- getParameter(parameterIndex)
- .setTimestamp(slots, parameterIndex - 1, x, cal);
+ getSite(parameterIndex)
+ .setTimestamp(x, calendar);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x)
+ throws SQLException {
+ setTimestamp(parameterIndex, x, getCalendar());
}
public void setNull(int parameterIndex, int sqlType, String typeName)
throws SQLException {
- getParameter(parameterIndex)
- .setNull(slots, parameterIndex - 1, sqlType, typeName);
+ getSite(parameterIndex)
+ .setNull(sqlType, typeName);
}
public void setURL(int parameterIndex, URL x) throws SQLException {
- getParameter(parameterIndex).setURL(slots, parameterIndex - 1, x);
+ getSite(parameterIndex).setURL(x);
}
public void setObject(int parameterIndex, Object x, int targetSqlType,
int scaleOrLength) throws SQLException {
- getParameter(parameterIndex)
- .setObject(slots, parameterIndex - 1, x, targetSqlType, scaleOrLength);
+ getSite(parameterIndex)
+ .setObject(x, targetSqlType, scaleOrLength);
}
// implement ParameterMetaData
@@ -268,6 +285,11 @@ public abstract class AvaticaPreparedStatement
}
}
+ protected AvaticaSite getSite(int param) throws SQLException {
+ final AvaticaParameter parameter = getParameter(param);
+ return new AvaticaSite(parameter, calendar, param - 1, slots);
+ }
+
public int getParameterCount() {
return signature.parameters.size();
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
index 6f528b3..f7b7ccd 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.avatica;
+import org.apache.calcite.avatica.remote.TypedValue;
import org.apache.calcite.avatica.util.ArrayImpl;
import org.apache.calcite.avatica.util.Cursor;
@@ -179,7 +180,7 @@ public class AvaticaResultSet implements ResultSet, ArrayImpl.Factory {
* @throws SQLException if execute fails for some reason.
*/
protected AvaticaResultSet execute() throws SQLException {
- final List<Object> parameterValues = statement.getBoundParameterValues();
+ final List<TypedValue> parameterValues = statement.getBoundParameterValues();
final Iterable<Object> iterable1 =
statement.connection.meta.createIterable(statement.handle, signature,
parameterValues, firstFrame);
@@ -377,7 +378,7 @@ public class AvaticaResultSet implements ResultSet, ArrayImpl.Factory {
public Object getObject(int columnIndex) throws SQLException {
final Cursor.Accessor accessor = getAccessor(columnIndex);
final ColumnMetaData metaData = columnMetaDataList.get(columnIndex - 1);
- return AvaticaParameter.get(accessor, metaData.type.id, localCalendar);
+ return AvaticaSite.get(accessor, metaData.type.id, localCalendar);
}
public Object getObject(String columnLabel) throws SQLException {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
new file mode 100644
index 0000000..047a8db
--- /dev/null
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
@@ -0,0 +1,578 @@
+/*
+ * 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.calcite.avatica;
+
+import org.apache.calcite.avatica.remote.TypedValue;
+import org.apache.calcite.avatica.util.Cursor;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+
+/**
+ * A location that a value can be written to or read from.
+ */
+public class AvaticaSite {
+ final AvaticaParameter parameter;
+ final Calendar calendar;
+ private final int index;
+ final TypedValue[] slots;
+
+ /** Value that means the parameter has been set to null.
+ * If value is null, parameter has not been set. */
+ public static final Object DUMMY_VALUE = Dummy.INSTANCE;
+
+ public AvaticaSite(AvaticaParameter parameter, Calendar calendar, int index,
+ TypedValue[] slots) {
+ this.parameter = parameter;
+ this.calendar = calendar;
+ this.index = index;
+ this.slots = slots;
+ }
+
+ private TypedValue wrap(ColumnMetaData.Rep rep, Object o,
+ Calendar calendar) {
+ return TypedValue.ofJdbc(rep, o, calendar);
+ }
+
+ private TypedValue wrap(ColumnMetaData.Rep rep, Object o) {
+ return TypedValue.ofJdbc(rep, o, calendar);
+ }
+
+ public boolean isSet(int index) {
+ return slots[index] != null;
+ }
+
+ public void setByte(byte o) {
+ slots[index] = wrap(ColumnMetaData.Rep.BYTE, o);
+ }
+
+ public void setChar(char o) {
+ slots[index] = wrap(ColumnMetaData.Rep.CHARACTER, o);
+ }
+
+ public void setShort(short o) {
+ slots[index] = wrap(ColumnMetaData.Rep.SHORT, o);
+ }
+
+ public void setInt(int o) {
+ slots[index] = wrap(ColumnMetaData.Rep.INTEGER, o);
+ }
+
+ public void setLong(long o) {
+ slots[index] = wrap(ColumnMetaData.Rep.LONG, o);
+ }
+
+ public void setBoolean(boolean o) {
+ slots[index] = wrap(ColumnMetaData.Rep.BOOLEAN, o);
+ }
+
+ public void setRowId(RowId x) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, x);
+ }
+
+ public void setNString(String o) {
+ slots[index] = wrap(ColumnMetaData.Rep.STRING, o);
+ }
+
+ public void setNCharacterStream(Reader value, long length) {
+ }
+
+ public void setNClob(NClob value) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, value);
+ }
+
+ public void setClob(Reader reader, long length) {
+ }
+
+ public void setBlob(InputStream inputStream, long length) {
+ }
+
+ public void setNClob(Reader reader, long length) {
+ }
+
+ public void setSQLXML(SQLXML xmlObject) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, xmlObject);
+ }
+
+ public void setAsciiStream(InputStream x, long length) {
+ }
+
+ public void setBinaryStream(InputStream x, long length) {
+ }
+
+ public void setCharacterStream(Reader reader, long length) {
+ }
+
+ public void setAsciiStream(InputStream x) {
+ }
+
+ public void setBinaryStream(InputStream x) {
+ }
+
+ public void setCharacterStream(Reader reader) {
+ }
+
+ public void setNCharacterStream(Reader value) {
+ }
+
+ public void setClob(Reader reader) {
+ }
+
+ public void setBlob(InputStream inputStream) {
+ }
+
+ public void setNClob(Reader reader) {
+ }
+
+ public void setUnicodeStream(InputStream x, int length) {
+ }
+
+ public void setFloat(float x) {
+ slots[index] = wrap(ColumnMetaData.Rep.FLOAT, x);
+ }
+
+ public void setDouble(double x) {
+ slots[index] = wrap(ColumnMetaData.Rep.DOUBLE, x);
+ }
+
+ public void setBigDecimal(BigDecimal x) {
+ slots[index] = wrap(ColumnMetaData.Rep.NUMBER, x);
+ }
+
+ public void setString(String x) {
+ slots[index] = wrap(ColumnMetaData.Rep.STRING, x);
+ }
+
+ public void setBytes(byte[] x) {
+ slots[index] = wrap(ColumnMetaData.Rep.BYTE_STRING, x);
+ }
+
+ public void setTimestamp(Timestamp x, Calendar calendar) {
+ slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP, x, calendar);
+ }
+
+ public void setTime(Time x, Calendar calendar) {
+ slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIME, x, calendar);
+ }
+
+ public void setDate(Date x, Calendar cal) {
+ slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_DATE, x, calendar);
+ }
+
+ public void setObject(Object x, int targetSqlType, Calendar calendar) {
+ if (x == null || Types.NULL == targetSqlType) {
+ setNull(targetSqlType);
+ return;
+ }
+ switch (targetSqlType) {
+ case Types.CLOB:
+ case Types.DATALINK:
+ case Types.NCLOB:
+ case Types.OTHER:
+ case Types.REF:
+ case Types.SQLXML:
+ case Types.STRUCT:
+ throw notImplemented();
+ case Types.ARRAY:
+ setArray(toArray(x));
+ break;
+ case Types.BIGINT:
+ setLong(toLong(x));
+ break;
+ case Types.BINARY:
+ case Types.LONGVARBINARY:
+ case Types.VARBINARY:
+ setBytes(toBytes(x));
+ break;
+ case Types.BIT:
+ case Types.BOOLEAN:
+ setBoolean(toBoolean(x));
+ break;
+ case Types.BLOB:
+ if (x instanceof Blob) {
+ setBlob((Blob) x);
+ break;
+ } else if (x instanceof InputStream) {
+ setBlob((InputStream) x);
+ }
+ throw unsupportedCast(x.getClass(), Blob.class);
+ case Types.DATE:
+ setDate(toDate(x), calendar);
+ break;
+ case Types.DECIMAL:
+ case Types.NUMERIC:
+ setBigDecimal(toBigDecimal(x));
+ break;
+ case Types.DISTINCT:
+ throw notImplemented();
+ case Types.DOUBLE:
+ case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
+ setDouble(toDouble(x));
+ break;
+ case Types.INTEGER:
+ setInt(toInt(x));
+ break;
+ case Types.JAVA_OBJECT:
+ setObject(x);
+ break;
+ case Types.LONGNVARCHAR:
+ case Types.LONGVARCHAR:
+ case Types.NVARCHAR:
+ case Types.VARCHAR:
+ case Types.CHAR:
+ case Types.NCHAR:
+ setString(toString(x));
+ break;
+ case Types.REAL:
+ setFloat(toFloat(x));
+ break;
+ case Types.ROWID:
+ if (x instanceof RowId) {
+ setRowId((RowId) x);
+ break;
+ }
+ throw unsupportedCast(x.getClass(), RowId.class);
+ case Types.SMALLINT:
+ setShort(toShort(x));
+ break;
+ case Types.TIME:
+ setTime(toTime(x), calendar);
+ break;
+ case Types.TIMESTAMP:
+ setTimestamp(toTimestamp(x), calendar);
+ break;
+ case Types.TINYINT:
+ setByte(toByte(x));
+ break;
+ default:
+ throw notImplemented();
+ }
+ }
+
+ /** Similar logic to {@link #setObject}. */
+ public static Object get(Cursor.Accessor accessor, int targetSqlType,
+ Calendar localCalendar) throws SQLException {
+ switch (targetSqlType) {
+ case Types.CLOB:
+ case Types.DATALINK:
+ case Types.NCLOB:
+ case Types.REF:
+ case Types.SQLXML:
+ case Types.STRUCT:
+ throw notImplemented();
+ case Types.ARRAY:
+ return accessor.getArray();
+ case Types.BIGINT:
+ final long aLong = accessor.getLong();
+ if (aLong == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aLong;
+ case Types.BINARY:
+ case Types.LONGVARBINARY:
+ case Types.VARBINARY:
+ return accessor.getBytes();
+ case Types.BIT:
+ case Types.BOOLEAN:
+ final boolean aBoolean = accessor.getBoolean();
+ if (!aBoolean && accessor.wasNull()) {
+ return null;
+ }
+ return aBoolean;
+ case Types.BLOB:
+ return accessor.getBlob();
+ case Types.DATE:
+ return accessor.getDate(localCalendar);
+ case Types.DECIMAL:
+ case Types.NUMERIC:
+ return accessor.getBigDecimal();
+ case Types.DISTINCT:
+ throw notImplemented();
+ case Types.DOUBLE:
+ case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
+ final double aDouble = accessor.getDouble();
+ if (aDouble == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aDouble;
+ case Types.INTEGER:
+ final int anInt = accessor.getInt();
+ if (anInt == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return anInt;
+ case Types.JAVA_OBJECT:
+ case Types.OTHER:
+ return accessor.getObject();
+ case Types.LONGNVARCHAR:
+ case Types.LONGVARCHAR:
+ case Types.NVARCHAR:
+ case Types.VARCHAR:
+ case Types.CHAR:
+ case Types.NCHAR:
+ return accessor.getString();
+ case Types.REAL:
+ final float aFloat = accessor.getFloat();
+ if (aFloat == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aFloat;
+ case Types.ROWID:
+ throw notImplemented();
+ case Types.SMALLINT:
+ final short aShort = accessor.getShort();
+ if (aShort == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aShort;
+ case Types.TIME:
+ return accessor.getTime(localCalendar);
+ case Types.TIMESTAMP:
+ return accessor.getTimestamp(localCalendar);
+ case Types.TINYINT:
+ final byte aByte = accessor.getByte();
+ if (aByte == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aByte;
+ default:
+ throw notImplemented();
+ }
+ }
+
+ public void setObject(Object x) {
+ slots[index] = TypedValue.ofJdbc(x, calendar);
+ }
+
+ public void setNull(int sqlType) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, null);
+ }
+
+ public void setRef(Ref x) {
+ }
+
+ public void setBlob(Blob x) {
+ }
+
+ public void setClob(Clob x) {
+ }
+
+ public void setArray(Array x) {
+ }
+
+ public void setNull(int sqlType, String typeName) {
+ }
+
+ public void setURL(URL x) {
+ }
+
+ public void setObject(Object x, int targetSqlType,
+ int scaleOrLength) {
+ }
+
+ private static RuntimeException unsupportedCast(Class<?> from, Class<?> to) {
+ return new UnsupportedOperationException("Cannot convert from "
+ + from.getCanonicalName() + " to " + to.getCanonicalName());
+ }
+
+ private static RuntimeException notImplemented() {
+ return new RuntimeException("not implemented");
+ }
+
+ private static Array toArray(Object x) {
+ if (x instanceof Array) {
+ return (Array) x;
+ }
+ throw unsupportedCast(x.getClass(), Array.class);
+ }
+
+ public static BigDecimal toBigDecimal(Object x) {
+ if (x instanceof BigDecimal) {
+ return (BigDecimal) x;
+ } else if (x instanceof BigInteger) {
+ return new BigDecimal((BigInteger) x);
+ } else if (x instanceof Number) {
+ if (x instanceof Double || x instanceof Float) {
+ return new BigDecimal(((Number) x).doubleValue());
+ } else {
+ return new BigDecimal(((Number) x).longValue());
+ }
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? BigDecimal.ONE : BigDecimal.ZERO;
+ } else if (x instanceof String) {
+ return new BigDecimal((String) x);
+ }
+ throw unsupportedCast(x.getClass(), BigDecimal.class);
+ }
+
+ private static boolean toBoolean(Object x) {
+ if (x instanceof Boolean) {
+ return (Boolean) x;
+ } else if (x instanceof Number) {
+ return ((Number) x).intValue() != 0;
+ } else if (x instanceof String) {
+ String s = (String) x;
+ if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) {
+ return true;
+ } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) {
+ return false;
+ }
+ }
+ throw unsupportedCast(x.getClass(), Boolean.TYPE);
+ }
+
+ private static byte toByte(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).byteValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? (byte) 1 : (byte) 0;
+ } else if (x instanceof String) {
+ return Byte.parseByte((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Byte.TYPE);
+ }
+ }
+
+ private static byte[] toBytes(Object x) {
+ if (x instanceof byte[]) {
+ return (byte[]) x;
+ }
+ if (x instanceof String) {
+ return ((String) x).getBytes();
+ }
+ throw unsupportedCast(x.getClass(), byte[].class);
+ }
+
+ private static Date toDate(Object x) {
+ if (x instanceof String) {
+ return Date.valueOf((String) x);
+ }
+ return new Date(toLong(x));
+ }
+
+ private static Time toTime(Object x) {
+ if (x instanceof String) {
+ return Time.valueOf((String) x);
+ }
+ return new Time(toLong(x));
+ }
+
+ private static Timestamp toTimestamp(Object x) {
+ if (x instanceof String) {
+ return Timestamp.valueOf((String) x);
+ }
+ return new Timestamp(toLong(x));
+ }
+
+ private static double toDouble(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).doubleValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1D : 0D;
+ } else if (x instanceof String) {
+ return Double.parseDouble((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Double.TYPE);
+ }
+ }
+
+ private static float toFloat(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).floatValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1F : 0F;
+ } else if (x instanceof String) {
+ return Float.parseFloat((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Float.TYPE);
+ }
+ }
+
+ private static int toInt(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).intValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1 : 0;
+ } else if (x instanceof String) {
+ return Integer.parseInt((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Integer.TYPE);
+ }
+ }
+
+ private static long toLong(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).longValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1L : 0L;
+ } else if (x instanceof String) {
+ return Long.parseLong((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Long.TYPE);
+ }
+ }
+
+ private static short toShort(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).shortValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? (short) 1 : (short) 0;
+ } else if (x instanceof String) {
+ return Short.parseShort((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Short.TYPE);
+ }
+ }
+
+ private static String toString(Object x) {
+ if (x instanceof String) {
+ return (String) x;
+ } else if (x instanceof Character
+ || x instanceof Boolean) {
+ return x.toString();
+ }
+ throw unsupportedCast(x.getClass(), String.class);
+ }
+
+ /** Singleton value to denote parameters that have been set to null (as
+ * opposed to not set).
+ *
+ * <p>Not a valid value for a parameter.
+ *
+ * <p>As an enum, it is serializable by Jackson. */
+ private enum Dummy {
+ INSTANCE
+ }
+}
+
+// End AvaticaSite.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
index 7049b40..7c6d3c2 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
@@ -16,13 +16,14 @@
*/
package org.apache.calcite.avatica;
+import org.apache.calcite.avatica.remote.TypedValue;
+
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -429,7 +430,7 @@ public abstract class AvaticaStatement
*
* @see org.apache.calcite.avatica.AvaticaConnection.Trojan#getParameterValues(AvaticaStatement)
*/
- protected List<Object> getParameterValues() {
+ protected List<TypedValue> getParameterValues() {
return Collections.emptyList();
}
@@ -438,18 +439,14 @@ public abstract class AvaticaStatement
* <p>If any of the parameters have not been bound, throws.
* If parameters have been bound to null, the value in the list is null.
*/
- protected List<Object> getBoundParameterValues() throws SQLException {
- final List<Object> list = new ArrayList<>();
- for (Object parameterValue : getParameterValues()) {
+ protected List<TypedValue> getBoundParameterValues() throws SQLException {
+ final List<TypedValue> parameterValues = getParameterValues();
+ for (Object parameterValue : parameterValues) {
if (parameterValue == null) {
throw new SQLException("unbound parameter");
}
- if (parameterValue == AvaticaParameter.DUMMY_VALUE) {
- parameterValue = null;
- }
- list.add(parameterValue);
}
- return list;
+ return parameterValues;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java b/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
index 470e34f..e0a50b6 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/ColumnMetaData.java
@@ -246,7 +246,7 @@ public class ColumnMetaData {
}
public String columnClassName() {
- return SqlType.valueOf(id).clazz.getName();
+ return SqlType.valueOf(id).boxedClass().getName();
}
public AvaticaType setRep(Rep rep) {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
index cadcd17..c796d32 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
@@ -16,6 +16,8 @@
*/
package org.apache.calcite.avatica;
+import org.apache.calcite.avatica.remote.TypedValue;
+
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -151,7 +153,7 @@ public interface Meta {
* requires to be not null; derived classes may instead choose to execute the
* relational expression in {@code signature}. */
Iterable<Object> createIterable(StatementHandle handle, Signature signature,
- List<Object> parameterValues, Frame firstFrame);
+ List<TypedValue> parameterValues, Frame firstFrame);
/** Prepares a statement.
*
@@ -191,7 +193,7 @@ public interface Meta {
* no limit
* @return Frame, or null if there are no more
*/
- Frame fetch(StatementHandle h, List<Object> parameterValues, int offset,
+ Frame fetch(StatementHandle h, List<TypedValue> parameterValues, int offset,
int fetchMaxRowCount);
/** Called during the creation of a statement to allocate a new handle.
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
index f8f35a7..4371047 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.avatica;
+import org.apache.calcite.avatica.remote.TypedValue;
import org.apache.calcite.avatica.util.ArrayIteratorCursor;
import org.apache.calcite.avatica.util.Cursor;
import org.apache.calcite.avatica.util.IteratorCursor;
@@ -685,14 +686,14 @@ public abstract class MetaImpl implements Meta {
}
public Iterable<Object> createIterable(StatementHandle handle,
- Signature signature, List<Object> parameterValues, Frame firstFrame) {
+ Signature signature, List<TypedValue> parameterValues, Frame firstFrame) {
if (firstFrame != null && firstFrame.done) {
return firstFrame.rows;
}
return new FetchIterable(handle, firstFrame, parameterValues);
}
- public Frame fetch(StatementHandle h, List<Object> parameterValues,
+ public Frame fetch(StatementHandle h, List<TypedValue> parameterValues,
int offset, int fetchMaxRowCount) {
return null;
}
@@ -760,10 +761,10 @@ public abstract class MetaImpl implements Meta {
private class FetchIterable implements Iterable<Object> {
private final StatementHandle handle;
private final Frame firstFrame;
- private final List<Object> parameterValues;
+ private final List<TypedValue> parameterValues;
public FetchIterable(StatementHandle handle, Frame firstFrame,
- List<Object> parameterValues) {
+ List<TypedValue> parameterValues) {
this.handle = handle;
this.firstFrame = firstFrame;
this.parameterValues = parameterValues;
@@ -779,10 +780,10 @@ public abstract class MetaImpl implements Meta {
private final StatementHandle handle;
private Frame frame;
private Iterator<Object> rows;
- private List<Object> parameterValues;
+ private List<TypedValue> parameterValues;
public FetchIterator(StatementHandle handle, Frame firstFrame,
- List<Object> parameterValues) {
+ List<TypedValue> parameterValues) {
this.handle = handle;
this.parameterValues = parameterValues;
if (firstFrame == null) {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7f8ce197/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java b/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java
index 90e9cba..b224469 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/SqlType.java
@@ -16,6 +16,8 @@
*/
package org.apache.calcite.avatica;
+import org.apache.calcite.avatica.util.ByteString;
+
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
@@ -291,28 +293,29 @@ import java.util.Map;
* -->
*/
public enum SqlType {
- BIT(Types.BIT, Boolean.class),
- BOOLEAN(Types.BOOLEAN, Boolean.class),
- TINYINT(Types.TINYINT, Byte.class),
- SMALLINT(Types.SMALLINT, Short.class),
- INTEGER(Types.INTEGER, Integer.class),
- BIGINT(Types.BIGINT, Long.class),
- NUMERIC(Types.NUMERIC, Object.class),
+ BIT(Types.BIT, boolean.class),
+ BOOLEAN(Types.BOOLEAN, boolean.class),
+ TINYINT(Types.TINYINT, byte.class),
+ SMALLINT(Types.SMALLINT, short.class),
+ INTEGER(Types.INTEGER, int.class),
+ BIGINT(Types.BIGINT, long.class),
+ NUMERIC(Types.NUMERIC, BigDecimal.class),
DECIMAL(Types.DECIMAL, BigDecimal.class),
- FLOAT(Types.FLOAT, Double.class),
- REAL(Types.REAL, Float.class),
- DOUBLE(Types.DOUBLE, Double.class),
- DATE(Types.DATE, java.sql.Date.class),
- TIME(Types.TIME, Time.class),
- TIMESTAMP(Types.TIMESTAMP, Timestamp.class),
+ FLOAT(Types.FLOAT, double.class),
+ REAL(Types.REAL, float.class),
+ DOUBLE(Types.DOUBLE, double.class),
+ DATE(Types.DATE, java.sql.Date.class, int.class),
+ TIME(Types.TIME, Time.class, int.class),
+ TIMESTAMP(Types.TIMESTAMP, Timestamp.class, long.class),
INTERVAL_YEAR_MONTH(Types.OTHER, Boolean.class),
INTERVAL_DAY_TIME(Types.OTHER, Boolean.class),
CHAR(Types.CHAR, String.class),
VARCHAR(Types.VARCHAR, String.class),
LONGVARCHAR(Types.LONGVARCHAR, String.class),
- BINARY(Types.BINARY, byte[].class),
- VARBINARY(Types.VARBINARY, byte[].class),
- LONGVARBINARY(Types.LONGVARBINARY, byte[].class),
+ BINARY(Types.BINARY, byte[].class, ByteString.class, String.class),
+ VARBINARY(Types.VARBINARY, byte[].class, ByteString.class, String.class),
+ LONGVARBINARY(Types.LONGVARBINARY, byte[].class, ByteString.class,
+ String.class),
NULL(Types.NULL, Void.class),
ANY(Types.JAVA_OBJECT, Object.class),
SYMBOL(Types.OTHER, Object.class),
@@ -323,7 +326,7 @@ public enum SqlType {
SQLXML(Types.SQLXML, java.sql.SQLXML.class),
MAP(Types.OTHER, Map.class),
DISTINCT(Types.DISTINCT, Object.class),
- STRUCT(Types.STRUCT, Object.class),
+ STRUCT(Types.STRUCT, Struct.class),
REF(Types.REF, Ref.class),
DATALINK(Types.DATALINK, URL.class),
JAVA_OBJECT(Types.JAVA_OBJECT, Object.class),
@@ -340,8 +343,16 @@ public enum SqlType {
/** Type id as appears in {@link java.sql.Types},
* e.g. {@link java.sql.Types#INTEGER}. */
public final int id;
+
+ /** Default Java type for this SQL type, as described in table B-1. */
public final Class clazz;
+ /** Class used internally in Calcite to represent instances of this type. */
+ public final Class internal;
+
+ /** Class used to serialize values of this type as JSON. */
+ public final Class serial;
+
private static final Map<Integer, SqlType> BY_ID = new HashMap<>();
static {
for (SqlType sqlType : values()) {
@@ -349,9 +360,19 @@ public enum SqlType {
}
}
- SqlType(int id, Class clazz) {
+ SqlType(int id, Class clazz, Class internal, Class serial) {
this.id = id;
this.clazz = clazz;
+ this.internal = internal;
+ this.serial = serial;
+ }
+
+ SqlType(int id, Class clazz, Class internal) {
+ this(id, clazz, internal, internal);
+ }
+
+ SqlType(int id, Class clazz) {
+ this(id, clazz, clazz, clazz);
}
public static SqlType valueOf(int type) {
@@ -362,6 +383,20 @@ public enum SqlType {
return sqlType;
}
+ /** Returns the boxed type. */
+ public Class boxedClass() {
+ return box(clazz);
+ }
+
+ /** Returns the boxed class. For example, {@code box(int.class)}
+ * returns {@code java.lang.Integer}. */
+ private static Class box(Class clazz) {
+ if (clazz.isPrimitive()) {
+ return BOX.get(clazz);
+ }
+ return clazz;
+ }
+
/** Returns the entries in JDBC table B-5. */
public static Iterable<Map.Entry<Class, SqlType>> getSetConversions() {
final ArrayList<Map.Entry<Class, SqlType>> list = new ArrayList<>();
@@ -375,10 +410,13 @@ public enum SqlType {
public static final Map<Class, EnumSet<SqlType>> SET_LIST;
public static final Map<Method, EnumSet<SqlType>> GET_LIST;
+ private static final Map<Class, Class> BOX;
static {
SET_LIST = new HashMap<>();
GET_LIST = new HashMap<>();
+ BOX = new HashMap<>();
+
EnumSet<SqlType> numericTypes = EnumSet.of(TINYINT, SMALLINT, INTEGER,
BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, BOOLEAN);
Class[] numericClasses = {
@@ -447,8 +485,8 @@ public enum SqlType {
concat(charTypes, binaryTypes, ncharTypes,
EnumSet.of(CLOB, NCLOB, SQLXML)));
GET_LIST.put(Method.GET_N_CHARACTER_STREAM,
- concat(charTypes, binaryTypes, ncharTypes,
- EnumSet.of(CLOB, NCLOB, SQLXML)));
+ concat(
+ charTypes, binaryTypes, ncharTypes, EnumSet.of(CLOB, NCLOB, SQLXML)));
GET_LIST.put(Method.GET_CLOB, EnumSet.of(CLOB, NCLOB));
GET_LIST.put(Method.GET_N_CLOB, EnumSet.of(CLOB, NCLOB));
GET_LIST.put(Method.GET_BLOB, EnumSet.of(BLOB));
@@ -459,6 +497,15 @@ public enum SqlType {
GET_LIST.put(Method.GET_OBJECT, EnumSet.allOf(SqlType.class));
GET_LIST.put(Method.GET_ROW_ID, EnumSet.of(ROWID));
GET_LIST.put(Method.GET_SQLXML, EnumSet.of(SQLXML));
+
+ BOX.put(boolean.class, Boolean.class);
+ BOX.put(byte.class, Byte.class);
+ BOX.put(char.class, Character.class);
+ BOX.put(short.class, Short.class);
+ BOX.put(int.class, Integer.class);
+ BOX.put(long.class, Long.class);
+ BOX.put(float.class, Float.class);
+ BOX.put(double.class, Double.class);
}
@SafeVarargs