You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by tl...@apache.org on 2021/04/05 11:46:54 UTC
[ignite] branch master updated: IGNITE-14451 fix corrupt PK index
tree caused fields order (closes #8951)
This is an automated email from the ASF dual-hosted git repository.
tledkov 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 55e5717 IGNITE-14451 fix corrupt PK index tree caused fields order (closes #8951)
55e5717 is described below
commit 55e57173adc5fa2a891fb6a9d8d8fefdaab87ba9
Author: tledkov <tl...@gridgain.com>
AuthorDate: Mon Apr 5 14:46:37 2021 +0300
IGNITE-14451 fix corrupt PK index tree caused fields order (closes #8951)
---
.../internal/processors/query/QueryEntityEx.java | 26 ++++++++++-
.../internal/processors/query/QueryUtils.java | 2 +-
.../processors/query/h2/CommandProcessor.java | 17 ++++---
.../processors/query/h2/H2TableDescriptor.java | 4 +-
.../processors/cache/index/BasicIndexTest.java | 54 ++++++++++++++++++++++
5 files changed, 89 insertions(+), 14 deletions(-)
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 655cf52..dde4b4e 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
@@ -34,6 +34,9 @@ public class QueryEntityEx extends QueryEntity {
/** Fields that must have non-null value. */
private Set<String> notNullFields;
+ /** Whether to preserve order specified by {@link #getKeyFields()} or not. */
+ private boolean preserveKeysOrder;
+
/**
* Default constructor.
*/
@@ -53,6 +56,8 @@ public class QueryEntityEx extends QueryEntity {
QueryEntityEx other0 = (QueryEntityEx)other;
notNullFields = other0.notNullFields != null ? new HashSet<>(other0.notNullFields) : null;
+
+ preserveKeysOrder = other0.preserveKeysOrder;
}
}
@@ -68,6 +73,23 @@ public class QueryEntityEx extends QueryEntity {
return this;
}
+ /**
+ * @return {@code true} if order should be preserved, {@code false} otherwise.
+ */
+ public boolean isPreserveKeysOrder() {
+ return preserveKeysOrder;
+ }
+
+ /**
+ * @param preserveKeysOrder Whether the order should be preserved or not.
+ * @return {@code this} for chaining.
+ */
+ public QueryEntity setPreserveKeysOrder(boolean preserveKeysOrder) {
+ this.preserveKeysOrder = preserveKeysOrder;
+
+ return this;
+ }
+
/** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (this == o)
@@ -78,7 +100,8 @@ public class QueryEntityEx extends QueryEntity {
QueryEntityEx entity = (QueryEntityEx)o;
- return super.equals(entity) && F.eq(notNullFields, entity.notNullFields);
+ return super.equals(entity) && F.eq(notNullFields, entity.notNullFields)
+ && preserveKeysOrder == entity.preserveKeysOrder;
}
/** {@inheritDoc} */
@@ -86,6 +109,7 @@ public class QueryEntityEx extends QueryEntity {
int res = super.hashCode();
res = 31 * res + (notNullFields != null ? notNullFields.hashCode() : 0);
+ res = 31 * res + (preserveKeysOrder ? 1 : 0);
return res;
}
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 1577932..9b4449e 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
@@ -655,7 +655,7 @@ public class QueryUtils {
d.addProperty(prop, false);
}
- if (!isKeyClsSqlType)
+ if (!isKeyClsSqlType && qryEntity instanceof QueryEntityEx && ((QueryEntityEx)qryEntity).isPreserveKeysOrder())
d.primaryKeyFields(keyFields);
// Sql-typed key/value doesn't have field property, but they may have precision and scale constraints.
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 fb314e6..f81e7f6 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
@@ -32,6 +32,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteCluster;
import org.apache.ignite.IgniteDataStreamer;
@@ -1059,7 +1060,7 @@ public class CommandProcessor {
* @return Query entity mimicking this SQL statement.
*/
private static QueryEntity toQueryEntity(GridSqlCreateTable createTbl) {
- QueryEntity res = new QueryEntity();
+ QueryEntityEx res = new QueryEntityEx();
res.setTableName(createTbl.tableName());
@@ -1132,9 +1133,12 @@ public class CommandProcessor {
res.setKeyFieldName(pkCol.columnName());
}
- else
+ else {
res.setKeyFields(createTbl.primaryKeyColumns());
+ res.setPreserveKeysOrder(true);
+ }
+
if (!createTbl.wrapValue()) {
GridSqlColumn valCol = null;
@@ -1156,13 +1160,8 @@ public class CommandProcessor {
res.setValueType(valTypeName);
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/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java
index f592341..6e181ce 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java
@@ -331,9 +331,7 @@ public class H2TableDescriptor {
if (QueryUtils.isSqlType(type.keyClass()))
keyCols.add(keyCol);
else {
- // SPECIFIED_SEQ_PK_KEYS check guarantee that request running on heterogeneous (RU) cluster can
- // perform equally on all nodes.
- if (!idx.kernalContext().recoveryMode()) {
+ if (!type.primaryKeyFields().isEmpty()) {
for (String keyName : type.primaryKeyFields()) {
GridQueryProperty prop = type.property(keyName);
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/BasicIndexTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/BasicIndexTest.java
index 9eefbc1..8c0c67b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/BasicIndexTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/BasicIndexTest.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+
import javax.cache.CacheException;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
@@ -316,6 +317,59 @@ public class BasicIndexTest extends AbstractIndexingCommonTest {
}
/**
+ * Checks that fields in primary index have correct order after node restart.
+ *
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testCorrectPkFieldsSequenceAfterRestart() throws Exception {
+ inlineSize = 10;
+
+ IgniteEx ig0 = startGrid(getConfiguration("0").setDataStorageConfiguration(
+ new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+ new DataRegionConfiguration().setPersistenceEnabled(true)
+ )
+ ));
+
+ ig0.cluster().state(ClusterState.ACTIVE);
+
+ {
+ GridQueryProcessor qryProc = ig0.context().query();
+
+ IgniteH2Indexing idx = (IgniteH2Indexing)(ig0).context().query().getIndexing();
+
+ String tblName = "T1";
+
+ qryProc.querySqlFields(new SqlFieldsQuery("CREATE TABLE PUBLIC." + tblName + " (F1 VARCHAR, F2 VARCHAR, F3 VARCHAR, " +
+ "CONSTRAINT PK PRIMARY KEY (F2, F1))"), true).getAll();
+
+ List<String> expect = Arrays.asList("F2", "F1");
+
+ checkPkFldSequence(tblName, expect, idx);
+ }
+
+ stopAllGrids();
+
+ ig0 = startGrid(getConfiguration("0").setDataStorageConfiguration(
+ new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+ new DataRegionConfiguration().setPersistenceEnabled(true)
+ )
+ ));
+
+ ig0.cluster().state(ClusterState.ACTIVE);
+
+ {
+ IgniteH2Indexing idx = (IgniteH2Indexing)(ig0).context().query().getIndexing();
+
+ String tblName = "T1";
+
+ List<String> expect = Arrays.asList("F2", "F1");
+
+ checkPkFldSequence(tblName, expect, idx);
+ }
+ }
+
+ /**
* Fields correctness checker.
*
* @param tblName Table name.