You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2023/08/25 07:56:06 UTC
[ignite-3] branch main updated: IGNITE-20015 Sql. Introduce new distribution function for system views (#2455)
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new bc17dfd795 IGNITE-20015 Sql. Introduce new distribution function for system views (#2455)
bc17dfd795 is described below
commit bc17dfd7955dd5565c0ca26d1a0bbf64bb0bc455
Author: Andrew V. Mashenkov <AM...@users.noreply.github.com>
AuthorDate: Fri Aug 25 10:56:00 2023 +0300
IGNITE-20015 Sql. Introduce new distribution function for system views (#2455)
---
modules/runner/build.gradle | 1 +
modules/sql-engine/build.gradle | 2 +
.../sql/engine/exec/DestinationFactory.java | 12 +-
.../sql/engine/exec/LogicalRelImplementor.java | 2 +-
.../internal/sql/engine/externalize/RelJson.java | 5 +
.../internal/sql/engine/trait/Destination.java | 3 +-
.../sql/engine/trait/DistributionFunction.java | 24 ++
.../ignite/internal/sql/engine/trait/Identity.java | 62 +++
.../sql/engine/trait/IgniteDistributions.java | 10 +
.../exec/IdentityDistributionFunctionSelfTest.java | 136 +++++++
.../planner/AbstractAggregatePlannerTest.java | 419 ++++++++++++++++++++-
.../sql/engine/planner/AggregatePlannerTest.java | 307 ++++++++++++---
.../planner/ColocatedHashAggregatePlannerTest.java | 218 ++++++++++-
.../planner/ColocatedSortAggregatePlannerTest.java | 216 +++++++++--
.../sql/engine/planner/DmlPlannerTest.java | 6 +-
.../planner/IdentityDistributionPlannerTest.java | 200 ++++++++++
.../planner/MapReduceHashAggregatePlannerTest.java | 138 ++++++-
.../planner/MapReduceSortAggregatePlannerTest.java | 205 +++++++---
.../sql/engine/planner/SetOpPlannerTest.java | 192 +++++++++-
.../internal/sql/engine/util/CursorUtils.java | 0
.../internal/sql/engine/util/MetadataMatcher.java | 0
.../sql/engine/util/NativeTypeWrapper.java | 0
.../internal/sql/engine/util/QueryChecker.java | 0
23 files changed, 1984 insertions(+), 174 deletions(-)
diff --git a/modules/runner/build.gradle b/modules/runner/build.gradle
index 1d11625efe..35795f4331 100644
--- a/modules/runner/build.gradle
+++ b/modules/runner/build.gradle
@@ -185,6 +185,7 @@ dependencies {
testFixturesImplementation project(':ignite-schema')
testFixturesImplementation testFixtures(project(':ignite-api'))
testFixturesImplementation testFixtures(project(':ignite-core'))
+ testFixturesImplementation testFixtures(project(':ignite-sql-engine'))
testFixturesImplementation testFixtures(project(':ignite-network'))
testFixturesImplementation libs.jetbrains.annotations
testFixturesImplementation libs.hamcrest.core
diff --git a/modules/sql-engine/build.gradle b/modules/sql-engine/build.gradle
index c7e33c78cf..0cffa3c8a4 100644
--- a/modules/sql-engine/build.gradle
+++ b/modules/sql-engine/build.gradle
@@ -92,5 +92,7 @@ dependencies {
testFixturesImplementation project(':ignite-core')
testFixturesImplementation project(':ignite-api')
testFixturesImplementation project(':ignite-schema')
+ testFixturesImplementation testFixtures(project(':ignite-core'))
testFixturesImplementation libs.jetbrains.annotations
+ testFixturesImplementation libs.hamcrest.core
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/DestinationFactory.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/DestinationFactory.java
index ff350add2a..d34dc34b5d 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/DestinationFactory.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/DestinationFactory.java
@@ -31,6 +31,7 @@ import org.apache.ignite.internal.sql.engine.trait.AllNodes;
import org.apache.ignite.internal.sql.engine.trait.Destination;
import org.apache.ignite.internal.sql.engine.trait.DistributionFunction;
import org.apache.ignite.internal.sql.engine.trait.DistributionFunction.AffinityDistribution;
+import org.apache.ignite.internal.sql.engine.trait.Identity;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
import org.apache.ignite.internal.sql.engine.trait.Partitioned;
import org.apache.ignite.internal.sql.engine.trait.RandomNode;
@@ -43,16 +44,19 @@ import org.apache.ignite.internal.util.IgniteUtils;
* physical representation - {@link Destination} function.
*/
class DestinationFactory<RowT> {
+ private final RowHandler<RowT> rowHandler;
private final HashFunctionFactory<RowT> hashFunctionFactory;
private final ResolvedDependencies dependencies;
/**
* Constructor.
*
+ * @param rowHandler Row handler.
* @param hashFunctionFactory Hash-function factory required to resolve hash-based distributions.
* @param dependencies Dependencies required to resolve row value dependent distributions.
*/
- DestinationFactory(HashFunctionFactory<RowT> hashFunctionFactory, ResolvedDependencies dependencies) {
+ DestinationFactory(RowHandler<RowT> rowHandler, HashFunctionFactory<RowT> hashFunctionFactory, ResolvedDependencies dependencies) {
+ this.rowHandler = rowHandler;
this.hashFunctionFactory = hashFunctionFactory;
this.dependencies = dependencies;
}
@@ -83,6 +87,12 @@ class DestinationFactory<RowT> {
case HASH_DISTRIBUTED: {
ImmutableIntList keys = distribution.getKeys();
+ if ("identity".equals(function.name())) {
+ assert !nullOrEmpty(group.nodeNames()) && !nullOrEmpty(keys) && keys.size() == 1;
+
+ return new Identity<>(rowHandler, keys.get(0), group.nodeNames());
+ }
+
assert !nullOrEmpty(group.assignments()) && !nullOrEmpty(keys);
List<List<String>> assignments = Commons.transform(group.assignments(), v -> Commons.transform(v, NodeWithTerm::name));
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java
index 9856df07f2..d894685874 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/LogicalRelImplementor.java
@@ -158,7 +158,7 @@ public class LogicalRelImplementor<RowT> implements IgniteRelVisitor<Node<RowT>>
this.resolvedDependencies = resolvedDependencies;
expressionFactory = ctx.expressionFactory();
- destinationFactory = new DestinationFactory<>(hashFuncFactory, resolvedDependencies);
+ destinationFactory = new DestinationFactory<>(ctx.rowHandler(), hashFuncFactory, resolvedDependencies);
}
/** {@inheritDoc} */
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java
index f66116c2d2..e9353b4b10 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/externalize/RelJson.java
@@ -676,6 +676,11 @@ class RelJson {
List<Integer> keys = (List<Integer>) map.get("keys");
switch (functionName) {
+ case "identity": {
+ assert keys.size() == 1;
+
+ return IgniteDistributions.identity(keys.get(0));
+ }
case "hash":
return IgniteDistributions.hash(keys, DistributionFunction.hash());
default: {
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/Destination.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/Destination.java
index 03f6c7323e..8a1d209d86 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/Destination.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/Destination.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.sql.engine.trait;
+import java.util.Collection;
import java.util.List;
/**
@@ -34,5 +35,5 @@ public interface Destination<RowT> {
/**
* Get all target nodes.
*/
- List<String> targets();
+ Collection<String> targets();
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/DistributionFunction.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/DistributionFunction.java
index 598bc880e0..340c304b9c 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/DistributionFunction.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/DistributionFunction.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.sql.engine.trait;
import java.util.Objects;
import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.rel.RelDistribution.Type;
import org.apache.calcite.rel.RelNode;
/**
@@ -104,6 +105,10 @@ public abstract class DistributionFunction {
return HashDistribution.INSTANCE;
}
+ public static DistributionFunction identity() {
+ return IdentityDistribution.INSTANCE;
+ }
+
/**
* Satisfy.
* TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
@@ -211,4 +216,23 @@ public abstract class DistributionFunction {
return "affinity[tableId=" + tableId + ", zoneId=" + zoneId + ']';
}
}
+
+ /**
+ * Distribution function, which treats column's raw value as a destination.
+ */
+ public static final class IdentityDistribution extends DistributionFunction {
+ public static final DistributionFunction INSTANCE = new IdentityDistribution();
+
+ /** {@inheritDoc} */
+ @Override
+ public Type type() {
+ return Type.HASH_DISTRIBUTED;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected String name0() {
+ return "identity";
+ }
+ }
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/Identity.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/Identity.java
new file mode 100644
index 0000000000..3558580c8d
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/Identity.java
@@ -0,0 +1,62 @@
+/*
+ * 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.sql.engine.trait;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.ignite.internal.sql.engine.exec.RowHandler;
+
+/**
+ * Destination, which uses a column raw value as a target.
+ */
+public class Identity<RowT> implements Destination<RowT> {
+ private final RowHandler<RowT> rowHandler;
+ private final Set<String> nodes;
+ private final int columnIndex;
+
+ /**
+ * Constructor.
+ *
+ * @param rowHandler Row handler.
+ * @param columnIndex Column index in a row, which used for affinity calculation.
+ * @param nodes Names of nodes, which are valid destinations.
+ */
+ public Identity(RowHandler<RowT> rowHandler, int columnIndex, List<String> nodes) {
+ this.rowHandler = rowHandler;
+ this.columnIndex = columnIndex;
+ this.nodes = Set.copyOf(nodes);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<String> targets(RowT row) {
+ Object node = rowHandler.get(columnIndex, row);
+
+ if (node instanceof String && nodes.contains(node)) {
+ return List.of((String) node);
+ }
+
+ throw new IllegalStateException("No target found.");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Set<String> targets() {
+ return nodes;
+ }
+}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/IgniteDistributions.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/IgniteDistributions.java
index 9f5a0c0057..599a291e56 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/IgniteDistributions.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/trait/IgniteDistributions.java
@@ -109,6 +109,16 @@ public class IgniteDistributions {
return canonize(new DistributionTrait(keys, function));
}
+ /**
+ * Creates an identity distribution that calculates destinations based on a raw value of the row field.
+ *
+ * @param key Distribution key ordinal.
+ * @return Identity distribution.
+ */
+ public static IgniteDistribution identity(int key) {
+ return canonize(new DistributionTrait(List.of(key), DistributionFunction.identity()));
+ }
+
/**
* See {@link RelTraitDef#canonize(org.apache.calcite.plan.RelTrait)}.
*/
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/IdentityDistributionFunctionSelfTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/IdentityDistributionFunctionSelfTest.java
new file mode 100644
index 0000000000..2b46f736b7
--- /dev/null
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/IdentityDistributionFunctionSelfTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.sql.engine.exec;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.calcite.rel.RelDistribution.Type;
+import org.apache.ignite.internal.schema.NativeTypes;
+import org.apache.ignite.internal.sql.engine.exec.row.RowSchema;
+import org.apache.ignite.internal.sql.engine.metadata.ColocationGroup;
+import org.apache.ignite.internal.sql.engine.trait.Destination;
+import org.apache.ignite.internal.sql.engine.trait.DistributionFunction.IdentityDistribution;
+import org.apache.ignite.internal.sql.engine.trait.Identity;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Identity distribution function self test.
+ */
+public class IdentityDistributionFunctionSelfTest {
+
+ private static final String NODE_1 = "node1";
+ private static final String NODE_2 = "node2";
+ private static final String NODE_3 = "node3";
+
+ private final RowHandler<Object[]> rowHandler = ArrayRowHandler.INSTANCE;
+
+ private final RowSchema rowSchema = RowSchema.builder()
+ .addField(NativeTypes.STRING)
+ .addField(NativeTypes.STRING)
+ .build();
+
+ private final ColocationGroup colocationGroup = ColocationGroup.forNodes(List.of(NODE_1, NODE_2, NODE_3));
+ private final DestinationFactory<Object[]> destinationFactory = new DestinationFactory<>(rowHandler, null, null);
+
+ @Test
+ public void identityDistributionTrait() {
+ IdentityDistribution function = new IdentityDistribution();
+
+ assertThat(function.type(), equalTo(Type.HASH_DISTRIBUTED));
+ assertThat(function.affinity(), is(false));
+ assertThat(function.name(), equalTo("identity"));
+ }
+
+ @Test
+ public void destinationTargets() {
+ Destination<Object[]> destination = destinationFactory.createDestination(IgniteDistributions.identity(0), colocationGroup);
+
+ assertThat(destination, instanceOf(Identity.class));
+
+ Collection<String> targets = destination.targets();
+
+ assertThat(targets.size(), equalTo(3));
+ assertThat(targets, containsInAnyOrder(NODE_1, NODE_2, NODE_3));
+ }
+
+ @Test
+ public void destinationRowTargets() {
+ Object[] row = rowHandler.factory(rowSchema).create(NODE_1, "Ne prikhodya v soznanie");
+
+ Destination<Object[]> destination0 = destinationFactory.createDestination(IgniteDistributions.identity(0), colocationGroup);
+ Destination<Object[]> destination1 = destinationFactory.createDestination(IgniteDistributions.identity(1), colocationGroup);
+
+ assertThat(destination0, instanceOf(Identity.class));
+
+ // Valid row has single target.
+ Collection<String> targets = destination0.targets(row);
+
+ assertThat(targets.size(), equalTo(1));
+ assertThat(targets, Matchers.contains(NODE_1));
+
+ // Validate column mapping
+ Object[] otherRow = rowHandler.factory(rowSchema).create("UNKNOWN", NODE_2);
+ targets = destination1.targets(otherRow);
+
+ assertThat(targets.size(), equalTo(1));
+ assertThat(targets, Matchers.contains(NODE_2));
+
+ // Check wrong mapping.
+ Assertions.assertThrows(IllegalStateException.class, () -> destination0.targets(otherRow));
+ }
+
+ @Test
+ public void destinationForInvalidRow() {
+ Destination<Object[]> destination = destinationFactory.createDestination(IgniteDistributions.identity(0), colocationGroup);
+
+ Object[] invalidRow1 = rowHandler.factory(rowSchema).create("UNKNOWN", NODE_2);
+ Assertions.assertThrows(IllegalStateException.class, () -> destination.targets(invalidRow1));
+
+ Object[] invalidRow2 = rowHandler.factory(rowSchema).create("", NODE_2);
+ Assertions.assertThrows(IllegalStateException.class, () -> destination.targets(invalidRow2));
+
+ Object[] invalidRow3 = rowHandler.factory(rowSchema).create(null, NODE_2);
+ Assertions.assertThrows(IllegalStateException.class, () -> destination.targets(invalidRow3));
+ }
+}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractAggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractAggregatePlannerTest.java
index 6272403614..f268ac7e49 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractAggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractAggregatePlannerTest.java
@@ -21,6 +21,7 @@ import static org.apache.ignite.internal.sql.engine.trait.IgniteDistributions.si
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
+import it.unimi.dsi.fastutil.ints.IntList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
@@ -37,6 +38,7 @@ import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceAggregateBase;
import org.apache.ignite.internal.sql.engine.schema.IgniteIndex.Collation;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
@@ -85,6 +87,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution: hash(0)
*/
CASE_1A("SELECT SUM(val0) FROM test", schema(hash())),
+ /**
+ * Query: SELECT SUM(val0) FROM test.
+ *
+ * <p>Distribution: identity(0)
+ */
+ CASE_1B("SELECT SUM(val0) FROM test", schema(identity())),
/**
* Query: SELECT SUM(DISTINCT val0) FROM test.
*
@@ -97,6 +105,24 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution: hash(0)
*/
CASE_2_1A("SELECT SUM(DISTINCT val0) FROM test", schema(hash())),
+ /**
+ * Query: SELECT SUM(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: identity(0)
+ */
+ CASE_2_1B("SELECT SUM(DISTINCT val0) FROM test", schema(identity())),
+ /**
+ * Query: SELECT SUM(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: hash(1)
+ */
+ CASE_2_1C("SELECT SUM(DISTINCT val0) FROM test", schema(hash(1))),
+ /**
+ * Query: SELECT SUM(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: identity(1)
+ */
+ CASE_2_1D("SELECT SUM(DISTINCT val0) FROM test", schema(identity(1))),
/**
* Query: SELECT COUNT(DISTINCT val0) FROM test.
*
@@ -110,17 +136,23 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
*/
CASE_2_2A("SELECT COUNT(DISTINCT val0) FROM test", schema(hash())),
/**
- * Query: SELECT SUM(DISTINCT val0) FROM test.
+ * Query: SELECT COUNT(DISTINCT val0) FROM test.
*
- * <p>Distribution: single
+ * <p>Distribution: identity(0)
*/
- CASE_2_3("SELECT SUM(DISTINCT val0) FROM test", schema(single())),
+ CASE_2_2B("SELECT COUNT(DISTINCT val0) FROM test", schema(identity())),
/**
- * Query: SELECT SUM(DISTINCT val0) FROM test.
+ * Query: SELECT COUNT(DISTINCT val0) FROM test.
*
- * <p>Distribution: hash(0)
+ * <p>Distribution: hash(1)
*/
- CASE_2_3A("SELECT SUM(DISTINCT val0) FROM test", schema(hash())),
+ CASE_2_2C("SELECT COUNT(DISTINCT val0) FROM test", schema(hash(1))),
+ /**
+ * Query: SELECT COUNT(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: identity(1)
+ */
+ CASE_2_2D("SELECT COUNT(DISTINCT val0) FROM test", schema(identity(1))),
/**
* Query: SELECT MIN(DISTINCT val0) FROM test.
*
@@ -133,6 +165,24 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution: hash(0)
*/
CASE_3_1A("SELECT MIN(DISTINCT val0) FROM test", schema(hash())),
+ /**
+ * Query: SELECT MIN(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: identity(0)
+ */
+ CASE_3_1B("SELECT MIN(DISTINCT val0) FROM test", schema(identity())),
+ /**
+ * Query: SELECT MIN(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: hash(1)
+ */
+ CASE_3_1C("SELECT MIN(DISTINCT val0) FROM test", schema(hash(1))),
+ /**
+ * Query: SELECT MIN(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: identity(1)
+ */
+ CASE_3_1D("SELECT MIN(DISTINCT val0) FROM test", schema(identity(1))),
/**
* Query: SELECT MAX(DISTINCT val0) FROM test.
*
@@ -145,6 +195,24 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution: hash(0)
*/
CASE_3_2A("SELECT MAX(DISTINCT val0) FROM test", schema(hash())),
+ /**
+ * Query: SELECT MAX(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: identity(0)
+ */
+ CASE_3_2B("SELECT MAX(DISTINCT val0) FROM test", schema(identity())),
+ /**
+ * Query: SELECT MAX(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: hash(1)
+ */
+ CASE_3_2C("SELECT MAX(DISTINCT val0) FROM test", schema(hash(1))),
+ /**
+ * Query: SELECT MAX(DISTINCT val0) FROM test.
+ *
+ * <p>Distribution: identity(1)
+ */
+ CASE_3_2D("SELECT MAX(DISTINCT val0) FROM test", schema(identity(1))),
/**
* Query: SELECT SUM(val0) FROM test GROUP BY grp0.
*
@@ -154,9 +222,27 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
/**
* Query: SELECT SUM(val0) FROM test GROUP BY grp0.
*
- * <p>Distribution hash
+ * <p>Distribution hash(0)
*/
CASE_5A("SELECT SUM(val0) FROM test GROUP BY grp0", schema(hash())),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_5B("SELECT SUM(val0) FROM test GROUP BY grp0", schema(identity())),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(3)
+ */
+ CASE_5C("SELECT SUM(val0) FROM test GROUP BY grp0", schema(hash(3))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(3)
+ */
+ CASE_5D("SELECT SUM(val0) FROM test GROUP BY grp0", schema(identity(3))),
/**
* Query: SELECT SUM(val0) FROM test GROUP BY grp1, grp0.
*
@@ -169,6 +255,18 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_6A("SELECT SUM(val0) FROM test GROUP BY grp1, grp0", schema(hash())),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp1, grp0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_6B("SELECT SUM(val0) FROM test GROUP BY grp1, grp0", schema(identity())),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp1, grp0.
+ *
+ * <p>Distribution hash(3, 4)
+ */
+ CASE_6C("SELECT SUM(val0) FROM test GROUP BY grp1, grp0", schema(hash(3, 4))),
/**
* Query: SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0.
*
@@ -181,6 +279,24 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_7_1A("SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0", schema(hash())),
+ /**
+ * Query: SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_7_1B("SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0", schema(identity())),
+ /**
+ * Query: SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0.
+ *
+ * <p>Distribution hash(3)
+ */
+ CASE_7_1C("SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0", schema(hash(3))),
+ /**
+ * Query: SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(3)
+ */
+ CASE_7_1D("SELECT COUNT(DISTINCT val0) FROM test GROUP BY grp0", schema(identity(3))),
/**
* Query: SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0.
*
@@ -193,6 +309,24 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_7_2A("SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0", schema(hash())),
+ /**
+ * Query: SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_7_2B("SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0", schema(identity())),
+ /**
+ * Query: SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0.
+ *
+ * <p>Distribution hash(3)
+ */
+ CASE_7_2C("SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0", schema(hash(3))),
+ /**
+ * Query: SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(3)
+ */
+ CASE_7_2D("SELECT grp0, COUNT(DISTINCT val0) as v1 FROM test GROUP BY grp0", schema(identity(3))),
/**
* Query: SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0.
*
@@ -208,15 +342,21 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
/**
* Query: SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0.
*
- * <p>Distribution single
+ * <p>Distribution identity(0)
*/
- CASE_7_4("SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0", schema(single())),
+ CASE_7_3B("SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0", schema(identity())),
/**
* Query: SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0.
*
- * <p>Distribution hash(0)
+ * <p>Distribution hash(3)
*/
- CASE_7_4A("SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0", schema(hash())),
+ CASE_7_3C("SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0", schema(hash(3))),
+ /**
+ * Query: SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0.
+ *
+ * <p>Distribution identity(3)
+ */
+ CASE_7_3D("SELECT SUM(DISTINCT val0) FROM test GROUP BY grp0", schema(identity(3))),
/**
* Query: SELECT MIN(DISTINCT val0) FROM test GROUP BY val1.
*
@@ -229,6 +369,24 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_8_1A("SELECT MIN(DISTINCT val0) FROM test GROUP BY val1", schema(hash())),
+ /**
+ * Query: SELECT MIN(DISTINCT val0) FROM test GROUP BY val1.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_8_1B("SELECT MIN(DISTINCT val0) FROM test GROUP BY val1", schema(identity())),
+ /**
+ * Query: SELECT MIN(DISTINCT val0) FROM test GROUP BY val1.
+ *
+ * <p>Distribution hash(2)
+ */
+ CASE_8_1C("SELECT MIN(DISTINCT val0) FROM test GROUP BY val1", schema(hash(2))),
+ /**
+ * Query: SELECT MIN(DISTINCT val0) FROM test GROUP BY val1.
+ *
+ * <p>Distribution identity(2)
+ */
+ CASE_8_1D("SELECT MIN(DISTINCT val0) FROM test GROUP BY val1", schema(identity(2))),
/**
* Query: SELECT MAX(DISTINCT val0) FROM test GROUP BY val1.
*
@@ -241,6 +399,24 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_8_2A("SELECT MAX(DISTINCT val0) FROM test GROUP BY val1", schema(hash())),
+ /**
+ * Query: SELECT MAX(DISTINCT val0) FROM test GROUP BY val1.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_8_2B("SELECT MAX(DISTINCT val0) FROM test GROUP BY val1", schema(identity())),
+ /**
+ * Query: SELECT MAX(DISTINCT val0) FROM test GROUP BY val1.
+ *
+ * <p>Distribution hash(2)
+ */
+ CASE_8_2C("SELECT MAX(DISTINCT val0) FROM test GROUP BY val1", schema(hash(2))),
+ /**
+ * Query: SELECT MAX(DISTINCT val0) FROM test GROUP BY val1.
+ *
+ * <p>Distribution identity(2)
+ */
+ CASE_8_2D("SELECT MAX(DISTINCT val0) FROM test GROUP BY val1", schema(identity(2))),
/**
* Query: SELECT SUM(val0) FROM test GROUP BY grp0.
*
@@ -257,6 +433,30 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_9A("SELECT SUM(val0) FROM test GROUP BY grp0", schema(hash(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0.
+ *
+ * <p>Index on (grp0, grp1)
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_9B("SELECT SUM(val0) FROM test GROUP BY grp0", schema(identity(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0.
+ *
+ * <p>Index on (grp0, grp1)
+ *
+ * <p>Distribution hash(3)
+ */
+ CASE_9C("SELECT SUM(val0) FROM test GROUP BY grp0", schema(hash(3), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0.
+ *
+ * <p>Index on (grp0, grp1)
+ *
+ * <p>Distribution identity(3)
+ */
+ CASE_9D("SELECT SUM(val0) FROM test GROUP BY grp0", schema(identity(3), addSortIndex("grp0", "grp1"))),
/**
* Query: SELECT SUM(val0) FROM test GROUP BY grp0, grp1.
*
@@ -269,6 +469,18 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_10A("SELECT SUM(val0) FROM test GROUP BY grp0, grp1", schema(hash(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0, grp1.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_10B("SELECT SUM(val0) FROM test GROUP BY grp0, grp1", schema(identity(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp0, grp1.
+ *
+ * <p>Distribution hash(3, 4)
+ */
+ CASE_10C("SELECT SUM(val0) FROM test GROUP BY grp0, grp1", schema(hash(3, 4), addSortIndex("grp0", "grp1"))),
/**
* Query: SELECT SUM(val0) FROM test GROUP BY grp1, grp0.
*
@@ -281,6 +493,18 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_11A("SELECT SUM(val0) FROM test GROUP BY grp1, grp0", schema(hash(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp1, grp0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_11B("SELECT SUM(val0) FROM test GROUP BY grp1, grp0", schema(identity(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT SUM(val0) FROM test GROUP BY grp1, grp0.
+ *
+ * <p>Distribution hash(4, 3)
+ */
+ CASE_11C("SELECT SUM(val0) FROM test GROUP BY grp1, grp0", schema(hash(4, 3), addSortIndex("grp0", "grp1"))),
/**
* Query: SELECT DISTINCT val0, val1 FROM test.
*
@@ -297,6 +521,31 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_12A("SELECT DISTINCT val0, val1 FROM test", schema(hash(), addSortIndex("val0"))),
+ /**
+ * Query: SELECT DISTINCT val0, val1 FROM test.
+ *
+ * <p>Index on val0
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_12B("SELECT DISTINCT val0, val1 FROM test", schema(identity(), addSortIndex("val0"))),
+ /**
+ * Query: SELECT DISTINCT val0, val1 FROM test.
+ *
+ * <p>Index on val0
+ *
+ * <p>Distribution hash(1)
+ */
+ CASE_12C("SELECT DISTINCT val0, val1 FROM test", schema(hash(1), addSortIndex("val0"))),
+
+ /**
+ * Query: SELECT DISTINCT val0, val1 FROM test.
+ *
+ * <p>Index on val0
+ *
+ * <p>Distribution identity(1)
+ */
+ CASE_12D("SELECT DISTINCT val0, val1 FROM test", schema(identity(1), addSortIndex("val0"))),
/**
* Query: SELECT DISTINCT grp0, grp1 FROM test.
*
@@ -313,6 +562,30 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_13A("SELECT DISTINCT grp0, grp1 FROM test", schema(hash(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT DISTINCT grp0, grp1 FROM test.
+ *
+ * <p>Index on (grp0, grp1)
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_13B("SELECT DISTINCT grp0, grp1 FROM test", schema(identity(), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT DISTINCT grp0, grp1 FROM test.
+ *
+ * <p>Index on (grp0, grp1)
+ *
+ * <p>Distribution hash(3)
+ */
+ CASE_13C("SELECT DISTINCT grp0, grp1 FROM test", schema(hash(3), addSortIndex("grp0", "grp1"))),
+ /**
+ * Query: SELECT DISTINCT grp0, grp1 FROM test.
+ *
+ * <p>Index on (grp0, grp1)
+ *
+ * <p>Distribution identity(3)
+ */
+ CASE_13D("SELECT DISTINCT grp0, grp1 FROM test", schema(identity(3), addSortIndex("grp0", "grp1"))),
/**
* Query: SELECT val0 FROM test WHERE VAL1 = (SELECT SUM(val1) FROM test).
*
@@ -325,6 +598,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_14A("SELECT val0 FROM test WHERE VAL1 = (SELECT SUM(val1) FROM test)", schema(hash())),
+ /**
+ * Query: SELECT val0 FROM test WHERE VAL1 = (SELECT SUM(val1) FROM test).
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_14B("SELECT val0 FROM test WHERE VAL1 = (SELECT SUM(val1) FROM test)", schema(identity())),
/**
* Query: SELECT val0 FROM test WHERE VAL1 = ANY(SELECT DISTINCT val1 FROM test).
*
@@ -337,6 +616,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_15A("SELECT val0 FROM test WHERE VAL1 = ANY(SELECT DISTINCT val1 FROM test)", schema(hash())),
+ /**
+ * Query: SELECT val0 FROM test WHERE VAL1 = ANY(SELECT DISTINCT val1 FROM test).
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_15B("SELECT val0 FROM test WHERE VAL1 = ANY(SELECT DISTINCT val1 FROM test)", schema(identity())),
/**
* Query: SELECT ID FROM test WHERE VAL0 IN (SELECT VAL0 FROM test).
*
@@ -353,6 +638,14 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_16A("SELECT ID FROM test WHERE VAL0 IN (SELECT VAL0 FROM test)", schema(hash(), indexByVal0Desc())),
+ /**
+ * Query: SELECT ID FROM test WHERE VAL0 IN (SELECT VAL0 FROM test).
+ *
+ * <p>Index on val0 DESC
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_16B("SELECT ID FROM test WHERE VAL0 IN (SELECT VAL0 FROM test)", schema(identity(), indexByVal0Desc())),
/**
* Query: SELECT (SELECT test.val0 FROM test t ORDER BY 1 LIMIT 1) FROM test.
*
@@ -365,6 +658,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_17A("SELECT (SELECT test.val0 FROM test t ORDER BY 1 LIMIT 1) FROM test", schema(hash())),
+ /**
+ * Query: SELECT (SELECT test.val0 FROM test t ORDER BY 1 LIMIT 1) FROM test.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_17B("SELECT (SELECT test.val0 FROM test t ORDER BY 1 LIMIT 1) FROM test", schema(identity())),
/**
* Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1.
*
@@ -377,6 +676,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_18_1A("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1", schema(hash())),
+ /**
+ * Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_18_1B("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1", schema(identity())),
/**
* Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1, val0.
*
@@ -389,6 +694,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_18_2A("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1, val0", schema(hash())),
+ /**
+ * Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1, val0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_18_2B("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1, val0", schema(identity())),
/**
* Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val1, val0 ORDER BY val0, val1.
*
@@ -401,7 +712,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_18_3A("SELECT val1, val0, COUNT(*) cnt FROM test GROUP BY val1, val0 ORDER BY val0, val1", schema(hash())),
-
+ /**
+ * Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val1, val0 ORDER BY val0, val1.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_18_3B("SELECT val1, val0, COUNT(*) cnt FROM test GROUP BY val1, val0 ORDER BY val0, val1", schema(identity())),
/**
* SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0.
*
@@ -414,6 +730,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_19_1A("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0", schema(hash())),
+ /**
+ * SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_19_1B("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0", schema(identity())),
/**
* Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1.
*
@@ -426,6 +748,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_19_2A("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1", schema(hash())),
+ /**
+ * Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_19_2B("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val1", schema(identity())),
/**
* Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1, cnt.
*
@@ -438,6 +766,12 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
* <p>Distribution hash(0)
*/
CASE_20A("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1, cnt", schema(hash())),
+ /**
+ * Query: SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1, cnt.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_20B("SELECT val0, val1, COUNT(*) cnt FROM test GROUP BY val0, val1 ORDER BY val0, val1, cnt", schema(identity())),
/**
* Query: SELECT /*+ EXPAND_DISTINCT_AGG */ SUM(DISTINCT val0), SUM(DISTINCT val1) FROM test GROUP BY grp0.
*
@@ -456,20 +790,63 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
*/
CASE_21A("SELECT /*+ EXPAND_DISTINCT_AGG */ SUM(DISTINCT val0), SUM(DISTINCT val1) FROM test GROUP BY grp0",
schema(hash(), addSortIndex("grp0", "val0"), addSortIndex("grp0", "val1"))),
-
+ /**
+ * Query: SELECT /*+ EXPAND_DISTINCT_AGG */ SUM(DISTINCT val0), SUM(DISTINCT val1) FROM test GROUP BY grp0.
+ *
+ * <p>Index on val0
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_21B("SELECT /*+ EXPAND_DISTINCT_AGG */ SUM(DISTINCT val0), SUM(DISTINCT val1) FROM test GROUP BY grp0",
+ schema(identity(), addSortIndex("grp0", "val0"), addSortIndex("grp0", "val1"))),
/**
* Query: SELECT val0, COUNT(val1) FROM test GROUP BY val0.
*
* <p>Distribution hash(0)
*/
CASE_22("SELECT val0, COUNT(val1) FROM test GROUP BY val0", schema(hash())),
-
+ /**
+ * Query: SELECT val0, COUNT(val1) FROM test GROUP BY val0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_22A("SELECT val0, COUNT(val1) FROM test GROUP BY val0", schema(identity())),
+ /**
+ * Query: SELECT val0, COUNT(val1) FROM test GROUP BY val0.
+ *
+ * <p>Distribution hash(1)
+ */
+ CASE_22B("SELECT val0, COUNT(val1) FROM test GROUP BY val0", schema(hash(1))),
+ /**
+ * Query: SELECT val0, COUNT(val1) FROM test GROUP BY val0.
+ *
+ * <p>Distribution identity(1)
+ */
+ CASE_22C("SELECT val0, COUNT(val1) FROM test GROUP BY val0", schema(identity(1))),
/**
* Query: SELECT val0, AVG(val1) FROM test GROUP BY val0.
*
* <p>Distribution hash(0)
*/
CASE_23("SELECT val0, AVG(val1) FROM test GROUP BY val0", schema(hash())),
+ /**
+ * Query: SELECT val0, AVG(val1) FROM test GROUP BY val0.
+ *
+ * <p>Distribution identity(0)
+ */
+ CASE_23A("SELECT val0, AVG(val1) FROM test GROUP BY val0", schema(identity())),
+ /**
+ * Query: SELECT val0, AVG(val1) FROM test GROUP BY val0.
+ *
+ * <p>Distribution hash(1)
+ */
+ CASE_23B("SELECT val0, AVG(val1) FROM test GROUP BY val0", schema(hash(1))),
+ /**
+ * Query: SELECT val0, AVG(val1) FROM test GROUP BY val0.
+ *
+ * <p>Distribution identity(1)
+ */
+ CASE_23C("SELECT val0, AVG(val1) FROM test GROUP BY val0", schema(identity(1))),
;
final String query;
@@ -551,7 +928,19 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest {
}
private static IgniteDistribution hash() {
- return someAffinity();
+ return IgniteDistributions.affinity(0, nextTableId(), DEFAULT_ZONE_ID);
+ }
+
+ private static IgniteDistribution hash(int... keys) {
+ return IgniteDistributions.affinity(IntList.of(keys), nextTableId(), DEFAULT_ZONE_ID);
+ }
+
+ private static IgniteDistribution identity() {
+ return IgniteDistributions.identity(0);
+ }
+
+ private static IgniteDistribution identity(int key) {
+ return IgniteDistributions.identity(key);
}
private static UnaryOperator<TableBuilder> indexByVal0Desc() {
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java
index 23a79d620d..8842af8cfc 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregatePlannerTest.java
@@ -55,6 +55,7 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
protected void simpleAggregate() throws Exception {
checkSimpleAggSingle(TestCase.CASE_1);
checkSimpleAggHash(TestCase.CASE_1A);
+ checkSimpleAggHash(TestCase.CASE_1B);
}
/**
@@ -66,11 +67,18 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
public void distinctAggregate() throws Exception {
checkDistinctAggSingle(TestCase.CASE_2_1);
checkDistinctAggSingle(TestCase.CASE_2_2);
- checkDistinctAggSingle(TestCase.CASE_2_3);
checkDistinctAggHash(TestCase.CASE_2_1A);
checkDistinctAggHash(TestCase.CASE_2_2A);
- checkDistinctAggHash(TestCase.CASE_2_3A);
+
+ checkDistinctAggHash(TestCase.CASE_2_1B);
+ checkDistinctAggHash(TestCase.CASE_2_2B);
+
+ checkColocatedDistinctAggHash(TestCase.CASE_2_1C);
+ checkColocatedDistinctAggHash(TestCase.CASE_2_2C);
+
+ checkColocatedDistinctAggHash(TestCase.CASE_2_1D);
+ checkColocatedDistinctAggHash(TestCase.CASE_2_2D);
}
/**
@@ -85,6 +93,15 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
checkSimpleAggHash(TestCase.CASE_3_1A);
checkSimpleAggHash(TestCase.CASE_3_2A);
+
+ checkSimpleAggHash(TestCase.CASE_3_1B);
+ checkSimpleAggHash(TestCase.CASE_3_2B);
+
+ checkSimpleAggHash(TestCase.CASE_3_1C);
+ checkSimpleAggHash(TestCase.CASE_3_2C);
+
+ checkSimpleAggHash(TestCase.CASE_3_1D);
+ checkSimpleAggHash(TestCase.CASE_3_2D);
}
/**
@@ -96,8 +113,16 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
checkSimpleAggWithGroupBySingle(TestCase.CASE_6);
checkSimpleAggWithGroupByHash(TestCase.CASE_5A);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5B);
+
//TODO replace with calls to test methods after https://issues.apache.org/jira/browse/IGNITE-20083 is resolved
assumeRun("checkSimpleAggWithGroupByHash", TestCase.CASE_6A);
+ assumeRun("checkSimpleAggWithGroupByHash", TestCase.CASE_6B);
+
+ checkSimpleAggWithColocatedGroupByHash(TestCase.CASE_5C);
+ checkSimpleAggWithColocatedGroupByHash(TestCase.CASE_5D);
+
+ checkSimpleAggWithColocatedGroupByHash(TestCase.CASE_6C);
}
/**
@@ -110,12 +135,22 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_1);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_2);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_3);
- checkDistinctAggWithGroupBySingle(TestCase.CASE_7_4);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_1A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_2A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_3A);
- checkDistinctAggWithGroupByHash(TestCase.CASE_7_4A);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3B);
+
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_1C);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_2C);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_3C);
+
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_1D);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_2D);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_3D);
}
/**
@@ -130,6 +165,15 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
checkSimpleAggWithGroupByHash(TestCase.CASE_8_1A);
checkSimpleAggWithGroupByHash(TestCase.CASE_8_2A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2B);
+
+ checkSimpleAggWithColocatedGroupByHash(TestCase.CASE_8_1C);
+ checkSimpleAggWithColocatedGroupByHash(TestCase.CASE_8_2C);
+
+ checkSimpleAggWithColocatedGroupByHash(TestCase.CASE_8_1D);
+ checkSimpleAggWithColocatedGroupByHash(TestCase.CASE_8_2D);
}
/**
@@ -146,6 +190,16 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
checkAggWithGroupByIndexColumnsSort(TestCase.CASE_9A);
checkAggWithGroupByIndexColumnsSort(TestCase.CASE_10A);
checkAggWithGroupByIndexColumnsSort(TestCase.CASE_11A);
+
+ checkAggWithGroupByIndexColumnsSort(TestCase.CASE_9B);
+ checkAggWithGroupByIndexColumnsSort(TestCase.CASE_10B);
+ checkAggWithGroupByIndexColumnsSort(TestCase.CASE_11B);
+
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_9C);
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_10C);
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_11C);
+
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_9D);
}
/**
@@ -155,15 +209,11 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
public void distinctWithoutAggregate() throws Exception {
checkGroupWithNoAggregateSingle(TestCase.CASE_12);
- assertPlan(TestCase.CASE_12A,
- nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isInstanceOf(IgniteExchange.class)
- .and(input(isTableScan("TEST")))
- ))
- )
- );
+ checkGroupWithNoAggregateHash(TestCase.CASE_12A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_12B);
+
+ checkColocatedGroupWithNoAggregateHash(TestCase.CASE_12C);
+ checkColocatedGroupWithNoAggregateHash(TestCase.CASE_12D);
}
/**
@@ -171,25 +221,13 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
*/
@Test
public void distinctWithoutAggregateUseIndex() throws Exception {
- assertPlan(TestCase.CASE_13,
- nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
- ));
+ checkGroupWithNoAggregateUseIndexSingle(TestCase.CASE_13);
- assertPlan(TestCase.CASE_13A,
- nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isInstanceOf(IgniteExchange.class)
- .and(input(isInstanceOf(IgniteMapSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
- ))
- ))
- ));
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13A);
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13B);
+
+ checkColocatedGroupWithNoAggregateUseIndexHash(TestCase.CASE_13C);
+ checkColocatedGroupWithNoAggregateUseIndexHash(TestCase.CASE_13D);
}
/**
@@ -199,6 +237,7 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
public void subqueryWithAggregateInWhereClause() throws Exception {
checkSimpleAggSingle(TestCase.CASE_14);
checkSimpleAggHash(TestCase.CASE_14A);
+ checkSimpleAggHash(TestCase.CASE_14B);
}
/**
@@ -216,6 +255,14 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
.and(input(isTableScan("TEST")))
))
));
+ assertPlan(TestCase.CASE_15B,
+ nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ));
}
/**
@@ -241,6 +288,15 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
))
),
additionalRulesToDisable);
+ assertPlan(TestCase.CASE_16B,
+ nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteMapSortAggregate.class)
+ .and(input(isIndexScan("TEST", "idx_val0")))
+ ))
+ ))
+ ),
+ additionalRulesToDisable);
}
/**
@@ -271,6 +327,18 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
))
))
));
+ assertPlan(TestCase.CASE_17B,
+ hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
+ .and(input(1, isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(input(isInstanceOf(IgniteLimit.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteSort.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ))
+ ))
+ ));
}
/**
@@ -285,6 +353,10 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2A, TraitUtils.createCollation(List.of(1, 0)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2B, TraitUtils.createCollation(List.of(1, 0)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -297,6 +369,9 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -321,6 +396,15 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
))
))
);
+ assertPlan(TestCase.CASE_20B,
+ isInstanceOf(IgniteSort.class)
+ .and(s -> s.collation().equals(TraitUtils.createCollation(List.of(0, 1, 2))))
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ );
}
@@ -368,20 +452,22 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
.and(input(0, subtreePredicate))
.and(input(1, subtreePredicate))
));
+ assertPlan(TestCase.CASE_21B, nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(input(0, subtreePredicate))
+ .and(input(1, subtreePredicate))
+ ));
}
/** Validate that we choose two-phase COUNT aggregate for COUNT by default. */
@Test
public void countAgg() throws Exception {
- Predicate<AggregateCall> countMap = (a) -> {
- return Objects.equals(a.getAggregation().getName(), "COUNT") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countMap = (a) ->
+ Objects.equals(a.getAggregation().getName(), "COUNT") && a.getArgList().equals(List.of(1));
- Predicate<AggregateCall> countReduce = (a) -> {
- return Objects.equals(a.getAggregation().getName(), "$SUM0") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countReduce = (a) ->
+ Objects.equals(a.getAggregation().getName(), "$SUM0") && a.getArgList().equals(List.of(1));
- assertPlan(TestCase.CASE_22, hasChildThat(isInstanceOf(IgniteReduceHashAggregate.class)
+ Predicate<RelNode> nonColocatedGroupBy = hasChildThat(isInstanceOf(IgniteReduceHashAggregate.class)
.and(in -> hasAggregates(countReduce).test(in.getAggregateCalls()))
.and(input(isInstanceOf(IgniteExchange.class)
.and(input(isInstanceOf(IgniteMapHashAggregate.class)
@@ -389,20 +475,44 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
.and(input(isTableScan("TEST")))
)
))
- )));
+ ));
+
+ Predicate<IgniteExchange> colocatedGroupBy = isInstanceOf(IgniteExchange.class)
+ .and(hasDistribution(IgniteDistributions.single()))
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(in -> hasAggregates(countMap).test(in.getAggCallList()))
+ .and(input(isTableScan("TEST")))
+ ));
+
+ assertPlan(TestCase.CASE_22, nonColocatedGroupBy);
+ assertPlan(TestCase.CASE_22A, nonColocatedGroupBy);
+
+ assertPlan(TestCase.CASE_22B, colocatedGroupBy);
+ assertPlan(TestCase.CASE_22C, colocatedGroupBy);
}
/** Validate that we choose single phase AVG aggregate for AVG by default. */
@Test
public void avgAgg() throws Exception {
- Predicate<AggregateCall> countMap = (a) -> {
- return Objects.equals(a.getAggregation().getName(), "AVG") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countMap = (a) -> Objects.equals(a.getAggregation().getName(), "AVG") && a.getArgList().equals(List.of(1));
- assertPlan(TestCase.CASE_23, isInstanceOf(IgniteColocatedHashAggregate.class)
+ Predicate<IgniteColocatedHashAggregate> nonColocated = isInstanceOf(IgniteColocatedHashAggregate.class)
.and(in -> hasAggregates(countMap).test(in.getAggCallList()))
.and(input(isInstanceOf(IgniteExchange.class)
- .and(hasDistribution(IgniteDistributions.single())))));
+ .and(hasDistribution(IgniteDistributions.single()))));
+
+ Predicate<IgniteExchange> colocatedGroupBy = isInstanceOf(IgniteExchange.class)
+ .and(hasDistribution(IgniteDistributions.single()))
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(in -> hasAggregates(countMap).test(in.getAggCallList()))
+ .and(input(isTableScan("TEST")))
+ ));
+
+ assertPlan(TestCase.CASE_23, nonColocated);
+ assertPlan(TestCase.CASE_23A, nonColocated);
+
+ assertPlan(TestCase.CASE_23B, colocatedGroupBy);
+ assertPlan(TestCase.CASE_23C, colocatedGroupBy);
}
private void checkSimpleAggSingle(TestCase testCase) throws Exception {
@@ -452,6 +562,18 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
);
}
+ private void checkSimpleAggWithColocatedGroupByHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasAggregate())
+ .and(hasGroups())
+ .and(input(isTableScan("TEST")))
+ ))
+ )
+ );
+ }
+
private void checkDistinctAggSingle(TestCase testCase) throws Exception {
assertPlan(testCase,
isInstanceOf(IgniteColocatedHashAggregate.class)
@@ -478,6 +600,22 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
);
}
+ private void checkColocatedDistinctAggHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteMapSortAggregate.class)
+ .and(hasAggregate())
+ .and(not(hasDistinctAggregate()))
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasGroups())
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ))
+ ));
+ }
+
private void checkDistinctAggWithGroupBySingle(TestCase testCase) throws Exception {
assertPlan(testCase,
nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
@@ -500,16 +638,16 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
);
}
- private void checkSimpleAggWithGroupByHashColocatedFromExchange(TestCase testCase) throws Exception {
+ private void checkDistinctAggWithColocatedGroupByHash(TestCase testCase) throws Exception {
assertPlan(testCase,
- nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
- .and(hasAggregate())
- .and(hasGroups())
- .and(input(isInstanceOf(IgniteExchange.class)
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasAggregate())
+ .and(hasGroups())
+ .and(hasDistinctAggregate())
.and(input(isTableScan("TEST")))
))
- )
- );
+ ));
}
private void checkAggWithGroupByIndexColumnsSingle(TestCase testCase) throws Exception {
@@ -534,6 +672,16 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
);
}
+ private void checkAggWithColocatedGroupByIndexColumnsHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(hasAggregate())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ));
+ }
+
private void checkGroupWithNoAggregateSingle(TestCase testCase) throws Exception {
assertPlan(testCase,
nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
@@ -543,6 +691,63 @@ public class AggregatePlannerTest extends AbstractAggregatePlannerTest {
));
}
+ private void checkGroupWithNoAggregateHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ));
+ }
+
+ private void checkColocatedGroupWithNoAggregateHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isTableScan("TEST")))
+ ))
+ ));
+ }
+
+ private void checkGroupWithNoAggregateUseIndexSingle(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ));
+ }
+
+ private void checkGroupWithNoAggregateUseIndexHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteMapSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ))
+ ));
+ }
+
+ private void checkColocatedGroupWithNoAggregateUseIndexHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ));
+ }
+
private void checkGroupsWithOrderByGroupColumnsSingle(TestCase testCase, RelCollation collation) throws Exception {
assertPlan(testCase,
isInstanceOf(IgniteColocatedSortAggregate.class)
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedHashAggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedHashAggregatePlannerTest.java
index aff3899acd..54fe13c0bb 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedHashAggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedHashAggregatePlannerTest.java
@@ -57,6 +57,7 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
protected void simpleAggregate() throws Exception {
checkSimpleAggSingle(TestCase.CASE_1);
checkSimpleAggHash(TestCase.CASE_1A);
+ checkSimpleAggHash(TestCase.CASE_1B);
}
/**
@@ -68,11 +69,18 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregate() throws Exception {
checkDistinctAggSingle(TestCase.CASE_2_1);
checkDistinctAggSingle(TestCase.CASE_2_2);
- checkDistinctAggSingle(TestCase.CASE_2_3);
checkDistinctAggHash(TestCase.CASE_2_1A);
checkDistinctAggHash(TestCase.CASE_2_2A);
- checkDistinctAggHash(TestCase.CASE_2_3A);
+
+ checkDistinctAggHash(TestCase.CASE_2_1B);
+ checkDistinctAggHash(TestCase.CASE_2_2B);
+
+ checkColocatedDistinctAggHash(TestCase.CASE_2_1C);
+ checkColocatedDistinctAggHash(TestCase.CASE_2_2C);
+
+ checkColocatedDistinctAggHash(TestCase.CASE_2_1D);
+ checkColocatedDistinctAggHash(TestCase.CASE_2_2D);
}
/**
@@ -87,6 +95,15 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggHash(TestCase.CASE_3_1A);
checkSimpleAggHash(TestCase.CASE_3_2A);
+
+ checkSimpleAggHash(TestCase.CASE_3_1B);
+ checkSimpleAggHash(TestCase.CASE_3_2B);
+
+ checkSimpleAggHash(TestCase.CASE_3_1C);
+ checkSimpleAggHash(TestCase.CASE_3_2C);
+
+ checkSimpleAggHash(TestCase.CASE_3_1D);
+ checkSimpleAggHash(TestCase.CASE_3_2D);
}
/**
@@ -99,6 +116,14 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_5A);
checkSimpleAggWithGroupByHash(TestCase.CASE_6A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_6B);
+
+ checkSimpleAggWithColocatedGroupBy(TestCase.CASE_5C);
+ checkSimpleAggWithColocatedGroupBy(TestCase.CASE_6C);
+
+ checkSimpleAggWithColocatedGroupBy(TestCase.CASE_5D);
}
/**
@@ -111,12 +136,22 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_1);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_2);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_3);
- checkDistinctAggWithGroupBySingle(TestCase.CASE_7_4);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_1A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_2A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_3A);
- checkDistinctAggWithGroupByHash(TestCase.CASE_7_4A);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3B);
+
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_1C);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_2C);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_3C);
+
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_1D);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_2D);
+ checkDistinctAggWithColocatedGroupByHash(TestCase.CASE_7_3D);
}
/**
@@ -131,6 +166,15 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_8_1A);
checkSimpleAggWithGroupByHash(TestCase.CASE_8_2A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2B);
+
+ checkSimpleAggWithColocatedGroupBy(TestCase.CASE_8_1C);
+ checkSimpleAggWithColocatedGroupBy(TestCase.CASE_8_2C);
+
+ checkSimpleAggWithColocatedGroupBy(TestCase.CASE_8_1D);
+ checkSimpleAggWithColocatedGroupBy(TestCase.CASE_8_2D);
}
/**
@@ -147,6 +191,16 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11A);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11B);
+
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_9C);
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_10C);
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_11C);
+
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_9D);
}
/**
@@ -156,15 +210,17 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctWithoutAggregate() throws Exception {
checkGroupWithNoAggregateSingle(TestCase.CASE_12);
checkGroupWithNoAggregateHash(TestCase.CASE_12A);
- }
+ checkGroupWithNoAggregateHash(TestCase.CASE_12B);
+
+ checkColocatedGroupWithNoAggregateHash(TestCase.CASE_12C);
+ checkColocatedGroupWithNoAggregateHash(TestCase.CASE_12D);
- /**
- * Validates a plan uses index for a query with DISTINCT and without aggregation functions.
- */
- @Test
- public void distinctWithoutAggregateUseIndex() throws Exception {
checkGroupWithNoAggregateSingle(TestCase.CASE_13);
checkGroupWithNoAggregateHash(TestCase.CASE_13A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_13B);
+
+ checkColocatedGroupWithNoAggregateHash(TestCase.CASE_13C);
+ checkColocatedGroupWithNoAggregateHash(TestCase.CASE_13D);
}
/**
@@ -174,6 +230,7 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void subqueryWithAggregateInWhereClause() throws Exception {
checkSimpleAggSingle(TestCase.CASE_14);
checkSimpleAggHash(TestCase.CASE_14A);
+ checkSimpleAggHash(TestCase.CASE_14B);
}
/**
@@ -183,6 +240,7 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregateInWhereClause() throws Exception {
checkGroupWithNoAggregateSingle(TestCase.CASE_15);
checkGroupWithNoAggregateHash(TestCase.CASE_15A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_15B);
}
/**
@@ -211,6 +269,16 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
),
ArrayUtils.concat(disableRules, additionalRulesToDisable)
);
+ assertPlan(TestCase.CASE_16B,
+ nodeOrAnyChild(isInstanceOf(IgniteSort.class)
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ),
+ ArrayUtils.concat(disableRules, additionalRulesToDisable)
+ );
}
/**
@@ -245,6 +313,20 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
),
disableRules
);
+ assertPlan(TestCase.CASE_17B,
+ hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
+ .and(input(1, isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(input(isInstanceOf(IgniteLimit.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteSort.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ))
+ ))
+ ),
+ disableRules
+ );
}
/**
@@ -259,6 +341,10 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2A, TraitUtils.createCollation(List.of(1, 0)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2B, TraitUtils.createCollation(List.of(1, 0)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -273,6 +359,10 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1A, TraitUtils.createCollation(List.of(0)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2A, TraitUtils.createCollation(List.of(1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_20A, TraitUtils.createCollation(List.of(0, 1, 2)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1B, TraitUtils.createCollation(List.of(0)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2B, TraitUtils.createCollation(List.of(1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_20B, TraitUtils.createCollation(List.of(0, 1, 2)));
}
/**
@@ -313,6 +403,10 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
.and(input(0, subtreePredicate))
.and(input(1, subtreePredicate))
), disableRules);
+ assertPlan(TestCase.CASE_21B, nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(input(0, subtreePredicate))
+ .and(input(1, subtreePredicate))
+ ), disableRules);
}
/**
@@ -320,14 +414,24 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
*/
@Test
public void testCountAgg() throws Exception {
- Predicate<AggregateCall> countMap = (a) -> {
- return Objects.equals(a.getAggregation().getName(), "COUNT") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countMap = (a) ->
+ Objects.equals(a.getAggregation().getName(), "COUNT") && a.getArgList().equals(List.of(1));
- assertPlan(TestCase.CASE_22, isInstanceOf(IgniteColocatedHashAggregate.class)
+ Predicate<IgniteColocatedHashAggregate> nonColocatedGroupBy = isInstanceOf(IgniteColocatedHashAggregate.class)
.and(in -> hasAggregates(countMap).test(in.getAggCallList()))
.and(input(isInstanceOf(IgniteExchange.class)
- .and(hasDistribution(IgniteDistributions.single())))), disableRules);
+ .and(hasDistribution(IgniteDistributions.single()))));
+
+ assertPlan(TestCase.CASE_22, nonColocatedGroupBy, disableRules);
+ assertPlan(TestCase.CASE_22A, nonColocatedGroupBy, disableRules);
+
+ Predicate<IgniteExchange> colocatedGroupBy = isInstanceOf(IgniteExchange.class)
+ .and(hasDistribution(IgniteDistributions.single()))
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(in -> hasAggregates(countMap).test(in.getAggCallList()))));
+
+ assertPlan(TestCase.CASE_22B, colocatedGroupBy, disableRules);
+ assertPlan(TestCase.CASE_22C, colocatedGroupBy, disableRules);
}
/**
@@ -335,14 +439,24 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
*/
@Test
public void testAvgAgg() throws Exception {
- Predicate<AggregateCall> countMap = (a) -> {
- return Objects.equals(a.getAggregation().getName(), "AVG") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countMap = (a) -> Objects.equals(a.getAggregation().getName(), "AVG") && a.getArgList().equals(List.of(1));
- assertPlan(TestCase.CASE_23, isInstanceOf(IgniteColocatedHashAggregate.class)
+ Predicate<IgniteColocatedHashAggregate> nonColocatedGroupBy = isInstanceOf(IgniteColocatedHashAggregate.class)
.and(in -> hasAggregates(countMap).test(in.getAggCallList()))
.and(input(isInstanceOf(IgniteExchange.class)
- .and(hasDistribution(IgniteDistributions.single())))), disableRules);
+ .and(hasDistribution(IgniteDistributions.single()))));
+
+ assertPlan(TestCase.CASE_23, nonColocatedGroupBy, disableRules);
+ assertPlan(TestCase.CASE_23A, nonColocatedGroupBy, disableRules);
+
+ Predicate<IgniteExchange> colocatedGroupBy = isInstanceOf(IgniteExchange.class)
+ .and(hasDistribution(IgniteDistributions.single()))
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(in -> hasAggregates(countMap).test(in.getAggCallList()))));
+
+ assertPlan(TestCase.CASE_23B, colocatedGroupBy, disableRules);
+ assertPlan(TestCase.CASE_23C, colocatedGroupBy, disableRules);
+
}
private void checkSimpleAggSingle(TestCase testCase) throws Exception {
@@ -390,6 +504,31 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkSimpleAggWithColocatedGroupBy(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasAggregate())
+ .and(hasGroups())
+ .and(input(isTableScan("TEST")))
+ ))),
+ disableRules
+ );
+ }
+
+ private void checkDistinctAggWithColocatedGroupByHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasAggregate())
+ .and(hasGroups())
+ .and(hasDistinctAggregate())
+ .and(input(isTableScan("TEST")))
+ ))),
+ disableRules
+ );
+ }
+
private void checkDistinctAggSingle(TestCase testCase) throws Exception {
assertPlan(testCase,
isInstanceOf(IgniteColocatedHashAggregate.class)
@@ -418,6 +557,21 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkColocatedDistinctAggHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasAggregate())
+ .and(not(hasDistinctAggregate()))
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasGroups())
+ .and(input(isTableScan("TEST")))
+ ))
+ )),
+ disableRules
+ );
+ }
+
private void checkDistinctAggWithGroupBySingle(TestCase testCase) throws Exception {
assertPlan(testCase,
nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
@@ -464,6 +618,18 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkAggWithColocatedGroupByIndexColumnsHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(hasAggregate())
+ .and(input(isTableScan("TEST")))
+ ))
+ ),
+ disableRules
+ );
+ }
+
private void checkGroupWithNoAggregateSingle(TestCase testCase) throws Exception {
assertPlan(testCase,
nodeOrAnyChild(isInstanceOf(IgniteColocatedHashAggregate.class)
@@ -488,6 +654,18 @@ public class ColocatedHashAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkColocatedGroupWithNoAggregateHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteColocatedHashAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isTableScan("TEST")))
+ ))
+ ),
+ disableRules
+ );
+ }
private void checkGroupsWithOrderByGroupColumnsSingle(TestCase testCase, RelCollation collation) throws Exception {
assertPlan(testCase,
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedSortAggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedSortAggregatePlannerTest.java
index 1a84130156..4c66544ec5 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedSortAggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/ColocatedSortAggregatePlannerTest.java
@@ -56,6 +56,7 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
protected void simpleAggregate() throws Exception {
checkSimpleAggSingle(TestCase.CASE_1);
checkSimpleAggHash(TestCase.CASE_1A);
+ checkSimpleAggHash(TestCase.CASE_1B);
}
/**
@@ -67,11 +68,18 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregate() throws Exception {
checkDistinctAggSingle(TestCase.CASE_2_1);
checkDistinctAggSingle(TestCase.CASE_2_2);
- checkDistinctAggSingle(TestCase.CASE_2_3);
checkDistinctAggHash(TestCase.CASE_2_1A);
checkDistinctAggHash(TestCase.CASE_2_2A);
- checkDistinctAggHash(TestCase.CASE_2_3A);
+
+ checkDistinctAggHash(TestCase.CASE_2_1B);
+ checkDistinctAggHash(TestCase.CASE_2_2B);
+
+ checkDistinctAggHash(TestCase.CASE_2_1C);
+ checkDistinctAggHash(TestCase.CASE_2_2C);
+
+ checkDistinctAggHash(TestCase.CASE_2_1D);
+ checkDistinctAggHash(TestCase.CASE_2_2D);
}
/**
@@ -86,6 +94,15 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggHash(TestCase.CASE_3_1A);
checkSimpleAggHash(TestCase.CASE_3_2A);
+
+ checkSimpleAggHash(TestCase.CASE_3_1B);
+ checkSimpleAggHash(TestCase.CASE_3_2B);
+
+ checkSimpleAggHash(TestCase.CASE_3_1C);
+ checkSimpleAggHash(TestCase.CASE_3_2C);
+
+ checkSimpleAggHash(TestCase.CASE_3_1D);
+ checkSimpleAggHash(TestCase.CASE_3_2D);
}
/**
@@ -98,6 +115,14 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_5A);
checkSimpleAggWithGroupByHash(TestCase.CASE_6A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_6B);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5C);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_6C);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5D);
}
/**
@@ -110,12 +135,22 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_1);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_2);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_3);
- checkDistinctAggWithGroupBySingle(TestCase.CASE_7_4);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_1A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_2A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_3A);
- checkDistinctAggWithGroupByHash(TestCase.CASE_7_4A);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3B);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1C);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2C);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3C);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1D);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2D);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3D);
}
/**
@@ -130,6 +165,15 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_8_1A);
checkSimpleAggWithGroupByHash(TestCase.CASE_8_2A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2B);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1C);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2C);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1D);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2D);
}
/**
@@ -146,6 +190,16 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11A);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11B);
+
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_9C);
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_10C);
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_11C);
+
+ checkAggWithColocatedGroupByIndexColumnsHash(TestCase.CASE_9D);
}
/**
@@ -156,6 +210,10 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupWithNoAggregateSingle(TestCase.CASE_12);
checkGroupWithNoAggregateHash(TestCase.CASE_12A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_12B);
+
+ checkGroupWithNoAggregateHash(TestCase.CASE_12C);
+ checkGroupWithNoAggregateHash(TestCase.CASE_12D);
}
/**
@@ -163,25 +221,13 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
*/
@Test
public void distinctWithoutAggregateUseIndex() throws Exception {
- assertPlan(TestCase.CASE_13,
- nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
- ),
- disableRules
- );
+ checkGroupWithNoAggregateUseIndexSingle(TestCase.CASE_13);
- assertPlan(TestCase.CASE_13A,
- nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isInstanceOf(IgniteExchange.class)
- .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
- ))
- ),
- disableRules
- );
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13A);
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13B);
+
+ checkColocatedGroupWithNoAggregateUseIndexHash(TestCase.CASE_13C);
+ checkColocatedGroupWithNoAggregateUseIndexHash(TestCase.CASE_13D);
}
/**
@@ -191,6 +237,7 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
public void subqueryWithAggregateInWhereClause() throws Exception {
checkSimpleAggSingle(TestCase.CASE_14);
checkSimpleAggHash(TestCase.CASE_14A);
+ checkSimpleAggHash(TestCase.CASE_14B);
}
/**
@@ -200,6 +247,7 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregateInWhereClause() throws Exception {
checkGroupWithNoAggregateSingle(TestCase.CASE_15);
checkGroupWithNoAggregateHash(TestCase.CASE_15A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_15B);
}
/**
@@ -227,6 +275,16 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
),
ArrayUtils.concat(disableRules, additionalRulesToDisable)
);
+ assertPlan(TestCase.CASE_16B,
+ not(nodeOrAnyChild(isInstanceOf(IgniteSort.class)))
+ .and(nodeOrAnyChild(input(1, isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isIndexScan("TEST", "idx_val0")))
+ ))
+ ))
+ ),
+ ArrayUtils.concat(disableRules, additionalRulesToDisable)
+ );
}
/**
@@ -261,6 +319,20 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
),
disableRules
);
+ assertPlan(TestCase.CASE_17B,
+ hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
+ .and(input(1, isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(input(isInstanceOf(IgniteLimit.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteSort.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ))
+ ))
+ ),
+ disableRules
+ );
}
/**
@@ -275,6 +347,10 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2A, TraitUtils.createCollation(List.of(1, 0)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2B, TraitUtils.createCollation(List.of(1, 0)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -287,6 +363,9 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -297,6 +376,7 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderByAndGroupByWithAdditionalSortingSingle(TestCase.CASE_20);
checkGroupsWithOrderByAndGroupByWithAdditionalSortingHash(TestCase.CASE_20A);
+ checkGroupsWithOrderByAndGroupByWithAdditionalSortingHash(TestCase.CASE_20B);
}
@@ -338,6 +418,10 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
.and(input(0, subtreePredicate))
.and(input(1, subtreePredicate))
), disableRules);
+ assertPlan(TestCase.CASE_21B, nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(input(0, subtreePredicate))
+ .and(input(1, subtreePredicate))
+ ), disableRules);
}
/**
@@ -345,15 +429,18 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
*/
@Test
public void testCountAgg() throws Exception {
- Predicate<AggregateCall> countMap = (a) -> {
- String aggName = a.getAggregation().getName();
- return Objects.equals(aggName, "COUNT") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countMap = (a) ->
+ Objects.equals(a.getAggregation().getName(), "COUNT") && a.getArgList().equals(List.of(1));
- assertPlan(TestCase.CASE_22, isInstanceOf(IgniteColocatedSortAggregate.class)
+ Predicate<IgniteColocatedSortAggregate> checkPlan = isInstanceOf(IgniteColocatedSortAggregate.class)
.and(in -> hasAggregates(countMap).test(in.getAggCallList()))
.and(input(isInstanceOf(IgniteExchange.class)
- .and(hasDistribution(IgniteDistributions.single())))), disableRules);
+ .and(hasDistribution(IgniteDistributions.single()))));
+
+ assertPlan(TestCase.CASE_22, checkPlan, disableRules);
+ assertPlan(TestCase.CASE_22A, checkPlan, disableRules);
+ assertPlan(TestCase.CASE_22B, checkPlan, disableRules);
+ assertPlan(TestCase.CASE_22C, checkPlan, disableRules);
}
/**
@@ -361,14 +448,17 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
*/
@Test
public void testAvgAgg() throws Exception {
- Predicate<AggregateCall> countMap = (a) -> {
- return Objects.equals(a.getAggregation().getName(), "AVG") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countMap = (a) -> Objects.equals(a.getAggregation().getName(), "AVG") && a.getArgList().equals(List.of(1));
- assertPlan(TestCase.CASE_23, isInstanceOf(IgniteColocatedSortAggregate.class)
+ Predicate<IgniteColocatedSortAggregate> checkPlan = isInstanceOf(IgniteColocatedSortAggregate.class)
.and(in -> hasAggregates(countMap).test(in.getAggCallList()))
.and(input(isInstanceOf(IgniteExchange.class)
- .and(hasDistribution(IgniteDistributions.single())))), disableRules);
+ .and(hasDistribution(IgniteDistributions.single()))));
+
+ assertPlan(TestCase.CASE_23, checkPlan, disableRules);
+ assertPlan(TestCase.CASE_23A, checkPlan, disableRules);
+ assertPlan(TestCase.CASE_23B, checkPlan, disableRules);
+ assertPlan(TestCase.CASE_23C, checkPlan, disableRules);
}
private void checkSimpleAggSingle(TestCase testCase) throws Exception {
@@ -495,6 +585,18 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkAggWithColocatedGroupByIndexColumnsHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(hasAggregate())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ),
+ disableRules
+ );
+ }
+
private void checkGroupWithNoAggregateSingle(TestCase testCase) throws Exception {
assertPlan(testCase,
nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
@@ -508,6 +610,43 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkGroupWithNoAggregateUseIndexSingle(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ),
+ disableRules
+ );
+ }
+
+ private void checkGroupWithNoAggregateUseIndexHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ),
+ disableRules
+ );
+ }
+
+ private void checkColocatedGroupWithNoAggregateUseIndexHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ),
+ disableRules
+ );
+ }
+
private void checkGroupWithNoAggregateHash(TestCase testCase) throws Exception {
assertPlan(testCase,
nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
@@ -523,6 +662,17 @@ public class ColocatedSortAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkGroupWi2thNoAggregateSingle(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteColocatedSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ),
+ disableRules
+ );
+ }
+
private void checkGroupsWithOrderByGroupColumnsSingle(TestCase testCase, RelCollation collation) throws Exception {
assertPlan(testCase,
isInstanceOf(IgniteColocatedSortAggregate.class)
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
index 06040d9b14..ae2db70e4f 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/DmlPlannerTest.java
@@ -173,7 +173,8 @@ public class DmlPlannerTest extends AbstractPlannerTest {
return Stream.of(
IgniteDistributions.single(),
IgniteDistributions.hash(List.of(0, 1)),
- IgniteDistributions.affinity(0, 2, "0")
+ IgniteDistributions.affinity(0, 2, "0"),
+ IgniteDistributions.identity(0)
);
}
@@ -188,7 +189,8 @@ public class DmlPlannerTest extends AbstractPlannerTest {
IgniteDistributions.affinity(1, 2, "0"),
IgniteDistributions.affinity(3, 2, "0"),
IgniteDistributions.affinity(List.of(1, 3), 2, "0"),
- IgniteDistributions.affinity(List.of(3, 1), 2, "0")
+ IgniteDistributions.affinity(List.of(3, 1), 2, "0"),
+ IgniteDistributions.identity(1)
);
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/IdentityDistributionPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/IdentityDistributionPlannerTest.java
new file mode 100644
index 0000000000..71344346cc
--- /dev/null
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/IdentityDistributionPlannerTest.java
@@ -0,0 +1,200 @@
+/*
+ * 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.sql.engine.planner;
+
+import static org.apache.ignite.internal.sql.engine.trait.IgniteDistributions.single;
+
+import org.apache.ignite.internal.schema.NativeTypes;
+import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
+import org.apache.ignite.internal.sql.engine.framework.TestTable;
+import org.apache.ignite.internal.sql.engine.rel.IgniteExchange;
+import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
+import org.apache.ignite.internal.sql.engine.rel.IgniteMergeJoin;
+import org.apache.ignite.internal.sql.engine.rel.IgniteTrimExchange;
+import org.apache.ignite.internal.sql.engine.schema.IgniteIndex.Collation;
+import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistribution;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test suite to verify join colocation when using
+ * {@link org.apache.ignite.internal.sql.engine.trait.DistributionFunction.IdentityDistribution} function.
+ */
+public class IdentityDistributionPlannerTest extends AbstractPlannerTest {
+
+ /**
+ * Join of the tables with same affinity is expected to be colocated.
+ */
+ @Test
+ public void joinSameTableIdentity() throws Exception {
+ TestTable tbl1 = simpleTable("TEST_TBL1", DEFAULT_TBL_SIZE, IgniteDistributions.identity(0));
+ TestTable tbl2 = simpleTable("TEST_TBL2", DEFAULT_TBL_SIZE, IgniteDistributions.identity(0));
+
+ IgniteSchema schema = createSchema(tbl1, tbl2);
+
+ String sql = "select count(*) "
+ + "from TEST_TBL1 t1 "
+ + "join TEST_TBL2 t2 on t1.id = t2.id";
+
+ assertPlan(sql, schema, nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(hasDistribution(IgniteDistributions.identity(0)))
+ .and(input(0, isInstanceOf(IgniteIndexScan.class)))
+ .and(input(1, isInstanceOf(IgniteIndexScan.class)))
+ ))
+ ));
+ }
+
+ /**
+ * Re-hashing based on affinity.
+ */
+ @Test
+ public void joinAffinityTableWithIdentityTable() throws Exception {
+ IgniteDistribution affinityDistribution = IgniteDistributions.affinity(0, nextTableId(), 0);
+
+ TestTable tbl1 = simpleTable("TEST_TBL1", 2 * DEFAULT_TBL_SIZE, IgniteDistributions.identity(0));
+ TestTable tbl2 = simpleTable("TEST_TBL2", DEFAULT_TBL_SIZE, affinityDistribution);
+
+ IgniteSchema schema = createSchema(tbl1, tbl2);
+
+ String sql = "select count(*) "
+ + "from TEST_TBL1 t1 "
+ + "join TEST_TBL2 t2 on t1.id = t2.id";
+
+ assertPlan(sql, schema, nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(hasDistribution(single()))
+ .and(nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(hasDistribution(IgniteDistributions.identity(0)))
+ .and(input(0, isInstanceOf(IgniteIndexScan.class)))
+ .and(input(1, isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteIndexScan.class)))
+ ))
+ ))
+ ));
+ }
+
+ /**
+ * Re-hashing based on identity function.
+ */
+ @Test
+ public void joinIndentityTableWithAffinityTable() throws Exception {
+ IgniteDistribution affinityDistribution = IgniteDistributions.affinity(0, nextTableId(), 0);
+
+ TestTable tbl1 = simpleTable("TEST_TBL1", DEFAULT_TBL_SIZE, IgniteDistributions.identity(0));
+ TestTable tbl2 = simpleTable("TEST_TBL2", 2 * DEFAULT_TBL_SIZE, affinityDistribution);
+
+ IgniteSchema schema = createSchema(tbl1, tbl2);
+
+ String sql = "select count(*) "
+ + "from TEST_TBL1 t1 "
+ + "join TEST_TBL2 t2 on t1.id = t2.id";
+
+ assertPlan(sql, schema, nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(hasDistribution(single()))
+ .and(nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(hasDistribution(affinityDistribution))
+ .and(input(0, isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteIndexScan.class)))
+ ))
+ .and(input(1, isInstanceOf(IgniteIndexScan.class)))
+ ))
+ ));
+ }
+
+ /**
+ * Join of the tables with same affinity is expected to be colocated.
+ */
+ @Test
+ public void joinTableWithDifferentIdentity() throws Exception {
+ TestTable tbl1 = complexTable("TEST_TBL1", DEFAULT_TBL_SIZE, IgniteDistributions.identity(0));
+ TestTable tbl2 = complexTable("TEST_TBL2", DEFAULT_TBL_SIZE, IgniteDistributions.identity(1));
+
+ IgniteSchema schema = createSchema(tbl1, tbl2);
+
+ String sql = "select count(*) "
+ + "from TEST_TBL1 t1 "
+ + "join TEST_TBL2 t2 on t1.id1 = t2.id2";
+
+ assertPlan(sql, schema, nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(hasDistribution(IgniteDistributions.identity(0)))
+ .and(input(0, isInstanceOf(IgniteIndexScan.class)))
+ .and(input(1, isInstanceOf(IgniteIndexScan.class)))
+ ))
+ ));
+ }
+
+ /**
+ * Join of the tables with identity and broadcast distribution is expected to be colocated.
+ */
+ @Test
+ public void joinTableWithIdentityAndBroadcastDistributions() throws Exception {
+ TestTable tbl1 = complexTable("TEST_TBL1", DEFAULT_TBL_SIZE, IgniteDistributions.identity(0));
+ TestTable tbl2 = complexTable("TEST_TBL2", DEFAULT_TBL_SIZE, IgniteDistributions.broadcast());
+
+ IgniteSchema schema = createSchema(tbl1, tbl2);
+
+ String sql = "select count(*) "
+ + "from TEST_TBL1 t1 "
+ + "join TEST_TBL2 t2 on t1.id1 = t2.id1";
+
+ assertPlan(sql, schema, nodeOrAnyChild(isInstanceOf(IgniteExchange.class)
+ .and(nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(hasDistribution(IgniteDistributions.identity(0)))
+ .and(input(0, isInstanceOf(IgniteIndexScan.class)))
+ .and(input(1, isInstanceOf(IgniteTrimExchange.class)
+ .and(input(isInstanceOf(IgniteIndexScan.class)))
+ ))
+ ))
+ ));
+ }
+
+ private static TestTable simpleTable(String tableName, int size, IgniteDistribution distribution) {
+ return TestBuilders.table()
+ .name(tableName)
+ .size(size)
+ .distribution(distribution)
+ .addColumn("ID", NativeTypes.STRING)
+ .addColumn("VAL", NativeTypes.STRING)
+ .sortedIndex()
+ .name("PK")
+ .addColumn("ID", Collation.ASC_NULLS_LAST)
+ .end()
+ .build();
+ }
+
+ private static TestTable complexTable(String tableName, int size, IgniteDistribution distribution) {
+ return TestBuilders.table()
+ .name(tableName)
+ .size(size)
+ .distribution(distribution)
+ .addColumn("ID1", NativeTypes.STRING)
+ .addColumn("ID2", NativeTypes.STRING)
+ .addColumn("VAL", NativeTypes.STRING)
+ .sortedIndex()
+ .name("IDX1")
+ .addColumn("ID1", Collation.ASC_NULLS_LAST)
+ .end()
+ .sortedIndex()
+ .name("IDX2")
+ .addColumn("ID2", Collation.ASC_NULLS_LAST)
+ .end()
+ .build();
+ }
+}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceHashAggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceHashAggregatePlannerTest.java
index 2d7472757b..a525b719eb 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceHashAggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceHashAggregatePlannerTest.java
@@ -61,6 +61,7 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
protected void simpleAggregate() throws Exception {
checkSimpleAggSingle(TestCase.CASE_1);
checkSimpleAggHash(TestCase.CASE_1A);
+ checkSimpleAggHash(TestCase.CASE_1B);
}
/**
@@ -72,11 +73,18 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregate() throws Exception {
checkDistinctAggSingle(TestCase.CASE_2_1);
checkDistinctAggSingle(TestCase.CASE_2_2);
- checkDistinctAggSingle(TestCase.CASE_2_3);
checkDistinctAggHash(TestCase.CASE_2_1A);
checkDistinctAggHash(TestCase.CASE_2_2A);
- checkDistinctAggHash(TestCase.CASE_2_3A);
+
+ checkDistinctAggHash(TestCase.CASE_2_1B);
+ checkDistinctAggHash(TestCase.CASE_2_2B);
+
+ checkDistinctAggHash(TestCase.CASE_2_1C);
+ checkDistinctAggHash(TestCase.CASE_2_2C);
+
+ checkDistinctAggHash(TestCase.CASE_2_1D);
+ checkDistinctAggHash(TestCase.CASE_2_2D);
}
/**
@@ -91,6 +99,15 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggHash(TestCase.CASE_3_1A);
checkSimpleAggHash(TestCase.CASE_3_2A);
+
+ checkSimpleAggHash(TestCase.CASE_3_1B);
+ checkSimpleAggHash(TestCase.CASE_3_2B);
+
+ checkSimpleAggHash(TestCase.CASE_3_1C);
+ checkSimpleAggHash(TestCase.CASE_3_2C);
+
+ checkSimpleAggHash(TestCase.CASE_3_1D);
+ checkSimpleAggHash(TestCase.CASE_3_2D);
}
/**
@@ -103,6 +120,14 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_5A);
checkSimpleAggWithGroupByHash(TestCase.CASE_6A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_6B);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5C);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_6C);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5D);
}
/**
@@ -115,13 +140,23 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_1);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_2);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_3);
- checkDistinctAggWithGroupBySingle(TestCase.CASE_7_4);
//TODO replace with calls to test methods after https://issues.apache.org/jira/browse/IGNITE-20083 is fixed
assumeRun("checkDistinctAggWithGroupByHash", TestCase.CASE_7_1A);
assumeRun("checkDistinctAggWithGroupByHash", TestCase.CASE_7_2A);
assumeRun("checkDistinctAggWithGroupByHash", TestCase.CASE_7_3A);
- assumeRun("checkDistinctAggWithGroupByHash", TestCase.CASE_7_4A);
+
+ assumeRun("checkDistinctAggWithGroupByHash", TestCase.CASE_7_1B);
+ assumeRun("checkDistinctAggWithGroupByHash", TestCase.CASE_7_2B);
+ assumeRun("checkDistinctAggWithGroupByHash", TestCase.CASE_7_3B);
+
+ assumeRun("checkDistinctAggWithColocatedGroupByHash", TestCase.CASE_7_1C);
+ assumeRun("checkDistinctAggWithColocatedGroupByHash", TestCase.CASE_7_2C);
+ assumeRun("checkDistinctAggWithColocatedGroupByHash", TestCase.CASE_7_3C);
+
+ assumeRun("checkDistinctAggWithColocatedGroupByHash", TestCase.CASE_7_1D);
+ assumeRun("checkDistinctAggWithColocatedGroupByHash", TestCase.CASE_7_2D);
+ assumeRun("checkDistinctAggWithColocatedGroupByHash", TestCase.CASE_7_3D);
}
/**
@@ -136,6 +171,15 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_8_1A);
checkSimpleAggWithGroupByHash(TestCase.CASE_8_2A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2B);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1C);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2C);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1D);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2D);
}
/**
@@ -152,6 +196,16 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11A);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11B);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9C);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10C);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11C);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9D);
}
/**
@@ -162,6 +216,9 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupWithNoAggregateSingle(TestCase.CASE_12);
//TODO replace with calls to test methods after https://issues.apache.org/jira/browse/IGNITE-20083 is resolved
assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_12A);
+ assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_12B);
+ assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_12C);
+ assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_12D);
}
/**
@@ -172,6 +229,9 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupWithNoAggregateSingle(TestCase.CASE_13);
//TODO replace with calls to test methods after https://issues.apache.org/jira/browse/IGNITE-20083 is resolved
assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_13A);
+ assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_13B);
+ assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_13C);
+ assumeRun("checkGroupWithNoAggregateHash", TestCase.CASE_13D);
}
/**
@@ -181,6 +241,7 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void subqueryWithAggregateInWhereClause() throws Exception {
checkSimpleAggSingle(TestCase.CASE_14);
checkSimpleAggHash(TestCase.CASE_14A);
+ checkSimpleAggHash(TestCase.CASE_14B);
}
/**
@@ -190,6 +251,7 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregateInWhereClause() throws Exception {
checkGroupWithNoAggregateSingle(TestCase.CASE_15);
checkGroupWithNoAggregateHash(TestCase.CASE_15A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_15B);
}
/**
@@ -222,6 +284,18 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
),
ArrayUtils.concat(disableRules, additionalRulesToDisable)
);
+ assertPlan(TestCase.CASE_16B,
+ nodeOrAnyChild(isInstanceOf(IgniteSort.class)
+ .and(input(isInstanceOf(IgniteReduceHashAggregate.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteMapHashAggregate.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ))
+ ),
+ ArrayUtils.concat(disableRules, additionalRulesToDisable)
+ );
}
/**
@@ -260,6 +334,22 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
),
disableRules
);
+ assertPlan(TestCase.CASE_17B,
+ hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
+ .and(input(1, isInstanceOf(IgniteReduceHashAggregate.class)
+ .and(input(isInstanceOf(IgniteMapHashAggregate.class)
+ .and(input(isInstanceOf(IgniteLimit.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteSort.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ))
+ ))
+ ))
+ ),
+ disableRules
+ );
}
/**
@@ -274,6 +364,10 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2A, TraitUtils.createCollation(List.of(1, 0)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_2B, TraitUtils.createCollation(List.of(1, 0)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_18_3B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -288,6 +382,10 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1A, TraitUtils.createCollation(List.of(0)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2A, TraitUtils.createCollation(List.of(1)));
checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_20A, TraitUtils.createCollation(List.of(0, 1, 2)));
+
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_1B, TraitUtils.createCollation(List.of(0)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_19_2B, TraitUtils.createCollation(List.of(1)));
+ checkGroupsWithOrderByGroupColumnsHash(TestCase.CASE_20B, TraitUtils.createCollation(List.of(0, 1, 2)));
}
/**
@@ -340,6 +438,7 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
//TODO Replace with uncommented code after https://issues.apache.org/jira/browse/IGNITE-20083 is resolved
assumeRun("", TestCase.CASE_21A);
+ assumeRun("", TestCase.CASE_21B);
/*
assertPlan(TestCase.CASE_21A, nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
.and(input(0, subtreePredicate))
@@ -363,7 +462,7 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
return Objects.equals(aggName, "$SUM0") && a.getArgList().equals(List.of(1));
};
- assertPlan(TestCase.CASE_22, hasChildThat(isInstanceOf(IgniteReduceHashAggregate.class)
+ Predicate<RelNode> nonColocated = hasChildThat(isInstanceOf(IgniteReduceHashAggregate.class)
.and(in -> hasAggregates(countReduce).test(in.getAggregateCalls()))
.and(input(isInstanceOf(IgniteExchange.class)
.and(input(isInstanceOf(IgniteMapHashAggregate.class)
@@ -371,7 +470,23 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
.and(input(isTableScan("TEST")))
)
))
- )), disableRules);
+ ));
+
+ assertPlan(TestCase.CASE_22, nonColocated, disableRules);
+ assertPlan(TestCase.CASE_22A, nonColocated, disableRules);
+
+ Predicate<RelNode> colocated = hasChildThat(isInstanceOf(IgniteReduceHashAggregate.class)
+ .and(in -> hasAggregates(countReduce).test(in.getAggregateCalls()))
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteMapHashAggregate.class)
+ .and(in -> hasAggregates(countMap).test(in.getAggCallList()))
+ .and(input(isTableScan("TEST")))
+ )
+ ))
+ ));
+
+ assertPlan(TestCase.CASE_22B, colocated, disableRules);
+ assertPlan(TestCase.CASE_22C, colocated, disableRules);
}
/**
@@ -382,7 +497,18 @@ public class MapReduceHashAggregatePlannerTest extends AbstractAggregatePlannerT
public void testAvgAgg() {
RuntimeException e = assertThrows(RuntimeException.class,
() -> assertPlan(TestCase.CASE_23, isInstanceOf(IgniteRel.class), disableRules));
+ assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
+
+ e = assertThrows(RuntimeException.class,
+ () -> assertPlan(TestCase.CASE_23A, isInstanceOf(IgniteRel.class), disableRules));
+ assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
+
+ e = assertThrows(RuntimeException.class,
+ () -> assertPlan(TestCase.CASE_23B, isInstanceOf(IgniteRel.class), disableRules));
+ assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
+ e = assertThrows(RuntimeException.class,
+ () -> assertPlan(TestCase.CASE_23C, isInstanceOf(IgniteRel.class), disableRules));
assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceSortAggregatePlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceSortAggregatePlannerTest.java
index d31d8c4ce6..a02267ab11 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceSortAggregatePlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/MapReduceSortAggregatePlannerTest.java
@@ -28,7 +28,6 @@ import java.util.function.Predicate;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.AggregateCall;
-import org.apache.calcite.sql.SqlAggFunction;
import org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin;
import org.apache.ignite.internal.sql.engine.rel.IgniteExchange;
import org.apache.ignite.internal.sql.engine.rel.IgniteLimit;
@@ -62,6 +61,7 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
protected void simpleAggregate() throws Exception {
checkSimpleAggSingle(TestCase.CASE_1);
checkSimpleAggHash(TestCase.CASE_1A);
+ checkSimpleAggHash(TestCase.CASE_1B);
}
/**
@@ -73,11 +73,18 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregate() throws Exception {
checkDistinctAggSingle(TestCase.CASE_2_1);
checkDistinctAggSingle(TestCase.CASE_2_2);
- checkDistinctAggSingle(TestCase.CASE_2_3);
checkDistinctAggHash(TestCase.CASE_2_1A);
checkDistinctAggHash(TestCase.CASE_2_2A);
- checkDistinctAggHash(TestCase.CASE_2_3A);
+
+ checkDistinctAggHash(TestCase.CASE_2_1B);
+ checkDistinctAggHash(TestCase.CASE_2_2B);
+
+ checkDistinctAggHash(TestCase.CASE_2_1C);
+ checkDistinctAggHash(TestCase.CASE_2_2C);
+
+ checkDistinctAggHash(TestCase.CASE_2_1D);
+ checkDistinctAggHash(TestCase.CASE_2_2D);
}
/**
@@ -92,6 +99,15 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggHash(TestCase.CASE_3_1A);
checkSimpleAggHash(TestCase.CASE_3_2A);
+
+ checkSimpleAggHash(TestCase.CASE_3_1B);
+ checkSimpleAggHash(TestCase.CASE_3_2B);
+
+ checkSimpleAggHash(TestCase.CASE_3_1C);
+ checkSimpleAggHash(TestCase.CASE_3_2C);
+
+ checkSimpleAggHash(TestCase.CASE_3_1D);
+ checkSimpleAggHash(TestCase.CASE_3_2D);
}
/**
@@ -104,6 +120,14 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_5A);
checkSimpleAggWithGroupByHash(TestCase.CASE_6A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_6B);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5C);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_6C);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_5D);
}
/**
@@ -116,12 +140,22 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_1);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_2);
checkDistinctAggWithGroupBySingle(TestCase.CASE_7_3);
- checkDistinctAggWithGroupBySingle(TestCase.CASE_7_4);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_1A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_2A);
checkDistinctAggWithGroupByHash(TestCase.CASE_7_3A);
- checkDistinctAggWithGroupByHash(TestCase.CASE_7_4A);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2B);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3B);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1C);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2C);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3C);
+
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_1D);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_2D);
+ checkDistinctAggWithGroupByHash(TestCase.CASE_7_3D);
}
/**
@@ -136,6 +170,15 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkSimpleAggWithGroupByHash(TestCase.CASE_8_1A);
checkSimpleAggWithGroupByHash(TestCase.CASE_8_2A);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1B);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2B);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1C);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2C);
+
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_1D);
+ checkSimpleAggWithGroupByHash(TestCase.CASE_8_2D);
}
/**
@@ -152,6 +195,16 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10A);
checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11A);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10B);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11B);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9C);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_10C);
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_11C);
+
+ checkAggWithGroupByIndexColumnsHash(TestCase.CASE_9D);
}
/**
@@ -162,6 +215,9 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupWithNoAggregateSingle(TestCase.CASE_12);
checkGroupWithNoAggregateHash(TestCase.CASE_12A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_12B);
+ checkGroupWithNoAggregateHash(TestCase.CASE_12C);
+ checkGroupWithNoAggregateHash(TestCase.CASE_12D);
}
/**
@@ -169,33 +225,13 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
*/
@Test
public void distinctWithoutAggregateUseIndex() throws Exception {
- assertPlan(TestCase.CASE_13,
- nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isInstanceOf(IgniteMapSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
- ))
- ),
- disableRules
- );
+ checkGroupWithNoAggregateUseIndexSingle(TestCase.CASE_13);
- assertPlan(TestCase.CASE_13A,
- nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isInstanceOf(IgniteExchange.class)
- .and(input(isInstanceOf(IgniteMapSortAggregate.class)
- .and(not(hasAggregate()))
- .and(hasGroups())
- .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
- ))
- ))
- ),
- disableRules
- );
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13A);
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13B);
+
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13C);
+ checkGroupWithNoAggregateUseIndexHash(TestCase.CASE_13D);
}
/**
@@ -205,6 +241,7 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
public void subqueryWithAggregateInWhereClause() throws Exception {
checkSimpleAggSingle(TestCase.CASE_14);
checkSimpleAggHash(TestCase.CASE_14A);
+ checkSimpleAggHash(TestCase.CASE_14B);
}
/**
@@ -214,6 +251,7 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
public void distinctAggregateInWhereClause() throws Exception {
checkGroupWithNoAggregateSingle(TestCase.CASE_15);
checkGroupWithNoAggregateHash(TestCase.CASE_15A);
+ checkGroupWithNoAggregateHash(TestCase.CASE_15B);
}
/**
@@ -242,6 +280,16 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
),
ArrayUtils.concat(disableRules, additionalRulesToDisable)
);
+ assertPlan(TestCase.CASE_16B,
+ nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteMapSortAggregate.class)
+ .and(input(isIndexScan("TEST", "idx_val0")))
+ ))
+ ))
+ ),
+ ArrayUtils.concat(disableRules, additionalRulesToDisable)
+ );
}
/**
@@ -280,6 +328,22 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
),
disableRules
);
+ assertPlan(TestCase.CASE_17B,
+ hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
+ .and(input(1, isInstanceOf(IgniteReduceSortAggregate.class)
+ .and(input(isInstanceOf(IgniteMapSortAggregate.class)
+ .and(input(isInstanceOf(IgniteLimit.class)
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteSort.class)
+ .and(input(isTableScan("TEST")))
+ ))
+ ))
+ ))
+ ))
+ ))
+ ),
+ disableRules
+ );
}
/**
@@ -294,6 +358,10 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_18_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_18_2A, TraitUtils.createCollation(List.of(1, 0)));
checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_18_3A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_18_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_18_2B, TraitUtils.createCollation(List.of(1, 0)));
+ checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_18_3B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -306,6 +374,9 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_19_1A, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_19_2A, TraitUtils.createCollation(List.of(1, 0)));
+
+ checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_19_1B, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithOrderBySubsetOfGroupColumnsHash(TestCase.CASE_19_2B, TraitUtils.createCollation(List.of(1, 0)));
}
/**
@@ -316,6 +387,7 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
checkGroupsWithGroupBySubsetOfSortColumnsSingle(TestCase.CASE_20, TraitUtils.createCollation(List.of(0, 1)));
checkGroupsWithGroupBySubsetOfSortColumnsHash(TestCase.CASE_20A, TraitUtils.createCollation(List.of(0, 1)));
+ checkGroupsWithGroupBySubsetOfSortColumnsHash(TestCase.CASE_20B, TraitUtils.createCollation(List.of(0, 1)));
}
/**
@@ -368,6 +440,10 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
.and(input(0, subtreePredicate))
.and(input(1, subtreePredicate))
), disableRules);
+ assertPlan(TestCase.CASE_21B, nodeOrAnyChild(isInstanceOf(IgniteMergeJoin.class)
+ .and(input(0, subtreePredicate))
+ .and(input(1, subtreePredicate))
+ ), disableRules);
}
/**
@@ -375,35 +451,46 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
*/
@Test
public void twoPhaseCountAgg() throws Exception {
- Predicate<AggregateCall> countMap = (a) -> {
- SqlAggFunction aggName = a.getAggregation();
- return Objects.equals(aggName.getName(), "COUNT") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countMap = (a) ->
+ Objects.equals(a.getAggregation().getName(), "COUNT") && a.getArgList().equals(List.of(1));
- Predicate<AggregateCall> countReduce = (a) -> {
- SqlAggFunction aggName = a.getAggregation();
- return Objects.equals(aggName.getName(), "$SUM0") && a.getArgList().equals(List.of(1));
- };
+ Predicate<AggregateCall> countReduce = (a) ->
+ Objects.equals(a.getAggregation().getName(), "$SUM0") && a.getArgList().equals(List.of(1));
- assertPlan(TestCase.CASE_22, hasChildThat(isInstanceOf(IgniteReduceSortAggregate.class)
+ Predicate<RelNode> nonColocated = hasChildThat(isInstanceOf(IgniteReduceSortAggregate.class)
.and(in -> hasAggregates(countReduce).test(in.getAggregateCalls()))
.and(input(isInstanceOf(IgniteExchange.class)
.and(input(isInstanceOf(IgniteMapSortAggregate.class)
.and(in -> hasAggregates(countMap).test(in.getAggCallList()))
)
))
- )), disableRules);
+ ));
+
+ assertPlan(TestCase.CASE_22, nonColocated, disableRules);
+ assertPlan(TestCase.CASE_22A, nonColocated, disableRules);
+ assertPlan(TestCase.CASE_22B, nonColocated, disableRules);
+ assertPlan(TestCase.CASE_22C, nonColocated, disableRules);
}
/**
- * Validates that AVG can not be used as two phase mode.
- * Should be fixed with TODO https://issues.apache.org/jira/browse/IGNITE-20009
+ * Validates that AVG can not be used as two phase mode. Should be fixed with TODO https://issues.apache.org/jira/browse/IGNITE-20009
*/
@Test
public void testAvgAgg() {
RuntimeException e = assertThrows(RuntimeException.class,
() -> assertPlan(TestCase.CASE_23, isInstanceOf(IgniteRel.class), disableRules));
+ assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
+ e = assertThrows(RuntimeException.class,
+ () -> assertPlan(TestCase.CASE_23A, isInstanceOf(IgniteRel.class), disableRules));
+ assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
+
+ e = assertThrows(RuntimeException.class,
+ () -> assertPlan(TestCase.CASE_23B, isInstanceOf(IgniteRel.class), disableRules));
+ assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
+
+ e = assertThrows(RuntimeException.class,
+ () -> assertPlan(TestCase.CASE_23C, isInstanceOf(IgniteRel.class), disableRules));
assertThat(e.getMessage(), containsString("There are not enough rules to produce a node with desired properties"));
}
@@ -627,6 +714,38 @@ public class MapReduceSortAggregatePlannerTest extends AbstractAggregatePlannerT
);
}
+ private void checkGroupWithNoAggregateUseIndexSingle(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isInstanceOf(IgniteMapSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ),
+ disableRules
+ );
+ }
+
+ private void checkGroupWithNoAggregateUseIndexHash(TestCase testCase) throws Exception {
+ assertPlan(testCase,
+ nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(IgniteMapSortAggregate.class)
+ .and(not(hasAggregate()))
+ .and(hasGroups())
+ .and(input(isIndexScan("TEST", "idx_grp0_grp1")))
+ ))
+ ))
+ ),
+ disableRules
+ );
+ }
+
private void checkGroupsWithOrderBySubsetOfGroupColumnsSingle(TestCase testCase, RelCollation collation) throws Exception {
assertPlan(testCase,
nodeOrAnyChild(isInstanceOf(IgniteReduceSortAggregate.class)
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SetOpPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SetOpPlannerTest.java
index 71307b59bd..519f8b7dad 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SetOpPlannerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SetOpPlannerTest.java
@@ -68,7 +68,10 @@ public class SetOpPlannerTest extends AbstractPlannerTest {
createTable("HASH_TBL1", IgniteDistributions.hash(List.of(0))),
createTable("AFFINITY_TBL2", IgniteDistributions.affinity(0, nextTableId(), DEFAULT_ZONE_ID)),
createTable("AFFINITY_TBL3", IgniteDistributions.affinity(1, nextTableId(), DEFAULT_ZONE_ID)),
- createTable("AFFINITY_TBL4", IgniteDistributions.affinity(0, nextTableId(), DEFAULT_ZONE_ID + 1))
+ createTable("AFFINITY_TBL4", IgniteDistributions.affinity(0, nextTableId(), DEFAULT_ZONE_ID + 1)),
+ createTable("IDENTITY_TBL1", IgniteDistributions.identity(0)),
+ createTable("IDENTITY_TBL2", IgniteDistributions.identity(0)),
+ createTable("IDENTITY_TBL3", IgniteDistributions.identity(1))
);
}
@@ -229,6 +232,25 @@ public class SetOpPlannerTest extends AbstractPlannerTest {
);
}
+ /**
+ * Tests SET operations on two tables with single and identity distribution.
+ *
+ * <p>{@link Type#SINGLETON Single} distribution cannot be colocated with identity distribution.
+ *
+ * @throws Exception If failed.
+ */
+ @ParameterizedTest
+ @EnumSource
+ public void testSetOpSingleAndIdentity(SetOp setOp) throws Exception {
+ String sql = "SELECT * FROM single_tbl1 "
+ + setOp(setOp)
+ + "SELECT * FROM identity_tbl1 ";
+
+ assertPlan(sql, publicSchema, isInstanceOf(setOp.colocated)
+ .and(hasDistribution(IgniteDistributions.single()))
+ .and(input(0, isTableScan("single_tbl1")))
+ .and(input(1, hasChildThat(isTableScan("identity_tbl1")))));
+ }
/**
* Tests SET operations on tables with the same affinity distribution.
@@ -479,6 +501,23 @@ public class SetOpPlannerTest extends AbstractPlannerTest {
.and(input(3, isTableScan("affinity_tbl2")))
))
);
+
+ sql = "SELECT * FROM random_tbl1 "
+ + setOpAll(setOp)
+ + "SELECT * FROM random_tbl2 "
+ + setOpAll(setOp)
+ + "SELECT * FROM identity_tbl1 "
+ + setOpAll(setOp)
+ + "SELECT * FROM identity_tbl2 ";
+
+ assertPlan(sql, publicSchema, isInstanceOf(setOp.reduce).and(IgniteSetOp::all)
+ .and(hasChildThat(isInstanceOf(setOp.map)
+ .and(input(0, isTableScan("random_tbl1")))
+ .and(input(1, isTableScan("random_tbl2")))
+ .and(input(2, isTableScan("identity_tbl1")))
+ .and(input(3, isTableScan("identity_tbl2")))
+ ))
+ );
}
/**
@@ -502,6 +541,157 @@ public class SetOpPlannerTest extends AbstractPlannerTest {
.and(input(2, isTableScan("affinity_tbl1")))
))
);
+
+ sql = "SELECT * FROM random_tbl1 "
+ + setOpAll(setOp)
+ + "SELECT * FROM random_tbl2 "
+ + setOp(setOp)
+ + "SELECT * FROM identity_tbl1 ";
+
+ assertPlan(sql, publicSchema, isInstanceOf(setOp.reduce).and(n -> !n.all())
+ .and(hasChildThat(isInstanceOf(setOp.map)
+ .and(input(0, isTableScan("random_tbl1")))
+ .and(input(1, isTableScan("random_tbl2")))
+ .and(input(2, isTableScan("identity_tbl1")))
+ ))
+ );
+ }
+
+ /**
+ * Tests SET operations on tables with the same identity distribution.
+ *
+ * <p>The operation is considered colocated because the tables are
+ * compared against the corresponding collocation columns.
+ *
+ * @throws Exception If failed.
+ */
+ @ParameterizedTest
+ @EnumSource
+ public void testSetOpIdentity(SetOp setOp) throws Exception {
+ String sql = "SELECT * FROM identity_tbl1 "
+ + setOp(setOp)
+ + "SELECT * FROM identity_tbl2 ";
+
+ assertPlan(sql, publicSchema, isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(setOp.colocated)
+ .and(hasDistribution(IgniteDistributions.identity(0)))
+ .and(input(0, isTableScan("identity_tbl1")))
+ .and(input(1, isTableScan("identity_tbl2")))
+ ))
+ );
+ }
+
+ /**
+ * Tests SET operations on two tables with identity and broadcast distribution.
+ *
+ * <p>The operation is considered colocated because {@link Type#BROADCAST_DISTRIBUTED broadcast}
+ * distribution satisfies any other distribution.
+ *
+ * @throws Exception If failed.
+ */
+ @ParameterizedTest
+ @EnumSource
+ public void testSetOpIdentityAndBroadcast(SetOp setOp) throws Exception {
+ String sql = "SELECT * FROM identity_tbl1 "
+ + setOp(setOp)
+ + "SELECT * FROM broadcast_tbl1 ";
+
+ assertPlan(sql, publicSchema, isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(setOp.colocated)
+ .and(hasDistribution(IgniteDistributions.identity(0)))
+ .and(input(0, isTableScan("identity_tbl1")))
+ .and(input(1, isInstanceOf(IgniteTrimExchange.class)
+ .and(input(isTableScan("broadcast_tbl1")))
+ ))
+ ))
+ );
+ }
+
+ /**
+ * Tests SET operations on tables with different identity distribution.
+ *
+ * <p>Different identity distributions cannot be colocated.
+ *
+ * @throws Exception If failed.
+ */
+ @ParameterizedTest
+ @EnumSource
+ public void testSetOpNonColocatedIdentity(SetOp setOp) throws Exception {
+ String sql = "SELECT * FROM identity_tbl1 "
+ + setOp(setOp)
+ + "SELECT * FROM identity_tbl3 ";
+
+ assertPlan(sql, publicSchema, isInstanceOf(setOp.reduce)
+ .and(hasChildThat(isInstanceOf(setOp.map)
+ .and(input(0, isTableScan("identity_tbl1")))
+ .and(input(1, isTableScan("identity_tbl3")))
+ ))
+ );
+ }
+
+ /**
+ * Tests SET operations on two tables with affinity and identity distribution.
+ *
+ * <p>Affinity distribution can not be colocated with identity distribution.
+ *
+ * @throws Exception If failed.
+ */
+ @ParameterizedTest
+ @EnumSource
+ public void testSetOpIdentityAndAffinity(SetOp setOp) throws Exception {
+ String sql = "SELECT * FROM identity_tbl1 "
+ + setOp(setOp)
+ + "SELECT * FROM affinity_tbl1 ";
+
+
+ assertPlan(sql, publicSchema, isInstanceOf(setOp.reduce)
+ .and(hasChildThat(isInstanceOf(setOp.map)
+ .and(input(0, isTableScan("identity_tbl1")))
+ .and(input(1, isTableScan("affinity_tbl1")))
+ ))
+ );
+
+ sql = "SELECT * FROM affinity_tbl1 "
+ + setOp(setOp)
+ + "SELECT * FROM identity_tbl1 ";
+
+
+ assertPlan(sql, publicSchema, isInstanceOf(setOp.reduce)
+ .and(hasChildThat(isInstanceOf(setOp.map)
+ .and(input(0, isTableScan("affinity_tbl1")))
+ .and(input(1, isTableScan("identity_tbl1")))
+ ))
+ );
+ }
+
+ /**
+ * Tests two SET operations (nested and outer) on two tables with the same identity distribution.
+ *
+ * <p>Nested operation is considered colocated because the tables are compared against the corresponding collocation columns.
+ * Outer operation considered colocated because the result of nested operation must have the distribution of one of the participating
+ * tables.
+ *
+ * @throws Exception If failed.
+ */
+ @ParameterizedTest
+ @EnumSource
+ public void testSetOpIdentityNested(SetOp setOp) throws Exception {
+ String sql = "SELECT * FROM identity_tbl2 " + setOp(setOp) + "("
+ + " SELECT * FROM identity_tbl1 "
+ + setOp(setOp)
+ + " SELECT * FROM identity_tbl2"
+ + ")";
+
+ assertPlan(sql, publicSchema, isInstanceOf(IgniteExchange.class)
+ .and(input(isInstanceOf(setOp.colocated)
+ .and(input(0, isTableScan("identity_tbl2")))
+ .and(input(1, isInstanceOf(setOp.colocated)
+ .and(input(0, isTableScan("identity_tbl1")))
+ .and(input(1, isTableScan("identity_tbl2")))
+ ))
+ )),
+ "MinusMergeRule", "IntersectMergeRule"
+ );
}
private String setOp(SetOp setOp) {
diff --git a/modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/CursorUtils.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/CursorUtils.java
similarity index 100%
rename from modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/CursorUtils.java
rename to modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/CursorUtils.java
diff --git a/modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java
similarity index 100%
rename from modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java
rename to modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java
diff --git a/modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/NativeTypeWrapper.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/NativeTypeWrapper.java
similarity index 100%
rename from modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/NativeTypeWrapper.java
rename to modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/NativeTypeWrapper.java
diff --git a/modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
similarity index 100%
rename from modules/runner/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
rename to modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java