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/10/09 14:51:26 UTC
[19/29] ignite git commit: IGNITE-6054: SQL: implemented "WRAP_KEY"
and "WRAP_VALUE" modes for CREATE TABLE. This closes #2784.
IGNITE-6054: SQL: implemented "WRAP_KEY" and "WRAP_VALUE" modes for CREATE TABLE. This closes #2784.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/79d94cf4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/79d94cf4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/79d94cf4
Branch: refs/heads/ignite-5937
Commit: 79d94cf4bbc906449a4c6995801fa61daaf80faa
Parents: 74f0400
Author: Alexander Paschenko <al...@gmail.com>
Authored: Fri Oct 6 18:04:44 2017 +0300
Committer: devozerov <pp...@gmail.com>
Committed: Fri Oct 6 18:04:44 2017 +0300
----------------------------------------------------------------------
.../jdbc/thin/JdbcThinMetadataSelfTest.java | 2 +-
.../cache/query/IgniteQueryErrorCode.java | 2 +-
.../processors/query/GridQueryIndexing.java | 22 +-
.../processors/query/GridQueryProcessor.java | 8 +-
.../query/QueryTypeDescriptorImpl.java | 42 ++-
.../query/property/QueryBinaryProperty.java | 1 -
...IgniteClientCacheInitializationFailTest.java | 18 +-
.../query/h2/DmlStatementsProcessor.java | 26 +-
.../internal/processors/query/h2/H2Schema.java | 17 +-
.../internal/processors/query/h2/H2TypeKey.java | 64 ++++
.../processors/query/h2/IgniteH2Indexing.java | 33 +-
.../query/h2/ddl/DdlStatementsProcessor.java | 36 ++-
.../query/h2/sql/GridSqlCreateTable.java | 34 +++
.../query/h2/sql/GridSqlQueryParser.java | 58 +++-
...ynamicColumnsAbstractConcurrentSelfTest.java | 57 ++--
...umnsConcurrentAtomicPartitionedSelfTest.java | 2 +-
...lumnsConcurrentAtomicReplicatedSelfTest.java | 2 +-
...currentTransactionalPartitionedSelfTest.java | 2 +-
...ncurrentTransactionalReplicatedSelfTest.java | 5 +-
.../H2DynamicColumnsAbstractBasicSelfTest.java | 44 +++
.../cache/index/H2DynamicTableSelfTest.java | 301 +++++++++++++++++--
.../query/IgniteSqlNotNullConstraintTest.java | 2 +-
.../h2/GridIndexingSpiAbstractSelfTest.java | 47 +--
.../Cache/Query/CacheDmlQueriesTest.cs | 4 +-
24 files changed, 673 insertions(+), 156 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
index 6c20de0..4e1ae4d 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
@@ -139,7 +139,7 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE TEST (ID INT, NAME VARCHAR(50), VAL VARCHAR(50), PRIMARY KEY (ID, NAME))");
- stmt.execute("CREATE TABLE \"Quoted\" (\"Id\" INT primary key, \"Name\" VARCHAR(50))");
+ stmt.execute("CREATE TABLE \"Quoted\" (\"Id\" INT primary key, \"Name\" VARCHAR(50)) WITH WRAP_KEY");
stmt.execute("CREATE INDEX \"MyTestIndex quoted\" on \"Quoted\" (\"Id\" DESC)");
stmt.execute("CREATE INDEX IDX ON TEST (ID ASC)");
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
index 8e5af31..e0ff9a4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
@@ -91,7 +91,7 @@ public final class IgniteQueryErrorCode {
/** Attempt to INSERT or MERGE {@code null} key. */
public final static int NULL_KEY = 4003;
- /** Attempt to INSERT or MERGE {@code null} value. */
+ /** Attempt to INSERT or MERGE {@code null} value, or to to set {@code null} to a {@code NOT NULL} column. */
public final static int NULL_VALUE = 4004;
/** {@link EntryProcessor} has thrown an exception during {@link IgniteCache#invokeAll}. */
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
index b8445ca..93d541d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
@@ -66,13 +66,13 @@ public interface GridQueryIndexing {
* Parses SQL query into two step query and executes it.
*
* @param schemaName Schema name.
+ * @param cacheName Cache name.
* @param qry Query.
* @param keepBinary Keep binary flag.
- * @param mainCacheId Main cache ID.
- * @return Cursor.
+ * @param mainCacheId Main cache ID. @return Cursor.
* @throws IgniteCheckedException If failed.
*/
- public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry,
+ public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, String cacheName, SqlQuery qry,
boolean keepBinary, int mainCacheId) throws IgniteCheckedException;
/**
@@ -109,12 +109,12 @@ public interface GridQueryIndexing {
* Executes regular query.
*
* @param schemaName Schema name.
- * @param qry Query.
+ * @param cacheName Cache name.
+ *@param qry Query.
* @param filter Cache name and key filter.
- * @param keepBinary Keep binary flag.
- * @return Cursor.
+ * @param keepBinary Keep binary flag. @return Cursor.
*/
- public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName, SqlQuery qry,
+ public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName, String cacheName, SqlQuery qry,
IndexingQueryFilter filter, boolean keepBinary) throws IgniteCheckedException;
/**
@@ -134,14 +134,14 @@ public interface GridQueryIndexing {
* Executes text query.
*
* @param schemaName Schema name.
+ * @param cacheName Cache name.
* @param qry Text query.
* @param typeName Type name.
- * @param filter Cache name and key filter.
- * @return Queried rows.
+ * @param filter Cache name and key filter. @return Queried rows.
* @throws IgniteCheckedException If failed.
*/
- public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName, String qry,
- String typeName, IndexingQueryFilter filter) throws IgniteCheckedException;
+ public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName, String cacheName,
+ String qry, String typeName, IndexingQueryFilter filter) throws IgniteCheckedException;
/**
* Create new index locally.
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 56e8a42..f044c1d 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
@@ -2044,7 +2044,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
return executeQuery(GridCacheQueryType.SQL, qry.getSql(), cctx,
new IgniteOutClosureX<QueryCursor<Cache.Entry<K, V>>>() {
@Override public QueryCursor<Cache.Entry<K, V>> applyx() throws IgniteCheckedException {
- return idx.queryDistributedSql(schemaName, qry, keepBinary, mainCacheId);
+ return idx.queryDistributedSql(schemaName, cctx.name(), qry, keepBinary, mainCacheId);
}
}, true);
}
@@ -2088,10 +2088,10 @@ public class GridQueryProcessor extends GridProcessorAdapter {
if (cctx.config().getQueryParallelism() > 1) {
qry.setDistributedJoins(true);
- return idx.queryDistributedSql(schemaName, qry, keepBinary, mainCacheId);
+ return idx.queryDistributedSql(schemaName, cctx.name(), qry, keepBinary, mainCacheId);
}
else
- return idx.queryLocalSql(schemaName, qry, idx.backupFilter(requestTopVer.get(),
+ return idx.queryLocalSql(schemaName, cctx.name(), qry, idx.backupFilter(requestTopVer.get(),
qry.getPartitions()), keepBinary);
}
}, true);
@@ -2344,7 +2344,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
String typeName = typeName(cacheName, resType);
String schemaName = idx.schema(cacheName);
- return idx.queryLocalText(schemaName, clause, typeName, filters);
+ return idx.queryLocalText(schemaName, cacheName, clause, typeName, filters);
}
}, true);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 e12476a..72adefd 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
@@ -24,12 +24,12 @@ 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.F;
import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.jetbrains.annotations.Nullable;
@@ -453,7 +453,7 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
* Sets key field name.
* @param keyFieldName Key field name.
*/
- public void keyFieldName(String keyFieldName) {
+ void keyFieldName(String keyFieldName) {
this.keyFieldName = keyFieldName;
}
@@ -464,10 +464,10 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
/**
* Sets value field name.
- * @param valueFieldName value field name.
+ * @param valFieldName value field name.
*/
- public void valueFieldName(String valueFieldName) {
- this.valFieldName = valueFieldName;
+ void valueFieldName(String valFieldName) {
+ this.valFieldName = valFieldName;
}
/** {@inheritDoc} */
@@ -480,6 +480,7 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
return keyFieldName != null ? aliases.get(keyFieldName) : null;
}
+ /** {@inheritDoc} */
@Nullable @Override public String valueFieldAlias() {
return valFieldName != null ? aliases.get(valFieldName) : null;
}
@@ -487,17 +488,34 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
/** {@inheritDoc} */
@SuppressWarnings("ForLoopReplaceableByForEach")
@Override public void validateKeyAndValue(Object key, Object val) throws IgniteCheckedException {
- if (validateProps == null)
+ if (F.isEmpty(validateProps))
return;
- final int size = validateProps.size();
+ for (int i = 0; i < validateProps.size(); ++i) {
+ GridQueryProperty prop = validateProps.get(i);
+
+ Object propVal;
+
+ int errCode;
+
+ if (F.eq(prop.name(), keyFieldName)) {
+ propVal = key;
+
+ errCode = IgniteQueryErrorCode.NULL_KEY;
+ }
+ else if (F.eq(prop.name(), valFieldName)) {
+ propVal = val;
+
+ errCode = IgniteQueryErrorCode.NULL_VALUE;
+ }
+ else {
+ propVal = prop.value(key, val);
- for (int idx = 0; idx < size; ++idx) {
- GridQueryProperty prop = validateProps.get(idx);
+ errCode = IgniteQueryErrorCode.NULL_VALUE;
+ }
- if (prop.value(key, val) == null)
- throw new IgniteSQLException("Null value is not allowed for field '" + prop.name() + "'",
- IgniteQueryErrorCode.NULL_VALUE);
+ if (propVal == null)
+ throw new IgniteSQLException("Null value is not allowed for column '" + prop.name() + "'", errCode);
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 5d90a43..18508a8 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
@@ -81,7 +81,6 @@ public class QueryBinaryProperty implements GridQueryProperty {
*/
public QueryBinaryProperty(GridKernalContext ctx, String propName, QueryBinaryProperty parent,
Class<?> type, @Nullable Boolean key, String alias, boolean notNull) {
-
this.ctx = ctx;
log = ctx.log(QueryBinaryProperty.class);
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
index 1ebf556..83dd9c9 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
@@ -193,7 +193,7 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
/**
* @param client Client.
*/
- @SuppressWarnings("ThrowableNotThrown")
+ @SuppressWarnings({"ThrowableNotThrown", "ThrowableResultOfMethodCallIgnored"})
private void checkFailedCache(final Ignite client, final String cacheName) {
GridTestUtils.assertThrows(log, new Callable<Object>() {
@Override public Object call() throws Exception {
@@ -236,14 +236,14 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
}
/** {@inheritDoc} */
- @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry,
- boolean keepBinary, int mainCacheId) throws IgniteCheckedException {
+ @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, String cacheName,
+ SqlQuery qry, boolean keepBinary, int mainCacheId) throws IgniteCheckedException {
return null;
}
/** {@inheritDoc} */
- @Override public List<FieldsQueryCursor<List<?>>> queryDistributedSqlFields(String schemaName, SqlFieldsQuery qry,
- boolean keepBinary, GridQueryCancel cancel,
+ @Override public List<FieldsQueryCursor<List<?>>> queryDistributedSqlFields(String schemaName,
+ SqlFieldsQuery qry, boolean keepBinary, GridQueryCancel cancel,
@Nullable Integer mainCacheId, boolean failOnMultipleStmts) throws IgniteCheckedException {
return null;
}
@@ -255,8 +255,8 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
}
/** {@inheritDoc} */
- @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryLocalSql(String schemaName, SqlQuery qry,
- IndexingQueryFilter filter, boolean keepBinary) throws IgniteCheckedException {
+ @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryLocalSql(String schemaName, String cacheName,
+ SqlQuery qry, IndexingQueryFilter filter, boolean keepBinary) throws IgniteCheckedException {
return null;
}
@@ -267,8 +267,8 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
}
/** {@inheritDoc} */
- @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String spaceName, String qry,
- String typeName, IndexingQueryFilter filter) throws IgniteCheckedException {
+ @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String spaceName,
+ String cacheName, String qry, String typeName, IndexingQueryFilter filter) throws IgniteCheckedException {
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 ee1875f..98117b2 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
@@ -49,13 +49,13 @@ import org.apache.ignite.binary.BinaryObjectBuilder;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.GridKernalContext;
-import org.apache.ignite.internal.processors.odbc.SqlStateCode;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheOperationContext;
import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
+import org.apache.ignite.internal.processors.odbc.SqlStateCode;
import org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator;
import org.apache.ignite.internal.processors.query.GridQueryCancel;
import org.apache.ignite.internal.processors.query.GridQueryFieldsResult;
@@ -255,13 +255,12 @@ public class DmlStatementsProcessor {
}
/**
- * Perform given statement against given data streamer. Only rows based INSERT and MERGE are supported
- * as well as key bound UPDATE and DELETE (ones with filter {@code WHERE _key = ?}).
+ * Perform given statement against given data streamer. Only rows based INSERT is supported.
*
* @param streamer Streamer to feed data to.
* @param stmt Statement.
* @param args Statement arguments.
- * @return Number of rows in given statement for INSERT and MERGE, {@code 1} otherwise.
+ * @return Number of rows in given INSERT statement.
* @throws IgniteCheckedException if failed.
*/
@SuppressWarnings({"unchecked", "ConstantConditions"})
@@ -916,11 +915,22 @@ public class DmlStatementsProcessor {
val = convert(val, rowDesc, desc.valueClass(), plan.colTypes[plan.valColIdx]);
}
- if (key == null)
- throw new IgniteSQLException("Key for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_KEY);
+ if (key == null) {
+ if (F.isEmpty(desc.keyFieldName()))
+ throw new IgniteSQLException("Key for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_KEY);
+ else
+ throw new IgniteSQLException("Null value is not allowed for column '" + desc.keyFieldName() + "'",
+ IgniteQueryErrorCode.NULL_KEY);
+ }
- if (val == null)
- throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE);
+ if (val == null) {
+ if (F.isEmpty(desc.valueFieldName()))
+ throw new IgniteSQLException("Value for INSERT, MERGE, or UPDATE must not be null",
+ IgniteQueryErrorCode.NULL_VALUE);
+ else
+ throw new IgniteSQLException("Null value is not allowed for column '" + desc.valueFieldName() + "'",
+ IgniteQueryErrorCode.NULL_VALUE);
+ }
Map<String, Object> newColVals = new HashMap<>();
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
index 3f39e6a..f5cf0f2 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
@@ -17,9 +17,8 @@
package org.apache.ignite.internal.processors.query.h2;
-import org.jsr166.ConcurrentHashMap8;
-
import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
@@ -30,10 +29,10 @@ public class H2Schema {
private final String schemaName;
/** */
- private final ConcurrentMap<String, H2TableDescriptor> tbls = new ConcurrentHashMap8<>();
+ private final ConcurrentMap<String, H2TableDescriptor> tbls = new ConcurrentHashMap<>();
/** */
- private final ConcurrentMap<String, H2TableDescriptor> typeToTbl = new ConcurrentHashMap8<>();
+ private final ConcurrentMap<H2TypeKey, H2TableDescriptor> typeToTbl = new ConcurrentHashMap<>();
/**
* Constructor.
@@ -70,8 +69,8 @@ public class H2Schema {
* @param typeName Type name.
* @return Table.
*/
- public H2TableDescriptor tableByTypeName(String typeName) {
- return typeToTbl.get(typeName);
+ public H2TableDescriptor tableByTypeName(String cacheName, String typeName) {
+ return typeToTbl.get(new H2TypeKey(cacheName, typeName));
}
/**
@@ -81,7 +80,7 @@ public class H2Schema {
if (tbls.putIfAbsent(tbl.tableName(), tbl) != null)
throw new IllegalStateException("Table already registered: " + tbl.fullTableName());
- if (typeToTbl.putIfAbsent(tbl.typeName(), tbl) != null)
+ if (typeToTbl.putIfAbsent(new H2TypeKey(tbl.cache().name(), tbl.typeName()), tbl) != null)
throw new IllegalStateException("Table already registered: " + tbl.fullTableName());
}
@@ -91,7 +90,7 @@ public class H2Schema {
public void remove(H2TableDescriptor tbl) {
tbls.remove(tbl.tableName());
- typeToTbl.remove(tbl.typeName());
+ typeToTbl.remove(new H2TypeKey(tbl.cache().name(), tbl.typeName()));
}
/**
@@ -104,7 +103,7 @@ public class H2Schema {
tbls.remove(tbl.tableName());
- typeToTbl.remove(tbl.typeName());
+ typeToTbl.remove(new H2TypeKey(tbl.cache().name(), tbl.typeName()));
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java
new file mode 100644
index 0000000..d39918c
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java
@@ -0,0 +1,64 @@
+/*
+ * 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.h2;
+
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Key for types lookup.
+ */
+public class H2TypeKey {
+ /** Cache name. */
+ private final String cacheName;
+
+ /** Type name. */
+ private final String typeName;
+
+ /**
+ * Constructor.
+ *
+ * @param cacheName Cache name.
+ * @param typeName Type name.
+ */
+ H2TypeKey(String cacheName, String typeName) {
+ this.cacheName = cacheName;
+ this.typeName = typeName;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ H2TypeKey other = (H2TypeKey)o;
+
+ return F.eq(typeName, other.typeName) && F.eq(cacheName, other.cacheName);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = cacheName.hashCode();
+
+ res = 31 * res + typeName.hashCode();
+
+ return res;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 fd7b9a8..22ed592 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
@@ -548,7 +548,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
GridCacheVersion ver,
long expirationTime,
long link) throws IgniteCheckedException {
- H2TableDescriptor tbl = tableDescriptor(schema(cacheName), type.name());
+ H2TableDescriptor tbl = tableDescriptor(schema(cacheName), cacheName, type.name());
if (tbl == null)
return; // Type was rejected.
@@ -572,7 +572,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
if (log.isDebugEnabled())
log.debug("Removing key from cache query index [locId=" + nodeId + ", key=" + key + ", val=" + val + ']');
- H2TableDescriptor tbl = tableDescriptor(schema(cacheName), type.name());
+ H2TableDescriptor tbl = tableDescriptor(schema(cacheName), cacheName, type.name());
if (tbl == null)
return;
@@ -777,10 +777,11 @@ public class IgniteH2Indexing implements GridQueryIndexing {
}
}
+ /** {@inheritDoc} */
@SuppressWarnings("unchecked")
- @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName, String qry,
- String typeName, IndexingQueryFilter filters) throws IgniteCheckedException {
- H2TableDescriptor tbl = tableDescriptor(schemaName, typeName);
+ @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName,
+ String cacheName, String qry, String typeName, IndexingQueryFilter filters) throws IgniteCheckedException {
+ H2TableDescriptor tbl = tableDescriptor(schemaName, cacheName, typeName);
if (tbl != null && tbl.luceneIndex() != null) {
GridRunningQueryInfo run = new GridRunningQueryInfo(qryIdGen.incrementAndGet(), qry, TEXT, schemaName,
@@ -1098,7 +1099,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
- @Override public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName,
+ @Override public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName, String cacheName,
final SqlQuery qry, final IndexingQueryFilter filter, final boolean keepBinary) throws IgniteCheckedException {
String type = qry.getType();
String sqlQry = qry.getSql();
@@ -1107,7 +1108,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
GridQueryCancel cancel = new GridQueryCancel();
- final GridCloseableIterator<IgniteBiTuple<K, V>> i = queryLocalSql(schemaName, sqlQry, alias,
+ final GridCloseableIterator<IgniteBiTuple<K, V>> i = queryLocalSql(schemaName, cacheName, sqlQry, alias,
F.asList(params), type, filter, cancel);
return new QueryCursorImpl<>(new Iterable<Cache.Entry<K, V>>() {
@@ -1142,19 +1143,19 @@ public class IgniteH2Indexing implements GridQueryIndexing {
* Executes regular query.
*
* @param schemaName Schema name.
+ * @param cacheName Cache name.
* @param qry Query.
* @param alias Table alias.
* @param params Query parameters.
* @param type Query return type.
- * @param filter Cache name and key filter.
- * @return Queried rows.
+ * @param filter Cache name and key filter. @return Queried rows.
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("unchecked")
- public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalSql(String schemaName,
+ public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalSql(String schemaName, String cacheName,
final String qry, String alias, @Nullable final Collection<Object> params, String type,
final IndexingQueryFilter filter, GridQueryCancel cancel) throws IgniteCheckedException {
- final H2TableDescriptor tbl = tableDescriptor(schemaName, type);
+ final H2TableDescriptor tbl = tableDescriptor(schemaName, cacheName, type);
if (tbl == null)
throw new IgniteSQLException("Failed to find SQL table for type: " + type,
@@ -1216,11 +1217,11 @@ public class IgniteH2Indexing implements GridQueryIndexing {
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
- @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry,
- boolean keepBinary, int mainCacheId) {
+ @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, String cacheName,
+ SqlQuery qry, boolean keepBinary, int mainCacheId) {
String type = qry.getType();
- H2TableDescriptor tblDesc = tableDescriptor(schemaName, type);
+ H2TableDescriptor tblDesc = tableDescriptor(schemaName, cacheName, type);
if (tblDesc == null)
throw new IgniteSQLException("Failed to find SQL table for type: " + type,
@@ -1829,13 +1830,13 @@ public class IgniteH2Indexing implements GridQueryIndexing {
* @param type Type name.
* @return Descriptor.
*/
- @Nullable private H2TableDescriptor tableDescriptor(String schemaName, String type) {
+ @Nullable private H2TableDescriptor tableDescriptor(String schemaName, String cacheName, String type) {
H2Schema schema = schemas.get(schemaName);
if (schema == null)
return null;
- return schema.tableByTypeName(type);
+ return schema.tableByTypeName(cacheName, type);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 affd903..f39e587 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
@@ -62,6 +62,7 @@ import org.h2.table.Column;
import org.h2.value.DataType;
import static org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.UPDATE_RESULT_META;
+import static org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.PARAM_WRAP_VALUE;
/**
* DDL statements processor.<p>
@@ -227,6 +228,10 @@ public class DdlStatementsProcessor {
cmd.tableName());
}
else {
+ if (QueryUtils.isSqlType(tbl.rowDescriptor().type().valueClass()))
+ throw new SchemaOperationException("Cannot add column(s) because table was created " +
+ "with " + PARAM_WRAP_VALUE + "=false option.");
+
List<QueryField> cols = new ArrayList<>(cmd.columns().length);
boolean allFieldsNullable = true;
@@ -373,11 +378,38 @@ public class DdlStatementsProcessor {
if (!F.isEmpty(createTbl.valueTypeName()))
valTypeName = createTbl.valueTypeName();
+ assert createTbl.wrapKey() != null;
+ assert createTbl.wrapValue() != null;
+
+ if (!createTbl.wrapKey()) {
+ GridSqlColumn pkCol = createTbl.columns().get(createTbl.primaryKeyColumns().iterator().next());
+
+ keyTypeName = DataType.getTypeClassName(pkCol.column().getType());
+
+ res.setKeyFieldName(pkCol.columnName());
+ }
+ else
+ res.setKeyFields(createTbl.primaryKeyColumns());
+
+ if (!createTbl.wrapValue()) {
+ GridSqlColumn valCol = null;
+
+ for (Map.Entry<String, GridSqlColumn> e : createTbl.columns().entrySet()) {
+ if (!createTbl.primaryKeyColumns().contains(e.getKey())) {
+ valCol = e.getValue();
+
+ break;
+ }
+ }
+
+ valTypeName = DataType.getTypeClassName(valCol.column().getType());
+
+ res.setValueFieldName(valCol.columnName());
+ }
+
res.setValueType(valTypeName);
res.setKeyType(keyTypeName);
- res.setKeyFields(createTbl.primaryKeyColumns());
-
if (!F.isEmpty(notNullFields)) {
QueryEntityEx res0 = new QueryEntityEx(res);
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 b73214f..de10826 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
@@ -71,6 +71,12 @@ public class GridSqlCreateTable extends GridSqlStatement {
/** Name of the column that represents affinity key. */
private String affinityKey;
+ /** Forcefully turn single column PK into an Object. */
+ private Boolean wrapKey;
+
+ /** Forcefully turn single column value into an Object. */
+ private Boolean wrapVal;
+
/** Extra WITH-params. */
private List<String> params;
@@ -271,6 +277,34 @@ public class GridSqlCreateTable extends GridSqlStatement {
}
/**
+ * @return Forcefully turn single column PK into an Object.
+ */
+ public Boolean wrapKey() {
+ return wrapKey;
+ }
+
+ /**
+ * @param wrapKey Forcefully turn single column PK into an Object.
+ */
+ public void wrapKey(boolean wrapKey) {
+ this.wrapKey = wrapKey;
+ }
+
+ /**
+ * @return Forcefully turn single column value into an Object.
+ */
+ public Boolean wrapValue() {
+ return wrapVal;
+ }
+
+ /**
+ * @param wrapVal Forcefully turn single column value into an Object..
+ */
+ public void wrapValue(boolean wrapVal) {
+ this.wrapVal = wrapVal;
+ }
+
+ /**
* @return Extra WITH-params.
*/
public List<String> params() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 3d7a1a0..bf72200 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
@@ -475,6 +475,12 @@ public class GridSqlQueryParser {
private static final String PARAM_VAL_TYPE = "VALUE_TYPE";
/** */
+ private static final String PARAM_WRAP_KEY = "WRAP_KEY";
+
+ /** */
+ public static final String PARAM_WRAP_VALUE = "WRAP_VALUE";
+
+ /** */
private final IdentityHashMap<Object, Object> h2ObjToGridObj = new IdentityHashMap<>();
/** */
@@ -1007,7 +1013,8 @@ public class GridSqlQueryParser {
pkCols.add(gridCol.columnName());
}
- int valColsNum = cols.size() - pkCols.size();
+ int keyColsNum = pkCols.size();
+ int valColsNum = cols.size() - keyColsNum;
if (valColsNum == 0)
throw new IgniteSQLException("Table must have at least one non PRIMARY KEY column.",
@@ -1052,6 +1059,44 @@ public class GridSqlQueryParser {
processExtraParam(e.getKey(), e.getValue(), res);
}
+ // Process key wrapping.
+ Boolean wrapKey = res.wrapKey();
+
+ if (wrapKey != null && !wrapKey) {
+ if (keyColsNum > 1) {
+ throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when composite primary key exists.",
+ IgniteQueryErrorCode.PARSING);
+ }
+
+ if (!F.isEmpty(res.keyTypeName())) {
+ throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when " + PARAM_KEY_TYPE + " is set.",
+ IgniteQueryErrorCode.PARSING);
+ }
+ }
+
+ boolean wrapKey0 = (res.wrapKey() != null && res.wrapKey()) || !F.isEmpty(res.keyTypeName()) || keyColsNum > 1;
+
+ res.wrapKey(wrapKey0);
+
+ // Process value wrapping.
+ Boolean wrapVal = res.wrapValue();
+
+ if (wrapVal != null && !wrapVal) {
+ if (valColsNum > 1) {
+ throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when multiple non-primary key " +
+ "columns exist.", IgniteQueryErrorCode.PARSING);
+ }
+
+ if (!F.isEmpty(res.valueTypeName())) {
+ throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when " + PARAM_VAL_TYPE + " is set.",
+ IgniteQueryErrorCode.PARSING);
+ }
+
+ res.wrapValue(false);
+ }
+ else
+ res.wrapValue(true); // By default value is always wrapped to allow for ALTER TABLE ADD COLUMN commands.
+
if (!F.isEmpty(res.valueTypeName()) && F.eq(res.keyTypeName(), res.valueTypeName()))
throw new IgniteSQLException("Key and value type names " +
"should be different for CREATE TABLE: " + res.valueTypeName(), IgniteQueryErrorCode.PARSING);
@@ -1336,6 +1381,17 @@ public class GridSqlQueryParser {
break;
+ case PARAM_WRAP_KEY: {
+ res.wrapKey(F.isEmpty(val) || Boolean.parseBoolean(val));
+
+ break;
+ }
+
+ case PARAM_WRAP_VALUE:
+ res.wrapValue(F.isEmpty(val) || Boolean.parseBoolean(val));
+
+ break;
+
default:
throw new IgniteSQLException("Unsupported parameter: " + name, IgniteQueryErrorCode.PARSING);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
index 969c985..3d4b2a3 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
@@ -82,7 +82,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
private static final String ATTR_FILTERED = "FILTERED";
/** SQL statement to create test table accompanied by template specification. */
- private static final String CREATE_SQL_WITH_TEMPLATE = CREATE_SQL + " WITH \"template=TPL\"";
+ private final String createSql;
/** Latches to block certain index operations. */
private static final ConcurrentHashMap<UUID, T3<CountDownLatch, AtomicBoolean, CountDownLatch>> BLOCKS =
@@ -103,6 +103,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
DynamicColumnsAbstractConcurrentSelfTest(CacheMode cacheMode, CacheAtomicityMode atomicityMode) {
this.cacheMode = cacheMode;
this.atomicityMode = atomicityMode;
+ createSql = CREATE_SQL + " WITH \"template=TPL\"";
}
/** {@inheritDoc} */
@@ -158,7 +159,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
createSqlCache(cli);
- run(cli, CREATE_SQL_WITH_TEMPLATE);
+ run(cli, createSql);
// Test migration between normal servers.
CountDownLatch idxLatch = blockIndexing(srv1Id);
@@ -210,7 +211,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
createSqlCache(srv1);
- run(srv1, CREATE_SQL_WITH_TEMPLATE);
+ run(srv1, createSql);
CountDownLatch idxLatch = blockIndexing(srv1);
@@ -253,7 +254,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
createSqlCache(srv1);
- run(srv1, CREATE_SQL_WITH_TEMPLATE);
+ run(srv1, createSql);
CountDownLatch idxLatch = blockIndexing(srv1);
@@ -296,7 +297,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
createSqlCache(srv1);
- run(srv1, CREATE_SQL_WITH_TEMPLATE);
+ run(srv1, createSql);
// Start data change operations from several threads.
final AtomicBoolean stopped = new AtomicBoolean();
@@ -309,7 +310,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
int key = ThreadLocalRandom.current().nextInt(0, LARGE_CACHE_SIZE);
int val = ThreadLocalRandom.current().nextInt();
- IgniteCache<BinaryObject, BinaryObject> cache = node.cache(CACHE_NAME);
+ IgniteCache<Object, BinaryObject> cache = node.cache(CACHE_NAME);
if (ThreadLocalRandom.current().nextBoolean())
cache.put(key(node, key), val(node, val));
@@ -342,15 +343,15 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
// Get expected values.
Set<Integer> expKeys = new HashSet<>();
- IgniteCache<BinaryObject, BinaryObject> cache = srv1.cache(CACHE_NAME).withKeepBinary();
+ IgniteCache<Object, BinaryObject> cache = srv1.cache(CACHE_NAME).withKeepBinary();
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
- BinaryObject key = key(srv1, i);
+ Object key = key(srv1, i);
BinaryObject val = cache.get(key);
if (val != null) {
- int id = key.field("ID");
+ int id = (Integer)key;
assertEquals(i, id);
@@ -363,17 +364,17 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
// Validate query result.
for (Ignite node : Ignition.allGrids()) {
- IgniteCache<BinaryObject, BinaryObject> nodeCache = node.cache(CACHE_NAME).withKeepBinary();
+ IgniteCache<Object, BinaryObject> nodeCache = node.cache(CACHE_NAME).withKeepBinary();
SqlQuery qry = new SqlQuery(valTypeName, "from " + TBL_NAME + " where mod(id, 2) <> 0");
- List<Cache.Entry<BinaryObject, BinaryObject>> res = nodeCache.query(qry).getAll();
+ List<Cache.Entry<Object, BinaryObject>> res = nodeCache.query(qry).getAll();
assertEquals("Cache size mismatch [exp=" + expKeys.size() + ", actual=" + res.size() + ']',
expKeys.size(), res.size());
- for (Cache.Entry<BinaryObject, BinaryObject> entry : res) {
- int key = entry.getKey().field("ID");
+ for (Cache.Entry<Object, BinaryObject> entry : res) {
+ int key = (Integer)entry.getKey();
int v = entry.getValue().field("v");
String name = entry.getValue().field("NAME");
@@ -399,13 +400,11 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
/**
* @param node Node.
- * @param key Value for ID field.
- * @return PERSON cache key.
+ * @param id Key.
+ * @return PERSON cache key (int or {@link BinaryObject}).
*/
- private BinaryObject key(Ignite node, int key) {
- String keyTypeName = ((IgniteEx)node).context().query().types(CACHE_NAME).iterator().next().keyTypeName();
-
- return node.binary().builder(keyTypeName).setField("ID", key).build();
+ private Object key(Ignite node, int id) {
+ return id;
}
/**
@@ -420,7 +419,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
createSqlCache(srv1);
- run(srv1, CREATE_SQL_WITH_TEMPLATE);
+ run(srv1, createSql);
awaitPartitionMapExchange();
@@ -481,7 +480,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
// Start cache and populate it with data.
createSqlCache(cli);
- run(cli, CREATE_SQL_WITH_TEMPLATE);
+ run(cli, createSql);
put(cli, 0, LARGE_CACHE_SIZE);
@@ -526,7 +525,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
createSqlCache(cli);
- run(cli, CREATE_SQL_WITH_TEMPLATE);
+ run(cli, createSql);
put(cli, 0, 5000);
@@ -539,8 +538,8 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
- IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" + dynColCnt.getAndIncrement(),
- Integer.class.getName()));
+ IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" +
+ dynColCnt.getAndIncrement(), Integer.class.getName()));
try {
fut.get();
@@ -641,7 +640,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
if (dynamicCache) {
createSqlCache(cli);
- run(cli, CREATE_SQL_WITH_TEMPLATE);
+ run(cli, createSql);
}
final String schemaName = dynamicCache ? QueryUtils.DFLT_SCHEMA : "idx";
@@ -677,7 +676,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
if (dynamicCache) {
DynamicColumnsAbstractConcurrentSelfTest.this.run(srvNode, DROP_SQL);
- DynamicColumnsAbstractConcurrentSelfTest.this.run(srvNode, CREATE_SQL_WITH_TEMPLATE);
+ DynamicColumnsAbstractConcurrentSelfTest.this.run(srvNode, createSql);
}
else {
srvNode.destroyCache("idx");
@@ -724,7 +723,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
createSqlCache(cli);
- run(cli, CREATE_SQL_WITH_TEMPLATE);
+ run(cli, createSql);
final AtomicBoolean stopped = new AtomicBoolean();
@@ -783,8 +782,8 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
- IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" + dynColCnt.getAndIncrement(),
- Integer.class.getName()));
+ IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" +
+ dynColCnt.getAndIncrement(), Integer.class.getName()));
try {
fut.get();
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
index ca68903..3f65fca 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
@@ -21,7 +21,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
/**
- * Test to check concurrent operations on dynamic columns on ATOMIC PARTITIONED cache.
+ * Test to check concurrent operations on dynamic columns on ATOMIC PARTITIONED cache with flat key.
*/
public class DynamicColumnsConcurrentAtomicPartitionedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
index 9a3a32c..289a01e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
@@ -21,7 +21,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
/**
- * Test to check concurrent operations on dynamic columns on ATOMIC REPLICATED cache.
+ * Test to check concurrent operations on dynamic columns on ATOMIC REPLICATED cache with flat key.
*/
public class DynamicColumnsConcurrentAtomicReplicatedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
index f42a447..371313e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
@@ -21,7 +21,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
/**
- * Test to check concurrent operations on dynamic columns on TRANSACTIONAL PARTITIONED cache.
+ * Test to check concurrent operations on dynamic columns on TRANSACTIONAL PARTITIONED cache with flat key.
*/
public class DynamicColumnsConcurrentTransactionalPartitionedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
index 2b53e42..f004b89 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
@@ -21,9 +21,10 @@ import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
/**
- * Test to check concurrent operations on dynamic columns on TRANSACTIONAL REPLICATED cache.
+ * Test to check concurrent operations on dynamic columns on TRANSACTIONAL REPLICATED cache with flat key.
*/
-public class DynamicColumnsConcurrentTransactionalReplicatedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
+public class DynamicColumnsConcurrentTransactionalReplicatedSelfTest
+ extends DynamicColumnsAbstractConcurrentSelfTest {
/**
* Constructor.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 5e64959..34be34d 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
@@ -302,6 +302,50 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum
}
/**
+ * Test that {@code ADD COLUMN} fails for non dynamic table that has flat value.
+ */
+ @SuppressWarnings({"unchecked", "ThrowFromFinallyBlock"})
+ public void testTestAlterTableOnFlatValueNonDynamicTable() {
+ CacheConfiguration c =
+ new CacheConfiguration("ints").setIndexedTypes(Integer.class, Integer.class)
+ .setSqlSchema(QueryUtils.DFLT_SCHEMA);
+
+ try {
+ grid(nodeIndex()).getOrCreateCache(c);
+
+ doTestAlterTableOnFlatValue("INTEGER");
+ }
+ finally {
+ grid(nodeIndex()).destroyCache("ints");
+ }
+ }
+
+ /**
+ * Test that {@code ADD COLUMN} fails for dynamic table that has flat value.
+ */
+ @SuppressWarnings({"unchecked", "ThrowFromFinallyBlock"})
+ public void testTestAlterTableOnFlatValueDynamicTable() {
+ try {
+ run("CREATE TABLE TEST (id int primary key, x varchar) with \"wrap_value=false\"");
+
+ doTestAlterTableOnFlatValue("TEST");
+ }
+ finally {
+ run("DROP TABLE TEST");
+ }
+ }
+
+ /**
+ * Test that {@code ADD COLUMN} fails for tables that have flat value.
+ * @param tblName table name.
+ */
+ private void doTestAlterTableOnFlatValue(String tblName) {
+ assertThrows("ALTER TABLE " + tblName + " ADD COLUMN y varchar",
+ "ADD COLUMN is not supported for tables created with wrap_value=false param. " +
+ "(To enable ADD COLUMN, create table with wrap_value=true param).");
+ }
+
+ /**
* @return Node index to run queries on.
*/
protected abstract int nodeIndex();
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 773e7e0..e0ab6c5 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
@@ -17,6 +17,11 @@
package org.apache.ignite.internal.processors.cache.index;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -59,6 +64,7 @@ import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.testframework.GridTestUtils;
import org.h2.jdbc.JdbcSQLException;
+import org.h2.value.DataType;
/**
* Tests for CREATE/DROP TABLE.
@@ -285,6 +291,14 @@ 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 testPlainKey() throws Exception {
+ doTestCreateTable(null, null, null, CacheWriteSynchronizationMode.FULL_SYNC);
+ }
+
+ /**
* Test that appending supplied arguments to {@code CREATE TABLE} results in creating new cache that has settings
* as expected
* @param cacheName Cache name, or {@code null} if the name generated by default should be used.
@@ -292,18 +306,19 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @param valTypeName Value type name, or {@code null} if the name generated by default should be used.
*/
private void doTestCustomNames(String cacheName, String keyTypeName, String valTypeName) {
- GridStringBuilder b = new GridStringBuilder("CREATE TABLE \"NameTest\" (id int primary key, x varchar) WITH ");
+ GridStringBuilder b = new GridStringBuilder("CREATE TABLE \"NameTest\" (id int primary key, x varchar) WITH " +
+ "wrap_key,wrap_value");
assert !F.isEmpty(cacheName) || !F.isEmpty(keyTypeName) || !F.isEmpty(valTypeName);
if (!F.isEmpty(cacheName))
- b.a("\"cache_name=").a(cacheName).a('"').a(',');
+ b.a(",\"cache_name=").a(cacheName).a('"');
if (!F.isEmpty(keyTypeName))
- b.a("\"key_type=").a(keyTypeName).a('"').a(',');
+ b.a(",\"key_type=").a(keyTypeName).a('"');
if (!F.isEmpty(valTypeName))
- b.a("\"value_type=").a(valTypeName).a('"');
+ b.a(",\"value_type=").a(valTypeName).a('"');
String res = b.toString();
@@ -312,8 +327,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
execute(client(), res);
- String resCacheName = U.firstNotNull(cacheName, QueryUtils.createTableCacheName(QueryUtils.DFLT_SCHEMA,
- "NameTest"));
+ String resCacheName = U.firstNotNull(cacheName, cacheName("NameTest"));
IgniteInternalCache<BinaryObject, BinaryObject> cache = client().cachex(resCacheName);
@@ -770,7 +784,8 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
* @throws Exception if failed.
*/
public void testAffinityKey() throws Exception {
- execute("CREATE TABLE \"City\" (\"name\" varchar primary key, \"code\" int) WITH \"affinityKey='name'\"");
+ execute("CREATE TABLE \"City\" (\"name\" varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+ "\"affinityKey='name'\"");
assertAffinityCacheConfiguration("City", "name");
@@ -783,7 +798,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
// We need unique name for this table to avoid conflicts with existing binary metadata.
execute("CREATE TABLE \"Person2\" (\"id\" int, \"city\" varchar," +
" \"name\" varchar, \"surname\" varchar, \"age\" int, PRIMARY KEY (\"id\", \"city\")) WITH " +
- "\"template=cache,affinityKey='city'\"");
+ "wrap_key,wrap_value,\"template=cache,affinityKey='city'\"");
assertAffinityCacheConfiguration("Person2", "city");
@@ -828,26 +843,31 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
*/
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public void testAffinityKeyCaseSensitivity() {
- execute("CREATE TABLE \"A\" (\"name\" varchar primary key, \"code\" int) WITH \"affinityKey='name'\"");
+ execute("CREATE TABLE \"A\" (\"name\" varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+ "\"affinityKey='name'\"");
assertAffinityCacheConfiguration("A", "name");
- execute("CREATE TABLE \"B\" (name varchar primary key, \"code\" int) WITH \"affinityKey=name\"");
+ execute("CREATE TABLE \"B\" (name varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+ "\"affinityKey=name\"");
assertAffinityCacheConfiguration("B", "NAME");
- execute("CREATE TABLE \"C\" (name varchar primary key, \"code\" int) WITH \"affinityKey=NamE\"");
+ execute("CREATE TABLE \"C\" (name varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+ "\"affinityKey=NamE\"");
assertAffinityCacheConfiguration("C", "NAME");
- execute("CREATE TABLE \"D\" (\"name\" varchar primary key, \"code\" int) WITH \"affinityKey=NAME\"");
+ execute("CREATE TABLE \"D\" (\"name\" varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+ "\"affinityKey=NAME\"");
assertAffinityCacheConfiguration("D", "name");
// Error arises because user has specified case sensitive affinity column name
GridTestUtils.assertThrows(null, new Callable<Object>() {
@Override public Object call() throws Exception {
- execute("CREATE TABLE \"E\" (name varchar primary key, \"code\" int) WITH \"affinityKey='Name'\"");
+ execute("CREATE TABLE \"E\" (name varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+ "\"affinityKey='Name'\"");
return null;
}
@@ -865,9 +885,19 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
}, IgniteSQLException.class, "Ambiguous affinity column name, use single quotes for case sensitivity: name");
execute("CREATE TABLE \"E\" (\"name\" varchar, \"Name\" int, val int, primary key(\"name\", " +
- "\"Name\")) WITH \"affinityKey='Name'\"");
+ "\"Name\")) WITH wrap_key,wrap_value,\"affinityKey='Name'\"");
assertAffinityCacheConfiguration("E", "Name");
+
+ execute("drop table a");
+
+ execute("drop table b");
+
+ execute("drop table c");
+
+ execute("drop table d");
+
+ execute("drop table e");
}
/**
@@ -914,7 +944,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
execute("create index on \"PUBLIC\".t (b desc)");
execute("drop table \"PUBLIC\".t");
- assertNull(client().cache("t"));
+ assertNull(client().cache(cacheName("t")));
execute("create table \"PUBLIC\".t (a int primary key, b varchar(30))");
@@ -944,6 +974,224 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
}
/**
+ * Test that it's impossible to create tables with same name regardless of key/value wrapping settings.
+ */
+ public void testWrappedAndUnwrappedKeyTablesInteroperability() {
+ {
+ execute("create table a (id int primary key, x varchar)");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_value",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key,wrap_value",
+ "Table already exists: A");
+
+ execute("drop table a");
+ }
+
+ {
+ execute("create table a (id int primary key, x varchar) with wrap_key");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar)",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_value",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key,wrap_value",
+ "Table already exists: A");
+
+ execute("drop table a");
+ }
+
+ {
+ execute("create table a (id int primary key, x varchar) with wrap_value");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar)",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key,wrap_value",
+ "Table already exists: A");
+
+ execute("drop table a");
+ }
+
+ {
+ execute("create table a (id int primary key, x varchar) with wrap_key,wrap_value");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar)",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_value",
+ "Table already exists: A");
+
+ assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key",
+ "Table already exists: A");
+
+ execute("drop table a");
+ }
+ }
+
+ /**
+ * Test that it's possible to create tables with matching key and/or value primitive types.
+ */
+ public void testDynamicTablesInteroperability() {
+ execute("create table a (id int primary key, x varchar) with \"wrap_value=false\"");
+
+ execute("create table b (id long primary key, y varchar) with \"wrap_value=false\"");
+
+ execute("create table c (id int primary key, z long) with \"wrap_value=false\"");
+
+ execute("create table d (id int primary key, w varchar) with \"wrap_value=false\"");
+
+ execute("drop table a");
+
+ execute("drop table b");
+
+ execute("drop table c");
+
+ execute("drop table d");
+ }
+
+ /**
+ * Test that when key or value has more than one column, wrap=false is forbidden.
+ */
+ public void testWrappingAlwaysOnWithComplexObjects() {
+ assertDdlCommandThrows("create table a (id int, x varchar, c long, primary key(id, c)) with \"wrap_key=false\"",
+ "WRAP_KEY cannot be false when composite primary key exists.");
+
+ assertDdlCommandThrows("create table a (id int, x varchar, c long, primary key(id)) with \"wrap_value=false\"",
+ "WRAP_VALUE cannot be false when multiple non-primary key columns exist.");
+ }
+
+ /**
+ * Test behavior when neither key nor value should be wrapped.
+ * @throws SQLException if failed.
+ */
+ public void testNoWrap() throws SQLException {
+ doTestKeyValueWrap(false, false);
+ }
+
+ /**
+ * Test behavior when only key is wrapped.
+ * @throws SQLException if failed.
+ */
+ public void testKeyWrap() throws SQLException {
+ doTestKeyValueWrap(true, false);
+ }
+
+ /**
+ * Test behavior when only value is wrapped.
+ * @throws SQLException if failed.
+ */
+ public void testValueWrap() throws SQLException {
+ doTestKeyValueWrap(false, true);
+ }
+
+ /**
+ * Test behavior when both key and value is wrapped.
+ * @throws SQLException if failed.
+ */
+ public void testKeyAndValueWrap() throws SQLException {
+ doTestKeyValueWrap(true, true);
+ }
+
+ /**
+ * Test behavior for given combination of wrap flags.
+ * @param wrapKey Whether key wrap should be enforced.
+ * @param wrapVal Whether value wrap should be enforced.
+ * @throws SQLException if failed.
+ */
+ private void doTestKeyValueWrap(boolean wrapKey, boolean wrapVal) throws SQLException {
+ try {
+ String sql = String.format("CREATE TABLE T (\"id\" int primary key, \"x\" varchar) WITH " +
+ "\"wrap_key=%b,wrap_value=%b\"", wrapKey, wrapVal);
+
+ if (wrapKey)
+ sql += ",\"key_type=tkey\"";
+
+ if (wrapVal)
+ sql += ",\"value_type=tval\"";
+
+ execute(sql);
+
+ execute("INSERT INTO T(\"id\", \"x\") values(1, 'a')");
+
+ LinkedHashMap<String, String> resCols = new LinkedHashMap<>();
+
+ List<Object> resData = new ArrayList<>();
+
+ try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1")) {
+ try (ResultSet colsRs = conn.getMetaData().getColumns(null, QueryUtils.DFLT_SCHEMA, "T", ".*")) {
+ while (colsRs.next())
+ resCols.put(colsRs.getString("COLUMN_NAME"),
+ DataType.getTypeClassName(DataType.convertSQLTypeToValueType(colsRs
+ .getShort("DATA_TYPE"))));
+ }
+
+ try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM T")) {
+ try (ResultSet dataRs = ps.executeQuery()) {
+ assertTrue(dataRs.next());
+
+ for (int i = 0; i < dataRs.getMetaData().getColumnCount(); i++)
+ resData.add(dataRs.getObject(i + 1));
+ }
+ }
+ }
+
+ LinkedHashMap<String, String> expCols = new LinkedHashMap<>();
+
+ expCols.put("id", Integer.class.getName());
+ expCols.put("x", String.class.getName());
+
+ assertEquals(expCols, resCols);
+
+ assertEqualsCollections(Arrays.asList(1, "a"), resData);
+
+ Object key = createKeyForWrapTest(1, wrapKey);
+
+ Object val = client().cache(cacheName("T")).withKeepBinary().get(key);
+
+ assertNotNull(val);
+
+ assertEquals(createValueForWrapTest("a", wrapVal), val);
+ }
+ finally {
+ execute("DROP TABLE IF EXISTS T");
+ }
+ }
+
+ /**
+ * @param key Key to wrap.
+ * @param wrap Whether key should be wrapped.
+ * @return (optionally wrapped) key.
+ */
+ private Object createKeyForWrapTest(int key, boolean wrap) {
+ if (!wrap)
+ return key;
+
+ return client().binary().builder("tkey").setField("id", key).build();
+ }
+
+ /**
+ * @param val Value to wrap.
+ * @param wrap Whether value should be wrapped.
+ * @return (optionally wrapped) value.
+ */
+ private Object createValueForWrapTest(String val, boolean wrap) {
+ if (!wrap)
+ return val;
+
+ return client().binary().builder("tval").setField("x", val).build();
+ }
+
+ /**
* Fill re-created table with data.
*/
private void fillRecreatedTable() {
@@ -1025,19 +1273,30 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
}
/**
- * Test that {@code DROP TABLE} on non-public schema causes an exception.
- *
- * @throws Exception if failed.
+ * Test that arbitrary command yields specific error.
+ * @param cmd Command.
+ * @param expErrMsg Expected error message.
*/
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
- public void testDropTableNotPublicSchema() throws Exception {
+ private void assertDdlCommandThrows(final String cmd, String expErrMsg) {
GridTestUtils.assertThrows(null, new Callable<Object>() {
@Override public Object call() throws Exception {
- execute("DROP TABLE \"cache_idx\".\"Person\"");
+ execute(cmd);
return null;
}
- }, IgniteSQLException.class, "DROP TABLE can only be executed on PUBLIC schema.");
+ }, IgniteSQLException.class, expErrMsg);
+ }
+
+ /**
+ * Test that {@code DROP TABLE} on non-public schema causes an exception.
+ *
+ * @throws Exception if failed.
+ */
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ public void testDropTableNotPublicSchema() throws Exception {
+ assertDdlCommandThrows("DROP TABLE \"cache_idx\".\"Person\"",
+ "DROP TABLE can only be executed on PUBLIC schema.");
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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
index b372eb3..8deb61f 100644
--- 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
@@ -86,7 +86,7 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
private static String CACHE_INTERCEPTOR = "cacheInterceptor";
/** Expected error message. */
- private static String ERR_MSG = "Null value is not allowed for field 'NAME'";
+ private static String ERR_MSG = "Null value is not allowed for column 'NAME'";
/** Expected error message for read-through restriction. */
private static String READ_THROUGH_ERR_MSG = "NOT NULL constraint is not supported when " +
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/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 1ee8a84..62860c0 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
@@ -251,20 +251,21 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
IgniteCache<Integer, BinaryObject> cacheB = ignite0.createCache(cacheBCfg());
- assertFalse(spi.queryLocalSql(spi.schema(typeAA.cacheName()), "select * from A.A", null, Collections.emptySet(),
- typeAA.name(), null, null).hasNext());
+ assertFalse(spi.queryLocalSql(spi.schema(typeAA.cacheName()), typeAA.cacheName(), "select * from A.A", null,
+ Collections.emptySet(), typeAA.name(), null, null).hasNext());
- assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), "select * from A.B", null, Collections.emptySet(),
- typeAB.name(), null, null).hasNext());
-
- assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select * from B.A", null, Collections.emptySet(),
- typeBA.name(), null, null).hasNext());
+ assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(), "select * from A.B", null,
+ Collections.emptySet(), typeAB.name(), null, null).hasNext());
- assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select * from B.A, A.B, A.A", null,
+ assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(), "select * from B.A", null,
Collections.emptySet(), typeBA.name(), null, null).hasNext());
+ assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(),
+ "select * from B.A, A.B, A.A", null, Collections.emptySet(), typeBA.name(), null, null).hasNext());
+
try {
- spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select aa.*, ab.*, ba.* from A.A aa, A.B ab, B.A ba",
+ spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(),
+ "select aa.*, ab.*, ba.* from A.A aa, A.B ab, B.A ba",
null, Collections.emptySet(), typeBA.name(), null, null).hasNext();
fail("Enumerations of aliases in select block must be prohibited");
@@ -273,11 +274,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
// all fine
}
- assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), "select ab.* from A.B ab", null,
- Collections.emptySet(), typeAB.name(), null, null).hasNext());
+ assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(), "select ab.* from A.B ab",
+ null, Collections.emptySet(), typeAB.name(), null, null).hasNext());
- assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select ba.* from B.A as ba", null,
- Collections.emptySet(), typeBA.name(), null, null).hasNext());
+ assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(),
+ "select ba.* from B.A as ba", null, Collections.emptySet(), typeBA.name(), null, null).hasNext());
cacheA.put(1, aa("A", 1, "Vasya", 10).build());
cacheA.put(1, ab(1, "Vasya", 20, "Some text about Vasya goes here.").build());
@@ -289,7 +290,7 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
// Query data.
Iterator<IgniteBiTuple<Integer, BinaryObjectImpl>> res = spi.queryLocalSql(spi.schema(typeAA.cacheName()),
- "from a order by age", null, Collections.emptySet(), typeAA.name(), null, null);
+ typeAA.cacheName(), "from a order by age", null, Collections.emptySet(), typeAA.name(), null, null);
assertTrue(res.hasNext());
assertEquals(aa("A", 3, "Borya", 18).build(), value(res.next()));
@@ -297,8 +298,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
assertEquals(aa("A", 2, "Valera", 19).build(), value(res.next()));
assertFalse(res.hasNext());
- res = spi.queryLocalSql(spi.schema(typeAA.cacheName()), "select aa.* from a aa order by aa.age", null,
- Collections.emptySet(), typeAA.name(), null, null);
+ res = spi.queryLocalSql(spi.schema(typeAA.cacheName()), typeAA.cacheName(),
+ "select aa.* from a aa order by aa.age", null, Collections.emptySet(), typeAA.name(), null, null);
assertTrue(res.hasNext());
assertEquals(aa("A", 3, "Borya", 18).build(), value(res.next()));
@@ -306,8 +307,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
assertEquals(aa("A", 2, "Valera", 19).build(), value(res.next()));
assertFalse(res.hasNext());
- res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), "from b order by name", null, Collections.emptySet(),
- typeAB.name(), null, null);
+ res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(), "from b order by name", null,
+ Collections.emptySet(), typeAB.name(), null, null);
assertTrue(res.hasNext());
assertEquals(ab(1, "Vasya", 20, "Some text about Vasya goes here.").build(), value(res.next()));
@@ -315,8 +316,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
assertEquals(ab(4, "Vitalya", 20, "Very Good guy").build(), value(res.next()));
assertFalse(res.hasNext());
- res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), "select bb.* from b as bb order by bb.name", null,
- Collections.emptySet(), typeAB.name(), null, null);
+ res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(),
+ "select bb.* from b as bb order by bb.name", null, Collections.emptySet(), typeAB.name(), null, null);
assertTrue(res.hasNext());
assertEquals(ab(1, "Vasya", 20, "Some text about Vasya goes here.").build(), value(res.next()));
@@ -324,8 +325,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
assertEquals(ab(4, "Vitalya", 20, "Very Good guy").build(), value(res.next()));
assertFalse(res.hasNext());
- res = spi.queryLocalSql(spi.schema(typeBA.cacheName()), "from a", null, Collections.emptySet(), typeBA.name(),
- null, null);
+ res = spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(), "from a", null,
+ Collections.emptySet(), typeBA.name(), null, null);
assertTrue(res.hasNext());
assertEquals(ba(2, "Kolya", 25, true).build(), value(res.next()));
@@ -333,7 +334,7 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
// Text queries
Iterator<IgniteBiTuple<Integer, BinaryObjectImpl>> txtRes = spi.queryLocalText(spi.schema(typeAB.cacheName()),
- "good", typeAB.name(), null);
+ typeAB.cacheName(), "good", typeAB.name(), null);
assertTrue(txtRes.hasNext());
assertEquals(ab(4, "Vitalya", 20, "Very Good guy").build(), value(txtRes.next()));
http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
index a6ddc8c..172cb90 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
@@ -122,7 +122,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery(
"insert into foo(_key, name) values (?, ?)", 1, "bar")).GetAll());
- Assert.AreEqual("Null value is not allowed for field 'ID'", ex.Message);
+ Assert.AreEqual("Null value is not allowed for column 'ID'", ex.Message);
}
/// <summary>
@@ -137,7 +137,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery(
"insert into foo(_key, id) values (?, ?)", 1, 2)).GetAll());
- Assert.AreEqual("Null value is not allowed for field 'NAME'", ex.Message);
+ Assert.AreEqual("Null value is not allowed for column 'NAME'", ex.Message);
}
/// <summary>