You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/09/13 08:06:45 UTC
[01/12] 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.
Repository: ignite
Updated Branches:
refs/heads/ignite-6149 072322f90 -> 16e52541e
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-6149
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;
+}
[12/12] ignite git commit: ignite-6149
Posted by sb...@apache.org.
ignite-6149
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/16e52541
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/16e52541
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/16e52541
Branch: refs/heads/ignite-6149
Commit: 16e52541ef799f1e135576636a69d89591a1fee2
Parents: b5cac1c
Author: sboikov <sb...@gridgain.com>
Authored: Wed Sep 13 11:06:37 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Sep 13 11:06:37 2017 +0300
----------------------------------------------------------------------
.../cache/query/GridCacheQueryAdapter.java | 7 ++++
.../cache/query/GridCacheQueryManager.java | 40 +++++++++++++++++---
2 files changed, 42 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/16e52541/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryAdapter.java
index 27b05c7..47e7e54 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryAdapter.java
@@ -261,6 +261,13 @@ public class GridCacheQueryAdapter<T> implements CacheQuery<T> {
}
/**
+ * @param mvccVer Mvcc version.
+ */
+ void mvccVersion(MvccCoordinatorVersion mvccVer) {
+ this.mvccVer = mvccVer;
+ }
+
+ /**
* @return Mvcc version.
*/
@Nullable MvccCoordinatorVersion mvccVersion() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/16e52541/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
index 069c863..075e492 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
@@ -76,6 +76,7 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtUnreservedPartitionException;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccCoordinatorVersion;
import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor;
@@ -613,7 +614,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
taskName));
}
- iter = scanIterator(qry, false);
+ iter = scanIterator(qry, false, null);
break;
@@ -819,11 +820,12 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
/**
* @param qry Query.
* @param locNode Local node.
+ * @param mvccCrd Non null mvcc coordinator node if need ack mvcc query as finished on iterator close.
* @return Full-scan row iterator.
* @throws IgniteCheckedException If failed to get iterator.
*/
@SuppressWarnings({"unchecked"})
- private GridCloseableIterator scanIterator(final GridCacheQueryAdapter<?> qry, boolean locNode)
+ private GridCloseableIterator scanIterator(final GridCacheQueryAdapter<?> qry, boolean locNode, ClusterNode mvccCrd)
throws IgniteCheckedException {
final IgniteBiPredicate<K, V> keyValFilter = qry.scanFilter();
@@ -870,7 +872,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
it = cctx.offheap().cacheIterator(cctx.cacheId(), true, backups, topVer, qry.mvccVersion());
}
- return new ScanQueryIterator(it, qry, topVer, locPart, keyValFilter, locNode, cctx, log);
+ return new ScanQueryIterator(it, qry, topVer, locPart, keyValFilter, locNode, cctx, mvccCrd, log);
}
catch (IgniteCheckedException | RuntimeException e) {
closeScanFilter(keyValFilter);
@@ -1459,7 +1461,20 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
taskName));
}
- GridCloseableIterator it = scanIterator(qry, true);
+ final ClusterNode mvccCrd;
+
+ // TODO IGNITE-3478.
+ if (cctx.mvccEnabled()) {
+ mvccCrd = cctx.shared().coordinators().coordinator(cctx.shared().exchange().readyAffinityVersion());
+
+ IgniteInternalFuture<MvccCoordinatorVersion> fut0 = cctx.shared().coordinators().requestQueryCounter(mvccCrd);
+
+ qry.mvccVersion(fut0.get());
+ }
+ else
+ mvccCrd = null;
+
+ GridCloseableIterator it = scanIterator(qry, true, mvccCrd);
updateStatistics = false;
@@ -2899,6 +2914,12 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
/** */
private IgniteCacheExpiryPolicy expiryPlc;
+ /** */
+ private ClusterNode mvccCrd;
+
+ /** */
+ private MvccCoordinatorVersion mvccVer;
+
/**
* @param it Iterator.
* @param qry Query.
@@ -2917,19 +2938,25 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
IgniteBiPredicate<K, V> scanFilter,
boolean locNode,
GridCacheContext cctx,
+ ClusterNode mvccCrd,
IgniteLogger log) {
+ assert mvccCrd == null || qry.mvccVersion() != null;
+
this.it = it;
this.topVer = topVer;
this.locPart = locPart;
this.scanFilter = scanFilter;
this.cctx = cctx;
+ this.mvccCrd = mvccCrd;
+ this.mvccVer = qry.mvccVersion();
+
this.log = log;
statsEnabled = locNode && cctx.config().isStatisticsEnabled();
readEvt = locNode && cctx.gridEvents().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
- if(readEvt){
+ if (readEvt){
taskName = cctx.kernalContext().task().resolveTaskName(qry.taskHash());
subjId = qry.subjectId();
}
@@ -2976,6 +3003,9 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
/** {@inheritDoc} */
@Override protected void onClose() {
+ if (mvccCrd != null)
+ dht.context().shared().coordinators().ackQueryDone(mvccCrd, mvccVer.counter());
+
if (expiryPlc != null && dht != null) {
dht.sendTtlUpdateRequest(expiryPlc);
[10/12] ignite git commit: IGNITE-6363 Added refresh icon.
Posted by sb...@apache.org.
IGNITE-6363 Added refresh icon.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/cc3ab699
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/cc3ab699
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/cc3ab699
Branch: refs/heads/ignite-6149
Commit: cc3ab6999a997bfe7247fc5ff8c4aaa5955c7a2e
Parents: 67d716f
Author: vsisko <vs...@gridgain.com>
Authored: Wed Sep 13 13:39:28 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Sep 13 13:39:28 2017 +0700
----------------------------------------------------------------------
modules/web-console/frontend/public/images/icons/index.js | 1 +
modules/web-console/frontend/public/images/icons/refresh.svg | 1 +
2 files changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/cc3ab699/modules/web-console/frontend/public/images/icons/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/images/icons/index.js b/modules/web-console/frontend/public/images/icons/index.js
index 2609550..5d8ac53 100644
--- a/modules/web-console/frontend/public/images/icons/index.js
+++ b/modules/web-console/frontend/public/images/icons/index.js
@@ -23,3 +23,4 @@ export manual from './manual.svg';
export download from './download.svg';
export filter from './filter.svg';
export search from './search.svg';
+export refresh from './refresh.svg';
http://git-wip-us.apache.org/repos/asf/ignite/blob/cc3ab699/modules/web-console/frontend/public/images/icons/refresh.svg
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/images/icons/refresh.svg b/modules/web-console/frontend/public/images/icons/refresh.svg
new file mode 100644
index 0000000..4252e88
--- /dev/null
+++ b/modules/web-console/frontend/public/images/icons/refresh.svg
@@ -0,0 +1 @@
+<svg id="refresh-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 20"><path d="M7 5.1v2.6l3.5-3.5L7 .7v2.6c-3.9 0-7 3.1-7 7C0 11.7.4 13 1.1 14l1.3-1.3c-.4-.7-.6-1.6-.6-2.5C1.7 7.4 4.1 5.1 7 5.1zm5.9 1.5l-1.3 1.3c.4.7.6 1.6.6 2.5 0 2.9-2.4 5.2-5.2 5.2V13l-3.5 3.5L7 20v-2.6c3.9 0 7-3.1 7-7 0-1.4-.4-2.7-1.1-3.8z" fill="currentColor"/></svg>
[11/12] ignite git commit: Merge remote-tracking branch
'remotes/origin/master' into ignite-6149
Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into ignite-6149
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b5cac1c0
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b5cac1c0
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b5cac1c0
Branch: refs/heads/ignite-6149
Commit: b5cac1c0d818967553c72d4699d1c66c57c1fb10
Parents: 072322f cc3ab69
Author: sboikov <sb...@gridgain.com>
Authored: Wed Sep 13 10:36:42 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Sep 13 10:36:42 2017 +0300
----------------------------------------------------------------------
assembly/release-fabric-base.xml | 2 +-
.../ignite/jdbc/thin/JdbcThinBatchSelfTest.java | 2 +-
.../jdbc/thin/JdbcThinStatementSelfTest.java | 41 +
.../org/apache/ignite/cache/QueryEntity.java | 32 +-
.../jdbc/thin/JdbcThinPreparedStatement.java | 12 +-
.../internal/jdbc/thin/JdbcThinStatement.java | 12 +-
.../internal/jdbc/thin/JdbcThinTcpIo.java | 6 +-
.../internal/jdbc2/JdbcSqlFieldsQuery.java | 2 +-
.../processors/cache/GridCacheContext.java | 26 +
.../processors/cache/GridCacheMapEntry.java | 23 +
.../distributed/dht/GridDhtTxPrepareFuture.java | 3 +
.../dht/atomic/GridDhtAtomicCache.java | 43 +-
.../GridNearAtomicSingleUpdateFuture.java | 9 +-
.../dht/atomic/GridNearAtomicUpdateFuture.java | 9 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 2 +-
.../cache/distributed/near/GridNearTxLocal.java | 14 +-
.../local/atomic/GridLocalAtomicCache.java | 21 +-
.../transactions/IgniteTxLocalAdapter.java | 2 +
.../odbc/jdbc/JdbcQueryExecuteRequest.java | 29 +-
.../odbc/jdbc/JdbcRequestHandler.java | 27 +-
.../processors/odbc/jdbc/JdbcStatementType.java | 32 +
.../processors/query/GridQueryProcessor.java | 28 +-
.../processors/query/GridQueryProperty.java | 7 +
.../query/GridQueryTypeDescriptor.java | 10 +
.../internal/processors/query/QueryField.java | 14 +-
.../internal/processors/query/QuerySchema.java | 11 +-
.../query/QueryTypeDescriptorImpl.java | 30 +
.../internal/processors/query/QueryUtils.java | 42 +-
.../query/property/QueryBinaryProperty.java | 12 +-
.../query/property/QueryClassProperty.java | 16 +-
.../query/h2/DmlStatementsProcessor.java | 10 +-
.../processors/query/h2/IgniteH2Indexing.java | 3 +-
.../query/h2/ddl/DdlStatementsProcessor.java | 18 +-
.../processors/query/h2/opt/GridH2Table.java | 6 +-
.../query/h2/sql/GridSqlCreateTable.java | 18 +
.../query/h2/sql/GridSqlQueryParser.java | 35 +-
.../cache/index/DynamicColumnsAbstractTest.java | 18 +-
.../H2DynamicColumnsAbstractBasicSelfTest.java | 28 +
.../cache/index/H2DynamicTableSelfTest.java | 95 +-
.../IgnitePersistentStoreSchemaLoadTest.java | 16 +-
.../query/IgniteSqlNotNullConstraintTest.java | 1060 ++++++++++++++++++
.../h2/GridIndexingSpiAbstractSelfTest.java | 10 +
.../query/h2/sql/GridQueryParsingTest.java | 25 +-
.../IgniteCacheQuerySelfTestSuite.java | 2 +
modules/platforms/cpp/odbc-test/Makefile.am | 1 +
.../cpp/odbc-test/project/vs/odbc-test.vcxproj | 1 +
.../project/vs/odbc-test.vcxproj.filters | 3 +
.../cpp/odbc-test/src/attributes_test.cpp | 208 ++++
.../platforms/cpp/odbc/include/ignite/odbc.h | 22 +-
.../cpp/odbc/include/ignite/odbc/connection.h | 47 +
modules/platforms/cpp/odbc/src/connection.cpp | 100 +-
modules/platforms/cpp/odbc/src/entry_points.cpp | 65 +-
modules/platforms/cpp/odbc/src/odbc.cpp | 46 +-
.../Cache/CacheAbstractTest.cs | 67 +-
.../Dataload/DataStreamerTest.cs | 49 +
.../Impl/Binary/BinaryWriterExtensions.cs | 8 +-
.../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs | 52 +-
.../Impl/Compute/ComputeImpl.cs | 2 +-
.../Impl/Datastream/DataStreamerBatch.cs | 10 +-
.../Impl/Services/ServiceProxySerializer.cs | 10 +-
.../frontend/public/images/icons/index.js | 1 +
.../frontend/public/images/icons/refresh.svg | 1 +
62 files changed, 2318 insertions(+), 238 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5cac1c0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
[06/12] ignite git commit: IGNITE-5648: SQL: Added support for NOT
NULL constraint. This closes #2341.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
new file mode 100644
index 0000000..dab474e
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
@@ -0,0 +1,1060 @@
+/*
+ * 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.query;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import javax.cache.CacheException;
+import javax.cache.processor.EntryProcessor;
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.EntryProcessorResult;
+import javax.cache.processor.MutableEntry;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.MemoryConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.jetbrains.annotations.Nullable;
+
+/** */
+public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
+ /** IP finder. */
+ private static final TcpDiscoveryVmIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** Name of client node. */
+ private static String NODE_CLIENT = "client";
+
+ /** Number of server nodes. */
+ private static int NODE_COUNT = 2;
+
+ /** Cache prefix. */
+ private static String CACHE_PREFIX = "person";
+
+ /** Transactional person cache. */
+ private static String CACHE_PERSON = "person-PARTITIONED-TRANSACTIONAL";
+
+ /** Name of SQL table. */
+ private static String TABLE_PERSON = "\"" + CACHE_PERSON + "\".\"PERSON\"";
+
+ /** Expected error message. */
+ private static String ERR_MSG = "Null value is not allowed for field 'NAME'";
+
+ /** OK value. */
+ private final Person okValue = new Person("Name", 18);
+
+ /** Bad value, violating constraint. */
+ private final Person badValue = new Person(null, 25);
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration c = super.getConfiguration(gridName);
+
+ TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+ disco.setIpFinder(IP_FINDER);
+ disco.setForceServerMode(true);
+
+ c.setDiscoverySpi(disco);
+
+ List<CacheConfiguration> ccfgs = new ArrayList<>();
+
+ ccfgs.addAll(cacheConfigurations());
+
+ c.setCacheConfiguration(ccfgs.toArray(new CacheConfiguration[ccfgs.size()]));
+
+ if (gridName.equals(NODE_CLIENT)) {
+ c.setClientMode(true);
+
+ // Not allowed to have local cache on client without memory config
+ c.setMemoryConfiguration(new MemoryConfiguration());
+ }
+
+ return c;
+ }
+
+ /** */
+ private List<CacheConfiguration> cacheConfigurations() {
+ List<CacheConfiguration> res = new ArrayList<>();
+
+ for (boolean wrt : new boolean[] { false, true}) {
+ res.add(buildCacheConfiguration(CacheMode.LOCAL, CacheAtomicityMode.ATOMIC, false, wrt));
+ res.add(buildCacheConfiguration(CacheMode.LOCAL, CacheAtomicityMode.TRANSACTIONAL, false, wrt));
+
+ res.add(buildCacheConfiguration(CacheMode.REPLICATED, CacheAtomicityMode.ATOMIC, false, wrt));
+ res.add(buildCacheConfiguration(CacheMode.REPLICATED, CacheAtomicityMode.TRANSACTIONAL, false, wrt));
+
+ res.add(buildCacheConfiguration(CacheMode.PARTITIONED, CacheAtomicityMode.ATOMIC, false, wrt));
+ res.add(buildCacheConfiguration(CacheMode.PARTITIONED, CacheAtomicityMode.ATOMIC, true, wrt));
+ res.add(buildCacheConfiguration(CacheMode.PARTITIONED, CacheAtomicityMode.TRANSACTIONAL, false, wrt));
+ res.add(buildCacheConfiguration(CacheMode.PARTITIONED, CacheAtomicityMode.TRANSACTIONAL, true, wrt));
+ }
+
+ return res;
+ }
+
+ /** */
+ private CacheConfiguration buildCacheConfiguration(CacheMode mode,
+ CacheAtomicityMode atomicityMode, boolean hasNear, boolean writeThrough) {
+
+ CacheConfiguration cfg = new CacheConfiguration(CACHE_PREFIX + "-" +
+ mode.name() + "-" + atomicityMode.name() + (hasNear ? "-near" : "") +
+ (writeThrough ? "-writethrough" : ""));
+
+ cfg.setCacheMode(mode);
+ cfg.setAtomicityMode(atomicityMode);
+ cfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+
+ QueryEntity qe = new QueryEntity(Integer.class, Person.class);
+
+ qe.setNotNullFields(Collections.singleton("name"));
+
+ cfg.setQueryEntities(F.asList(qe));
+
+ if (hasNear)
+ cfg.setNearConfiguration(new NearCacheConfiguration().setNearStartSize(100));
+
+ if (writeThrough) {
+ cfg.setCacheStoreFactory(singletonFactory(new TestStore()));
+ cfg.setWriteThrough(true);
+ }
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGrids(NODE_COUNT);
+
+ startGrid(NODE_CLIENT);
+
+ awaitPartitionMapExchange();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ cleanup();
+ }
+
+ /** */
+ public void testQueryEntityGetSetNotNullFields() throws Exception {
+ QueryEntity qe = new QueryEntity();
+
+ assertNull(qe.getNotNullFields());
+
+ Set<String> val = Collections.singleton("test");
+
+ qe.setNotNullFields(val);
+
+ assertEquals(val, Collections.singleton("test"));
+
+ qe.setNotNullFields(null);
+
+ assertNull(qe.getNotNullFields());
+ }
+
+ /** */
+ public void testQueryEntityEquals() throws Exception {
+ QueryEntity a = new QueryEntity();
+
+ QueryEntity b = new QueryEntity();
+
+ assertEquals(a, b);
+
+ a.setNotNullFields(Collections.singleton("test"));
+
+ assertFalse(a.equals(b));
+
+ b.setNotNullFields(Collections.singleton("test"));
+
+ assertTrue(a.equals(b));
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxPut() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ cache.put(key1, okValue);
+
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ cache.put(key2, badValue);
+
+ return null;
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxPutIfAbsent() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ cache.putIfAbsent(key1, badValue);
+
+ return null;
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+
+ assertEquals(0, cache.size());
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxGetAndPut() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ cache.getAndPut(key1, badValue);
+
+ return null;
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+
+ assertEquals(0, cache.size());
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxGetAndPutIfAbsent() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ assertEquals(0, cache.size());
+
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return cache.getAndPutIfAbsent(key1, badValue);
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+
+ assertEquals(0, cache.size());
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxReplace() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ cache.put(key1, okValue);
+
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return cache.replace(key1, badValue);
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+
+ assertEquals(1, cache.size());
+ assertEquals(okValue, cache.get(key1));
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxGetAndReplace() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ cache.put(key1, okValue);
+
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return cache.getAndReplace(key1, badValue);
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+
+ assertEquals(1, cache.size());
+ assertEquals(okValue, cache.get(key1));
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxPutAll() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ Throwable t = GridTestUtils.assertThrowsWithCause(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ cache.putAll(F.asMap(key1, okValue, key2, badValue));
+
+ return null;
+ }
+ }, IgniteSQLException.class);
+
+ IgniteSQLException ex = X.cause(t, IgniteSQLException.class);
+
+ assertNotNull(ex);
+
+ assertTrue(ex.getMessage().contains(ERR_MSG));
+
+ assertEquals(isLocalAtomic() ? 1 : 0, cache.size());
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxInvoke() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return cache.invoke(key1, new TestEntryProcessor(badValue));
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+
+ assertEquals(0, cache.size());
+ }
+ });
+ }
+
+ /** */
+ public void testAtomicOrImplicitTxInvokeAll() throws Exception {
+ executeWithAllCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ final Map<Integer, EntryProcessorResult<Object>> r = cache.invokeAll(F.asMap(
+ key1, new TestEntryProcessor(okValue),
+ key2, new TestEntryProcessor(badValue)));
+
+ assertNotNull(r);
+
+ GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return r.get(key2).get();
+ }
+ }, IgniteCheckedException.class, ERR_MSG);
+
+ assertEquals(1, cache.size());
+ }
+ });
+ }
+
+ /** */
+ public void testTxPutCreate() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.put(key1, okValue);
+ cache.put(key2, badValue);
+
+ tx.commit();
+ }
+
+ assertEquals(0, cache.size());
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxPutUpdate() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.put(key1, okValue);
+ cache.put(key2, okValue);
+ cache.put(key2, badValue);
+
+ tx.commit();
+ }
+
+ assertEquals(0, cache.size());
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxPutIfAbsent() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.putIfAbsent(key1, badValue);
+
+ tx.commit();
+ }
+
+ assertEquals(0, cache.size());
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxGetAndPut() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.getAndPut(key1, badValue);
+
+ tx.commit();
+ }
+
+ assertEquals(0, cache.size());
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxGetAndPutIfAbsent() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.getAndPutIfAbsent(key1, badValue);
+
+ tx.commit();
+ }
+
+ assertEquals(0, cache.size());
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxReplace() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ cache.put(1, okValue);
+
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.replace(key1, badValue);
+
+ tx.commit();
+ }
+
+ assertEquals(1, cache.size());
+ assertEquals(okValue, cache.get(key1));
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxGetAndReplace() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ cache.put(key1, okValue);
+
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.getAndReplace(key1, badValue);
+
+ tx.commit();
+ }
+
+ assertEquals(1, cache.size());
+ assertEquals(okValue, cache.get(key1));
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxPutAll() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.putAll(F.asMap(key1, okValue, key2, badValue));
+
+ tx.commit();
+ }
+
+ assertEquals(0, cache.size());
+
+ return null;
+ }
+ }, CacheException.class, ERR_MSG);
+ }
+ });
+ }
+
+ /** */
+ public void testTxInvoke() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+ cache.put(key1, okValue);
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ cache.invoke(key1, new TestEntryProcessor(badValue));
+
+ tx.commit();
+ }
+
+ return null;
+ }
+ }, EntryProcessorException.class, ERR_MSG);
+
+ assertEquals(1, cache.size());
+ assertEquals(okValue, cache.get(key1));
+ }
+ });
+ }
+
+ /** */
+ public void testTxInvokeAll() throws Exception {
+ executeWithAllTxCaches(new TestClosure() {
+ @Override public void run() throws Exception {
+
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
+ final Map<Integer, EntryProcessorResult<Object>> r = cache.invokeAll(F.asMap(
+ key1, new TestEntryProcessor(okValue),
+ key2, new TestEntryProcessor(badValue)));
+
+ assertNotNull(r);
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return r.get(key2).get();
+ }
+ }, EntryProcessorException.class, ERR_MSG);
+
+ tx.rollback();
+ }
+
+ assertEquals(0, cache.size());
+ }
+ });
+ }
+
+ /** */
+ public void testDynamicTableCreateNotNullFieldsAllowed() throws Exception {
+ executeSql("CREATE TABLE test(id INT PRIMARY KEY, field INT NOT NULL)");
+
+ String cacheName = QueryUtils.createTableCacheName("PUBLIC", "TEST");
+
+ IgniteEx client = grid(NODE_CLIENT);
+
+ CacheConfiguration ccfg = client.context().cache().cache(cacheName).configuration();
+
+ QueryEntity qe = (QueryEntity)F.first(ccfg.getQueryEntities());
+
+ assertEquals(Collections.singleton("FIELD"), qe.getNotNullFields());
+
+ checkState("PUBLIC", "TEST", "FIELD");
+ }
+
+ /** */
+ public void testAlterTableAddColumnNotNullFieldAllowed() throws Exception {
+ executeSql("CREATE TABLE test(id INT PRIMARY KEY, age INT)");
+
+ executeSql("ALTER TABLE test ADD COLUMN name CHAR NOT NULL");
+
+ checkState("PUBLIC", "TEST", "NAME");
+ }
+
+ /** */
+ public void testAtomicNotNullCheckDmlInsertValues() throws Exception {
+ checkNotNullCheckDmlInsertValues(CacheAtomicityMode.ATOMIC);
+ }
+
+ /** */
+ public void testTransactionalNotNullCheckDmlInsertValues() throws Exception {
+ checkNotNullCheckDmlInsertValues(CacheAtomicityMode.TRANSACTIONAL);
+ }
+
+ /** */
+ private void checkNotNullCheckDmlInsertValues(CacheAtomicityMode atomicityMode) throws Exception {
+ executeSql("CREATE TABLE test(id INT PRIMARY KEY, name VARCHAR NOT NULL) WITH \"atomicity="
+ + atomicityMode.name() + "\"");
+
+ GridTestUtils.assertThrows(log(), new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ executeSql("INSERT INTO test(id, name) " +
+ "VALUES (1, 'ok'), (2, NULLIF('a', 'a')), (3, 'ok')");
+
+ return null;
+ }
+ }, IgniteSQLException.class, ERR_MSG);
+
+ List<List<?>> result = executeSql("SELECT id, name FROM test ORDER BY id");
+
+ assertEquals(0, result.size());
+
+ executeSql("INSERT INTO test(id, name) VALUES (1, 'ok'), (2, 'ok2'), (3, 'ok3')");
+
+ result = executeSql("SELECT id, name FROM test ORDER BY id");
+
+ assertEquals(3, result.size());
+ }
+
+ /** */
+ public void testAtomicAddColumnNotNullCheckDmlInsertValues() throws Exception {
+ checkAddColumnNotNullCheckDmlInsertValues(CacheAtomicityMode.ATOMIC);
+ }
+
+ /** */
+ public void testTransactionalAddColumnNotNullCheckDmlInsertValues() throws Exception {
+ checkAddColumnNotNullCheckDmlInsertValues(CacheAtomicityMode.TRANSACTIONAL);
+ }
+
+ /** */
+ private void checkAddColumnNotNullCheckDmlInsertValues(CacheAtomicityMode atomicityMode) throws Exception {
+ executeSql("CREATE TABLE test(id INT PRIMARY KEY, age INT) WITH \"atomicity="
+ + atomicityMode.name() + "\"");
+
+ executeSql("ALTER TABLE test ADD COLUMN name VARCHAR NOT NULL");
+
+ GridTestUtils.assertThrows(log(), new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ executeSql("INSERT INTO test(id, name, age) " +
+ "VALUES (1, 'ok', 1), (2, NULLIF('a', 'a'), 2), (3, 'ok', 3)");
+
+ return null;
+ }
+ }, IgniteSQLException.class, ERR_MSG);
+
+ List<List<?>> result = executeSql("SELECT id, name, age FROM test ORDER BY id");
+
+ assertEquals(0, result.size());
+
+ executeSql("INSERT INTO test(id, name) VALUES (1, 'ok'), (2, 'ok2'), (3, 'ok3')");
+
+ result = executeSql("SELECT id, name FROM test ORDER BY id");
+
+ assertEquals(3, result.size());
+ }
+
+ /** */
+ public void testNotNullCheckDmlInsertFromSelect() throws Exception {
+ executeSql("CREATE TABLE test(id INT PRIMARY KEY, name VARCHAR, age INT)");
+
+ executeSql("INSERT INTO test(id, name, age) VALUES (1, 'Macy', 25), (2, null, 25), (3, 'John', 30)");
+
+ GridTestUtils.assertThrows(log(), new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return executeSql("INSERT INTO " + TABLE_PERSON +
+ "(_key, name, age) " +
+ "SELECT id, name, age FROM test");
+ }
+ }, IgniteSQLException.class, ERR_MSG);
+
+ List<List<?>> result = executeSql("SELECT _key, name FROM " + TABLE_PERSON + " ORDER BY _key");
+
+ assertEquals(0, result.size());
+
+ executeSql("DELETE FROM test WHERE id = 2");
+
+ result = executeSql("INSERT INTO " + TABLE_PERSON + "(_key, name, age) " + "SELECT id, name, age FROM test");
+
+ assertEquals(2L, result.get(0).get(0));
+ }
+
+ /** */
+ public void testNotNullCheckDmlUpdateValues() throws Exception {
+ executeSql("CREATE TABLE test(id INT PRIMARY KEY, name VARCHAR NOT NULL)");
+
+ executeSql("INSERT INTO test(id, name) VALUES (1, 'John')");
+
+ GridTestUtils.assertThrows(log(), new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return executeSql("UPDATE test SET name = NULLIF(id, 1) WHERE id = 1");
+ }
+ }, IgniteSQLException.class, ERR_MSG);
+
+ List<List<?>> result = executeSql("SELECT id, name FROM test");
+
+ assertEquals(1, result.size());
+ assertEquals(1, result.get(0).get(0));
+ assertEquals("John", result.get(0).get(1));
+
+ executeSql("UPDATE test SET name = 'James' WHERE id = 1");
+
+ result = executeSql("SELECT id, name FROM test");
+
+ assertEquals(1, result.get(0).get(0));
+ assertEquals("James", result.get(0).get(1));
+ }
+
+ /** */
+ public void testNotNullCheckDmlUpdateFromSelect() throws Exception {
+ executeSql("CREATE TABLE src(id INT PRIMARY KEY, name VARCHAR)");
+ executeSql("CREATE TABLE dest(id INT PRIMARY KEY, name VARCHAR NOT NULL)");
+
+ executeSql("INSERT INTO dest(id, name) VALUES (1, 'William'), (2, 'Warren'), (3, 'Robert')");
+ executeSql("INSERT INTO src(id, name) VALUES (1, 'Bill'), (2, null), (3, 'Bob')");
+
+ GridTestUtils.assertThrows(log(), new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ return executeSql("UPDATE dest" +
+ " p SET (name) = " +
+ "(SELECT name FROM src t WHERE p.id = t.id)");
+ }
+ }, IgniteSQLException.class, ERR_MSG);
+
+ List<List<?>> result = executeSql("SELECT id, name FROM dest ORDER BY id");
+
+ assertEquals(3, result.size());
+
+ assertEquals(1, result.get(0).get(0));
+ assertEquals("William", result.get(0).get(1));
+
+ assertEquals(2, result.get(1).get(0));
+ assertEquals("Warren", result.get(1).get(1));
+
+ assertEquals(3, result.get(2).get(0));
+ assertEquals("Robert", result.get(2).get(1));
+
+ executeSql("UPDATE src SET name = 'Ren' WHERE id = 2");
+
+ executeSql("UPDATE dest p SET (name) = (SELECT name FROM src t WHERE p.id = t.id)");
+
+ result = executeSql("SELECT id, name FROM dest ORDER BY id");
+
+ assertEquals(3, result.size());
+
+ assertEquals(1, result.get(0).get(0));
+ assertEquals("Bill", result.get(0).get(1));
+
+ assertEquals(2, result.get(1).get(0));
+ assertEquals("Ren", result.get(1).get(1));
+
+ assertEquals(3, result.get(2).get(0));
+ assertEquals("Bob", result.get(2).get(1));
+ }
+
+ /** */
+ private void executeWithAllCaches(TestClosure clo) throws Exception {
+ for (CacheConfiguration ccfg : cacheConfigurations())
+ executeForCache(ccfg, clo, TransactionConcurrency.OPTIMISTIC, TransactionIsolation.READ_COMMITTED);
+ }
+
+ /** */
+ private void executeWithAllTxCaches(final TestClosure clo) throws Exception {
+ for (CacheConfiguration ccfg : cacheConfigurations()) {
+ if (ccfg.getAtomicityMode() == CacheAtomicityMode.TRANSACTIONAL) {
+ for (TransactionConcurrency con : TransactionConcurrency.values()) {
+ for (TransactionIsolation iso : TransactionIsolation.values())
+ executeForCache(ccfg, clo, con, iso);
+ }
+ }
+ }
+ }
+
+ /** */
+ private void executeForCache(CacheConfiguration ccfg, TestClosure clo, TransactionConcurrency concurrency,
+ TransactionIsolation isolation) throws Exception {
+
+ Ignite ignite = grid(NODE_CLIENT);
+ executeForNodeAndCache(ccfg, ignite, clo, concurrency, isolation);
+
+ for (int node = 0; node < NODE_COUNT; node++) {
+ ignite = grid(node);
+
+ executeForNodeAndCache(ccfg, ignite, clo, concurrency, isolation);
+ }
+ }
+
+ /** */
+ private void executeForNodeAndCache(CacheConfiguration ccfg, Ignite ignite, TestClosure clo,
+ TransactionConcurrency concurrency, TransactionIsolation isolation) throws Exception {
+ String cacheName = ccfg.getName();
+
+ IgniteCache cache;
+
+ if (ignite.configuration().isClientMode() &&
+ ccfg.getCacheMode() == CacheMode.PARTITIONED &&
+ ccfg.getNearConfiguration() != null)
+ cache = ignite.getOrCreateNearCache(ccfg.getName(), ccfg.getNearConfiguration());
+ else
+ cache = ignite.cache(ccfg.getName());
+
+ cache.removeAll();
+
+ assertEquals(0, cache.size());
+
+ clo.configure(ignite, cache, concurrency, isolation);
+
+ log.info("Running test with node " + ignite.name() + ", cache " + cacheName);
+
+ clo.key1 = 1;
+ clo.key2 = 4;
+
+ clo.run();
+ }
+
+ /** */
+ private List<List<?>> executeSql(String sqlText) throws Exception {
+ GridQueryProcessor qryProc = grid(NODE_CLIENT).context().query();
+
+ return qryProc.querySqlFieldsNoCache(new SqlFieldsQuery(sqlText), true).getAll();
+ }
+
+ /** */
+ private void cleanup() throws Exception {
+ for (CacheConfiguration ccfg: cacheConfigurations()) {
+ String cacheName = ccfg.getName();
+
+ if (ccfg.getCacheMode() == CacheMode.LOCAL) {
+ grid(NODE_CLIENT).cache(cacheName).clear();
+
+ for (int node = 0; node < NODE_COUNT; node++)
+ grid(node).cache(cacheName).clear();
+ }
+ else {
+ if (ccfg.getCacheMode() == CacheMode.PARTITIONED && ccfg.getNearConfiguration() != null) {
+ IgniteCache cache = grid(NODE_CLIENT).getOrCreateNearCache(cacheName, ccfg.getNearConfiguration());
+
+ cache.clear();
+ }
+
+ grid(NODE_CLIENT).cache(cacheName).clear();
+ }
+ }
+
+ executeSql("DROP TABLE test IF EXISTS");
+ }
+
+ /** */
+ private void checkState(String schemaName, String tableName, String fieldName) {
+ IgniteEx client = grid(NODE_CLIENT);
+
+ checkNodeState(client, schemaName, tableName, fieldName);
+
+ for (int i = 0; i < NODE_COUNT; i++)
+ checkNodeState(grid(i), schemaName, tableName, fieldName);
+ }
+
+ /** */
+ private void checkNodeState(IgniteEx node, String schemaName, String tableName, String fieldName) {
+ String cacheName = F.eq(schemaName, QueryUtils.DFLT_SCHEMA) ?
+ QueryUtils.createTableCacheName(schemaName, tableName) : schemaName;
+
+ DynamicCacheDescriptor desc = node.context().cache().cacheDescriptor(cacheName);
+
+ assertNotNull("Cache descriptor not found", desc);
+
+ QuerySchema schema = desc.schema();
+
+ assertNotNull(schema);
+
+ QueryEntity entity = null;
+
+ for (QueryEntity e : schema.entities()) {
+ if (F.eq(tableName, e.getTableName())) {
+ entity = e;
+
+ break;
+ }
+ }
+
+ assertNotNull(entity);
+
+ assertNotNull(entity.getNotNullFields());
+
+ assertTrue(entity.getNotNullFields().contains(fieldName));
+ }
+
+ /** */
+ public static class Person {
+ /** */
+ @QuerySqlField
+ private String name;
+
+ /** */
+ @QuerySqlField
+ private int age;
+
+ /** */
+ public Person(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ /** */
+ @Override public int hashCode() {
+ return (name == null ? 0 : name.hashCode()) ^ age;
+ }
+
+ /** */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (!(o instanceof Person))
+ return false;
+
+ Person other = (Person)o;
+
+ return F.eq(other.name, name) && other.age == age;
+ }
+ }
+
+ /** */
+ public class TestEntryProcessor implements EntryProcessor<Integer, Person, Object> {
+ /** Value to set. */
+ private Person value;
+
+ /** */
+ public TestEntryProcessor(Person value) {
+ this.value = value;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object process(MutableEntry<Integer, Person> entry,
+ Object... objects) throws EntryProcessorException {
+
+ entry.setValue(value);
+
+ return null;
+ }
+ }
+
+ /** */
+ public abstract class TestClosure {
+ /** */
+ protected Ignite ignite;
+
+ /** */
+ protected IgniteCache<Integer, Person> cache;
+
+ /** */
+ protected TransactionConcurrency concurrency;
+
+ /** */
+ protected TransactionIsolation isolation;
+
+ /** */
+ public int key1;
+
+ /** */
+ public int key2;
+
+ /** */
+ public void configure(Ignite ignite, IgniteCache<Integer, Person> cache, TransactionConcurrency concurrency,
+ TransactionIsolation isolation) {
+ this.ignite = ignite;
+ this.cache = cache;
+ this.concurrency = concurrency;
+ this.isolation = isolation;
+ }
+
+ /** */
+ protected boolean isLocalAtomic() {
+ CacheConfiguration cfg = cache.getConfiguration(CacheConfiguration.class);
+
+ return cfg.getCacheMode() == CacheMode.LOCAL && cfg.getAtomicityMode() == CacheAtomicityMode.ATOMIC;
+ }
+
+ /** */
+ public abstract void run() throws Exception;
+ }
+
+ /**
+ * Test store.
+ */
+ private static class TestStore extends CacheStoreAdapter<Integer, Person> {
+ /** {@inheritDoc} */
+ @Override public void loadCache(IgniteBiInClosure<Integer, Person> clo, @Nullable Object... args) {
+ // No-op
+ }
+
+ /** {@inheritDoc} */
+ @Override public Person load(Integer key) {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void write(javax.cache.Cache.Entry<? extends Integer, ? extends Person> e) {
+ // No-op
+ }
+
+ /** {@inheritDoc} */
+ @Override public void delete(Object key) {
+ // No-op
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index e1ab8e6..1ee8a84 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -554,6 +554,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
@Override public GridQueryProperty parent() {
return null;
}
+
+ /** */
+ @Override public boolean notNull() {
+ return false;
+ }
};
}
@@ -643,6 +648,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
@Nullable @Override public String valueFieldAlias() {
return null;
}
+
+ /** {@inheritDoc} */
+ @Override public void validateKeyAndValue(Object key, Object value) throws IgniteCheckedException {
+ // No-op.
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
index 770a375..6a78df3 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
@@ -584,9 +584,9 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
assertCreateTableEquals(
buildCreateTable("sch1", "Person", "cache", F.asList("id"),
false, c("id", Value.INT), c("city", Value.STRING), c("name", Value.STRING),
- c("surname", Value.STRING), c("age", Value.INT)),
+ c("surname", Value.STRING), cn("age", Value.INT)),
"CREATE TABLE sch1.\"Person\" (\"id\" integer PRIMARY KEY, \"city\" varchar," +
- " \"name\" varchar, \"surname\" varchar, \"age\" integer) WITH " +
+ " \"name\" varchar, \"surname\" varchar, \"age\" integer NOT NULL) WITH " +
"\"template=cache\"");
assertParseThrows("create table Person (id int)",
@@ -598,9 +598,6 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
assertParseThrows("create table Person (id int primary key)",
IgniteSQLException.class, "No cache value related columns found");
- assertParseThrows("create table Person (id int primary key, age int not null) WITH \"cacheTemplate=cache\"",
- IgniteSQLException.class, "Non nullable columns are not supported [colName=AGE]");
-
assertParseThrows("create table Person (id int primary key, age int unique) WITH \"template=cache\"",
IgniteSQLException.class, "Too many constraints - only PRIMARY KEY is supported for CREATE TABLE");
@@ -635,6 +632,9 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
assertAlterTableAddColumnEquals(buildAlterTableAddColumn("SCH2", "City", false, true,
c("POPULATION", Value.INT)), "ALTER TABLE IF EXISTS SCH2.\"City\" ADD (population int)");
+ assertAlterTableAddColumnEquals(buildAlterTableAddColumn("SCH2", "City", false, true,
+ cn("POPULATION", Value.INT)), "ALTER TABLE IF EXISTS SCH2.\"City\" ADD (population int NOT NULL)");
+
// There's no table with such name, but H2 parsing does not fail just yet.
assertAlterTableAddColumnEquals(buildAlterTableAddColumn("SCH2", "City", false, false,
c("POPULATION", Value.INT)), "ALTER TABLE SCH2.\"City\" ADD (population int)");
@@ -846,6 +846,21 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
}
/**
+ * Constructs non-nullable column.
+ *
+ * @param name Column name.
+ * @param type Column data type.
+ * @return {@link GridSqlColumn} with given name and type.
+ */
+ private static GridSqlColumn cn(String name, int type) {
+ Column col = new Column(name, type);
+
+ col.setNullable(false);
+
+ return new GridSqlColumn(col, null, name);
+ }
+
+ /**
* Parse SQL and compare it to expected instance of DROP TABLE.
*/
private void assertDropTableEquals(GridSqlDropTable exp, String sql) throws Exception {
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 040d0af..e5e37cc 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -126,6 +126,7 @@ import org.apache.ignite.internal.processors.query.h2.IgniteSqlBigIntegerKeyTest
import org.apache.ignite.internal.processors.query.IgniteQueryDedicatedPoolTest;
import org.apache.ignite.internal.processors.query.IgniteSqlEntryCacheModeAgnosticTest;
import org.apache.ignite.internal.processors.query.IgniteSqlKeyValueFieldsTest;
+import org.apache.ignite.internal.processors.query.IgniteSqlNotNullConstraintTest;
import org.apache.ignite.internal.processors.query.IgniteSqlRoutingTest;
import org.apache.ignite.internal.processors.query.IgniteSqlSchemaIndexingTest;
import org.apache.ignite.internal.processors.query.IgniteSqlSegmentedIndexMultiNodeSelfTest;
@@ -329,6 +330,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
suite.addTestSuite(IgniteCacheDistributedPartitionQueryConfigurationSelfTest.class);
suite.addTestSuite(IgniteSqlKeyValueFieldsTest.class);
suite.addTestSuite(IgniteSqlRoutingTest.class);
+ suite.addTestSuite(IgniteSqlNotNullConstraintTest.class);
suite.addTestSuite(LongIndexNameTest.class);
suite.addTestSuite(GridCacheQuerySqlFieldInlineSizeSelfTest.class);
[07/12] ignite git commit: IGNITE-5648: SQL: Added support for NOT
NULL constraint. This closes #2341.
Posted by sb...@apache.org.
IGNITE-5648: SQL: Added support for NOT NULL constraint. This closes #2341.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/43be051c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/43be051c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/43be051c
Branch: refs/heads/ignite-6149
Commit: 43be051cd33f0e35a5bf05fa3dbe73660d2dcdd2
Parents: 8c23805
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Tue Sep 12 16:53:50 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Sep 12 16:53:50 2017 +0300
----------------------------------------------------------------------
.../org/apache/ignite/cache/QueryEntity.java | 32 +-
.../processors/cache/GridCacheContext.java | 26 +
.../processors/cache/GridCacheMapEntry.java | 23 +
.../distributed/dht/GridDhtTxPrepareFuture.java | 3 +
.../dht/atomic/GridDhtAtomicCache.java | 43 +-
.../GridNearAtomicSingleUpdateFuture.java | 9 +-
.../dht/atomic/GridNearAtomicUpdateFuture.java | 9 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 2 +-
.../cache/distributed/near/GridNearTxLocal.java | 14 +-
.../local/atomic/GridLocalAtomicCache.java | 21 +-
.../transactions/IgniteTxLocalAdapter.java | 2 +
.../processors/query/GridQueryProcessor.java | 21 +-
.../processors/query/GridQueryProperty.java | 7 +
.../query/GridQueryTypeDescriptor.java | 10 +
.../internal/processors/query/QueryField.java | 14 +-
.../internal/processors/query/QuerySchema.java | 11 +-
.../query/QueryTypeDescriptorImpl.java | 30 +
.../internal/processors/query/QueryUtils.java | 42 +-
.../query/property/QueryBinaryProperty.java | 12 +-
.../query/property/QueryClassProperty.java | 16 +-
.../query/h2/DmlStatementsProcessor.java | 10 +-
.../processors/query/h2/IgniteH2Indexing.java | 3 +-
.../query/h2/ddl/DdlStatementsProcessor.java | 15 +-
.../processors/query/h2/opt/GridH2Table.java | 6 +-
.../query/h2/sql/GridSqlQueryParser.java | 4 -
.../cache/index/DynamicColumnsAbstractTest.java | 14 +-
.../H2DynamicColumnsAbstractBasicSelfTest.java | 28 +
.../query/IgniteSqlNotNullConstraintTest.java | 1060 ++++++++++++++++++
.../h2/GridIndexingSpiAbstractSelfTest.java | 10 +
.../query/h2/sql/GridQueryParsingTest.java | 25 +-
.../IgniteCacheQuerySelfTestSuite.java | 2 +
31 files changed, 1475 insertions(+), 49 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
index 6440b48..fe54670 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
@@ -83,6 +83,9 @@ public class QueryEntity implements Serializable {
/** Table name. */
private String tableName;
+ /** Fields that must have non-null value. */
+ private Set<String> notNullFields;
+
/**
* Creates an empty query entity.
*/
@@ -109,6 +112,8 @@ public class QueryEntity implements Serializable {
idxs = other.idxs != null ? new ArrayList<>(other.idxs) : null;
tableName = other.tableName;
+
+ notNullFields = other.notNullFields != null ? new HashSet<>(other.notNullFields) : null;
}
/**
@@ -355,6 +360,27 @@ public class QueryEntity implements Serializable {
}
/**
+ * Gets names of fields that must be checked for null.
+ *
+ * @return Set of names of fields that must have non-null values.
+ */
+ @Nullable public Set<String> getNotNullFields() {
+ return notNullFields;
+ }
+
+ /**
+ * Sets names of fields that must checked for null.
+ *
+ * @param notNullFields Set of names of fields that must have non-null values.
+ * @return {@code this} for chaining.
+ */
+ public QueryEntity setNotNullFields(@Nullable Set<String> notNullFields) {
+ this.notNullFields = notNullFields;
+
+ return this;
+ }
+
+ /**
* Utility method for building query entities programmatically.
* @param fullName Full name of the field.
* @param type Type of the field.
@@ -604,12 +630,14 @@ public class QueryEntity implements Serializable {
F.eq(keyFields, entity.keyFields) &&
F.eq(aliases, entity.aliases) &&
F.eqNotOrdered(idxs, entity.idxs) &&
- F.eq(tableName, entity.tableName);
+ F.eq(tableName, entity.tableName) &&
+ F.eq(notNullFields, entity.notNullFields);
}
/** {@inheritDoc} */
@Override public int hashCode() {
- return Objects.hash(keyType, valType, keyFieldName, valueFieldName, fields, keyFields, aliases, idxs, tableName);
+ return Objects.hash(keyType, valType, keyFieldName, valueFieldName, fields, keyFields, aliases, idxs,
+ tableName, notNullFields);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
index b6faf47..120007f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
@@ -630,6 +630,13 @@ public class GridCacheContext<K, V> implements Externalizable {
}
/**
+ * @return {@code True} in case cache supports query.
+ */
+ public boolean isQueryEnabled() {
+ return !F.isEmpty(cacheCfg.getQueryEntities());
+ }
+
+ /**
* @return {@code True} if entries should not be deleted from cache immediately.
*/
public boolean deferredDelete() {
@@ -1804,6 +1811,25 @@ public class GridCacheContext<K, V> implements Externalizable {
}
/**
+ * Performs validation of provided key and value against configured constraints.
+ *
+ * @param key Key.
+ * @param val Value.
+ * @throws IgniteCheckedException, If validation fails.
+ */
+ public void validateKeyAndValue(KeyCacheObject key, CacheObject val) throws IgniteCheckedException {
+ if (!isQueryEnabled())
+ return;
+
+ try {
+ ctx.query().validateKeyAndValue(cacheObjCtx, key, val);
+ }
+ catch (RuntimeException e) {
+ throw U.cast(e);
+ }
+ }
+
+ /**
* @param map Map.
* @param key Key.
* @param val Value.
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 61f6fb4..958f156 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -1419,6 +1419,9 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
updated0 = cctx.unwrapTemporary(entry.getValue());
updated = cctx.toCacheObject(updated0);
+
+ if (updated != null) // no validation for remove case
+ cctx.validateKeyAndValue(key, updated);
}
else
updated = old;
@@ -4165,6 +4168,26 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
return;
}
+ else if ((invokeRes == null || invokeRes.getValue() == null) && writeObj != null) {
+ try {
+ cctx.validateKeyAndValue(entry.key, (CacheObject)writeObj);
+ }
+ catch (Exception e) {
+ initResultOnCancelUpdate(null, true);
+
+ updateRes = new GridCacheUpdateAtomicResult(UpdateOutcome.INVOKE_NO_OP,
+ oldVal,
+ null,
+ new IgniteBiTuple<>(null, e),
+ CU.TTL_ETERNAL,
+ CU.EXPIRE_TIME_ETERNAL,
+ null,
+ null,
+ 0);
+
+ return;
+ }
+ }
op = writeObj == null ? DELETE : UPDATE;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index 47dcefc..e048696 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -419,6 +419,9 @@ public final class GridDhtTxPrepareFuture extends GridCacheCompoundFuture<Ignite
procRes = processor.process(invokeEntry, t.get2());
val = cacheCtx.toCacheObject(invokeEntry.getValue(true));
+
+ if (val != null) // no validation for remove case
+ cacheCtx.validateKeyAndValue(key, val);
}
catch (Exception e) {
err = e;
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index 7d0f747..a50a707 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@ -2105,35 +2105,52 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(entry.key(), old,
entry.version(), req.keepBinary(), entry);
- CacheObject updated;
+ CacheObject updated = null;
+
+ if (invokeRes == null)
+ invokeRes = new GridCacheReturn(node.isLocal());
+
+ CacheInvokeResult curInvokeRes = null;
+
+ boolean validation = false;
try {
Object computed = entryProcessor.process(invokeEntry, req.invokeArguments());
if (computed != null) {
- if (invokeRes == null)
- invokeRes = new GridCacheReturn(node.isLocal());
-
computed = ctx.unwrapTemporary(computed);
- invokeRes.addEntryProcessResult(ctx, entry.key(), invokeEntry.key(), computed, null,
- req.keepBinary());
+ curInvokeRes = CacheInvokeResult.fromResult(computed);
}
if (!invokeEntry.modified())
continue;
+ else {
+ updatedVal = ctx.unwrapTemporary(invokeEntry.getValue());
+
+ updated = ctx.toCacheObject(updatedVal);
- updatedVal = ctx.unwrapTemporary(invokeEntry.getValue());
+ validation = true;
- updated = ctx.toCacheObject(updatedVal);
+ ctx.validateKeyAndValue(entry.key(), updated);
+ }
}
catch (Exception e) {
- if (invokeRes == null)
- invokeRes = new GridCacheReturn(node.isLocal());
-
- invokeRes.addEntryProcessResult(ctx, entry.key(), invokeEntry.key(), null, e, req.keepBinary());
+ curInvokeRes = CacheInvokeResult.fromError(e);
updated = old;
+
+ if (validation) {
+ res.addSkippedIndex(i);
+
+ continue;
+ }
+ }
+ finally {
+ if (curInvokeRes != null) {
+ invokeRes.addEntryProcessResult(ctx, entry.key(), invokeEntry.key(), curInvokeRes.result(),
+ curInvokeRes.error(), req.keepBinary());
+ }
}
if (updated == null) {
@@ -2272,6 +2289,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
assert updated != null;
+ ctx.validateKeyAndValue(entry.key(), updated);
+
if (putMap == null) {
putMap = new LinkedHashMap<>(size, 1.0f);
writeVals = new ArrayList<>(size);
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java
index 67542ca..b2f9218 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java
@@ -30,6 +30,7 @@ import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
+import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException;
import org.apache.ignite.internal.processors.cache.CacheStoppedException;
import org.apache.ignite.internal.processors.cache.EntryProcessorResourceInjectorProxy;
@@ -48,7 +49,9 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.CREATE;
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE;
/**
* DHT atomic cache near update future.
@@ -542,8 +545,12 @@ public class GridNearAtomicSingleUpdateFuture extends GridNearAtomicAbstractUpda
KeyCacheObject cacheKey = cctx.toCacheKeyObject(key);
- if (op != TRANSFORM)
+ if (op != TRANSFORM) {
val = cctx.toCacheObject(val);
+
+ if (op == CREATE || op == UPDATE)
+ cctx.validateKeyAndValue(cacheKey, (CacheObject)val);
+ }
else
val = EntryProcessorResourceInjectorProxy.wrap(cctx.kernalContext(), (EntryProcessor)val);
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
index 930012a..e516a99 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
@@ -34,6 +34,7 @@ import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
+import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException;
import org.apache.ignite.internal.processors.cache.CacheStoppedException;
import org.apache.ignite.internal.processors.cache.EntryProcessorResourceInjectorProxy;
@@ -57,7 +58,9 @@ import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.CREATE;
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE;
/**
* DHT atomic cache near update future.
@@ -983,8 +986,12 @@ public class GridNearAtomicUpdateFuture extends GridNearAtomicAbstractUpdateFutu
if (remapKeys != null && !remapKeys.contains(cacheKey))
continue;
- if (op != TRANSFORM)
+ if (op != TRANSFORM) {
val = cctx.toCacheObject(val);
+
+ if (op == CREATE || op == UPDATE)
+ cctx.validateKeyAndValue(cacheKey, (CacheObject)val);
+ }
else
val = EntryProcessorResourceInjectorProxy.wrap(cctx.kernalContext(), (EntryProcessor)val);
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index c978848..77c68bd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -445,7 +445,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
ClusterNode primary = updated.primary();
- assert !primary.isLocal() || !cctx.kernalContext().clientNode();
+ assert !primary.isLocal() || !cctx.kernalContext().clientNode() || write.context().isLocal();
// Minor optimization to not create MappingKey: on client node can not have mapping for local node.
Object key = cctx.kernalContext().clientNode() ? primary.id() :
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index a894097..c55276c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -1252,8 +1252,13 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter implements AutoClosea
break; // While.
}
+ CacheObject cVal = cacheCtx.toCacheObject(val);
+
+ if (op == CREATE || op == UPDATE)
+ cacheCtx.validateKeyAndValue(cacheKey, cVal);
+
txEntry = addEntry(op,
- cacheCtx.toCacheObject(val),
+ cVal,
entryProcessor,
invokeArgs,
entry,
@@ -1356,8 +1361,13 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter implements AutoClosea
GridCacheOperation op = rmv ? DELETE : entryProcessor != null ? TRANSFORM :
v != null ? UPDATE : CREATE;
+ CacheObject cVal = cacheCtx.toCacheObject(val);
+
+ if (op == CREATE || op == UPDATE)
+ cacheCtx.validateKeyAndValue(cacheKey, cVal);
+
txEntry = addEntry(op,
- cacheCtx.toCacheObject(val),
+ cVal,
entryProcessor,
invokeArgs,
entry,
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
index e99c9e8..1be264d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
@@ -866,8 +866,11 @@ public class GridLocalAtomicCache<K, V> extends GridLocalCache<K, V> {
KeyCacheObject cacheKey = ctx.toCacheKeyObject(key);
- if (op == UPDATE)
+ if (op == UPDATE) {
val = ctx.toCacheObject(val);
+
+ ctx.validateKeyAndValue(cacheKey, (CacheObject)val);
+ }
else if (op == TRANSFORM)
ctx.kernalContext().resource().inject(val, GridResourceIoc.AnnotationSet.ENTRY_PROCESSOR, ctx.name());
@@ -1055,6 +1058,8 @@ public class GridLocalAtomicCache<K, V> extends GridLocalCache<K, V> {
Object updatedVal = null;
CacheInvokeResult invokeRes = null;
+ boolean validation = false;
+
try {
Object computed = entryProcessor.process(invokeEntry, invokeArgs);
@@ -1064,11 +1069,23 @@ public class GridLocalAtomicCache<K, V> extends GridLocalCache<K, V> {
if (computed != null)
invokeRes = CacheInvokeResult.fromResult(ctx.unwrapTemporary(computed));
+
+ if (invokeEntry.modified()) {
+ validation = true;
+
+ ctx.validateKeyAndValue(entry.key(), updated);
+ }
}
catch (Exception e) {
invokeRes = CacheInvokeResult.fromError(e);
updated = old;
+
+ if (validation) {
+ invokeResMap.put((K)entry.key().value(ctx.cacheObjectContext(), false), invokeRes);
+
+ continue;
+ }
}
if (invokeRes != null)
@@ -1175,6 +1192,8 @@ public class GridLocalAtomicCache<K, V> extends GridLocalCache<K, V> {
cacheVal = ctx.toCacheObject(ctx.unwrapTemporary(interceptorVal));
}
+ ctx.validateKeyAndValue(entry.key(), cacheVal);
+
if (putMap == null) {
putMap = new LinkedHashMap<>(size, 1.0f);
writeVals = new ArrayList<>(size);
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index e7ebaae..7ab921c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -1203,6 +1203,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
key0 = invokeEntry.key();
}
+ ctx.validateKeyAndValue(txEntry.key(), ctx.toCacheObject(val0));
+
if (res != null)
ret.addEntryProcessResult(ctx, txEntry.key(), key0, res, null, txEntry.keepBinary());
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 323bae6..593a3b2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -2241,7 +2241,7 @@ private IgniteInternalFuture<Object> rebuildIndexesFromHash(@Nullable final Stri
for (QueryField col : cols) {
try {
props.add(new QueryBinaryProperty(ctx, col.name(), null, Class.forName(col.typeName()),
- false, null));
+ false, null, !col.isNullable()));
}
catch (ClassNotFoundException e) {
throw new SchemaOperationException("Class not found for new property: " + col.typeName());
@@ -2593,6 +2593,25 @@ private IgniteInternalFuture<Object> rebuildIndexesFromHash(@Nullable final Stri
}
/**
+ * Performs validation of provided key and value against configured constraints.
+ * Throws runtime exception if validation fails.
+ *
+ * @param coctx Cache object context.
+ * @param key Key.
+ * @param val Value.
+ * @throws IgniteCheckedException, If error happens.
+ */
+ public void validateKeyAndValue(CacheObjectContext coctx, KeyCacheObject key, CacheObject val)
+ throws IgniteCheckedException {
+ QueryTypeDescriptorImpl desc = typeByValue(coctx.cacheName(), coctx, key, val, false);
+
+ if (desc == null)
+ return;
+
+ desc.validateKeyAndValue(key, val);
+ }
+
+ /**
* @param ver Version.
*/
public static void setRequestAffinityTopologyVersion(AffinityTopologyVersion ver) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
index fb4c037..c8ae212 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
@@ -63,4 +63,11 @@ public interface GridQueryProperty {
* @return Parent property or {@code null} if this property is not nested.
*/
public GridQueryProperty parent();
+
+ /**
+ * Gets the flag restricting {@code null} value for this property.
+ *
+ * @return {@code true} if property does not allow {@code null} value.
+ */
+ public boolean notNull();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
index c149335..dcf850c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
@@ -167,4 +167,14 @@ public interface GridQueryTypeDescriptor {
* @return value field alias.
*/
@Nullable public String valueFieldAlias();
+
+ /**
+ * Performs validation of given key and value against configured constraints.
+ * Throws runtime exception if validation fails.
+ *
+ * @param key Key.
+ * @param val Value.
+ * @throws IgniteCheckedException, If failure happens.
+ */
+ public void validateKeyAndValue(Object key, Object val) throws IgniteCheckedException;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
index 968c287..8c7d367 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
@@ -34,13 +34,18 @@ public class QueryField implements Serializable {
/** Class name for this field's values. */
private final String typeName;
+ /** Nullable flag. */
+ private final boolean nullable;
+
/**
* @param name Field name.
* @param typeName Class name for this field's values.
+ * @param nullable Nullable flag.
*/
- public QueryField(String name, String typeName) {
+ public QueryField(String name, String typeName, boolean nullable) {
this.name = name;
this.typeName = typeName;
+ this.nullable = nullable;
}
/**
@@ -57,6 +62,13 @@ public class QueryField implements Serializable {
return typeName;
}
+ /**
+ * @return {@code true}, if field is nullable.
+ */
+ public boolean isNullable() {
+ return nullable;
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(QueryField.class, this);
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java
index ccbba93..40da780 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.query;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import org.apache.ignite.cache.QueryEntity;
@@ -163,8 +164,16 @@ public class QuerySchema implements Serializable {
if (target == null)
return;
- for (QueryField field : op0.columns())
+ for (QueryField field : op0.columns()) {
target.getFields().put(field.name(), field.typeName());
+
+ if (!field.isNullable()) {
+ if (target.getNotNullFields() == null)
+ target.setNotNullFields(new HashSet<String>());
+
+ target.getNotNullFields().add(field.name());
+ }
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
index 0b77c4c..e12476a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
@@ -22,9 +22,12 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.internal.A;
@@ -101,6 +104,9 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
/** Obsolete. */
private volatile boolean obsolete;
+ /** */
+ private List<GridQueryProperty> validateProps;
+
/**
* Constructor.
*
@@ -367,6 +373,13 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
if (uppercaseProps.put(name.toUpperCase(), prop) != null && failOnDuplicate)
throw new IgniteCheckedException("Property with upper cased name '" + name + "' already exists.");
+ if (prop.notNull()) {
+ if (validateProps == null)
+ validateProps = new ArrayList<>();
+
+ validateProps.add(prop);
+ }
+
fields.put(name, prop.type());
}
@@ -470,4 +483,21 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
@Nullable @Override public String valueFieldAlias() {
return valFieldName != null ? aliases.get(valFieldName) : null;
}
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ @Override public void validateKeyAndValue(Object key, Object val) throws IgniteCheckedException {
+ if (validateProps == null)
+ return;
+
+ final int size = validateProps.size();
+
+ for (int idx = 0; idx < size; ++idx) {
+ GridQueryProperty prop = validateProps.get(idx);
+
+ if (prop.value(key, val) == null)
+ throw new IgniteSQLException("Null value is not allowed for field '" + prop.name() + "'",
+ IgniteQueryErrorCode.NULL_VALUE);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
index 26fc776..76efb71 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
@@ -222,6 +222,7 @@ public class QueryUtils {
normalEntity.setKeyFields(entity.getKeyFields());
normalEntity.setKeyFieldName(entity.getKeyFieldName());
normalEntity.setValueFieldName(entity.getValueFieldName());
+ normalEntity.setNotNullFields(entity.getNotNullFields());
// Normalize table name.
String normalTblName = entity.getTableName();
@@ -495,6 +496,7 @@ public class QueryUtils {
public static void processBinaryMeta(GridKernalContext ctx, QueryEntity qryEntity, QueryTypeDescriptorImpl d)
throws IgniteCheckedException {
Set<String> keyFields = qryEntity.getKeyFields();
+ Set<String> notNulls = qryEntity.getNotNullFields();
// We have to distinguish between empty and null keyFields when the key is not of SQL type -
// when a key is not of SQL type, absence of a field in nonnull keyFields tell us that this field
@@ -521,8 +523,11 @@ public class QueryUtils {
else
isKeyField = (hasKeyFields ? keyFields.contains(entry.getKey()) : null);
+ boolean notNull = notNulls != null && notNulls.contains(entry.getKey());
+
QueryBinaryProperty prop = buildBinaryProperty(ctx, entry.getKey(),
- U.classForName(entry.getValue(), Object.class, true), d.aliases(), isKeyField);
+ U.classForName(entry.getValue(), Object.class, true),
+ d.aliases(), isKeyField, notNull);
d.addProperty(prop, false);
}
@@ -539,6 +544,8 @@ public class QueryUtils {
*/
public static void processClassMeta(QueryEntity qryEntity, QueryTypeDescriptorImpl d, CacheObjectContext coCtx)
throws IgniteCheckedException {
+ Set<String> notNulls = qryEntity.getNotNullFields();
+
for (Map.Entry<String, String> entry : qryEntity.getFields().entrySet()) {
GridQueryProperty prop = buildProperty(
d.keyClass(),
@@ -548,6 +555,7 @@ public class QueryUtils {
entry.getKey(),
U.classForName(entry.getValue(), Object.class),
d.aliases(),
+ notNulls != null && notNulls.contains(entry.getKey()),
coCtx);
d.addProperty(prop, false);
@@ -661,10 +669,11 @@ public class QueryUtils {
* @param aliases Aliases.
* @param isKeyField Key ownership flag, as defined in {@link QueryEntity#keyFields}: {@code true} if field belongs
* to key, {@code false} if it belongs to value, {@code null} if QueryEntity#keyFields is null.
+ * @param notNull {@code true} if {@code null} value is not allowed.
* @return Binary property.
*/
public static QueryBinaryProperty buildBinaryProperty(GridKernalContext ctx, String pathStr, Class<?> resType,
- Map<String, String> aliases, @Nullable Boolean isKeyField) throws IgniteCheckedException {
+ Map<String, String> aliases, @Nullable Boolean isKeyField, boolean notNull) throws IgniteCheckedException {
String[] path = pathStr.split("\\.");
QueryBinaryProperty res = null;
@@ -680,7 +689,7 @@ public class QueryUtils {
String alias = aliases.get(fullName.toString());
// The key flag that we've found out is valid for the whole path.
- res = new QueryBinaryProperty(ctx, prop, res, resType, isKeyField, alias);
+ res = new QueryBinaryProperty(ctx, prop, res, resType, isKeyField, alias, notNull);
}
return res;
@@ -692,21 +701,25 @@ public class QueryUtils {
* @param pathStr Path string.
* @param resType Result type.
* @param aliases Aliases.
+ * @param notNull {@code true} if {@code null} value is not allowed.
+ * @param coCtx Cache object context.
* @return Class property.
* @throws IgniteCheckedException If failed.
*/
public static QueryClassProperty buildClassProperty(Class<?> keyCls, Class<?> valCls, String pathStr,
- Class<?> resType, Map<String,String> aliases, CacheObjectContext coCtx) throws IgniteCheckedException {
+ Class<?> resType, Map<String,String> aliases, boolean notNull, CacheObjectContext coCtx)
+ throws IgniteCheckedException {
QueryClassProperty res = buildClassProperty(
true,
keyCls,
pathStr,
resType,
aliases,
+ notNull,
coCtx);
if (res == null) // We check key before value consistently with BinaryProperty.
- res = buildClassProperty(false, valCls, pathStr, resType, aliases, coCtx);
+ res = buildClassProperty(false, valCls, pathStr, resType, aliases, notNull, coCtx);
if (res == null)
throw new IgniteCheckedException(propertyInitializationExceptionMessage(keyCls, valCls, pathStr, resType));
@@ -722,11 +735,14 @@ public class QueryUtils {
* @param pathStr Path string.
* @param resType Result type.
* @param aliases Aliases.
+ * @param notNull {@code true} if {@code null} value is not allowed.
+ * @param coCtx Cache object context.
* @return Class property.
* @throws IgniteCheckedException If failed.
*/
- public static GridQueryProperty buildProperty(Class<?> keyCls, Class<?> valCls, String keyFieldName, String valueFieldName, String pathStr,
- Class<?> resType, Map<String,String> aliases, CacheObjectContext coCtx) throws IgniteCheckedException {
+ public static GridQueryProperty buildProperty(Class<?> keyCls, Class<?> valCls, String keyFieldName,
+ String valueFieldName, String pathStr, Class<?> resType, Map<String,String> aliases, boolean notNull,
+ CacheObjectContext coCtx) throws IgniteCheckedException {
if (pathStr.equals(keyFieldName))
return new KeyOrValProperty(true, pathStr, keyCls);
@@ -738,6 +754,7 @@ public class QueryUtils {
pathStr,
resType,
aliases,
+ notNull,
coCtx);
}
@@ -763,11 +780,13 @@ public class QueryUtils {
* @param pathStr String representing path to the property. May contains dots '.' to identify nested fields.
* @param resType Expected result type.
* @param aliases Aliases.
+ * @param notNull {@code true} if {@code null} value is not allowed.
+ * @param coCtx Cache object context.
* @return Property instance corresponding to the given path.
*/
@SuppressWarnings("ConstantConditions")
public static QueryClassProperty buildClassProperty(boolean key, Class<?> cls, String pathStr, Class<?> resType,
- Map<String,String> aliases, CacheObjectContext coCtx) {
+ Map<String,String> aliases, boolean notNull, CacheObjectContext coCtx) {
String[] path = pathStr.split("\\.");
QueryClassProperty res = null;
@@ -787,7 +806,7 @@ public class QueryUtils {
if (accessor == null)
return null;
- QueryClassProperty tmp = new QueryClassProperty(accessor, key, alias, coCtx);
+ QueryClassProperty tmp = new QueryClassProperty(accessor, key, alias, notNull, coCtx);
tmp.parent(res);
@@ -1221,5 +1240,10 @@ public class QueryUtils {
@Override public GridQueryProperty parent() {
return null;
}
+
+ /** {@inheritDoc} */
+ @Override public boolean notNull() {
+ return true;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
index d8b907e..5d90a43 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
@@ -65,6 +65,9 @@ public class QueryBinaryProperty implements GridQueryProperty {
/** Whether user was warned about missing property. */
private volatile boolean warned;
+ /** */
+ private final boolean notNull;
+
/**
* Constructor.
*
@@ -74,9 +77,10 @@ public class QueryBinaryProperty implements GridQueryProperty {
* @param type Result type.
* @param key {@code true} if key property, {@code false} otherwise, {@code null} if unknown.
* @param alias Field alias.
+ * @param notNull {@code true} if null value is not allowed.
*/
public QueryBinaryProperty(GridKernalContext ctx, String propName, QueryBinaryProperty parent,
- Class<?> type, @Nullable Boolean key, String alias) {
+ Class<?> type, @Nullable Boolean key, String alias, boolean notNull) {
this.ctx = ctx;
@@ -86,6 +90,7 @@ public class QueryBinaryProperty implements GridQueryProperty {
this.alias = F.isEmpty(alias) ? propName : alias;
this.parent = parent;
this.type = type;
+ this.notNull = notNull;
if (key != null)
this.isKeyProp = key ? 1 : -1;
@@ -266,4 +271,9 @@ public class QueryBinaryProperty implements GridQueryProperty {
@Override public GridQueryProperty parent() {
return parent;
}
+
+ /** {@inheritDoc} */
+ @Override public boolean notNull() {
+ return notNull;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
index 80b9c87..076a769 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryClassProperty.java
@@ -44,19 +44,28 @@ public class QueryClassProperty implements GridQueryProperty {
/** */
private final CacheObjectContext coCtx;
+ /** */
+ private final boolean notNull;
+
/**
* Constructor.
*
* @param accessor Way of accessing the property.
+ * @param key {@code true} if key property, {@code false} otherwise.
+ * @param name Property name.
+ * @param notNull {@code true} if null value is not allowed.
+ * @param coCtx Cache Object Context.
*/
public QueryClassProperty(QueryPropertyAccessor accessor, boolean key, String name,
- @Nullable CacheObjectContext coCtx) {
+ boolean notNull, @Nullable CacheObjectContext coCtx) {
this.accessor = accessor;
this.key = key;
this.name = !F.isEmpty(name) ? name : accessor.getPropertyName();
+ this.notNull = notNull;
+
this.coCtx = coCtx;
}
@@ -127,4 +136,9 @@ public class QueryClassProperty implements GridQueryProperty {
@Override public GridQueryProperty parent() {
return parent;
}
+
+ /** {@inheritDoc} */
+ @Override public boolean notNull() {
+ return notNull;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
index 0ff9cfe..0634a52 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
@@ -611,6 +611,8 @@ public class DmlStatementsProcessor {
newVal = ((BinaryObjectBuilder) newVal).build();
}
+ desc.type().validateKeyAndValue(key, newVal);
+
Object srcVal = row.get(1);
if (bin && !(srcVal instanceof BinaryObject))
@@ -764,14 +766,15 @@ public class DmlStatementsProcessor {
// If we have just one item to put, just do so
if (plan.rowsNum == 1) {
- IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(),
- plan);
+ IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(), plan);
cctx.cache().put(t.getKey(), t.getValue());
+
return 1;
}
else {
int resCnt = 0;
+
Map<Object, Object> rows = new LinkedHashMap<>();
for (Iterator<List<?>> it = cursor.iterator(); it.hasNext();) {
@@ -783,6 +786,7 @@ public class DmlStatementsProcessor {
if ((pageSize > 0 && rows.size() == pageSize) || !it.hasNext()) {
cctx.cache().putAll(rows);
+
resCnt += rows.size();
if (it.hasNext())
@@ -952,6 +956,8 @@ public class DmlStatementsProcessor {
val = ((BinaryObjectBuilder) val).build();
}
+ desc.validateKeyAndValue(key, val);
+
return new IgniteBiTuple<>(key, val);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 3d3ed84..a07d48e 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -1644,7 +1644,8 @@ public class IgniteH2Indexing implements GridQueryIndexing {
sql.a(',').a(VER_FIELD_NAME).a(" OTHER INVISIBLE");
for (Map.Entry<String, Class<?>> e : tbl.type().fields().entrySet())
- sql.a(',').a(H2Utils.withQuotes(e.getKey())).a(' ').a(dbTypeFromClass(e.getValue()));
+ sql.a(',').a(H2Utils.withQuotes(e.getKey())).a(' ').a(dbTypeFromClass(e.getValue()))
+ .a(tbl.type().property(e.getKey()).notNull()? " NOT NULL" : "");
sql.a(')');
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
index 6f3c3ba..03f4e1f 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
@@ -20,9 +20,11 @@ package org.apache.ignite.internal.processors.query.h2.ddl;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.cache.QueryIndex;
@@ -241,7 +243,8 @@ public class DdlStatementsProcessor {
}
cols.add(new QueryField(col.columnName(),
- DataType.getTypeClassName(col.column().getType())));
+ DataType.getTypeClassName(col.column().getType()),
+ col.column().isNullable()));
}
if (cols != null) {
@@ -335,12 +338,21 @@ public class DdlStatementsProcessor {
res.setTableName(createTbl.tableName());
+ Set<String> notNullFields = null;
+
for (Map.Entry<String, GridSqlColumn> e : createTbl.columns().entrySet()) {
GridSqlColumn gridCol = e.getValue();
Column col = gridCol.column();
res.addQueryField(e.getKey(), DataType.getTypeClassName(col.getType()), null);
+
+ if (!col.isNullable()) {
+ if (notNullFields == null)
+ notNullFields = new HashSet<>();
+
+ notNullFields.add(e.getKey());
+ }
}
String valTypeName = QueryUtils.createTableValueTypeName(createTbl.schemaName(), createTbl.tableName());
@@ -350,6 +362,7 @@ public class DdlStatementsProcessor {
res.setKeyType(keyTypeName);
res.setKeyFields(createTbl.primaryKeyColumns());
+ res.setNotNullFields(notNullFields);
return res;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
index 694346c..45bb9c7 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
@@ -985,7 +985,11 @@ public class GridH2Table extends TableBase {
}
try {
- newCols[pos++] = new Column(col.name(), DataType.getTypeFromClass(Class.forName(col.typeName())));
+ Column c = new Column(col.name(), DataType.getTypeFromClass(Class.forName(col.typeName())));
+
+ c.setNullable(col.isNullable());
+
+ newCols[pos++] = c;
}
catch (ClassNotFoundException e) {
throw new IgniteSQLException("H2 data type not found for class: " + col.typeName(), e);
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
index d19e66f..a2de62b 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
@@ -1029,10 +1029,6 @@ public class GridSqlQueryParser {
throw new IgniteSQLException("AUTO_INCREMENT columns are not supported [colName=" + col.getName() + ']',
IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
- if (!col.isNullable())
- throw new IgniteSQLException("Non nullable columns are not supported [colName=" + col.getName() + ']',
- IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
-
if (COLUMN_IS_COMPUTED.get(col))
throw new IgniteSQLException("Computed columns are not supported [colName=" + col.getName() + ']',
IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
index 75b9a30..978c504 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
@@ -116,6 +116,14 @@ public abstract class DynamicColumnsAbstractTest extends GridCommonAbstractTest
assertEquals(col.name(), e.getKey());
assertEquals(col.typeName(), e.getValue());
+
+ if (!col.isNullable()) {
+ assertNotNull(entity.getNotNullFields());
+
+ assertTrue(entity.getNotNullFields().contains(col.name()));
+ }
+ else if (entity.getNotNullFields() != null)
+ assertFalse(entity.getNotNullFields().contains(col.name()));
}
}
@@ -151,6 +159,8 @@ public abstract class DynamicColumnsAbstractTest extends GridCommonAbstractTest
assertEquals(col.name(), e.getKey());
assertEquals(col.typeName(), e.getValue().getName());
+
+ assertTrue(col.isNullable() || desc.property(col.name()).notNull());
}
}
@@ -183,6 +193,8 @@ public abstract class DynamicColumnsAbstractTest extends GridCommonAbstractTest
assertFalse(rowDesc.isKeyValueOrVersionColumn(i));
+ assertEquals(col.isNullable(), c.isNullable());
+
try {
assertEquals(DataType.getTypeFromClass(Class.forName(col.typeName())),
rowDesc.fieldType(i - GridH2AbstractKeyValueRow.DEFAULT_COLUMNS_COUNT));
@@ -213,7 +225,7 @@ public abstract class DynamicColumnsAbstractTest extends GridCommonAbstractTest
* @return New column with given name and type.
*/
protected static QueryField c(String name, String typeName) {
- return new QueryField(name, typeName);
+ return new QueryField(name, typeName, true);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/43be051c/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
index 651a3f7..6455cad 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
@@ -266,6 +266,34 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum
}
/**
+ * Test addition of column with not null constraint.
+ */
+ public void testAddNotNullColumn() {
+ run("ALTER TABLE Person ADD COLUMN age int NOT NULL");
+
+ doSleep(500);
+
+ QueryField c = new QueryField("AGE", Integer.class.getName(), false);
+
+ for (Ignite node : Ignition.allGrids())
+ checkNodeState((IgniteEx)node, QueryUtils.DFLT_SCHEMA, "PERSON", c);
+ }
+
+ /**
+ * Test addition of column explicitly defined as nullable.
+ */
+ public void testAddNullColumn() {
+ run("ALTER TABLE Person ADD COLUMN age int NULL");
+
+ doSleep(500);
+
+ QueryField c = new QueryField("AGE", Integer.class.getName(), true);
+
+ for (Ignite node : Ignition.allGrids())
+ checkNodeState((IgniteEx)node, QueryUtils.DFLT_SCHEMA, "PERSON", c);
+ }
+
+ /**
* @return Node index to run queries on.
*/
protected abstract int nodeIndex();
[05/12] ignite git commit: IGNITE-6151: Review fixes
Posted by sb...@apache.org.
IGNITE-6151: Review fixes
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8c238056
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8c238056
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8c238056
Branch: refs/heads/ignite-6149
Commit: 8c2380568093ed6566c983d4cb11e10c1d7a68c1
Parents: 0bc1d84
Author: Igor Sapego <is...@gridgain.com>
Authored: Tue Sep 12 16:10:51 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Tue Sep 12 16:10:51 2017 +0300
----------------------------------------------------------------------
modules/platforms/cpp/odbc-test/src/attributes_test.cpp | 4 ++--
modules/platforms/cpp/odbc/src/connection.cpp | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/8c238056/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/attributes_test.cpp b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
index 3ac46cb..f8cb5ac 100644
--- a/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
@@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE(ConnectionAttributeConnectionDeadGet)
{
Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
- SQLINTEGER dead = SQL_CD_TRUE;
+ SQLUINTEGER dead = SQL_CD_TRUE;
SQLRETURN ret;
ret = SQLGetConnectAttr(dbc, SQL_ATTR_CONNECTION_DEAD, &dead, 0, 0);
@@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(ConnectionAttributeConnectionDeadSet)
{
Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
- SQLINTEGER dead = SQL_CD_TRUE;
+ SQLUINTEGER dead = SQL_CD_TRUE;
SQLRETURN ret;
ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_DEAD, &dead, 0);
http://git-wip-us.apache.org/repos/asf/ignite/blob/8c238056/modules/platforms/cpp/odbc/src/connection.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp
index 53626d1..472eb75 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -351,9 +351,9 @@ namespace ignite
{
case SQL_ATTR_CONNECTION_DEAD:
{
- SQLINTEGER *val = reinterpret_cast<SQLINTEGER*>(buf);
+ SQLUINTEGER *val = reinterpret_cast<SQLUINTEGER*>(buf);
- *val = static_cast<SQLINTEGER>(connected ? SQL_CD_FALSE : SQL_CD_TRUE);
+ *val = connected ? SQL_CD_FALSE : SQL_CD_TRUE;
if (valueLen)
*valueLen = SQL_IS_INTEGER;
@@ -384,7 +384,7 @@ namespace ignite
{
case SQL_ATTR_CONNECTION_DEAD:
{
- AddStatusRecord(SqlState::SHY092_OPTION_TYPE_OUT_OF_RANGE, "Attribute can not be retrieved.");
+ AddStatusRecord(SqlState::SHY092_OPTION_TYPE_OUT_OF_RANGE, "Attribute is read only.");
return SqlResult::AI_ERROR;
}
[02/12] ignite git commit: IGNITE-5703: SQL: Added
WRITE_SYNCHRONIZATION_MODE parameter to CREATE TABLE command. This closes
#2591.
Posted by sb...@apache.org.
IGNITE-5703: SQL: Added WRITE_SYNCHRONIZATION_MODE parameter to CREATE TABLE command. This closes #2591.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c61f134e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c61f134e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c61f134e
Branch: refs/heads/ignite-6149
Commit: c61f134e21d8b8e17057b40c53e757eff6e8490d
Parents: acd7861
Author: Alexander Paschenko <al...@gmail.com>
Authored: Tue Sep 12 11:40:47 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Sep 12 11:40:47 2017 +0300
----------------------------------------------------------------------
.../processors/query/GridQueryProcessor.java | 7 +-
.../query/h2/ddl/DdlStatementsProcessor.java | 3 +-
.../query/h2/sql/GridSqlCreateTable.java | 18 ++++
.../query/h2/sql/GridSqlQueryParser.java | 31 ++++++-
.../cache/index/H2DynamicTableSelfTest.java | 95 ++++++++++++++++----
.../IgnitePersistentStoreSchemaLoadTest.java | 16 +---
6 files changed, 137 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/c61f134e/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index ea4c576..323bae6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -1362,13 +1362,15 @@ public class GridQueryProcessor extends GridProcessorAdapter {
* @param cacheGroup Cache group name.
* @param affinityKey Affinity key column name.
* @param atomicityMode Atomicity mode.
+ * @param writeSyncMode Write synchronization mode.
* @param backups Backups.
* @param ifNotExists Quietly ignore this command if table already exists.
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("unchecked")
public void dynamicTableCreate(String schemaName, QueryEntity entity, String templateName, String cacheGroup,
- String affinityKey, @Nullable CacheAtomicityMode atomicityMode, int backups, boolean ifNotExists)
+ String affinityKey, @Nullable CacheAtomicityMode atomicityMode,
+ @Nullable CacheWriteSynchronizationMode writeSyncMode, int backups, boolean ifNotExists)
throws IgniteCheckedException {
assert !F.isEmpty(templateName);
assert backups >= 0;
@@ -1398,6 +1400,9 @@ public class GridQueryProcessor extends GridProcessorAdapter {
if (atomicityMode != null)
ccfg.setAtomicityMode(atomicityMode);
+ if (writeSyncMode != null)
+ ccfg.setWriteSynchronizationMode(writeSyncMode);
+
ccfg.setBackups(backups);
ccfg.setSqlSchema(schemaName);
http://git-wip-us.apache.org/repos/asf/ignite/blob/c61f134e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
index f322010..6f3c3ba 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
@@ -181,7 +181,8 @@ public class DdlStatementsProcessor {
throw err;
ctx.query().dynamicTableCreate(cmd.schemaName(), e, cmd.templateName(), cmd.cacheGroup(),
- cmd.affinityKey(), cmd.atomicityMode(), cmd.backups(), cmd.ifNotExists());
+ cmd.affinityKey(), cmd.atomicityMode(), cmd.writeSynchronizationMode(), cmd.backups(),
+ cmd.ifNotExists());
}
}
else if (stmt0 instanceof GridSqlDropTable) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/c61f134e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
index fa76123..d28ee7a 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
@@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
/**
* CREATE TABLE statement.
@@ -43,6 +44,9 @@ public class GridSqlCreateTable extends GridSqlStatement {
/** Atomicity mode for new cache. */
private CacheAtomicityMode atomicityMode;
+ /** Write sync mode. */
+ private CacheWriteSynchronizationMode writeSyncMode;
+
/** Backups number for new cache. */
private int backups;
@@ -104,6 +108,20 @@ public class GridSqlCreateTable extends GridSqlStatement {
}
/**
+ * @return Write sync mode for new cache.
+ */
+ public CacheWriteSynchronizationMode writeSynchronizationMode() {
+ return writeSyncMode;
+ }
+
+ /**
+ * @param writeSyncMode Write sync mode for new cache.
+ */
+ public void writeSynchronizationMode(CacheWriteSynchronizationMode writeSyncMode) {
+ this.writeSyncMode = writeSyncMode;
+ }
+
+ /**
* @return Backups number for new cache.
*/
public int backups() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/c61f134e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
index 97e9d5d..d19e66f 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
@@ -30,6 +30,7 @@ import java.util.Map;
import javax.cache.CacheException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.cache.QueryIndex;
import org.apache.ignite.cache.QueryIndexType;
import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
@@ -437,6 +438,9 @@ public class GridSqlQueryParser {
private static final String PARAM_AFFINITY_KEY = "AFFINITYKEY";
/** */
+ private static final String PARAM_WRITE_SYNC = "WRITE_SYNCHRONIZATION_MODE";
+
+ /** */
private final IdentityHashMap<Object, Object> h2ObjToGridObj = new IdentityHashMap<>();
/** */
@@ -1125,17 +1129,17 @@ public class GridSqlQueryParser {
case PARAM_ATOMICITY:
ensureNotEmpty(name, val);
- CacheAtomicityMode mode;
+ CacheAtomicityMode atomicityMode;
if (CacheAtomicityMode.TRANSACTIONAL.name().equalsIgnoreCase(val))
- mode = CacheAtomicityMode.TRANSACTIONAL;
+ atomicityMode = CacheAtomicityMode.TRANSACTIONAL;
else if (CacheAtomicityMode.ATOMIC.name().equalsIgnoreCase(val))
- mode = CacheAtomicityMode.ATOMIC;
+ atomicityMode = CacheAtomicityMode.ATOMIC;
else
throw new IgniteSQLException("Invalid value of \"" + PARAM_ATOMICITY + "\" parameter " +
"(should be either TRANSACTIONAL or ATOMIC): " + val, IgniteQueryErrorCode.PARSING);
- res.atomicityMode(mode);
+ res.atomicityMode(atomicityMode);
break;
@@ -1187,6 +1191,25 @@ public class GridSqlQueryParser {
break;
+ case PARAM_WRITE_SYNC:
+ ensureNotEmpty(name, val);
+
+ CacheWriteSynchronizationMode writeSyncMode;
+
+ if (CacheWriteSynchronizationMode.FULL_ASYNC.name().equalsIgnoreCase(val))
+ writeSyncMode = CacheWriteSynchronizationMode.FULL_ASYNC;
+ else if (CacheWriteSynchronizationMode.FULL_SYNC.name().equalsIgnoreCase(val))
+ writeSyncMode = CacheWriteSynchronizationMode.FULL_SYNC;
+ else if (CacheWriteSynchronizationMode.PRIMARY_SYNC.name().equalsIgnoreCase(val))
+ writeSyncMode = CacheWriteSynchronizationMode.PRIMARY_SYNC;
+ else
+ throw new IgniteSQLException("Invalid value of \"" + PARAM_WRITE_SYNC + "\" parameter " +
+ "(should be FULL_SYNC, FULL_ASYNC, or PRIMARY_SYNC): " + val, IgniteQueryErrorCode.PARSING);
+
+ res.writeSynchronizationMode(writeSyncMode);
+
+ break;
+
default:
throw new IgniteSQLException("Unsupported parameter: " + name, IgniteQueryErrorCode.PARSING);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/c61f134e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
index d737a0f..0be6c70 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
@@ -77,6 +77,8 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
Ignition.start(cfg);
client().addCacheConfiguration(cacheConfiguration());
+ client().addCacheConfiguration(cacheConfiguration().setName(CACHE_NAME + "_async")
+ .setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_ASYNC));
}
/** {@inheritDoc} */
@@ -107,7 +109,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testCreateTable() throws Exception {
- doTestCreateTable(CACHE_NAME, null, null);
+ doTestCreateTable(CACHE_NAME, null, null, null);
}
/**
@@ -115,7 +117,15 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testCreateTableWithCacheGroup() throws Exception {
- doTestCreateTable(CACHE_NAME, "MyGroup", null);
+ doTestCreateTable(CACHE_NAME, "MyGroup", null, null);
+ }
+
+ /**
+ * Test that {@code CREATE TABLE} actually creates new cache from template, H2 table and type descriptor on all nodes.
+ * @throws Exception if failed.
+ */
+ public void testCreateTableWithWriteSyncMode() throws Exception {
+ doTestCreateTable(CACHE_NAME + "_async", null, null, CacheWriteSynchronizationMode.FULL_ASYNC);
}
/**
@@ -124,7 +134,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testCreateTableReplicated() throws Exception {
- doTestCreateTable("REPLICATED", null, CacheMode.REPLICATED);
+ doTestCreateTable("REPLICATED", null, CacheMode.REPLICATED, CacheWriteSynchronizationMode.FULL_SYNC);
}
/**
@@ -133,7 +143,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testCreateTablePartitioned() throws Exception {
- doTestCreateTable("PARTITIONED", null, CacheMode.PARTITIONED);
+ doTestCreateTable("PARTITIONED", null, CacheMode.PARTITIONED, CacheWriteSynchronizationMode.FULL_SYNC);
}
/**
@@ -142,7 +152,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testCreateTableReplicatedCaseInsensitive() throws Exception {
- doTestCreateTable("replicated", null, CacheMode.REPLICATED);
+ doTestCreateTable("replicated", null, CacheMode.REPLICATED, CacheWriteSynchronizationMode.FULL_SYNC);
}
/**
@@ -151,7 +161,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testCreateTablePartitionedCaseInsensitive() throws Exception {
- doTestCreateTable("partitioned", null, CacheMode.PARTITIONED);
+ doTestCreateTable("partitioned", null, CacheMode.PARTITIONED, CacheWriteSynchronizationMode.FULL_SYNC);
}
/**
@@ -160,7 +170,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testCreateTableNoTemplate() throws Exception {
- doTestCreateTable(null, null, CacheMode.PARTITIONED);
+ doTestCreateTable(null, null, CacheMode.PARTITIONED, CacheWriteSynchronizationMode.FULL_SYNC);
}
/**
@@ -173,6 +183,33 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
}
/**
+ * Test that {@code CREATE TABLE} with given write sync mode actually creates new cache as needed.
+ * @throws Exception if failed.
+ */
+ public void testFullSyncWriteMode() throws Exception {
+ doTestCreateTable(null, null, null, CacheWriteSynchronizationMode.FULL_SYNC,
+ "write_synchronization_mode=full_sync");
+ }
+
+ /**
+ * Test that {@code CREATE TABLE} with given write sync mode actually creates new cache as needed.
+ * @throws Exception if failed.
+ */
+ public void testPrimarySyncWriteMode() throws Exception {
+ doTestCreateTable(null, null, null, CacheWriteSynchronizationMode.PRIMARY_SYNC,
+ "write_synchronization_mode=primary_sync");
+ }
+
+ /**
+ * Test that {@code CREATE TABLE} with given write sync mode actually creates new cache as needed.
+ * @throws Exception if failed.
+ */
+ public void testFullAsyncWriteMode() throws Exception {
+ doTestCreateTable(null, null, null, CacheWriteSynchronizationMode.FULL_ASYNC,
+ "write_synchronization_mode=full_async");
+ }
+
+ /**
* Perform a check on given table name considering case sensitivity.
* @param tblName Table name to check.
* @param sensitive Whether table should be created w/case sensitive name or not.
@@ -277,13 +314,21 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* H2 table and type descriptor on all nodes, optionally with cache type check.
* @param tplCacheName Template cache name.
* @param cacheGrp Cache group name, or {@code null} if no group is set.
- * @param mode Expected cache mode, or {@code null} if no check is needed.
+ * @param cacheMode Expected cache mode, or {@code null} if no check is needed.
+ * @param writeSyncMode Expected write sync mode, or {@code null} if no check is needed.
+ * @param additionalParams Supplemental parameters to append to {@code CREATE TABLE} SQL.
*/
- private void doTestCreateTable(String tplCacheName, String cacheGrp, CacheMode mode) {
- execute("CREATE TABLE \"Person\" (\"id\" int, \"city\" varchar," +
+ private void doTestCreateTable(String tplCacheName, String cacheGrp, CacheMode cacheMode,
+ CacheWriteSynchronizationMode writeSyncMode, String... additionalParams) {
+ String sql = "CREATE TABLE \"Person\" (\"id\" int, \"city\" varchar," +
" \"name\" varchar, \"surname\" varchar, \"age\" int, PRIMARY KEY (\"id\", \"city\")) WITH " +
(F.isEmpty(tplCacheName) ? "" : "\"template=" + tplCacheName + "\",") + "\"backups=10,atomicity=atomic\"" +
- (F.isEmpty(cacheGrp) ? "" : ",\"cacheGroup=" + cacheGrp + '"'));
+ (F.isEmpty(cacheGrp) ? "" : ",\"cacheGroup=" + cacheGrp + '"');
+
+ for (String p : additionalParams)
+ sql += ",\"" + p + "\"";
+
+ execute(sql);
String cacheName = cacheName("Person");
@@ -296,7 +341,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
assertNotNull(cacheDesc);
- if (mode == CacheMode.REPLICATED)
+ if (cacheMode == CacheMode.REPLICATED)
assertEquals(Integer.MAX_VALUE, cacheDesc.cacheConfiguration().getBackups());
else
assertEquals(10, cacheDesc.cacheConfiguration().getBackups());
@@ -307,8 +352,11 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
assertEquals(cacheGrp, cacheDesc.groupDescriptor().groupName());
- if (mode != null)
- assertEquals(mode, cacheDesc.cacheConfiguration().getCacheMode());
+ if (cacheMode != null)
+ assertEquals(cacheMode, cacheDesc.cacheConfiguration().getCacheMode());
+
+ if (writeSyncMode != null)
+ assertEquals(writeSyncMode, cacheDesc.cacheConfiguration().getWriteSynchronizationMode());
QueryTypeDescriptorImpl desc = typeExisting(node, cacheName, "Person");
@@ -374,6 +422,23 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
}
/**
+ * Test that attempting to omit mandatory value of WRITE_SYNCHRONIZATION_MODE parameter yields an error.
+ */
+ public void testEmptyWriteSyncMode() {
+ assertCreateTableWithParamsThrows("write_synchronization_mode=",
+ "Parameter value cannot be empty: WRITE_SYNCHRONIZATION_MODE");
+ }
+
+ /**
+ * Test that attempting to provide invalid value of WRITE_SYNCHRONIZATION_MODE parameter yields an error.
+ */
+ public void testInvalidWriteSyncMode() {
+ assertCreateTableWithParamsThrows("write_synchronization_mode=invalid",
+ "Invalid value of \"WRITE_SYNCHRONIZATION_MODE\" parameter " +
+ "(should be FULL_SYNC, FULL_ASYNC, or PRIMARY_SYNC): invalid");
+ }
+
+ /**
* Test that attempting to {@code CREATE TABLE} that already exists does not yield an error if the statement
* contains {@code IF NOT EXISTS} clause.
* @throws Exception if failed.
@@ -536,7 +601,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
e.setValueType("City");
queryProcessor(client()).dynamicTableCreate("PUBLIC", e, CacheMode.PARTITIONED.name(), null,
- null, CacheAtomicityMode.ATOMIC, 10, false);
+ null, CacheAtomicityMode.ATOMIC, null, 10, false);
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/c61f134e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgnitePersistentStoreSchemaLoadTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgnitePersistentStoreSchemaLoadTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgnitePersistentStoreSchemaLoadTest.java
index 927de07..349f062 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgnitePersistentStoreSchemaLoadTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgnitePersistentStoreSchemaLoadTest.java
@@ -36,7 +36,6 @@ import org.apache.ignite.internal.IgniteInterruptedCheckedException;
import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
import org.apache.ignite.internal.processors.cache.persistence.DbCheckpointListener;
import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
-import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
@@ -151,7 +150,8 @@ public class IgnitePersistentStoreSchemaLoadTest extends GridCommonAbstractTest
idx.setName(IDX_NAME);
- ig0.context().query().dynamicTableCreate(SCHEMA_NAME, getEntity(), TMPL_NAME, null, null, null, 1, true);
+ ig0.context().query().dynamicTableCreate(SCHEMA_NAME, getEntity(), TMPL_NAME, null, null, null,
+ null, 1, true);
assert indexCnt(ig0, CACHE_NAME) == 0;
@@ -183,7 +183,7 @@ public class IgnitePersistentStoreSchemaLoadTest extends GridCommonAbstractTest
}
});
- ig0.context().query().dynamicTableCreate(SCHEMA_NAME, getEntity(), TMPL_NAME, null, null, null, 1, true);
+ ig0.context().query().dynamicTableCreate(SCHEMA_NAME, getEntity(), TMPL_NAME, null, null, null, null, 1, true);
assert indexCnt(ig0, CACHE_NAME) == 0;
@@ -222,21 +222,13 @@ public class IgnitePersistentStoreSchemaLoadTest extends GridCommonAbstractTest
int cnt = 0;
- for (QueryEntity entity : desc.schema().entities()) {
+ for (QueryEntity entity : desc.schema().entities())
cnt += entity.getIndexes().size();
- }
return cnt;
}
/**
- * @return Indexing.
- */
- private IgniteH2Indexing getIndexing(IgniteEx ignite) {
- return U.field(ignite.context().query(), "idx");
- }
-
- /**
*
*/
private void deleteWorkFiles() throws IgniteCheckedException {
[04/12] ignite git commit: IGNITE-6151: Impemented getting and
setting of the SQL_ATTR_CONNECTION_DEAD
Posted by sb...@apache.org.
IGNITE-6151: Impemented getting and setting of the SQL_ATTR_CONNECTION_DEAD
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0bc1d847
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0bc1d847
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0bc1d847
Branch: refs/heads/ignite-6149
Commit: 0bc1d8477c0f0783cc046cabed9a0bb7d3518b0f
Parents: f5bbc70
Author: Igor Sapego <is...@gridgain.com>
Authored: Tue Sep 12 14:44:07 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Tue Sep 12 14:44:07 2017 +0300
----------------------------------------------------------------------
modules/platforms/cpp/odbc-test/Makefile.am | 1 +
.../cpp/odbc-test/project/vs/odbc-test.vcxproj | 1 +
.../project/vs/odbc-test.vcxproj.filters | 3 +
.../cpp/odbc-test/src/attributes_test.cpp | 208 +++++++++++++++++++
.../platforms/cpp/odbc/include/ignite/odbc.h | 22 +-
.../cpp/odbc/include/ignite/odbc/connection.h | 47 +++++
modules/platforms/cpp/odbc/src/connection.cpp | 100 ++++++++-
modules/platforms/cpp/odbc/src/entry_points.cpp | 65 +++---
modules/platforms/cpp/odbc/src/odbc.cpp | 46 +++-
9 files changed, 440 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am
index 7756181..69b62f9 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -78,6 +78,7 @@ ignite_odbc_tests_SOURCES = \
src/sql_date_time_functions_test.cpp \
src/sql_outer_join_test.cpp \
src/api_robustness_test.cpp \
+ src/attributes_test.cpp \
../odbc/src/cursor.cpp \
../odbc/src/config/connection_info.cpp \
../odbc/src/app/application_data_buffer.cpp \
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
index d06064b..3977a24 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -164,6 +164,7 @@
<ClCompile Include="..\..\..\odbc\src\utility.cpp" />
<ClCompile Include="..\..\src\api_robustness_test.cpp" />
<ClCompile Include="..\..\src\application_data_buffer_test.cpp" />
+ <ClCompile Include="..\..\src\attributes_test.cpp" />
<ClCompile Include="..\..\src\column_test.cpp" />
<ClCompile Include="..\..\src\configuration_test.cpp" />
<ClCompile Include="..\..\src\connection_info_test.cpp" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
index 91c029e..2a0c7b4 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
@@ -124,6 +124,9 @@
<ClCompile Include="..\..\src\meta_queries_test.cpp">
<Filter>Code</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\attributes_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\test_type.h">
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/attributes_test.cpp b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
new file mode 100644
index 0000000..3ac46cb
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#include <sql.h>
+#include <sqlext.h>
+
+#include <vector>
+#include <string>
+
+#ifndef _MSC_VER
+# define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignite.h"
+#include "ignite/ignition.h"
+#include "ignite/impl/binary/binary_utils.h"
+
+#include "test_type.h"
+#include "test_utils.h"
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::cache::query;
+using namespace ignite::common;
+using namespace ignite_test;
+
+using namespace boost::unit_test;
+
+using ignite::impl::binary::BinaryUtils;
+
+/**
+ * Test setup fixture.
+ */
+struct AttributesTestSuiteFixture
+{
+ void Prepare()
+ {
+ // Allocate an environment handle
+ SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
+
+ BOOST_REQUIRE(env != NULL);
+
+ // We want ODBC 3 support
+ SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
+
+ // Allocate a connection handle
+ SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
+
+ BOOST_REQUIRE(dbc != NULL);
+ }
+
+ /**
+ * Establish connection to node.
+ *
+ * @param connectStr Connection string.
+ */
+ void Connect(const std::string& connectStr)
+ {
+ Prepare();
+
+ // Connect string
+ std::vector<SQLCHAR> connectStr0;
+
+ connectStr0.reserve(connectStr.size() + 1);
+ std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
+
+ SQLCHAR outstr[ODBC_BUFFER_SIZE];
+ SQLSMALLINT outstrlen;
+
+ // Connecting to ODBC server.
+ SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
+ outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ // Allocate a statement handle
+ SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
+
+ BOOST_REQUIRE(stmt != NULL);
+ }
+
+ void Disconnect()
+ {
+ // Releasing statement handle.
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+
+ // Disconneting from the server.
+ SQLDisconnect(dbc);
+
+ // Releasing allocated handles.
+ SQLFreeHandle(SQL_HANDLE_DBC, dbc);
+ SQLFreeHandle(SQL_HANDLE_ENV, env);
+ }
+
+ /**
+ * Constructor.
+ */
+ AttributesTestSuiteFixture() :
+ env(NULL),
+ dbc(NULL),
+ stmt(NULL)
+ {
+ const char* config = NULL;
+
+#ifdef IGNITE_TESTS_32
+ config = "queries-test-32.xml";
+#else
+ config = "queries-test.xml";
+#endif
+
+ grid = StartNode(config, "NodeMain");
+ }
+
+ void CheckSQLDiagnosticError(int16_t handleType, SQLHANDLE handle, const std::string& expectSqlState)
+ {
+ SQLCHAR state[ODBC_BUFFER_SIZE];
+ SQLINTEGER nativeError = 0;
+ SQLCHAR message[ODBC_BUFFER_SIZE];
+ SQLSMALLINT messageLen = 0;
+
+ SQLRETURN ret = SQLGetDiagRec(handleType, handle, 1, state, &nativeError, message, sizeof(message), &messageLen);
+
+ const std::string sqlState = reinterpret_cast<char*>(state);
+ BOOST_REQUIRE_EQUAL(ret, SQL_SUCCESS);
+ BOOST_REQUIRE_EQUAL(sqlState, expectSqlState);
+ BOOST_REQUIRE(messageLen > 0);
+ }
+
+ void CheckSQLConnectionDiagnosticError(const std::string& expectSqlState)
+ {
+ CheckSQLDiagnosticError(SQL_HANDLE_DBC, dbc, expectSqlState);
+ }
+
+ /**
+ * Destructor.
+ */
+ ~AttributesTestSuiteFixture()
+ {
+ Disconnect();
+
+ Ignition::StopAll(true);
+ }
+
+ /** Node started during the test. */
+ Ignite grid;
+
+ /** ODBC Environment. */
+ SQLHENV env;
+
+ /** ODBC Connect. */
+ SQLHDBC dbc;
+
+ /** ODBC Statement. */
+ SQLHSTMT stmt;
+};
+
+BOOST_FIXTURE_TEST_SUITE(AttributesTestSuite, AttributesTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(ConnectionAttributeConnectionDeadGet)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLINTEGER dead = SQL_CD_TRUE;
+ SQLRETURN ret;
+
+ ret = SQLGetConnectAttr(dbc, SQL_ATTR_CONNECTION_DEAD, &dead, 0, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ BOOST_REQUIRE_EQUAL(dead, SQL_CD_FALSE);
+}
+
+BOOST_AUTO_TEST_CASE(ConnectionAttributeConnectionDeadSet)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLINTEGER dead = SQL_CD_TRUE;
+ SQLRETURN ret;
+
+ ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_DEAD, &dead, 0);
+
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+
+ // According to https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetconnectattr-function#diagnostics
+ CheckSQLConnectionDiagnosticError("HY092");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc/include/ignite/odbc.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc.h b/modules/platforms/cpp/odbc/include/ignite/odbc.h
index 639a02a..402d737 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc.h
@@ -251,6 +251,13 @@ namespace ignite
SQLRETURN SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN strLengthOrIndicator);
+ SQLRETURN SQLDescribeParam(SQLHSTMT stmt,
+ SQLUSMALLINT paramNum,
+ SQLSMALLINT* dataType,
+ SQLULEN* paramSize,
+ SQLSMALLINT* decimalDigits,
+ SQLSMALLINT* nullable);
+
SQLRETURN SQLError(SQLHENV env,
SQLHDBC conn,
SQLHSTMT stmt,
@@ -260,13 +267,16 @@ namespace ignite
SQLSMALLINT msgBufLen,
SQLSMALLINT* msgResLen);
- SQLRETURN SQLDescribeParam(SQLHSTMT stmt,
- SQLUSMALLINT paramNum,
- SQLSMALLINT* dataType,
- SQLULEN* paramSize,
- SQLSMALLINT* decimalDigits,
- SQLSMALLINT* nullable);
+ SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER valueBuf,
+ SQLINTEGER valueBufLen,
+ SQLINTEGER* valueResLen);
+ SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER value,
+ SQLINTEGER valueLen);
} // namespace ignite
#endif //_IGNITE_ODBC
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
index da19e1b..fa80a01 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
@@ -162,6 +162,25 @@ namespace ignite
*/
void TransactionRollback();
+ /**
+ * Get connection attribute.
+ *
+ * @param attr Attribute type.
+ * @param buf Buffer for value.
+ * @param bufLen Buffer length.
+ * @param valueLen Resulting value length.
+ */
+ void GetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER *valueLen);
+
+ /**
+ * Set connection attribute.
+ *
+ * @param attr Attribute type.
+ * @param value Value pointer.
+ * @param valueLen Value length.
+ */
+ void SetAttribute(int attr, void* value, SQLINTEGER valueLen);
+
private:
IGNITE_NO_COPY_ASSIGNMENT(Connection);
@@ -192,6 +211,11 @@ namespace ignite
SqlResult::Type InternalRelease();
/**
+ * Close connection.
+ */
+ void Close();
+
+ /**
* Get info of any type.
* Internal call.
*
@@ -229,6 +253,29 @@ namespace ignite
SqlResult::Type InternalTransactionRollback();
/**
+ * Get connection attribute.
+ * Internal call.
+ *
+ * @param attr Attribute type.
+ * @param buf Buffer for value.
+ * @param bufLen Buffer length.
+ * @param valueLen Resulting value length.
+ * @return Operation result.
+ */
+ SqlResult::Type InternalGetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen);
+
+ /**
+ * Set connection attribute.
+ * Internal call.
+ *
+ * @param attr Attribute type.
+ * @param value Value pointer.
+ * @param valueLen Value length.
+ * @return Operation result.
+ */
+ SqlResult::Type InternalSetAttribute(int attr, void* value, SQLINTEGER valueLen);
+
+ /**
* Receive specified number of bytes.
*
* @param dst Buffer for data.
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc/src/connection.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp
index 80d1695..53626d1 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -136,7 +136,12 @@ namespace ignite
return SqlResult::AI_ERROR;
}
- return MakeRequestHandshake();
+ SqlResult::Type res = MakeRequestHandshake();
+
+ if (res == SqlResult::AI_ERROR)
+ Close();
+
+ return res;
}
void Connection::Release()
@@ -153,11 +158,16 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ Close();
+
+ return SqlResult::AI_SUCCESS;
+ }
+
+ void Connection::Close()
+ {
socket.Close();
connected = false;
-
- return SqlResult::AI_SUCCESS;
}
Statement* Connection::CreateStatement()
@@ -217,7 +227,11 @@ namespace ignite
LOG_MSG("Sent: " << res);
if (res <= 0)
+ {
+ Close();
+
return sent;
+ }
sent += res;
}
@@ -240,7 +254,11 @@ namespace ignite
IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not receive message header");
if (hdr.len < 0)
- IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Message lenght is negative");
+ {
+ Close();
+
+ IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Message length is negative");
+ }
if (hdr.len == 0)
return;
@@ -272,7 +290,11 @@ namespace ignite
LOG_MSG("Receive res: " << res << " remain: " << remain);
if (res <= 0)
+ {
+ Close();
+
return received;
+ }
remain -= static_cast<size_t>(res);
}
@@ -311,6 +333,74 @@ namespace ignite
IGNITE_ODBC_API_CALL(InternalTransactionRollback());
}
+ void Connection::GetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen)
+ {
+ IGNITE_ODBC_API_CALL(InternalGetAttribute(attr, buf, bufLen, valueLen));
+ }
+
+ SqlResult::Type Connection::InternalGetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen)
+ {
+ if (!buf)
+ {
+ AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Data buffer is NULL.");
+
+ return SqlResult::AI_ERROR;
+ }
+
+ switch (attr)
+ {
+ case SQL_ATTR_CONNECTION_DEAD:
+ {
+ SQLINTEGER *val = reinterpret_cast<SQLINTEGER*>(buf);
+
+ *val = static_cast<SQLINTEGER>(connected ? SQL_CD_FALSE : SQL_CD_TRUE);
+
+ if (valueLen)
+ *valueLen = SQL_IS_INTEGER;
+
+ break;
+ }
+
+ default:
+ {
+ AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Specified attribute is not supported.");
+
+ return SqlResult::AI_ERROR;
+ }
+ }
+
+ return SqlResult::AI_SUCCESS;
+ }
+
+ void Connection::SetAttribute(int attr, void* value, SQLINTEGER valueLen)
+ {
+ IGNITE_ODBC_API_CALL(InternalSetAttribute(attr, value, valueLen));
+ }
+
+ SqlResult::Type Connection::InternalSetAttribute(int attr, void* value, SQLINTEGER valueLen)
+ {
+ switch (attr)
+ {
+ case SQL_ATTR_CONNECTION_DEAD:
+ {
+ AddStatusRecord(SqlState::SHY092_OPTION_TYPE_OUT_OF_RANGE, "Attribute can not be retrieved.");
+
+ return SqlResult::AI_ERROR;
+ }
+
+ default:
+ {
+ AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Specified attribute is not supported.");
+
+ return SqlResult::AI_ERROR;
+ }
+ }
+
+ return SqlResult::AI_SUCCESS;
+ }
+
SqlResult::Type Connection::InternalTransactionRollback()
{
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
@@ -383,8 +473,6 @@ namespace ignite
AddStatusRecord(SqlState::S08001_CANNOT_CONNECT, constructor.str());
- InternalRelease();
-
return SqlResult::AI_ERROR;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc/src/entry_points.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/entry_points.cpp b/modules/platforms/cpp/odbc/src/entry_points.cpp
index e241a9f..d3c9e26 100644
--- a/modules/platforms/cpp/odbc/src/entry_points.cpp
+++ b/modules/platforms/cpp/odbc/src/entry_points.cpp
@@ -216,8 +216,7 @@ SQLRETURN SQL_API SQLNativeSql(SQLHDBC conn,
SQLINTEGER outQueryBufferLen,
SQLINTEGER* outQueryLen)
{
- return ignite::SQLNativeSql(conn, inQuery, inQueryLen,
- outQueryBuffer, outQueryBufferLen, outQueryLen);
+ return ignite::SQLNativeSql(conn, inQuery, inQueryLen, outQueryBuffer, outQueryBufferLen, outQueryLen);
}
@@ -239,8 +238,7 @@ SQLRETURN SQL_API SQLColAttribute(SQLHSTMT stmt,
SQLPOINTER numericAttr)
#endif
{
- return ignite::SQLColAttribute(stmt, columnNum, fieldId,
- strAttr, bufferLen, strAttrLen, (SQLLEN*)numericAttr);
+ return ignite::SQLColAttribute(stmt, columnNum, fieldId, strAttr, bufferLen, strAttrLen, (SQLLEN*)numericAttr);
}
SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT stmt,
@@ -327,8 +325,7 @@ SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT handleType,
SQLSMALLINT bufferLen,
SQLSMALLINT* resLen)
{
- return ignite::SQLGetDiagField(handleType, handle,
- recNum, diagId, buffer, bufferLen, resLen);
+ return ignite::SQLGetDiagField(handleType, handle, recNum, diagId, buffer, bufferLen, resLen);
}
SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT handleType,
@@ -340,8 +337,7 @@ SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT handleType,
SQLSMALLINT msgBufferLen,
SQLSMALLINT* msgLen)
{
- return ignite::SQLGetDiagRec(handleType, handle, recNum,
- sqlState, nativeError, msgBuffer, msgBufferLen, msgLen);
+ return ignite::SQLGetDiagRec(handleType, handle, recNum, sqlState, nativeError, msgBuffer, msgBufferLen, msgLen);
}
SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT type)
@@ -349,9 +345,7 @@ SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT type)
return ignite::SQLGetTypeInfo(stmt, type);
}
-SQLRETURN SQL_API SQLEndTran(SQLSMALLINT handleType,
- SQLHANDLE handle,
- SQLSMALLINT completionType)
+SQLRETURN SQL_API SQLEndTran(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT completionType)
{
return ignite::SQLEndTran(handleType, handle, completionType);
}
@@ -381,8 +375,7 @@ SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env,
SQLINTEGER valueBufLen,
SQLINTEGER* valueResLen)
{
- return ignite::SQLGetEnvAttr(env, attr,
- valueBuf, valueBufLen, valueResLen);
+ return ignite::SQLGetEnvAttr(env, attr, valueBuf, valueBufLen, valueResLen);
}
SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT stmt,
@@ -405,9 +398,7 @@ SQLRETURN SQL_API SQLParamData(SQLHSTMT stmt, SQLPOINTER* value)
return ignite::SQLParamData(stmt, value);
}
-SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt,
- SQLPOINTER data,
- SQLLEN strLengthOrIndicator)
+SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN strLengthOrIndicator)
{
return ignite::SQLPutData(stmt, data, strLengthOrIndicator);
}
@@ -419,8 +410,7 @@ SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt,
SQLSMALLINT* decimalDigits,
SQLSMALLINT* nullable)
{
- return ignite::SQLDescribeParam(stmt, paramNum, dataType,
- paramSize, decimalDigits, nullable);
+ return ignite::SQLDescribeParam(stmt, paramNum, dataType, paramSize, decimalDigits, nullable);
}
SQLRETURN SQL_API SQLError(SQLHENV env,
@@ -432,8 +422,24 @@ SQLRETURN SQL_API SQLError(SQLHENV env,
SQLSMALLINT msgBufLen,
SQLSMALLINT* msgResLen)
{
- return ignite::SQLError(env, conn, stmt, state,
- error, msgBuf, msgBufLen, msgResLen);
+ return ignite::SQLError(env, conn, stmt, state, error, msgBuf, msgBufLen, msgResLen);
+}
+
+SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER valueBuf,
+ SQLINTEGER valueBufLen,
+ SQLINTEGER* valueResLen)
+{
+ return ignite::SQLGetConnectAttr(conn, attr, valueBuf, valueBufLen, valueResLen);
+}
+
+SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER value,
+ SQLINTEGER valueLen)
+{
+ return ignite::SQLSetConnectAttr(conn, attr, value, valueLen);
}
//
@@ -564,25 +570,6 @@ SQLRETURN SQL_API SQLSetScrollOptions(SQLHSTMT stmt,
return SQL_SUCCESS;
}
-SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC conn,
- SQLINTEGER attr,
- SQLPOINTER valueBuf,
- SQLINTEGER valueBufLen,
- SQLINTEGER* valueResLen)
-{
- LOG_MSG("SQLGetConnectAttr called");
- return SQL_SUCCESS;
-}
-
-SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC conn,
- SQLINTEGER attr,
- SQLPOINTER value,
- SQLINTEGER valueLen)
-{
- LOG_MSG("SQLSetConnectAttr called");
- return SQL_SUCCESS;
-}
-
SQLRETURN SQL_API SQLBulkOperations(SQLHSTMT stmt,
SQLUSMALLINT operation)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/0bc1d847/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index 1862465..baa276a 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -1140,9 +1140,9 @@ namespace ignite
SQLINTEGER* valueResLen)
{
using namespace odbc;
- using namespace odbc::type_traits;
+ using namespace type_traits;
- using odbc::app::ApplicationDataBuffer;
+ using app::ApplicationDataBuffer;
LOG_MSG("SQLGetEnvAttr called");
@@ -1310,4 +1310,46 @@ namespace ignite
return SQL_SUCCESS;
}
+ SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER valueBuf,
+ SQLINTEGER valueBufLen,
+ SQLINTEGER* valueResLen)
+ {
+ using namespace odbc;
+ using namespace type_traits;
+
+ using app::ApplicationDataBuffer;
+
+ LOG_MSG("SQLGetConnectAttr called");
+
+ Connection *connection = reinterpret_cast<Connection*>(conn);
+
+ if (!connection)
+ return SQL_INVALID_HANDLE;
+
+ connection->GetAttribute(attr, valueBuf, valueBufLen, valueResLen);
+
+ return connection->GetDiagnosticRecords().GetReturnCode();
+ }
+
+ SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER value,
+ SQLINTEGER valueLen)
+ {
+ using odbc::Connection;
+
+ LOG_MSG("SQLSetConnectAttr called");
+
+ Connection *connection = reinterpret_cast<Connection*>(conn);
+
+ if (!connection)
+ return SQL_INVALID_HANDLE;
+
+ connection->SetAttribute(attr, value, valueLen);
+
+ return connection->GetDiagnosticRecords().GetReturnCode();
+ }
+
} // namespace ignite;
[09/12] ignite git commit: IGNITE-6354 .NET: Fix DataStreamer with
complex object graphs
Posted by sb...@apache.org.
IGNITE-6354 .NET: Fix DataStreamer with complex object graphs
This closes #2645
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/67d716f0
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/67d716f0
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/67d716f0
Branch: refs/heads/ignite-6149
Commit: 67d716f00806c8d69f8339b090e0ddd877b225e3
Parents: ed3d2a5
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Tue Sep 12 17:41:38 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Tue Sep 12 17:41:38 2017 +0300
----------------------------------------------------------------------
.../Cache/CacheAbstractTest.cs | 67 ++++++++------------
.../Dataload/DataStreamerTest.cs | 49 ++++++++++++++
.../Impl/Binary/BinaryWriterExtensions.cs | 8 +--
.../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs | 52 ++++++++-------
.../Impl/Compute/ComputeImpl.cs | 2 +-
.../Impl/Datastream/DataStreamerBatch.cs | 10 +--
.../Impl/Services/ServiceProxySerializer.cs | 10 ++-
7 files changed, 120 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/67d716f0/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
index 27ac3f4..39a18fe 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
@@ -128,14 +128,18 @@ namespace Apache.Ignite.Core.Tests.Cache
return GetIgnite(idx).GetCache<TK, TV>(CacheName());
}
- protected ICache<int, int> Cache()
+ protected ICache<int, int> Cache(bool async = false)
{
- return Cache<int, int>(0);
+ var cache = Cache<int, int>(0);
+
+ return async ? cache.WrapAsync() : cache;
}
- private ICache<TK, TV> Cache<TK, TV>()
+ private ICache<TK, TV> Cache<TK, TV>(bool async = false)
{
- return Cache<TK, TV>(0);
+ var cache = Cache<TK, TV>(0);
+
+ return async ? cache : cache.WrapAsync();
}
private ICacheAffinity Affinity()
@@ -404,39 +408,26 @@ namespace Apache.Ignite.Core.Tests.Cache
}
[Test]
- public void TestPut()
+ public void TestPut([Values(true, false)] bool async)
{
- var cache = Cache();
+ var cache = Cache(async);
cache.Put(1, 1);
Assert.AreEqual(1, cache.Get(1));
- }
-
- [Test]
- public void TestPutxAsync()
- {
- var cache = Cache().WrapAsync();
-
- cache.Put(1, 1);
-
- Assert.AreEqual(1, cache.Get(1));
- }
-
- [Test]
- public void TestPutIfAbsent()
- {
- var cache = Cache();
- Assert.IsFalse(cache.ContainsKey(1));
+ // Objects.
+ var cache2 = Cache<Container, Container>(async);
- Assert.AreEqual(true, cache.PutIfAbsent(1, 1));
+ var obj1 = new Container {Id = 1};
+ var obj2 = new Container {Id = 2};
- Assert.AreEqual(1, cache.Get(1));
+ obj1.Inner = obj2;
+ obj2.Inner = obj1;
- Assert.AreEqual(false, cache.PutIfAbsent(1, 2));
+ cache2[obj1] = obj2;
- Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache2[obj1].Id);
}
[Test]
@@ -458,7 +449,7 @@ namespace Apache.Ignite.Core.Tests.Cache
[Test]
public void TestGetAndPutIfAbsentAsync()
{
- var cache = Cache().WrapAsync();
+ var cache = Cache(true);
Assert.IsFalse(cache.ContainsKey(1));
@@ -476,9 +467,9 @@ namespace Apache.Ignite.Core.Tests.Cache
}
[Test]
- public void TestPutIfAbsentAsync()
+ public void TestPutIfAbsent([Values(true, false)] bool async)
{
- var cache = Cache().WrapAsync();
+ var cache = Cache(async);
Assert.Throws<KeyNotFoundException>(() => cache.Get(1));
Assert.IsFalse(cache.ContainsKey(1));
@@ -599,12 +590,7 @@ namespace Apache.Ignite.Core.Tests.Cache
[Test]
public void TestPutAll([Values(true, false)] bool async)
{
- var cache = Cache();
-
- if (async)
- {
- cache = cache.WrapAsync();
- }
+ var cache = Cache(async);
// Primitives.
cache.PutAll(new Dictionary<int, int> { { 1, 1 }, { 2, 2 }, { 3, 3 } });
@@ -614,12 +600,7 @@ namespace Apache.Ignite.Core.Tests.Cache
Assert.AreEqual(3, cache.Get(3));
// Objects.
- var cache2 = Cache<int, Container>();
-
- if (async)
- {
- cache2 = cache2.WrapAsync();
- }
+ var cache2 = Cache<int, Container>(async);
var obj1 = new Container();
var obj2 = new Container();
@@ -2565,6 +2546,8 @@ namespace Apache.Ignite.Core.Tests.Cache
private class Container
{
+ public int Id;
+
public Container Inner;
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/67d716f0/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
index 85ee976..fe5955f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
@@ -168,6 +168,46 @@ namespace Apache.Ignite.Core.Tests.Dataload
}
/// <summary>
+ /// Tests object graphs with loops.
+ /// </summary>
+ [Test]
+ public void TestObjectGraphs()
+ {
+ var obj1 = new Container();
+ var obj2 = new Container();
+ var obj3 = new Container();
+ var obj4 = new Container();
+
+ obj1.Inner = obj2;
+ obj2.Inner = obj1;
+ obj3.Inner = obj1;
+ obj4.Inner = new Container();
+
+ using (var ldr = _grid.GetDataStreamer<int, Container>(CacheName))
+ {
+ ldr.AllowOverwrite = true;
+
+ ldr.AddData(1, obj1);
+ ldr.AddData(2, obj2);
+ ldr.AddData(3, obj3);
+ ldr.AddData(4, obj4);
+ }
+
+ var cache = _grid.GetCache<int, Container>(CacheName);
+
+ var res = cache[1];
+ Assert.AreEqual(res, res.Inner.Inner);
+
+ Assert.IsNotNull(cache[2].Inner);
+ Assert.IsNotNull(cache[2].Inner.Inner);
+ Assert.IsNotNull(cache[3].Inner);
+ Assert.IsNotNull(cache[3].Inner.Inner);
+
+ Assert.IsNotNull(cache[4].Inner);
+ Assert.IsNull(cache[4].Inner.Inner);
+ }
+
+ /// <summary>
/// Test "tryFlush".
/// </summary>
[Test]
@@ -572,5 +612,14 @@ namespace Apache.Ignite.Core.Tests.Dataload
{
public int Val { get; set; }
}
+
+ /// <summary>
+ /// Container class.
+ /// </summary>
+ private class Container
+ {
+ public Container Inner;
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/67d716f0/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriterExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriterExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriterExtensions.cs
index 02b5dec..f75fcf8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriterExtensions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriterExtensions.cs
@@ -92,12 +92,12 @@ namespace Apache.Ignite.Core.Impl.Binary
if (selector == null)
{
foreach (var val in vals)
- writer.Write(val);
+ writer.WriteObjectDetached(val);
}
else
{
foreach (var val in vals)
- writer.Write(selector(val));
+ writer.WriteObjectDetached(selector(val));
}
}
@@ -142,7 +142,7 @@ namespace Apache.Ignite.Core.Impl.Binary
{
foreach (var val in vals)
{
- writer.Write(val);
+ writer.WriteObjectDetached(val);
size++;
}
@@ -151,7 +151,7 @@ namespace Apache.Ignite.Core.Impl.Binary
{
foreach (var val in vals)
{
- writer.Write(selector(val));
+ writer.WriteObjectDetached(selector(val));
size++;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/67d716f0/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
index 64eee8d..05644cd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
@@ -250,17 +250,21 @@ namespace Apache.Ignite.Core.Impl.Cache
var p0 = new CacheEntryFilterHolder(p, (k, v) => p.Invoke(new CacheEntry<TK, TV>((TK) k, (TV) v)),
Marshaller, IsKeepBinary);
- writer.WriteObject(p0);
+ writer.WriteObjectDetached(p0);
}
else
- writer.WriteObject<CacheEntryFilterHolder>(null);
+ {
+ writer.WriteObjectDetached<CacheEntryFilterHolder>(null);
+ }
if (args != null && args.Length > 0)
{
writer.WriteInt(args.Length);
foreach (var o in args)
- writer.WriteObject(o);
+ {
+ writer.WriteObjectDetached(o);
+ }
}
else
{
@@ -337,7 +341,7 @@ namespace Apache.Ignite.Core.Impl.Cache
var res = DoOutInOpX((int)CacheOp.Peek,
w =>
{
- w.Write(key);
+ w.WriteObjectDetached(key);
w.WriteInt(EncodePeekModes(modes));
},
(s, r) => r == True ? new CacheResult<TV>(Unmarshal<TV>(s)) : new CacheResult<TV>(),
@@ -473,8 +477,8 @@ namespace Apache.Ignite.Core.Impl.Cache
return DoOutOpAsync(CacheOp.GetAndPutAsync, w =>
{
- w.WriteObject(key);
- w.WriteObject(val);
+ w.WriteObjectDetached(key);
+ w.WriteObjectDetached(val);
}, r => GetCacheResult(r));
}
@@ -499,8 +503,8 @@ namespace Apache.Ignite.Core.Impl.Cache
return DoOutOpAsync(CacheOp.GetAndReplaceAsync, w =>
{
- w.WriteObject(key);
- w.WriteObject(val);
+ w.WriteObjectDetached(key);
+ w.WriteObjectDetached(val);
}, r => GetCacheResult(r));
}
@@ -567,8 +571,8 @@ namespace Apache.Ignite.Core.Impl.Cache
return DoOutOpAsync(CacheOp.GetAndPutIfAbsentAsync, w =>
{
- w.WriteObject(key);
- w.WriteObject(val);
+ w.WriteObjectDetached(key);
+ w.WriteObjectDetached(val);
}, r => GetCacheResult(r));
}
@@ -617,9 +621,9 @@ namespace Apache.Ignite.Core.Impl.Cache
return DoOutOpAsync<bool>(CacheOp.Replace3Async, w =>
{
- w.WriteObject(key);
- w.WriteObject(oldVal);
- w.WriteObject(newVal);
+ w.WriteObjectDetached(key);
+ w.WriteObjectDetached(oldVal);
+ w.WriteObjectDetached(newVal);
});
}
@@ -838,8 +842,8 @@ namespace Apache.Ignite.Core.Impl.Cache
return DoOutInOpX((int) CacheOp.Invoke,
writer =>
{
- writer.Write(key);
- writer.Write(holder);
+ writer.WriteObjectDetached(key);
+ writer.WriteObjectDetached(holder);
},
(input, res) => res == True ? Unmarshal<TRes>(input) : default(TRes),
_readException);
@@ -858,8 +862,8 @@ namespace Apache.Ignite.Core.Impl.Cache
return DoOutOpAsync(CacheOp.InvokeAsync, writer =>
{
- writer.Write(key);
- writer.Write(holder);
+ writer.WriteObjectDetached(key);
+ writer.WriteObjectDetached(holder);
},
r =>
{
@@ -1319,8 +1323,8 @@ namespace Apache.Ignite.Core.Impl.Cache
{
return DoOutInOpX((int) op, w =>
{
- w.Write(x);
- w.Write(y);
+ w.WriteObjectDetached(x);
+ w.WriteObjectDetached(y);
}, _readException);
}
@@ -1331,9 +1335,9 @@ namespace Apache.Ignite.Core.Impl.Cache
{
return DoOutInOpX((int) op, w =>
{
- w.Write(x);
- w.Write(y);
- w.Write(z);
+ w.WriteObjectDetached(x);
+ w.WriteObjectDetached(y);
+ w.WriteObjectDetached(z);
}, _readException);
}
@@ -1364,8 +1368,8 @@ namespace Apache.Ignite.Core.Impl.Cache
return DoOutInOpX((int)cacheOp,
w =>
{
- w.Write(x);
- w.Write(y);
+ w.WriteObjectDetached(x);
+ w.WriteObjectDetached(y);
},
(stream, res) => res == True ? new CacheResult<TV>(Unmarshal<TV>(stream)) : new CacheResult<TV>(),
_readException);
http://git-wip-us.apache.org/repos/asf/ignite/blob/67d716f0/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeImpl.cs
index 06f9ad4..3c684ae 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeImpl.cs
@@ -590,7 +590,7 @@ namespace Apache.Ignite.Core.Impl.Compute
try
{
- writer.WriteObject(jobHolder);
+ writer.WriteObjectDetached(jobHolder);
}
catch (Exception)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/67d716f0/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerBatch.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerBatch.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerBatch.cs
index 66ee695..38a8ea8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerBatch.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerBatch.cs
@@ -221,8 +221,8 @@ namespace Apache.Ignite.Core.Impl.Datastream
{
foreach (KeyValuePair<TK, TV> item in entries)
{
- writer.Write(item.Key);
- writer.Write(item.Value);
+ writer.WriteObjectDetached(item.Key);
+ writer.WriteObjectDetached(item.Value);
}
continue;
@@ -232,8 +232,8 @@ namespace Apache.Ignite.Core.Impl.Datastream
DataStreamerEntry<TK, TV> entry = val as DataStreamerEntry<TK, TV>;
if (entry != null) {
- writer.Write(entry.Key);
- writer.Write(entry.Value);
+ writer.WriteObjectDetached(entry.Key);
+ writer.WriteObjectDetached(entry.Value);
continue;
}
@@ -243,7 +243,7 @@ namespace Apache.Ignite.Core.Impl.Datastream
if (rmvEntry != null)
{
- writer.Write(rmvEntry.Key);
+ writer.WriteObjectDetached(rmvEntry.Key);
writer.Write<object>(null);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/67d716f0/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs
index b4273b1..fc6009a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxySerializer.cs
@@ -56,7 +56,9 @@ namespace Apache.Ignite.Core.Impl.Services
{
// Write as is
foreach (var arg in arguments)
- writer.WriteObject(arg);
+ {
+ writer.WriteObjectDetached(arg);
+ }
}
else
{
@@ -200,9 +202,13 @@ namespace Apache.Ignite.Core.Impl.Services
var hnd = GetPlatformArgWriter(param, arg);
if (hnd != null)
+ {
hnd(writer, arg);
+ }
else
- writer.WriteObject(arg);
+ {
+ writer.WriteObjectDetached(arg);
+ }
}
/// <summary>
[03/12] ignite git commit: IGNITE-6253 .NET: Use DocFX for API
documentation
Posted by sb...@apache.org.
IGNITE-6253 .NET: Use DocFX for API documentation
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f5bbc709
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f5bbc709
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f5bbc709
Branch: refs/heads/ignite-6149
Commit: f5bbc709fb79eb00e4044adc7aaf03abf9508fa6
Parents: c61f134
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Tue Sep 12 11:29:15 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Tue Sep 12 12:40:07 2017 +0300
----------------------------------------------------------------------
assembly/release-fabric-base.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/f5bbc709/assembly/release-fabric-base.xml
----------------------------------------------------------------------
diff --git a/assembly/release-fabric-base.xml b/assembly/release-fabric-base.xml
index 7484dfa..a16d996 100644
--- a/assembly/release-fabric-base.xml
+++ b/assembly/release-fabric-base.xml
@@ -88,7 +88,7 @@
<!-- Move .Net docs. -->
<fileSet>
- <directory>modules/clients/target/dotnetdoc/html</directory>
+ <directory>modules/clients/target/dotnetdoc</directory>
<outputDirectory>/platforms/dotnet/docs</outputDirectory>
</fileSet>
[08/12] ignite git commit: Added more memory to
DynamicColumnsAbstractTest.
Posted by sb...@apache.org.
Added more memory to DynamicColumnsAbstractTest.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ed3d2a5e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ed3d2a5e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ed3d2a5e
Branch: refs/heads/ignite-6149
Commit: ed3d2a5edbe9b4b20dd02eeedc7636abdc0548c5
Parents: 43be051
Author: devozerov <vo...@gridgain.com>
Authored: Tue Sep 12 17:33:23 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Sep 12 17:33:23 2017 +0300
----------------------------------------------------------------------
.../processors/cache/index/DynamicColumnsAbstractTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/ed3d2a5e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
index 978c504..00f345e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
@@ -264,8 +264,8 @@ public abstract class DynamicColumnsAbstractTest extends GridCommonAbstractTest
.setMemoryPolicies(
new MemoryPolicyConfiguration()
.setName("default")
- .setMaxSize(32 * 1024 * 1024L)
- .setInitialSize(32 * 1024 * 1024L)
+ .setMaxSize(128 * 1024 * 1024L)
+ .setInitialSize(128 * 1024 * 1024L)
);
cfg.setMemoryConfiguration(memCfg);