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/03/23 18:26:17 UTC
[3/9] incubator-calcite git commit: [CALCITE-618] Add Avatica support
for getTables (Julian Hyde and Nick Dimiduk)
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/avatica/src/test/java/org/apache/calcite/avatica/test/RemoteDriverTest.java
----------------------------------------------------------------------
diff --git a/avatica/src/test/java/org/apache/calcite/avatica/test/RemoteDriverTest.java b/avatica/src/test/java/org/apache/calcite/avatica/test/RemoteDriverTest.java
index 5cf1ea5..c007f02 100644
--- a/avatica/src/test/java/org/apache/calcite/avatica/test/RemoteDriverTest.java
+++ b/avatica/src/test/java/org/apache/calcite/avatica/test/RemoteDriverTest.java
@@ -16,21 +16,34 @@
*/
package org.apache.calcite.avatica.test;
+import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.jdbc.JdbcMeta;
import org.apache.calcite.avatica.remote.LocalJsonService;
+import org.apache.calcite.avatica.remote.LocalService;
import org.apache.calcite.avatica.remote.MockJsonService;
+import org.apache.calcite.avatica.remote.Service;
+
+import net.hydromatic.scott.data.hsqldb.ScottHsqldb;
import org.junit.Ignore;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* Unit test for Avatica Remote JDBC driver.
@@ -40,7 +53,20 @@ public class RemoteDriverTest {
MockJsonService.Factory.class.getName();
public static final String LJS =
- LocalJsonService.Factory.class.getName();
+ LocalJdbcServiceFactory.class.getName();
+
+ public static final String QRJS =
+ QuasiRemoteJdbcServiceFactory.class.getName();
+
+ private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB;
+
+ private Connection mjs() throws SQLException {
+ return DriverManager.getConnection("jdbc:avatica:remote:factory=" + MJS);
+ }
+
+ private Connection ljs() throws SQLException {
+ return DriverManager.getConnection("jdbc:avatica:remote:factory=" + QRJS);
+ }
@Test public void testRegister() throws Exception {
final Connection connection =
@@ -50,6 +76,33 @@ public class RemoteDriverTest {
assertThat(connection.isClosed(), is(true));
}
+ @Test public void testSchemas() throws Exception {
+ final Connection connection = mjs();
+ final ResultSet resultSet =
+ connection.getMetaData().getSchemas(null, null);
+ assertFalse(resultSet.next());
+ final ResultSetMetaData metaData = resultSet.getMetaData();
+ assertTrue(metaData.getColumnCount() >= 2);
+ assertEquals("TABLE_CATALOG", metaData.getColumnName(1));
+ assertEquals("TABLE_SCHEM", metaData.getColumnName(2));
+ resultSet.close();
+ connection.close();
+ }
+
+ @Test public void testTables() throws Exception {
+ final Connection connection = mjs();
+ final ResultSet resultSet =
+ connection.getMetaData().getTables(null, null, null, new String[0]);
+ assertFalse(resultSet.next());
+ final ResultSetMetaData metaData = resultSet.getMetaData();
+ assertTrue(metaData.getColumnCount() >= 3);
+ assertEquals("TABLE_CAT", metaData.getColumnName(1));
+ assertEquals("TABLE_SCHEM", metaData.getColumnName(2));
+ assertEquals("TABLE_NAME", metaData.getColumnName(3));
+ resultSet.close();
+ connection.close();
+ }
+
@Ignore
@Test public void testNoFactory() throws Exception {
final Connection connection =
@@ -68,8 +121,7 @@ public class RemoteDriverTest {
@Ignore
@Test public void testCatalogsMock() throws Exception {
- final Connection connection =
- DriverManager.getConnection("jdbc:avatica:remote:factory=" + MJS);
+ final Connection connection = mjs();
assertThat(connection.isClosed(), is(false));
final ResultSet resultSet = connection.getMetaData().getSchemas();
assertFalse(resultSet.next());
@@ -81,6 +133,164 @@ public class RemoteDriverTest {
connection.close();
assertThat(connection.isClosed(), is(true));
}
+
+ @Test public void testStatementExecuteQueryLocal() throws Exception {
+ checkStatementExecuteQuery(ljs(), false);
+ }
+
+ @Ignore
+ @Test public void testStatementExecuteQueryMock() throws Exception {
+ checkStatementExecuteQuery(mjs(), false);
+ }
+
+ @Ignore
+ @Test public void testPrepareExecuteQueryLocal() throws Exception {
+ checkStatementExecuteQuery(ljs(), true);
+ }
+
+ @Ignore
+ @Test public void testPrepareExecuteQueryMock() throws Exception {
+ checkStatementExecuteQuery(mjs(), true);
+ }
+
+ private void checkStatementExecuteQuery(Connection connection,
+ boolean prepare) throws SQLException {
+ final String sql = "select * from (\n"
+ + " values (1, 'a'), (null, 'b'), (3, 'c')) as t (c1, c2)";
+ final Statement statement;
+ final ResultSet resultSet;
+ final ParameterMetaData parameterMetaData;
+ if (prepare) {
+ final PreparedStatement ps = connection.prepareStatement(sql);
+ statement = ps;
+ parameterMetaData = ps.getParameterMetaData();
+ resultSet = ps.executeQuery();
+ } else {
+ statement = connection.createStatement();
+ parameterMetaData = null;
+ resultSet = statement.executeQuery(sql);
+ }
+ if (parameterMetaData != null) {
+ assertThat(parameterMetaData.getParameterCount(), equalTo(2));
+ }
+ final ResultSetMetaData metaData = resultSet.getMetaData();
+ assertEquals(2, metaData.getColumnCount());
+ assertEquals("C1", metaData.getColumnName(1));
+ assertEquals("C2", metaData.getColumnName(2));
+ assertTrue(resultSet.next());
+ assertTrue(resultSet.next());
+ assertTrue(resultSet.next());
+ assertFalse(resultSet.next());
+ resultSet.close();
+ statement.close();
+ connection.close();
+ }
+
+ @Test public void testPrepareBindExecuteFetch() throws Exception {
+ checkPrepareBindExecuteFetch(ljs());
+ }
+
+ private void checkPrepareBindExecuteFetch(Connection connection)
+ throws SQLException {
+ final String sql = "select cast(? as integer) * 3 as c, 'x' as x\n"
+ + "from (values (1, 'a'))";
+ final PreparedStatement ps =
+ connection.prepareStatement(sql);
+ final ResultSetMetaData metaData = ps.getMetaData();
+ assertEquals(2, metaData.getColumnCount());
+ assertEquals("C", metaData.getColumnName(1));
+ assertEquals("X", metaData.getColumnName(2));
+ try {
+ final ResultSet resultSet = ps.executeQuery();
+ fail("expected error, got " + resultSet);
+ } catch (SQLException e) {
+ assertThat(e.getMessage(),
+ equalTo("exception while executing query: unbound parameter"));
+ }
+
+ final ParameterMetaData parameterMetaData = ps.getParameterMetaData();
+ assertThat(parameterMetaData.getParameterCount(), equalTo(1));
+
+ ps.setInt(1, 10);
+ final ResultSet resultSet = ps.executeQuery();
+ assertTrue(resultSet.next());
+ assertThat(resultSet.getInt(1), equalTo(30));
+ assertFalse(resultSet.next());
+ resultSet.close();
+
+ ps.setInt(1, 20);
+ final ResultSet resultSet2 = ps.executeQuery();
+ assertFalse(resultSet2.isClosed());
+ assertTrue(resultSet2.next());
+ assertThat(resultSet2.getInt(1), equalTo(60));
+ assertThat(resultSet2.wasNull(), is(false));
+ assertFalse(resultSet2.next());
+ resultSet2.close();
+
+ ps.setObject(1, null);
+ final ResultSet resultSet3 = ps.executeQuery();
+ assertTrue(resultSet3.next());
+ assertThat(resultSet3.getInt(1), equalTo(0));
+ assertThat(resultSet3.wasNull(), is(true));
+ assertFalse(resultSet3.next());
+ resultSet3.close();
+
+ ps.close();
+ connection.close();
+ }
+
+ /** Factory that creates a service based on a local JDBC connection. */
+ public static class LocalJdbcServiceFactory implements Service.Factory {
+ @Override public Service create(AvaticaConnection connection) {
+ try {
+ Connection connection1 =
+ DriverManager.getConnection(CONNECTION_SPEC.url,
+ CONNECTION_SPEC.username, CONNECTION_SPEC.password);
+ return new LocalService(new JdbcMeta(connection1));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /** Factory that creates a service based on a local JDBC connection. */
+ public static class QuasiRemoteJdbcServiceFactory implements Service.Factory {
+ @Override public Service create(AvaticaConnection connection) {
+ try {
+ Connection connection1 =
+ DriverManager.getConnection(CONNECTION_SPEC.url,
+ CONNECTION_SPEC.username, CONNECTION_SPEC.password);
+ final JdbcMeta jdbcMeta = new JdbcMeta(connection1);
+ final LocalService localService = new LocalService(jdbcMeta);
+ final LocalJsonService localJsonService =
+ new LocalJsonService(localService);
+ return localJsonService;
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /** Information necessary to create a JDBC connection. Specify one to run
+ * tests against a different database. (hsqldb is the default.) */
+ public static class ConnectionSpec {
+ public final String url;
+ public final String username;
+ public final String password;
+ public final String driver;
+
+ public ConnectionSpec(String url, String username, String password,
+ String driver) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ this.driver = driver;
+ }
+
+ public static final ConnectionSpec HSQLDB =
+ new ConnectionSpec(ScottHsqldb.URI, ScottHsqldb.USER,
+ ScottHsqldb.PASSWORD, "org.hsqldb.jdbcDriver");
+ }
}
// End RemoteDriverTest.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 36a88f5..34059f7 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -89,6 +89,11 @@ limitations under the License.
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>net.hydromatic</groupId>
+ <artifactId>scott-data-hsqldb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/main/java/org/apache/calcite/jdbc/CalciteJdbc41Factory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteJdbc41Factory.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteJdbc41Factory.java
index 0b87f0f..e5a567c 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteJdbc41Factory.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteJdbc41Factory.java
@@ -91,13 +91,13 @@ public class CalciteJdbc41Factory extends CalciteFactory {
}
public CalciteResultSet newResultSet(AvaticaStatement statement,
- Meta.Signature signature, TimeZone timeZone, Iterable<Object> iterable) {
+ Meta.Signature signature, TimeZone timeZone, Meta.Frame firstFrame) {
final ResultSetMetaData metaData =
newResultSetMetaData(statement, signature);
final CalcitePrepare.CalciteSignature calciteSignature =
(CalcitePrepare.CalciteSignature) signature;
return new CalciteResultSet(statement, calciteSignature, metaData, timeZone,
- iterable);
+ firstFrame);
}
public ResultSetMetaData newResultSetMetaData(AvaticaStatement statement,
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
index 152e918..cf395f6 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
@@ -157,7 +157,7 @@ public class CalciteMetaImpl extends MetaImpl {
final Iterable<Object> iterable = (Iterable<Object>) (Iterable) enumerable;
return createResultSet(Collections.<String, Object>emptyMap(),
columns, CursorFactory.record(clazz, fields, fieldNames),
- iterable);
+ new Frame(0, true, iterable));
}
@Override protected <E> MetaResultSet
@@ -165,12 +165,12 @@ public class CalciteMetaImpl extends MetaImpl {
final List<ColumnMetaData> columns = fieldMetaData(clazz).columns;
final CursorFactory cursorFactory = CursorFactory.deduce(columns, clazz);
return createResultSet(Collections.<String, Object>emptyMap(), columns,
- cursorFactory, Collections.emptyList());
+ cursorFactory, Frame.EMPTY);
}
protected MetaResultSet createResultSet(
Map<String, Object> internalParameters, List<ColumnMetaData> columns,
- CursorFactory cursorFactory, final Iterable<Object> iterable) {
+ CursorFactory cursorFactory, final Frame firstFrame) {
try {
final CalciteConnectionImpl connection = getConnection();
final AvaticaStatement statement = connection.createStatement();
@@ -180,10 +180,10 @@ public class CalciteMetaImpl extends MetaImpl {
columns, cursorFactory, -1, null) {
@Override public Enumerable<Object> enumerable(
DataContext dataContext) {
- return Linq4j.asEnumerable(iterable);
+ return Linq4j.asEnumerable(firstFrame.rows);
}
};
- return new MetaResultSet(statement.getId(), true, signature, iterable);
+ return new MetaResultSet(statement.getId(), true, signature, firstFrame);
} catch (SQLException e) {
throw new RuntimeException(e);
}
@@ -441,7 +441,7 @@ public class CalciteMetaImpl extends MetaImpl {
}
@Override public Iterable<Object> createIterable(StatementHandle handle,
- Signature signature, Iterable<Object> iterable) {
+ Signature signature, List<Object> parameterValues, Frame firstFrame) {
try {
//noinspection unchecked
final CalcitePrepare.CalciteSignature<Object> calciteSignature =
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/main/java/org/apache/calcite/jdbc/CalciteResultSet.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteResultSet.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteResultSet.java
index 72f31ef..777524b 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteResultSet.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteResultSet.java
@@ -20,6 +20,7 @@ import org.apache.calcite.avatica.AvaticaResultSet;
import org.apache.calcite.avatica.AvaticaStatement;
import org.apache.calcite.avatica.ColumnMetaData;
import org.apache.calcite.avatica.Handler;
+import org.apache.calcite.avatica.Meta;
import org.apache.calcite.avatica.util.Cursor;
import org.apache.calcite.linq4j.Enumerator;
import org.apache.calcite.linq4j.Linq4j;
@@ -42,8 +43,8 @@ public class CalciteResultSet extends AvaticaResultSet {
CalciteResultSet(AvaticaStatement statement,
CalcitePrepare.CalciteSignature calciteSignature,
ResultSetMetaData resultSetMetaData, TimeZone timeZone,
- Iterable<Object> iterable) {
- super(statement, calciteSignature, resultSetMetaData, timeZone, iterable);
+ Meta.Frame firstFrame) {
+ super(statement, calciteSignature, resultSetMetaData, timeZone, firstFrame);
}
@Override protected CalciteResultSet execute() throws SQLException {
@@ -68,7 +69,7 @@ public class CalciteResultSet extends AvaticaResultSet {
final CalciteResultSet resultSet =
new CalciteResultSet(statement,
(CalcitePrepare.CalciteSignature) signature, resultSetMetaData,
- localCalendar.getTimeZone(), iterable);
+ localCalendar.getTimeZone(), new Meta.Frame(0, true, iterable));
final Cursor cursor = resultSet.createCursor(elementType, iterable);
final List<ColumnMetaData> columnMetaDataList;
if (elementType instanceof ColumnMetaData.StructType) {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java b/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
index 0819dcf..2d4c3f2 100644
--- a/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
+++ b/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
@@ -126,7 +126,7 @@ public class MaterializationService {
Functions.adapt(calciteSignature.columns,
new Function1<ColumnMetaData, ColumnMetaData.Rep>() {
public ColumnMetaData.Rep apply(ColumnMetaData column) {
- return column.type.representation;
+ return column.type.rep;
}
}),
new AbstractQueryable<Object>() {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 97eb68a..298f8d6 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -50,6 +50,7 @@ import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.Lists;
import net.hydromatic.foodmart.data.hsqldb.FoodmartHsqldb;
+import net.hydromatic.scott.data.hsqldb.ScottHsqldb;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -100,11 +101,11 @@ public class CalciteAssert {
* MySQL manually with the foodmart data set, otherwise there will be test
* failures. To run against MySQL, specify '-Dcalcite.test.db=mysql' on the
* java command line. */
- public static final ConnectionSpec CONNECTION_SPEC =
+ public static final DatabaseInstance DB =
Util.first(System.getProperty("calcite.test.db"), "hsqldb")
.equals("mysql")
- ? ConnectionSpec.MYSQL
- : ConnectionSpec.HSQLDB;
+ ? DatabaseInstance.MYSQL
+ : DatabaseInstance.HSQLDB;
/** Whether to enable slow tests. Default is false. */
public static final boolean ENABLE_SLOW =
@@ -633,12 +634,9 @@ public class CalciteAssert {
return rootSchema.add("foodmart",
new ReflectiveSchema(new JdbcTest.FoodmartSchema()));
case JDBC_FOODMART:
+ final ConnectionSpec cs = DB.foodmart;
final DataSource dataSource =
- JdbcSchema.dataSource(
- CONNECTION_SPEC.url,
- CONNECTION_SPEC.driver,
- CONNECTION_SPEC.username,
- CONNECTION_SPEC.password);
+ JdbcSchema.dataSource(cs.url, cs.driver, cs.username, cs.password);
return rootSchema.add("foodmart",
JdbcSchema.create(rootSchema, "foodmart", dataSource, null,
"foodmart"));
@@ -1438,23 +1436,22 @@ public class CalciteAssert {
/** Information necessary to create a JDBC connection. Specify one to run
* tests against a different database. (hsqldb is the default.) */
- public enum ConnectionSpec {
- HSQLDB(FoodmartHsqldb.URI, "FOODMART", "FOODMART",
- "org.hsqldb.jdbcDriver"),
- MYSQL("jdbc:mysql://localhost/foodmart", "foodmart", "foodmart",
- "com.mysql.jdbc.Driver");
-
- public final String url;
- public final String username;
- public final String password;
- public final String driver;
-
- ConnectionSpec(String url, String username, String password,
- String driver) {
- this.url = url;
- this.username = username;
- this.password = password;
- this.driver = driver;
+ public enum DatabaseInstance {
+ HSQLDB(
+ new ConnectionSpec(FoodmartHsqldb.URI, "FOODMART", "FOODMART",
+ "org.hsqldb.jdbcDriver"),
+ new ConnectionSpec(ScottHsqldb.URI, ScottHsqldb.USER,
+ ScottHsqldb.PASSWORD, "org.hsqldb.jdbcDriver")),
+ MYSQL(
+ new ConnectionSpec("jdbc:mysql://localhost/foodmart", "foodmart",
+ "foodmart", "com.mysql.jdbc.Driver"), null);
+
+ public final ConnectionSpec foodmart;
+ public final ConnectionSpec scott;
+
+ DatabaseInstance(ConnectionSpec foodmart, ConnectionSpec scott) {
+ this.foodmart = foodmart;
+ this.scott = scott;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/test/java/org/apache/calcite/test/ConnectionSpec.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/ConnectionSpec.java b/core/src/test/java/org/apache/calcite/test/ConnectionSpec.java
new file mode 100644
index 0000000..4142083
--- /dev/null
+++ b/core/src/test/java/org/apache/calcite/test/ConnectionSpec.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.calcite.test;
+
+/** Information necessary to create a JDBC connection.
+ *
+ * <p>Specify one to run tests against a different database. */
+public class ConnectionSpec {
+ public final String url;
+ public final String username;
+ public final String password;
+ public final String driver;
+
+ public ConnectionSpec(String url, String username, String password,
+ String driver) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ this.driver = driver;
+ }
+}
+
+// End ConnectionSpec.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
index 08d2903..78c1249 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
@@ -32,7 +32,7 @@ public class JdbcAdapterTest {
+ " JdbcTableScan(table=[[foodmart, sales_fact_1997]])\n"
+ " JdbcTableScan(table=[[foodmart, sales_fact_1998]])")
.runs()
- .enable(CalciteAssert.CONNECTION_SPEC.url.startsWith("jdbc:hsqldb:"))
+ .enable(CalciteAssert.DB == CalciteAssert.DatabaseInstance.HSQLDB)
.planHasSql("SELECT *\n"
+ "FROM \"foodmart\".\"sales_fact_1997\"\n"
+ "UNION ALL\n"
@@ -48,7 +48,7 @@ public class JdbcAdapterTest {
+ " select * from \"sales_fact_1998\")\n"
+ "where \"product_id\" = 1")
.runs()
- .enable(CalciteAssert.CONNECTION_SPEC.url.startsWith("jdbc:hsqldb:"))
+ .enable(CalciteAssert.DB == CalciteAssert.DatabaseInstance.HSQLDB)
.planHasSql("SELECT *\n"
+ "FROM \"foodmart\".\"sales_fact_1997\"\n"
+ "WHERE \"product_id\" = 1\n"
@@ -63,7 +63,7 @@ public class JdbcAdapterTest {
.query("select \"store_id\", \"store_name\" from \"store\"\n"
+ "where \"store_name\" in ('Store 1', 'Store 10', 'Store 11', 'Store 15', 'Store 16', 'Store 24', 'Store 3', 'Store 7')")
.runs()
- .enable(CalciteAssert.CONNECTION_SPEC.url.startsWith("jdbc:hsqldb:"))
+ .enable(CalciteAssert.DB == CalciteAssert.DatabaseInstance.HSQLDB)
.planHasSql(
"SELECT \"store_id\", \"store_name\"\n"
+ "FROM \"foodmart\".\"store\"\n"
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 0024bf1..989243f 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -177,10 +177,10 @@ public class JdbcTest {
public static final String FOODMART_SCHEMA = " {\n"
+ " type: 'jdbc',\n"
+ " name: 'foodmart',\n"
- + " jdbcDriver: '" + CalciteAssert.CONNECTION_SPEC.driver + "',\n"
- + " jdbcUser: '" + CalciteAssert.CONNECTION_SPEC.username + "',\n"
- + " jdbcPassword: '" + CalciteAssert.CONNECTION_SPEC.password + "',\n"
- + " jdbcUrl: '" + CalciteAssert.CONNECTION_SPEC.url + "',\n"
+ + " jdbcDriver: '" + CalciteAssert.DB.foodmart.driver + "',\n"
+ + " jdbcUser: '" + CalciteAssert.DB.foodmart.username + "',\n"
+ + " jdbcPassword: '" + CalciteAssert.DB.foodmart.password + "',\n"
+ + " jdbcUrl: '" + CalciteAssert.DB.foodmart.url + "',\n"
+ " jdbcCatalog: null,\n"
+ " jdbcSchema: 'foodmart'\n"
+ " }\n";
@@ -4644,8 +4644,21 @@ public class JdbcTest {
+ "from \"hr\".\"emps\"\n"
+ "where \"deptno\" < ? and \"name\" like ?");
+ // execute with vars unbound - gives error
+ ResultSet resultSet;
+ try {
+ resultSet = preparedStatement.executeQuery();
+ fail("expected error, got " + resultSet);
+ } catch (SQLException e) {
+ assertThat(e.getMessage(),
+ equalTo(
+ "exception while executing query: unbound parameter"));
+ }
+
// execute with both vars null - no results
- ResultSet resultSet = preparedStatement.executeQuery();
+ preparedStatement.setNull(1, java.sql.Types.INTEGER);
+ preparedStatement.setNull(2, java.sql.Types.VARCHAR);
+ resultSet = preparedStatement.executeQuery();
assertFalse(resultSet.next());
// execute with ?0=15, ?1='%' - 3 rows
@@ -5943,7 +5956,7 @@ public class JdbcTest {
}
})
.returns("C=0\n");
- switch (CalciteAssert.CONNECTION_SPEC) {
+ switch (CalciteAssert.DB) {
case HSQLDB:
assertThat(Util.toLinux(sqls[0]),
equalTo("SELECT COUNT(*) AS \"C\"\n"
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/doc/avatica.md
----------------------------------------------------------------------
diff --git a/doc/avatica.md b/doc/avatica.md
new file mode 100644
index 0000000..32cc905
--- /dev/null
+++ b/doc/avatica.md
@@ -0,0 +1,81 @@
+# Avatica
+
+## Introduction
+
+Avatica is a framework for building JDBC and ODBC drivers for databases,
+and an RPC wire protocol.
+
+![Avatica Architecture]
+(https://raw.githubusercontent.com/julianhyde/share/master/slides/avatica-architecture.png)
+
+Avatica's Java binding has very few dependencies.
+Even though it is part of Apache Calcite it does not depend on other parts of
+Calcite. It depends only on JDK 1.7+ and Jackson.
+
+Avatica's wire protocol is JSON over HTTP.
+The Java implementation uses Jackson to convert request/response command
+objects to/from JSON.
+
+Avatica-Server is a Java implementation of Avatica RPC.
+It embeds the Jetty HTTP server.
+
+Core concepts:
+* Meta is a local API sufficient to implement any Avatica provider
+* Factory creates implementations of the JDBC classes (Driver, Connection,
+ Statement, ResultSet) on top of a Meta
+* Service is an interface that implements the functions of Meta in terms
+ of request and response command objects
+
+## JDBC
+
+Avatica implements JDBC by means of Factory.
+Factory creates implementations of the JDBC classes (Driver, Connection,
+Statement, PreparedStatement, ResultSet) on top of a Meta.
+
+## ODBC
+
+Work has not started on Avatica ODBC.
+
+Avatica ODBC would use the same wire protocol and could use the same server
+implementation in Java. The ODBC client would be written in C or C++.
+
+Since the Avatica protocol abstracts many of the differences between providers,
+the same ODBC client could be used for different databases.
+
+## Project structure
+
+We know that it is important that client libraries have minimal dependencies.
+
+Avatica is currently part of Apache Calcite.
+It does not depend upon any other part of Calcite.
+At some point Avatica could become a separate project.
+
+Packages:
+* [org.apache.calcite.avatica](http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/avatica/package-summary.html) Core framework
+* [org.apache.calcite.avatica.remote](http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/avatica/remote/package-summary.html) JDBC driver that uses remote procedure calls
+* [org.apache.calcite.avatica.server](http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/avatica/server/package-summary.html) HTTP server
+* [org.apache.calcite.avatica.util](http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/avatica/util/package-summary.html) Utilities
+
+## Status
+
+### Implemented
+* Create connection, create statement, metadata, prepare, bind, execute, fetch
+* RPC using JSON over HTTP
+* Local implementation
+* Implementation over an existing JDBC driver
+* Composite RPCs (combining several requests into one round trip)
+ * Execute-Fetch
+ * Metadata-Fetch (metadata calls such as getTables return all rows)
+
+### Not implemented
+* ODBC
+* RPCs
+ * CloseStatement
+ * CloseConnection
+* Composite RPCs
+ * CreateStatement-Prepare
+ * CloseStatement-CloseConnection
+ * Prepare-Execute-Fetch (Statement.executeQuery should fetch first N rows)
+* Remove statements from statement table
+* DML (INSERT, UPDATE, DELETE)
+* Statement.execute applied to SELECT statement
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/4d2f647a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 54fd593..683f173 100644
--- a/pom.xml
+++ b/pom.xml
@@ -131,6 +131,11 @@ limitations under the License.
<version>11.0.2</version>
</dependency>
<dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ </dependency>
+ <dependency>
<groupId>io.airlift.tpch</groupId>
<artifactId>tpch</artifactId>
<version>0.1</version>
@@ -159,7 +164,21 @@ limitations under the License.
<groupId>net.hydromatic</groupId>
<artifactId>quidem</artifactId>
<version>0.3</version>
- <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.hydromatic</groupId>
+ <artifactId>scott-data-hsqldb</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>net.hydromatic</groupId>
+ <artifactId>tpcds</artifactId>
+ <version>0.3</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.opencsv</groupId>
+ <artifactId>opencsv</artifactId>
+ <version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@@ -192,17 +211,6 @@ limitations under the License.
<version>5.1.5-jhyde</version>
</dependency>
<dependency>
- <groupId>net.hydromatic</groupId>
- <artifactId>tpcds</artifactId>
- <version>0.3</version>
- <type>jar</type>
- </dependency>
- <dependency>
- <groupId>net.sf.opencsv</groupId>
- <artifactId>opencsv</artifactId>
- <version>2.3</version>
- </dependency>
- <dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>0.9.0-incubating</version>
@@ -228,11 +236,6 @@ limitations under the License.
<version>0.7.1</version>
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.11</version>
- </dependency>
- <dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>