This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new bc55dad9e35 IGNITE-25712 SQL: Fix key fields wrapping in index for
tables created with DDL on existing cache - Fixes #12452.
bc55dad9e35 is described below
commit bc55dad9e35e9b47bec8d09385cd0fa3d8581e4c
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Thu Apr 30 09:18:27 2026 +0300
IGNITE-25712 SQL: Fix key fields wrapping in index for tables created with
DDL on existing cache - Fixes #12452.
Signed-off-by: Aleksey Plekhanov <[email protected]>
---
.../query/calcite/exec/ddl/DdlCommandHandler.java | 16 +-
.../query/index/sorted/SortedSegmentedIndex.java | 6 +-
.../processors/query/GridQueryTypeDescriptor.java | 17 ++
.../internal/processors/query/QueryEntityEx.java | 20 +-
.../processors/query/QueryTypeDescriptorImpl.java | 13 +
.../internal/processors/query/QueryUtils.java | 1 +
.../query/schema/management/TableDescriptor.java | 2 +-
.../processors/query/h2/CommandProcessor.java | 1 +
.../index/ComplexPrimaryKeyUnwrapSelfTest.java | 263 ++++++++++++++++++---
9 files changed, 294 insertions(+), 45 deletions(-)
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
index e7c268d8918..ae0ee556f84 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
@@ -309,9 +309,10 @@ public class DdlCommandHandler {
/** */
private QueryEntity toQueryEntity(CreateTableCommand cmd) {
- QueryEntity res = new QueryEntity();
+ QueryEntityEx res = new QueryEntityEx();
res.setTableName(cmd.tableName());
+ res.sql(true);
Set<String> notNullFields = null;
@@ -369,7 +370,7 @@ public class DdlCommandHandler {
if (!F.isEmpty(cmd.primaryKeyColumns())) {
res.setKeyFields(new LinkedHashSet<>(cmd.primaryKeyColumns()));
- res = new QueryEntityEx(res).setPreserveKeysOrder(true);
+ res.setPreserveKeysOrder(true);
}
}
else if (!F.isEmpty(cmd.primaryKeyColumns()) &&
cmd.primaryKeyColumns().size() == 1) {
@@ -383,19 +384,14 @@ public class DdlCommandHandler {
// if pk is not explicitly set, we create it ourselves
keyTypeName = IgniteUuid.class.getName();
- res = new QueryEntityEx(res).implicitPk(true);
+ res.implicitPk(true);
}
res.setValueType(F.isEmpty(cmd.valueTypeName()) ? valTypeName :
cmd.valueTypeName());
res.setKeyType(keyTypeName);
- if (!F.isEmpty(notNullFields)) {
- QueryEntityEx res0 = new QueryEntityEx(res);
-
- res0.setNotNullFields(notNullFields);
-
- res = res0;
- }
+ if (!F.isEmpty(notNullFields))
+ res.setNotNullFields(notNullFields);
return res;
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/SortedSegmentedIndex.java
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/SortedSegmentedIndex.java
index 92738a48b8f..9d1e6f8e165 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/SortedSegmentedIndex.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/SortedSegmentedIndex.java
@@ -69,7 +69,7 @@ public interface SortedSegmentedIndex extends Index {
* Finds first index row for specified tree segment and cache filter.
*
* @param segment Number of tree segment to find.
- * @param qryCtx External index qyery context.
+ * @param qryCtx External index query context.
* @return Cursor of found index rows.
*/
public GridCursor<IndexRow> findFirst(int segment, IndexQueryContext
qryCtx)
@@ -79,7 +79,7 @@ public interface SortedSegmentedIndex extends Index {
* Finds last index row for specified tree segment and cache filter.
*
* @param segment Number of tree segment to find.
- * @param qryCtx External index qyery context.
+ * @param qryCtx External index query context.
* @return Cursor of found index rows.
*/
public GridCursor<IndexRow> findLast(int segment, IndexQueryContext qryCtx)
@@ -88,7 +88,7 @@ public interface SortedSegmentedIndex extends Index {
/**
* Takes only one first or last index record.
*
- * @param qryCtx External index qyery context.
+ * @param qryCtx External index query context.
* @param first {@code True} to take first index value. {@code False} to
take last index value.
*/
public GridCursor<IndexRow> findFirstOrLast(IndexQueryContext qryCtx,
boolean first) throws IgniteCheckedException;
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 02a62128489..06d4e4e938b 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
@@ -236,6 +236,23 @@ public interface GridQueryTypeDescriptor {
*/
public void implicitPk(boolean implicitPk);
+ /**
+ * Gets whether a type was created by SQL.
+ *
+ * NOTE: There is a difference between query type descriptor sql flag and
cache descriptor sql flag. The same flag
+ * on cache descriptor specifies whether entire cache was created by sql,
but query type descriptor sql flag can
+ * be set to true even when cache sql flag is false (for example, when
cache was created by cache API,
+ * but query type was added by SQL).
+ */
+ public boolean sql();
+
+ /**
+ * Sets whether a type was created by DDL.
+ *
+ * @param sql Whether a type was created by SQL.
+ */
+ public void sql(boolean sql);
+
/**
* @return {@code true} if absent PK parts should be filled with defaults,
{@code false} otherwise.
*/
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryEntityEx.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryEntityEx.java
index 54085294c63..3c615142cd0 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryEntityEx.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryEntityEx.java
@@ -50,6 +50,9 @@ public class QueryEntityEx extends QueryEntity {
/** INLINE_SIZE for affinity field index. */
private Integer affKeyInlineSize;
+ /** Whether query entity was created by SQL. */
+ private boolean sql;
+
/**
* Default constructor.
*/
@@ -77,6 +80,7 @@ public class QueryEntityEx extends QueryEntity {
fillAbsentPKsWithDefaults = other0.fillAbsentPKsWithDefaults;
pkInlineSize = other0.pkInlineSize != null ? other0.pkInlineSize :
-1;
affKeyInlineSize = other0.affKeyInlineSize != null ?
other0.affKeyInlineSize : -1;
+ sql = other0.sql;
}
}
@@ -121,6 +125,18 @@ public class QueryEntityEx extends QueryEntity {
return this;
}
+ /** */
+ public boolean sql() {
+ return sql;
+ }
+
+ /** */
+ public QueryEntityEx sql(boolean sql) {
+ this.sql = sql;
+
+ return this;
+ }
+
/**
* @return {@code true} if absent PK parts should be filled with defaults,
{@code false} otherwise.
*/
@@ -204,7 +220,8 @@ public class QueryEntityEx extends QueryEntity {
&& preserveKeysOrder == entity.preserveKeysOrder
&& implicitPk == entity.implicitPk
&& Objects.equals(pkInlineSize, entity.pkInlineSize)
- && Objects.equals(affKeyInlineSize, entity.affKeyInlineSize);
+ && Objects.equals(affKeyInlineSize, entity.affKeyInlineSize)
+ && sql == entity.sql;
}
/** {@inheritDoc} */
@@ -216,6 +233,7 @@ public class QueryEntityEx extends QueryEntity {
res = 31 * res + (implicitPk ? 1 : 0);
res = 31 * res + (pkInlineSize != null ? pkInlineSize.hashCode() : 0);
res = 31 * res + (affKeyInlineSize != null ?
affKeyInlineSize.hashCode() : 0);
+ res = 31 * res + (sql ? 1 : 0);
return res;
}
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 2ad7a194cc0..7b917e69a4d 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
@@ -162,6 +162,9 @@ public class QueryTypeDescriptorImpl implements
GridQueryTypeDescriptor {
/** @see SqlConfiguration#isValidationEnabled() */
private final boolean validateTypes;
+ /** */
+ private boolean sql;
+
/**
* Constructor.
*
@@ -834,6 +837,16 @@ public class QueryTypeDescriptorImpl implements
GridQueryTypeDescriptor {
this.implicitPk = implicitPk;
}
+ /** {@inheritDoc} */
+ @Override public boolean sql() {
+ return sql;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void sql(boolean sql) {
+ this.sql = sql;
+ }
+
/** {@inheritDoc} */
@Override public boolean fillAbsentPKsWithDefaults() {
return fillAbsentPKsWithDefaults;
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 e2f829b5187..782012cc9da 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
@@ -629,6 +629,7 @@ public class QueryUtils {
desc.primaryKeyInlineSize(qe.getPrimaryKeyInlineSize() != null ?
qe.getPrimaryKeyInlineSize() : -1);
desc.affinityFieldInlineSize(qe.getAffinityKeyInlineSize() != null
? qe.getAffinityKeyInlineSize() : -1);
+ desc.sql(qe.sql());
}
else {
desc.primaryKeyInlineSize(-1);
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/management/TableDescriptor.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/management/TableDescriptor.java
index 4c339e6c23f..938bc7b5836 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/management/TableDescriptor.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/management/TableDescriptor.java
@@ -57,7 +57,7 @@ public class TableDescriptor {
public TableDescriptor(GridCacheContextInfo<?, ?> cacheInfo,
GridQueryTypeDescriptor typeDesc, boolean isSql) {
this.cacheInfo = cacheInfo;
this.typeDesc = typeDesc;
- this.isSql = isSql;
+ this.isSql = isSql || typeDesc.sql();
if (F.isEmpty(typeDesc.affinityKey()) ||
Objects.equals(typeDesc.affinityKey(), typeDesc.keyFieldName()))
affKey = QueryUtils.KEY_FIELD_NAME;
diff --git
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/CommandProcessor.java
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/CommandProcessor.java
index d56a96fb02d..4f1091c8884 100644
---
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/CommandProcessor.java
+++
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/CommandProcessor.java
@@ -450,6 +450,7 @@ public class CommandProcessor extends SqlCommandProcessor {
QueryEntityEx res = new QueryEntityEx();
res.setTableName(createTbl.tableName());
+ res.sql(true);
Set<String> notNullFields = null;
diff --git
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrimaryKeyUnwrapSelfTest.java
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrimaryKeyUnwrapSelfTest.java
index 9d890fcc475..48c65fdc195 100644
---
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrimaryKeyUnwrapSelfTest.java
+++
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/ComplexPrimaryKeyUnwrapSelfTest.java
@@ -25,7 +25,9 @@ import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.CU;
import org.junit.Test;
/**
@@ -55,19 +57,104 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
*/
@Test
public void testComplexPk() {
+ checkComplexPk(false);
+ }
+
+ /**
+ * Test using PK indexes for complex primary key for DDL on existing cache.
+ */
+ @Test
+ public void testComplexPkExistingCache() {
+ checkComplexPk(true);
+ }
+
+ /** */
+ private void checkComplexPk(boolean existingCache) {
String tblName = createTableName();
+ if (existingCache)
+ node().createCache(tblName);
+
executeSql("CREATE TABLE " + tblName + " (id int, name varchar, age
int, company varchar, city varchar, " +
- "primary key (id, name, city))");
+ "primary key (id, name, city))" + (existingCache ? " WITH
\"CACHE_NAME=" + tblName + "\"" : ""));
checkUsingIndexes(tblName, "1", 2);
}
+ /**
+ * Test using PK indexes for complex primary key and affinity key.
+ */
+ @Test
+ public void testComplexPkWithAffinityKey() {
+ checkComplexPkWithAffinityKey(false);
+ }
+
+ /**
+ * Test using PK indexes for complex primary key and affinity key for DDL
on existing cache.
+ */
+ @Test
+ public void testComplexPkWithAffinityKeyExistingCache() {
+ checkComplexPkWithAffinityKey(true);
+ }
+
+ /** */
+ private void checkComplexPkWithAffinityKey(boolean existingCache) {
+ String tblName = createTableName();
+
+ if (existingCache)
+ node().createCache(tblName);
+
+ executeSql("CREATE TABLE " + tblName + " (id int, name varchar, age
int, company varchar, city varchar, " +
+ "primary key (id, name, city)) " +
+ "WITH \"affinity_key=id" +
+ (existingCache ? ",CACHE_NAME=" + tblName : "") + "\"");
+
+ // For the new cache unwrapped key field is used as affinity key, but
for the existing cache
+ // affinity key can't be changed, so we can't prune partitions for
query on ID field.
+ checkUsingIndexes(tblName, "1", existingCache ? 2 : 1);
+ }
+
+ /**
+ * Test using PK indexes for complex primary key for DDL on existing cache
on multiple nodes.
+ */
+ @Test
+ public void testComplexPkExistingCacheMultiNode() throws Exception {
+ String tblName = createTableName();
+
+ try (IgniteEx ignite1 = startGrid(1)) {
+ node().createCache(tblName);
+
+ executeSql("CREATE TABLE " + tblName + " (id int, name varchar,
age int, company varchar, city varchar, " +
+ "primary key (id, name, city)) WITH \"CACHE_NAME=" + tblName +
"\"");
+
+ // Check on remote node, started before table created.
+ checkUsingIndexes(ignite1, tblName, "1", 2);
+
+ try (IgniteEx ignite2 = startGrid(2)) {
+ // Check on remote node, started after table created.
+ checkUsingIndexes(ignite2, tblName, "1", 2);
+ }
+ }
+ }
+
/**
* Test using PK indexes for simple primary key.
*/
@Test
public void testSimplePk() {
+ checkSimplePk(false);
+ }
+
+ /**
+ * Test using PK indexes for simple primary key for DDL on existing cache.
+ */
+ @Test
+ public void testSimplePkExistingCache() {
+ checkSimplePk(true);
+ }
+
+ /** */
+ private void checkSimplePk(boolean existingCache) {
//ToDo: IGNITE-8386: need to add DATE type into the test.
HashMap<String, String> types = new HashMap() {
{
@@ -85,21 +172,23 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
put("bigint", "1");
put("varchar_ignorecase", "'1'");
put("time", "'11:11:11'");
- put("timestamp", "'20018-11-02 11:11:11'");
+ put("timestamp", "'2018-11-02 11:11:11'");
put("uuid", "'1'");
}
};
for (Map.Entry<String, String> entry : types.entrySet()) {
-
String tblName = createTableName();
+ if (existingCache)
+ node().createCache(tblName);
+
String type = entry.getKey();
String val = entry.getValue();
executeSql("CREATE TABLE " + tblName +
" (id " + type + " , name varchar, age int, company varchar,
city varchar," +
- " primary key (id))");
+ " primary key (id))" + (existingCache ? " WITH \"CACHE_NAME="
+ tblName + "\"" : ""));
checkUsingIndexes(tblName, val, 1);
}
@@ -110,6 +199,19 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
*/
@Test
public void testSimplePkWithAffinityKey() {
+ checkSimplePkWithAffinityKey(false);
+ }
+
+ /**
+ * Test using PK indexes for simple primary key and affinity key on
existing cache.
+ */
+ @Test
+ public void testSimplePkWithAffinityKeyExistingCache() {
+ checkSimplePkWithAffinityKey(true);
+ }
+
+ /** */
+ private void checkSimplePkWithAffinityKey(boolean existingCache) {
//ToDo: IGNITE-8386: need to add DATE type into the test.
HashMap<String, String> types = new HashMap() {
{
@@ -127,21 +229,24 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
put("bigint", "1");
put("varchar_ignorecase", "'1'");
put("time", "'11:11:11'");
- put("timestamp", "'20018-11-02 11:11:11'");
+ put("timestamp", "'2018-11-02 11:11:11'");
put("uuid", "'1'");
}
};
for (Map.Entry<String, String> entry : types.entrySet()) {
-
String tblName = createTableName();
String type = entry.getKey();
String val = entry.getValue();
+ if (existingCache)
+ node().createCache(tblName);
+
executeSql("CREATE TABLE " + tblName +
" (id " + type + " , name varchar, age int, company varchar,
city varchar," +
- " primary key (id)) WITH \"affinity_key=id\"");
+ " primary key (id)) WITH \"affinity_key=id" +
+ (existingCache ? ",CACHE_NAME=" + tblName : "") + "\"");
checkUsingIndexes(tblName, val, 1);
}
@@ -152,12 +257,31 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
*/
@Test
public void testWrappedPk() {
+ checkWrappedPk(false);
+ }
+
+ /**
+ * Test using PK indexes for wrapped primary key on existsing cache.
+ */
+ @Test
+ public void testWrappedPkExistingCache() {
+ checkWrappedPk(true);
+ }
+
+ /** */
+ private void checkWrappedPk(boolean existingCache) {
String tblName = createTableName();
+ if (existingCache)
+ node().createCache(tblName);
+
executeSql("CREATE TABLE " + tblName + " (id int, name varchar, age
int, company varchar, city varchar, " +
- "primary key (id)) WITH \"wrap_key=true\"");
+ "primary key (id)) WITH \"wrap_key=true" +
+ (existingCache ? ",CACHE_NAME=" + tblName : "") + "\"");
- checkUsingIndexes(tblName, "1", 1);
+ // For the new cache unwrapped key field is used as affinity key, but
for the existing cache
+ // affinity key can't be changed, so we can't prune partitions for
query on ID field.
+ checkUsingIndexes(tblName, "1", existingCache ? 2 : 1);
}
/**
@@ -165,13 +289,31 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
*/
@Test
public void testInlineSizeNoWrap() {
- executeSql("DROP TABLE IF EXISTS TABLE1");
- executeSql("CREATE TABLE IF NOT EXISTS TABLE1 ( " +
+ checkInlineSizeNoWrap(false);
+ }
+
+ /**
+ * Test single column PK without wrapping calculate correct inline size on
existing cache.
+ */
+ @Test
+ public void testInlineSizeNoWrapExistingCache() {
+ checkInlineSizeNoWrap(true);
+ }
+
+ /** */
+ private void checkInlineSizeNoWrap(boolean existingCache) {
+ String tblName = createTableName();
+
+ if (existingCache)
+ node().createCache(tblName);
+
+ executeSql("CREATE TABLE IF NOT EXISTS " + tblName + "( " +
" id varchar(15), " +
" col varchar(100), " +
- " PRIMARY KEY(id) ) ");
- assertEquals(18, executeSql(
- "select INLINE_SIZE from SYS.INDEXES where TABLE_NAME = 'TABLE1'
and IS_PK = true").get(0).get(0));
+ " PRIMARY KEY(id) ) " +
+ (existingCache ? "WITH \"CACHE_NAME=" + tblName + "\"" : "")
+ );
+ assertEquals(18, pkInlineSize(tblName));
}
/**
@@ -179,13 +321,30 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
*/
@Test
public void testInlineSizeWrap() {
- executeSql("DROP TABLE IF EXISTS TABLE1");
- executeSql("CREATE TABLE IF NOT EXISTS TABLE1 ( " +
+ checkInlineSizeWrap(false);
+ }
+
+ /**
+ * Test single column PK with wrapping calculate correct inline size on
existing cache.
+ */
+ @Test
+ public void testInlineSizeWrapExistingCache() {
+ checkInlineSizeWrap(true);
+ }
+
+ /** */
+ private void checkInlineSizeWrap(boolean existingCache) {
+ String tblName = createTableName();
+
+ if (existingCache)
+ node().createCache(tblName);
+
+ executeSql("CREATE TABLE IF NOT EXISTS " + tblName + "( " +
" id varchar(15), " +
" col varchar(100), " +
- " PRIMARY KEY(id) ) WITH \"wrap_key=true\"");
- assertEquals(18, executeSql(
- "select INLINE_SIZE from SYS.INDEXES where TABLE_NAME = 'TABLE1'
and IS_PK = true").get(0).get(0));
+ " PRIMARY KEY(id) ) " +
+ " WITH \"wrap_key=true" + (existingCache ? ",CACHE_NAME=" +
tblName : "") + "\"");
+ assertEquals(18, pkInlineSize(tblName));
}
/**
@@ -193,34 +352,78 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
*/
@Test
public void testInlineSizeWrap2() {
- executeSql("DROP TABLE IF EXISTS TABLE1");
- executeSql("CREATE TABLE IF NOT EXISTS TABLE1 ( " +
+ checkInlineSizeWrap2(false);
+ }
+
+ /**
+ * Test two column PK with wrapping calculate correct inline size on
existing cache.
+ */
+ @Test
+ public void testInlineSizeWrap2ExistingCache() {
+ checkInlineSizeWrap2(true);
+ }
+
+ /** */
+ private void checkInlineSizeWrap2(boolean existingCache) {
+ String tblName = createTableName();
+
+ if (existingCache)
+ node().createCache(tblName);
+
+ executeSql("CREATE TABLE IF NOT EXISTS " + tblName + "( " +
" id varchar(15), " +
" id2 uuid, " +
" col varchar(100), " +
- " PRIMARY KEY(id, id2) ) WITH \"wrap_key=true\"");
- assertEquals(35, executeSql(
- "select INLINE_SIZE from SYS.INDEXES where TABLE_NAME = 'TABLE1'
and IS_PK = true").get(0).get(0));
+ " PRIMARY KEY(id, id2) ) " +
+ " WITH \"wrap_key=true" + (existingCache ? ",CACHE_NAME=" +
tblName : "") + "\"");
+ assertEquals(35, pkInlineSize(tblName));
+ }
+
+ /** */
+ private int pkInlineSize(String tblName) {
+ return (int)executeSql("select INLINE_SIZE from SYS.INDEXES " +
+ "where TABLE_NAME = '" + tblName + "' and IS_PK =
true").get(0).get(0);
}
/**
* Check using PK indexes for few cases.
*
* @param tblName Name of table which should be checked to using PK
indexes.
- * @param expResCnt Expceted result count.
+ * @param expResCnt Expected result count.
*/
private void checkUsingIndexes(String tblName, String idVal, int
expResCnt) {
+ checkUsingIndexes(node(), tblName, idVal, expResCnt);
+ }
+
+ /**
+ * Check using PK indexes for few cases.
+ *
+ * @param node Ignite node.
+ * @param tblName Name of table which should be checked to using PK
indexes.
+ * @param expResCnt Expected result count.
+ */
+ private void checkUsingIndexes(IgniteEx node, String tblName, String
idVal, int expResCnt) {
+ IgniteInternalFuture<?> rebuildFut = indexRebuildFuture(node,
CU.cacheId(tblName));
+
+ try {
+ if (rebuildFut != null)
+ rebuildFut.get(5_000L);
+ }
+ catch (Exception e) {
+ throw new AssertionError(e);
+ }
+
String explainSQL = "explain SELECT * FROM " + tblName + " WHERE ";
- List<List<?>> results = executeSql(explainSQL + "id=" + idVal);
+ List<List<?>> results = executeSql(node, explainSQL + "id=" + idVal);
assertUsingPkIndex(results, expResCnt);
- results = executeSql(explainSQL + "id=" + idVal + " and name=''");
+ results = executeSql(node, explainSQL + "id=" + idVal + " and
name=''");
assertUsingPkIndex(results, expResCnt);
- results = executeSql(explainSQL + "id=" + idVal + " and name='' and
city='' and age=0");
+ results = executeSql(node, explainSQL + "id=" + idVal + " and name=''
and city='' and age=0");
assertUsingPkIndex(results, expResCnt);
}
@@ -252,14 +455,14 @@ public class ComplexPrimaryKeyUnwrapSelfTest extends
AbstractIndexingCommonTest
* Check that explain plan result shown using PK index and don't use scan.
*
* @param results Result of execut explain plan query.
- * @param expResCnt Expceted result count.
+ * @param expResCnt Expected result count.
*/
private void assertUsingPkIndex(List<List<?>> results, int expResCnt) {
assertEquals(expResCnt, results.size());
String explainPlan = (String)results.get(0).get(0);
- assertTrue(explainPlan.contains("\"_key_PK"));
+ assertTrue("Current plan=[" + explainPlan + ']',
explainPlan.contains("\"_key_PK"));
assertFalse(explainPlan.contains("_SCAN_"));
}