You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/09/12 09:02:58 UTC
[2/4] ignite git commit: IGNITE-6326: JDBC thin driver: as of now
error is thrown before query execution in case of type mismatch (executeQuery,
executeUpdate). This closes #2631.
IGNITE-6326: JDBC thin driver: as of now error is thrown before query execution in case of type mismatch (executeQuery, executeUpdate). This closes #2631.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/acd78616
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/acd78616
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/acd78616
Branch: refs/heads/ignite-5896
Commit: acd786160f612e300b82ac95d5470cd50a431622
Parents: 25f8c57
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Tue Sep 12 10:52:04 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Sep 12 10:52:04 2017 +0300
----------------------------------------------------------------------
.../ignite/jdbc/thin/JdbcThinBatchSelfTest.java | 2 +-
.../jdbc/thin/JdbcThinStatementSelfTest.java | 41 ++++++++++++++++++++
.../jdbc/thin/JdbcThinPreparedStatement.java | 12 +++---
.../internal/jdbc/thin/JdbcThinStatement.java | 12 +++---
.../internal/jdbc/thin/JdbcThinTcpIo.java | 6 ++-
.../internal/jdbc2/JdbcSqlFieldsQuery.java | 2 +-
.../odbc/jdbc/JdbcQueryExecuteRequest.java | 29 +++++++++++++-
.../odbc/jdbc/JdbcRequestHandler.java | 27 ++++++++++---
.../processors/odbc/jdbc/JdbcStatementType.java | 32 +++++++++++++++
9 files changed, 141 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
index 5781e00..5e2e39e 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
@@ -173,7 +173,7 @@ public class JdbcThinBatchSelfTest extends JdbcThinAbstractDmlStatementSelfTest
for (int i = 0; i < BATCH_SIZE; ++i)
assertEquals("Invalid update count",i + 1, updCnts[i]);
- if (!e.getMessage().contains("Query produced result set [qry=select * from Person, args=[]]")) {
+ if (!e.getMessage().contains("Given statement type does not match that declared by JDBC driver")) {
log.error("Invalid exception: ", e);
fail();
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
index 97e3300..234a319 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
@@ -1013,6 +1013,47 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
"Statement is closed");
}
+ /**
+ * @throws Exception If failed.
+ */
+ public void testStatementTypeMismatchSelect() throws Exception {
+ GridTestUtils.assertThrows(log,
+ new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ stmt.executeUpdate("select 1;");
+
+ return null;
+ }
+ },
+ SQLException.class,
+ "Given statement type does not match that declared by JDBC driver");
+
+ assert stmt.getResultSet() == null : "Not results expected. Last statement is executed with exception";
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testStatementTypeMismatchUpdate() throws Exception {
+ GridTestUtils.assertThrows(log,
+ new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ stmt.executeQuery("update test set val=28 where _key=1");
+
+ return null;
+ }
+ },
+ SQLException.class,
+ "Given statement type does not match that declared by JDBC driver");
+
+ ResultSet rs = stmt.executeQuery("select val from test where _key=1");
+
+ assert rs.next();
+ assert rs.getInt(1) == 1 : "The data must not be updated. " +
+ "Because update statement is executed via 'executeQuery' method." +
+ " Data [val=" + rs.getInt(1) + ']';
+ }
+
/** */
private void fillCache() {
IgniteCache<String, Person> cachePerson = grid(0).cache(DEFAULT_CACHE_NAME);
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
index 49a1029..5aa503c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
@@ -44,6 +44,7 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaParamsResult;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcStatementType;
/**
* JDBC prepared statement implementation.
@@ -73,7 +74,7 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
/** {@inheritDoc} */
@Override public ResultSet executeQuery() throws SQLException {
- executeWithArguments();
+ executeWithArguments(JdbcStatementType.SELECT_STATEMENT_TYPE);
ResultSet rs = getResultSet();
@@ -90,7 +91,7 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
/** {@inheritDoc} */
@Override public int executeUpdate() throws SQLException {
- executeWithArguments();
+ executeWithArguments(JdbcStatementType.UPDATE_STMT_TYPE);
int res = getUpdateCount();
@@ -230,7 +231,7 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
/** {@inheritDoc} */
@Override public boolean execute() throws SQLException {
- executeWithArguments();
+ executeWithArguments(JdbcStatementType.ANY_STATEMENT_TYPE);
return rs.isQuery();
}
@@ -238,10 +239,11 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
/**
* Execute query with arguments and nullify them afterwards.
*
+ * @param stmtType Expected statement type.
* @throws SQLException If failed.
*/
- private void executeWithArguments() throws SQLException {
- execute0(sql, args);
+ private void executeWithArguments(JdbcStatementType stmtType) throws SQLException {
+ execute0(stmtType, sql, args);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
index df77261..44477cd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
@@ -33,6 +33,7 @@ import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteResult;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcStatementType;
import static java.sql.ResultSet.CONCUR_READ_ONLY;
import static java.sql.ResultSet.FETCH_FORWARD;
@@ -90,7 +91,7 @@ public class JdbcThinStatement implements Statement {
/** {@inheritDoc} */
@Override public ResultSet executeQuery(String sql) throws SQLException {
- execute0(sql, null);
+ execute0(JdbcStatementType.SELECT_STATEMENT_TYPE, sql, null);
ResultSet rs = getResultSet();
@@ -101,12 +102,13 @@ public class JdbcThinStatement implements Statement {
}
/**
+ * @param stmtType Expected statement type.
* @param sql Sql query.
* @param args Query parameters.
*
* @throws SQLException Onj error.
*/
- protected void execute0(String sql, List<Object> args) throws SQLException {
+ protected void execute0(JdbcStatementType stmtType, String sql, List<Object> args) throws SQLException {
ensureNotClosed();
if (rs != null) {
@@ -121,7 +123,7 @@ public class JdbcThinStatement implements Statement {
throw new SQLException("SQL query is empty.");
try {
- JdbcQueryExecuteResult res = conn.io().queryExecute(conn.getSchema(), pageSize, maxRows,
+ JdbcQueryExecuteResult res = conn.io().queryExecute(stmtType, conn.getSchema(), pageSize, maxRows,
sql, args);
assert res != null;
@@ -141,7 +143,7 @@ public class JdbcThinStatement implements Statement {
/** {@inheritDoc} */
@Override public int executeUpdate(String sql) throws SQLException {
- execute0(sql, null);
+ execute0(JdbcStatementType.UPDATE_STMT_TYPE, sql, null);
int res = getUpdateCount();
@@ -246,7 +248,7 @@ public class JdbcThinStatement implements Statement {
@Override public boolean execute(String sql) throws SQLException {
ensureNotClosed();
- execute0(sql, null);
+ execute0(JdbcStatementType.ANY_STATEMENT_TYPE, sql, null);
return rs.isQuery();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index f29f8b1..9775254 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -57,6 +57,7 @@ import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryMetadataResult;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcResponse;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcStatementType;
import org.apache.ignite.internal.util.ipc.loopback.IpcClientTcpEndpoint;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteProductVersion;
@@ -315,6 +316,7 @@ public class JdbcThinTcpIo {
}
/**
+ * @param stmtType Expected statement type.
* @param cache Cache name.
* @param fetchSize Fetch size.
* @param maxRows Max rows.
@@ -324,10 +326,10 @@ public class JdbcThinTcpIo {
* @throws IOException On error.
* @throws IgniteCheckedException On error.
*/
- public JdbcQueryExecuteResult queryExecute(String cache, int fetchSize, int maxRows,
+ public JdbcQueryExecuteResult queryExecute(JdbcStatementType stmtType, String cache, int fetchSize, int maxRows,
String sql, List<Object> args)
throws IOException, IgniteCheckedException {
- return sendRequest(new JdbcQueryExecuteRequest(cache, fetchSize, maxRows, sql,
+ return sendRequest(new JdbcQueryExecuteRequest(stmtType, cache, fetchSize, maxRows, sql,
args == null ? null : args.toArray(new Object[args.size()])), DYNAMIC_SIZE_MSG_CAP);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java
index 3d4eaba..d8b9a26 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java
@@ -35,7 +35,7 @@ public final class JdbcSqlFieldsQuery extends SqlFieldsQuery {
* @param sql SQL query.
* @param isQry Flag indicating whether this object denotes a query or an update operation.
*/
- JdbcSqlFieldsQuery(String sql, boolean isQry) {
+ public JdbcSqlFieldsQuery(String sql, boolean isQry) {
super(sql);
this.isQry = isQry;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java
index 0b26dce..1c6262e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.odbc.jdbc;
+import java.io.IOException;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.internal.binary.BinaryReaderExImpl;
import org.apache.ignite.internal.binary.BinaryWriterExImpl;
@@ -47,6 +48,9 @@ public class JdbcQueryExecuteRequest extends JdbcRequest {
@GridToStringInclude(sensitive = true)
private Object[] args;
+ /** Expected statement type. */
+ private JdbcStatementType stmtType;
+
/**
*/
JdbcQueryExecuteRequest() {
@@ -54,14 +58,15 @@ public class JdbcQueryExecuteRequest extends JdbcRequest {
}
/**
+ * @param stmtType Expected statement type.
* @param schemaName Cache name.
* @param pageSize Fetch size.
* @param maxRows Max rows.
* @param sqlQry SQL query.
* @param args Arguments list.
*/
- public JdbcQueryExecuteRequest(String schemaName, int pageSize, int maxRows, String sqlQry,
- Object[] args) {
+ public JdbcQueryExecuteRequest(JdbcStatementType stmtType, String schemaName, int pageSize, int maxRows,
+ String sqlQry, Object[] args) {
super(QRY_EXEC);
this.schemaName = F.isEmpty(schemaName) ? null : schemaName;
@@ -69,6 +74,7 @@ public class JdbcQueryExecuteRequest extends JdbcRequest {
this.maxRows = maxRows;
this.sqlQry = sqlQry;
this.args = args;
+ this.stmtType = stmtType;
}
/**
@@ -106,6 +112,13 @@ public class JdbcQueryExecuteRequest extends JdbcRequest {
return schemaName;
}
+ /**
+ * @return Expected statement type.
+ */
+ public JdbcStatementType expectedStatementType() {
+ return stmtType;
+ }
+
/** {@inheritDoc} */
@Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
super.writeBinary(writer);
@@ -121,6 +134,8 @@ public class JdbcQueryExecuteRequest extends JdbcRequest {
for (Object arg : args)
SqlListenerUtils.writeObject(writer, arg, false);
}
+
+ writer.writeByte((byte)stmtType.ordinal());
}
/** {@inheritDoc} */
@@ -138,6 +153,16 @@ public class JdbcQueryExecuteRequest extends JdbcRequest {
for (int i = 0; i < argsNum; ++i)
args[i] = SqlListenerUtils.readObject(reader, false);
+
+ try {
+ if (reader.available() > 0)
+ stmtType = JdbcStatementType.values()[reader.readByte()];
+ else
+ stmtType = JdbcStatementType.ANY_STATEMENT_TYPE;
+ }
+ catch (IOException e) {
+ throw new BinaryObjectException(e);
+ }
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index d2508a6..3ccc195 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -28,13 +28,13 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
-import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteVersionUtils;
import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.jdbc2.JdbcSqlFieldsQuery;
import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
import org.apache.ignite.internal.processors.odbc.SqlListenerRequestHandler;
@@ -223,7 +223,24 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler {
try {
String sql = req.sqlQuery();
- SqlFieldsQuery qry = new SqlFieldsQuery(sql);
+ SqlFieldsQuery qry;
+
+ switch(req.expectedStatementType()) {
+ case ANY_STATEMENT_TYPE:
+ qry = new SqlFieldsQuery(sql);
+
+ break;
+
+ case SELECT_STATEMENT_TYPE:
+ qry = new JdbcSqlFieldsQuery(sql, true);
+
+ break;
+
+ default:
+ assert req.expectedStatementType() == JdbcStatementType.UPDATE_STMT_TYPE;
+
+ qry = new JdbcSqlFieldsQuery(sql, false);
+ }
qry.setArgs(req.arguments());
@@ -389,7 +406,7 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler {
if (q.sql() != null)
sql = q.sql();
- SqlFieldsQuery qry = new SqlFieldsQuery(sql);
+ SqlFieldsQuery qry = new JdbcSqlFieldsQuery(sql, false);
qry.setArgs(q.args());
@@ -404,9 +421,7 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler {
QueryCursorImpl<List<?>> qryCur = (QueryCursorImpl<List<?>>)ctx.query()
.querySqlFieldsNoCache(qry, true);
- if (qryCur.isQuery())
- throw new IgniteCheckedException("Query produced result set [qry=" + q.sql() + ", args=" +
- Arrays.toString(q.args()) + ']');
+ assert !qryCur.isQuery();
List<List<?>> items = qryCur.getAll();
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd78616/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java
new file mode 100644
index 0000000..aec2d12
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java
@@ -0,0 +1,32 @@
+/*
+ * 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.ignite.internal.processors.odbc.jdbc;
+
+/**
+ * JDBC statement type.
+ */
+public enum JdbcStatementType {
+ /** Any statement type. */
+ ANY_STATEMENT_TYPE,
+
+ /** Select statement type. */
+ SELECT_STATEMENT_TYPE,
+
+ /** DML / DDL statement type. */
+ UPDATE_STMT_TYPE;
+}