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/04/03 15:02:39 UTC
[06/10] incubator-calcite git commit: [CALCITE-654] Tighten up
AvaticaStatement#execute semantics (Nick Dimiduk)
[CALCITE-654] Tighten up AvaticaStatement#execute semantics (Nick Dimiduk)
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/0ea085b7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/0ea085b7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/0ea085b7
Branch: refs/heads/master
Commit: 0ea085b7858cbf0e8b250ac238d4f1def1ff20f5
Parents: ba07b09
Author: Nick Dimiduk <nd...@gmail.com>
Authored: Mon Mar 30 17:42:26 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Fri Apr 3 01:10:05 2015 -0700
----------------------------------------------------------------------
.../apache/calcite/avatica/jdbc/JdbcMeta.java | 21 +++++++++--
.../calcite/avatica/RemoteDriverTest.java | 26 ++++++++++++--
.../calcite/avatica/AvaticaStatement.java | 37 +++++++++++++-------
3 files changed, 66 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/0ea085b7/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 90e8c2a..b5fb561 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
@@ -708,13 +708,28 @@ public class JdbcMeta implements Meta {
final PreparedStatement statement = connection.prepareStatement(sql);
final int id = System.identityHashCode(statement);
final StatementInfo info = new StatementInfo(statement);
- statementCache.put(id, info);
- info.resultSet = statement.executeQuery();
- MetaResultSet mrs = JdbcResultSet.create(ch.id, id, info.resultSet);
+ statementCache.put(id, info); // TODO: must we retain a statement in all cases?
+ boolean ret = statement.execute();
+ info.resultSet = statement.getResultSet();
+ assert ret || info.resultSet == null;
+ final MetaResultSet mrs;
+ if (info.resultSet == null) {
+ // build a non-JDBC result that contains the update count
+ int updateCount = statement.getUpdateCount();
+ List<ColumnMetaData> columns = new ArrayList<>(1);
+ columns.add(UPDATE_COL);
+ List<Object> val = new ArrayList<>();
+ val.add(new Object[] { updateCount });
+ mrs = new MetaResultSet(ch.id, id, true, new Signature(columns, sql, null, null,
+ CursorFactory.ARRAY), new Frame(0, true, val));
+ } else {
+ mrs = JdbcResultSet.create(ch.id, id, info.resultSet);
+ }
if (LOG.isTraceEnabled()) {
StatementHandle h = new StatementHandle(ch.id, id, null);
LOG.trace("prepAndExec statement " + h);
}
+ // TODO: review client to ensure statementId is updated when appropriate
return mrs;
} catch (SQLException e) {
throw propagate(e);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/0ea085b7/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 a2ab87a..2b9c111 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
@@ -152,7 +152,6 @@ public class RemoteDriverTest {
checkStatementExecuteQuery(mjs(), false);
}
- @Ignore
@Test public void testPrepareExecuteQueryLocal() throws Exception {
checkStatementExecuteQuery(ljs(), true);
}
@@ -180,7 +179,7 @@ public class RemoteDriverTest {
resultSet = statement.executeQuery(sql);
}
if (parameterMetaData != null) {
- assertThat(parameterMetaData.getParameterCount(), equalTo(2));
+ assertThat(parameterMetaData.getParameterCount(), equalTo(0));
}
final ResultSetMetaData metaData = resultSet.getMetaData();
assertEquals(2, metaData.getColumnCount());
@@ -195,6 +194,27 @@ public class RemoteDriverTest {
connection.close();
}
+ @Test public void testCreateInsertUpdateDrop() throws Exception {
+ final String drop = "drop table TEST_TABLE if exists";
+ final String create = "create table TEST_TABLE("
+ + "id int not null, "
+ + "msg varchar(3) not null)";
+ final String insert = "insert into TEST_TABLE values(1, 'foo')";
+ final String update = "update TEST_TABLE set msg='bar' where id=1";
+ try (Connection connection = ljs();
+ Statement statement = connection.createStatement()) {
+ boolean ret;
+ assertFalse(statement.execute(drop));
+ assertEquals(0, statement.getUpdateCount());
+ assertFalse(statement.execute(create));
+ assertEquals(0, statement.getUpdateCount());
+ assertFalse(statement.execute(insert));
+ assertEquals(1, statement.getUpdateCount());
+ assertFalse(statement.execute(update));
+ assertEquals(0, statement.executeUpdate(drop));
+ }
+ }
+
@Test public void testStatementLifecycle() throws Exception {
try (AvaticaConnection connection = (AvaticaConnection) ljs()) {
Map<Integer, AvaticaStatement> clientMap = connection.statementMap;
@@ -312,6 +332,8 @@ public class RemoteDriverTest {
connection.close();
}
+
+
/**
* Factory that creates a service based on a local JDBC connection.
*/
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/0ea085b7/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 8276b07..1a7e5ec 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
@@ -17,6 +17,7 @@
package org.apache.calcite.avatica;
import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
@@ -55,6 +56,7 @@ public abstract class AvaticaStatement
private int fetchSize;
private int fetchDirection;
protected int maxRowCount = 0;
+ private int updateCount = -1;
/**
* Creates an AvaticaStatement.
@@ -89,21 +91,30 @@ public abstract class AvaticaStatement
// implement Statement
public boolean execute(String sql) throws SQLException {
- try {
- // In JDBC, maxRowCount = 0 means no limit; in prepare it means LIMIT 0
- final int maxRowCount1 = maxRowCount <= 0 ? -1 : maxRowCount;
- ResultSet resultSet =
- connection.prepareAndExecuteInternal(this, sql, maxRowCount1);
- if (resultSet.isClosed()) {
- return false;
+ ResultSet resultSet = executeQuery(sql);
+ ResultSetMetaData md = resultSet.getMetaData();
+ // hackish, but be sure we're looking at an update count result, not user data
+ if (md.getCatalogName(1).equalsIgnoreCase("avatica_internal")
+ && md.getTableName(1).equalsIgnoreCase("update_result")
+ && md.getColumnCount() == 1
+ && md.getColumnName(1).equalsIgnoreCase("u")) {
+ if (!resultSet.next()) {
+ throw new SQLException("expected one row, got zero");
}
- return true;
- } catch (RuntimeException e) {
- throw connection.helper.createException("while executing SQL: " + sql, e);
+ this.updateCount = resultSet.getInt(1);
+ if (resultSet.next()) {
+ throw new SQLException("expected one row, got two or more");
+ }
+ resultSet.close();
+ return false;
+ } else {
+ return !resultSet.isClosed();
}
}
public ResultSet executeQuery(String sql) throws SQLException {
+ // reset previous state before moving forward.
+ this.updateCount = -1;
try {
// In JDBC, maxRowCount = 0 means no limit; in prepare it means LIMIT 0
final int maxRowCount1 = maxRowCount <= 0 ? -1 : maxRowCount;
@@ -122,12 +133,12 @@ public abstract class AvaticaStatement
if (!resultSet.next()) {
throw new SQLException("expected one row, got zero");
}
- int result = resultSet.getInt(1);
+ this.updateCount = resultSet.getInt(1);
if (resultSet.next()) {
throw new SQLException("expected one row, got two or more");
}
resultSet.close();
- return result;
+ return this.updateCount;
}
public synchronized void close() throws SQLException {
@@ -240,7 +251,7 @@ public abstract class AvaticaStatement
}
public int getUpdateCount() throws SQLException {
- return -1;
+ return updateCount;
}
public boolean getMoreResults() throws SQLException {