This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a commit to branch ignite-18208
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit 0aa0268750413a21b0a92e226dc7d134fb77eb4a
Author: amashenkov <[email protected]>
AuthorDate: Tue Feb 14 14:30:05 2023 +0300

    Merge aggregates tests.
---
 .../planner/AbstractAggregatePlannerTest.java      |  56 +-
 .../planner/AggregateDistinctPlannerTest.java      | 122 -----
 .../sql/engine/planner/AggregatePlannerTest.java   | 569 +++++++++++++++------
 .../engine/planner/HashAggregatePlannerTest.java   | 129 -----
 .../engine/planner/SortAggregatePlannerTest.java   | 251 ---------
 5 files changed, 469 insertions(+), 658 deletions(-)

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 547320af33..53e1bb1574 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
@@ -18,7 +18,20 @@
 package org.apache.ignite.internal.sql.engine.planner;
 
 import java.util.UUID;
+import java.util.function.Supplier;
+import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.sql.SqlExplainLevel;
+import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedAggregateBase;
+import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedHashAggregate;
+import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedSortAggregate;
+import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapAggregateBase;
+import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapHashAggregate;
+import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapSortAggregate;
+import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceAggregateBase;
+import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceHashAggregate;
+import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceSortAggregate;
 import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem;
@@ -26,7 +39,7 @@ import 
org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem;
 /**
  * Base class for further planner test implementations.
  */
-public class AbstractAggregatePlannerTest extends AbstractPlannerTest {
+public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest 
{
     /**
      * Creates table with broadcast distribution.
      *
@@ -70,4 +83,45 @@ public class AbstractAggregatePlannerTest extends 
AbstractPlannerTest {
                 IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID)
         );
     }
+
+    protected static Supplier<String> invalidPlanErrorMessage(IgniteRel phys) {
+        return () -> "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES);
+    }
+
+    enum AggregateAlgorithm {
+        SORT(
+                IgniteColocatedSortAggregate.class,
+                IgniteMapSortAggregate.class,
+                IgniteReduceSortAggregate.class,
+                "MapReduceHashAggregateConverterRule",
+                "ColocatedHashAggregateConverterRule"
+        ),
+
+        HASH(
+                IgniteColocatedHashAggregate.class,
+                IgniteMapHashAggregate.class,
+                IgniteReduceHashAggregate.class,
+                "MapReduceSortAggregateConverterRule",
+                "ColocatedSortAggregateConverterRule"
+        );
+
+        public final Class<? extends IgniteColocatedAggregateBase> colocated;
+
+        public final Class<? extends IgniteMapAggregateBase> map;
+
+        public final Class<? extends IgniteReduceAggregateBase> reduce;
+
+        public final String[] rulesToDisable;
+
+        AggregateAlgorithm(
+                Class<? extends IgniteColocatedAggregateBase> colocated,
+                Class<? extends IgniteMapAggregateBase> map,
+                Class<? extends IgniteReduceAggregateBase> reduce,
+                String... rulesToDisable) {
+            this.colocated = colocated;
+            this.map = map;
+            this.reduce = reduce;
+            this.rulesToDisable = rulesToDisable;
+        }
+    }
 }
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregateDistinctPlannerTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregateDistinctPlannerTest.java
deleted file mode 100644
index bc0118fa8f..0000000000
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AggregateDistinctPlannerTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.util.CollectionUtils.nullOrEmpty;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.sql.SqlExplainLevel;
-import org.apache.ignite.internal.sql.engine.rel.IgniteAggregate;
-import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
-import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
-import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedAggregateBase;
-import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedHashAggregate;
-import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedSortAggregate;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapAggregateBase;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapHashAggregate;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapSortAggregate;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceAggregateBase;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceHashAggregate;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceSortAggregate;
-import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.EnumSource;
-
-/**
- * AggregateDistinctPlannerTest.
- * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
- */
-public class AggregateDistinctPlannerTest extends AbstractAggregatePlannerTest 
{
-    /**
-     * MapReduceDistinctWithIndex.
-     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
-     *
-     * @throws Exception If failed.
-     */
-    @ParameterizedTest
-    @EnumSource
-    public void mapReduceDistinctWithIndex(AggregateAlgorithm algo) throws 
Exception {
-        TestTable tbl = createAffinityTable("TEST").addIndex("val0_val1", 1, 
2);
-
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-
-        publicSchema.addTable(tbl);
-
-        String sql = "SELECT DISTINCT val0, val1 FROM test";
-
-        IgniteRel phys = physicalPlan(
-                sql,
-                publicSchema,
-                algo.rulesToDisable
-        );
-
-        IgniteAggregate mapAgg = findFirstNode(phys, byClass(algo.map));
-        IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, 
byClass(algo.reduce));
-
-        assertNotNull(rdcAgg, "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES));
-        assertNotNull(mapAgg, "Invalid plan\n" + RelOptUtil.toString(phys));
-
-        assertTrue(nullOrEmpty(rdcAgg.getAggregateCalls()), "Invalid plan\n" + 
RelOptUtil.toString(phys));
-        assertTrue(nullOrEmpty(mapAgg.getAggCallList()), "Invalid plan\n" + 
RelOptUtil.toString(phys));
-
-        if (algo == AggregateAlgorithm.SORT) {
-            assertNotNull(findFirstNode(phys, byClass(IgniteIndexScan.class)));
-        }
-    }
-
-    enum AggregateAlgorithm {
-        SORT(
-                IgniteColocatedSortAggregate.class,
-                IgniteMapSortAggregate.class,
-                IgniteReduceSortAggregate.class,
-                "ColocatedHashAggregateConverterRule",
-                "MapReduceHashAggregateConverterRule",
-                "ColocatedSortAggregateConverterRule"
-        ),
-
-        HASH(
-                IgniteColocatedHashAggregate.class,
-                IgniteMapHashAggregate.class,
-                IgniteReduceHashAggregate.class,
-                "ColocatedSortAggregateConverterRule",
-                "MapReduceSortAggregateConverterRule",
-                "ColocatedHashAggregateConverterRule"
-        );
-
-        public final Class<? extends IgniteColocatedAggregateBase> single;
-
-        public final Class<? extends IgniteMapAggregateBase> map;
-
-        public final Class<? extends IgniteReduceAggregateBase> reduce;
-
-        public final String[] rulesToDisable;
-
-        AggregateAlgorithm(
-                Class<? extends IgniteColocatedAggregateBase> single,
-                Class<? extends IgniteMapAggregateBase> map,
-                Class<? extends IgniteReduceAggregateBase> reduce,
-                String... rulesToDisable) {
-            this.single = single;
-            this.map = map;
-            this.reduce = reduce;
-            this.rulesToDisable = rulesToDisable;
-        }
-    }
-}
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 0c882f1c4d..209bf79f5f 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
@@ -19,19 +19,21 @@ package org.apache.ignite.internal.sql.engine.planner;
 
 import static org.apache.ignite.internal.util.ArrayUtils.concat;
 import static org.apache.ignite.internal.util.CollectionUtils.first;
+import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.math.BigDecimal;
-import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
-import java.util.function.Predicate;
 import java.util.stream.Stream;
 import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelFieldCollation;
 import org.apache.calcite.rel.SingleRel;
 import org.apache.calcite.rel.core.Aggregate;
 import org.apache.calcite.rel.core.AggregateCall;
@@ -40,24 +42,26 @@ import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.sql.SqlExplainLevel;
 import org.apache.calcite.sql.fun.SqlAvgAggFunction;
+import org.apache.calcite.sql.fun.SqlCountAggFunction;
 import org.apache.ignite.internal.sql.engine.rel.IgniteAggregate;
+import 
org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin;
 import org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan;
+import org.apache.ignite.internal.sql.engine.rel.IgniteLimit;
 import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
 import org.apache.ignite.internal.sql.engine.rel.IgniteSort;
+import org.apache.ignite.internal.sql.engine.rel.IgniteTableScan;
 import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedAggregateBase;
-import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedHashAggregate;
 import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedSortAggregate;
 import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapAggregateBase;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapHashAggregate;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapSortAggregate;
 import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceAggregateBase;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceHashAggregate;
 import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceSortAggregate;
 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.apache.ignite.internal.sql.engine.trait.TraitUtils;
-import org.apache.ignite.internal.util.Pair;
+import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
+import org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem;
+import org.apache.ignite.internal.util.ArrayUtils;
 import org.hamcrest.core.IsInstanceOf;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -95,10 +99,10 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
 
         IgniteColocatedAggregateBase agg = findFirstNode(phys, 
byClass(algo.colocated));
 
-        assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
+        assertNotNull(agg, invalidPlanErrorMessage(phys));
 
         assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
+                invalidPlanErrorMessage(phys).get(),
                 first(agg.getAggCallList()).getAggregation(),
                 IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
 
@@ -122,7 +126,7 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
 
         publicSchema.addTable(tbl);
 
-        String sql = "SELECT AVG(val0) FILTER(WHERE val1 > 10) FROM test GROUP 
BY grp0";
+        String sql = "SELECT AVG(val0) FROM test GROUP BY grp0";
 
         IgniteRel phys = physicalPlan(
                 sql,
@@ -132,10 +136,9 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
 
         IgniteColocatedAggregateBase agg = findFirstNode(phys, 
byClass(algo.colocated));
 
-        assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
+        assertNotNull(agg, invalidPlanErrorMessage(phys));
 
-        assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
+        assertThat(invalidPlanErrorMessage(phys).get(),
                 first(agg.getAggCallList()).getAggregation(),
                 IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
 
@@ -144,48 +147,38 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
         }
     }
 
-    /**
-     * MapReduceGroupBy.
-     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
-     *
-     * @throws Exception If failed.
-     */
     @ParameterizedTest
-    @EnumSource
-    public void mapReduceGroupBy(AggregateAlgorithm algo) throws Exception {
-        TestTable tbl = createAffinityTable("TEST");
-
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-
-        publicSchema.addTable(tbl);
-
-        String sql = "SELECT AVG(val0) FILTER (WHERE val1 > 10) FROM test 
GROUP BY grp1, grp0";
-
-        IgniteRel phys = physicalPlan(
-                sql,
-                publicSchema,
-                algo.rulesToDisable
+    @EnumSource(AggregateAlgorithm.class)
+    public void colocated(AggregateAlgorithm algo) throws Exception {
+        IgniteSchema schema = createSchema(
+                createTable(
+                        "EMP", IgniteDistributions.affinity(1, 
UUID.randomUUID(), DEFAULT_ZONE_ID),
+                        "EMPID", Integer.class,
+                        "DEPTID", Integer.class,
+                        "NAME", String.class,
+                        "SALARY", Integer.class
+                ).addIndex("DEPTID", 1),
+                createTable(
+                        "DEPT", IgniteDistributions.affinity(0, 
UUID.randomUUID(), DEFAULT_ZONE_ID),
+                        "DEPTID", Integer.class,
+                        "NAME", String.class
+                ).addIndex("DEPTID", 0)
         );
 
-        IgniteMapAggregateBase mapAgg = findFirstNode(phys, byClass(algo.map));
-        IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, 
byClass(algo.reduce));
-
-        assertNotNull(rdcAgg, "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES));
-        assertNotNull(mapAgg, "Invalid plan\n" + RelOptUtil.toString(phys));
+        String sql = "SELECT SUM(SALARY) FROM emp GROUP BY deptid";
 
-        assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
-                first(rdcAgg.getAggregateCalls()).getAggregation(),
-                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
+        assertPlan(sql, schema, hasChildThat(isInstanceOf(algo.colocated)
+                        .and(hasDistribution(IgniteDistributions.affinity(0, 
UUID.randomUUID(), DEFAULT_ZONE_ID)))),
+                algo.rulesToDisable);
 
-        assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
-                first(mapAgg.getAggCallList()).getAggregation(),
-                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
+        sql = "SELECT dept.deptid, agg.cnt "
+                + "FROM dept "
+                + "JOIN (SELECT deptid, COUNT(*) AS cnt FROM emp GROUP BY 
deptid) AS agg ON dept.deptid = agg.deptid";
 
-        if (algo == AggregateAlgorithm.SORT) {
-            assertNotNull(findFirstNode(phys, byClass(IgniteSort.class)));
-        }
+        assertPlan(sql, schema, hasChildThat(isInstanceOf(Join.class)
+                        .and(input(0, 
hasDistribution(IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID))))
+                        .and(input(1, 
hasDistribution(IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID))))),
+                algo.rulesToDisable);
     }
 
     /**
@@ -202,7 +195,7 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
 
         publicSchema.addTable(tbl);
 
-        String sql = "SELECT AVG(val0), grp0 FROM TEST GROUP BY grp0 UNION ALL 
SELECT val0, grp0 FROM test";
+        String sql = "SELECT AVG(val0), grp0 FROM test GROUP BY grp0 UNION ALL 
SELECT val0, grp0 FROM test";
 
         IgniteRel phys = physicalPlan(
                 sql,
@@ -218,8 +211,7 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
         phys = physicalPlan(
                 sql,
                 publicSchema,
-                concat(algo.rulesToDisable, "SortSingleAggregateConverterRule",
-                        "HashSingleAggregateConverterRule")
+                concat(algo.rulesToDisable)
         );
 
         IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, 
byClass(algo.reduce));
@@ -227,6 +219,38 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
         assertEquals(IgniteDistributions.single(), 
TraitUtils.distribution(rdcAgg));
     }
 
+    /**
+     * CollationPermuteSingle.
+     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void collationPermuteSingle() throws Exception {
+        TestTable tbl = createAffinityTable("TEST").addIndex("grp0_1", 3, 4);
+
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+
+        publicSchema.addTable(tbl);
+
+        String sql = "SELECT MIN(val0) FROM test GROUP BY grp1, grp0";
+
+        IgniteRel phys = physicalPlan(
+                sql,
+                publicSchema,
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+
+        IgniteColocatedSortAggregate agg = findFirstNode(phys, 
byClass(IgniteColocatedSortAggregate.class));
+
+        assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
+
+        assertNull(
+                findFirstNode(phys, byClass(IgniteSort.class)),
+                "Invalid plan\n" + RelOptUtil.toString(phys)
+        );
+    }
+
     /**
      * ExpandDistinctAggregates.
      * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
@@ -259,7 +283,7 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
                         .anyMatch(n -> ((Aggregate) 
n).getAggCallList().stream()
                                 .anyMatch(AggregateCall::isDistinct)
                         ),
-                "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES)
+                invalidPlanErrorMessage(phys)
         );
 
         assertNotNull(
@@ -271,23 +295,95 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
         assertTrue(
                 findNodes(phys, byClass(algo.reduce)).stream()
                         .allMatch(n -> ((IgniteReduceAggregateBase) 
n).getAggregateCalls().isEmpty()),
-                "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES)
+                invalidPlanErrorMessage(phys)
         );
 
         assertTrue(
                 findNodes(phys, byClass(algo.map)).stream()
                         .allMatch(n -> ((Aggregate) 
n).getAggCallList().isEmpty()),
-                "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES)
+                invalidPlanErrorMessage(phys)
         );
 
         // Check the second aggregation step contains accumulators.
         assertTrue(
                 findNodes(phys, byClass(algo.colocated)).stream()
                         .noneMatch(n -> ((Aggregate) 
n).getAggCallList().isEmpty()),
-                "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES)
+                invalidPlanErrorMessage(phys)
         );
     }
 
+    /**
+     * MapReduceGroupBy.
+     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
+     *
+     * @throws Exception If failed.
+     */
+    @ParameterizedTest
+    @EnumSource
+    public void mapReduceGroupBy(AggregateAlgorithm algo) throws Exception {
+        TestTable tbl = createAffinityTable("TEST");
+
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+
+        publicSchema.addTable(tbl);
+
+        String sql = "SELECT AVG(val0) FILTER (WHERE val1 > 10) FROM test 
GROUP BY grp1, grp0";
+
+        IgniteRel phys = physicalPlan(
+                sql,
+                publicSchema,
+                algo.rulesToDisable
+        );
+
+        IgniteMapAggregateBase mapAgg = findFirstNode(phys, byClass(algo.map));
+        IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, 
byClass(algo.reduce));
+
+        assertNotNull(rdcAgg, invalidPlanErrorMessage(phys));
+        assertNotNull(mapAgg, invalidPlanErrorMessage(phys));
+
+        assertThat(invalidPlanErrorMessage(phys).get(),
+                first(rdcAgg.getAggregateCalls()).getAggregation(),
+                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
+
+        assertThat(invalidPlanErrorMessage(phys).get(),
+                first(mapAgg.getAggCallList()).getAggregation(),
+                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
+
+        if (algo == AggregateAlgorithm.SORT) {
+            assertNotNull(findFirstNode(phys, byClass(IgniteSort.class)));
+        }
+    }
+
+    /**
+     * Check that map aggregate does not contain distinct accumulator and can 
be planned at all.
+     *
+     * @throws Exception If failed.
+     */
+    @ParameterizedTest
+    @EnumSource
+    public void mapAggregateWithoutDistinctAcc(AggregateAlgorithm algo) throws 
Exception {
+        TestTable tbl = createAffinityTable("TEST");
+
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+
+        publicSchema.addTable(tbl);
+
+        checkDistinctInMapAggNode("SELECT COUNT(*) FROM test", publicSchema, 
algo);
+        checkDistinctInMapAggNode("SELECT COUNT(DISTINCT val0) FROM test", 
publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT AVG(DISTINCT val0) FROM test", 
publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT SUM(DISTINCT val0) FROM test", 
publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT MIN(DISTINCT val0) FROM test", 
publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT MAX(DISTINCT val0) FROM test", 
publicSchema, algo);
+
+        checkDistinctInMapAggNode("SELECT COUNT(DISTINCT val0) FROM test GROUP 
BY val1, grp0", publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT val1, COUNT(DISTINCT val0) as v1 
FROM test GROUP BY val1", publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT AVG(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT SUM(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT MIN(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT MAX(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema, algo);
+        checkDistinctInMapAggNode("SELECT val0 FROM test WHERE VAL1 = 
ANY(SELECT DISTINCT val1 FROM test)", publicSchema, algo);
+    }
+
     @ParameterizedTest
     @MethodSource("provideAlgoAndDistribution")
     public void singleSumTypes(AggregateAlgorithm algo, IgniteDistribution 
distr) throws Exception {
@@ -328,7 +424,7 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
 
         SingleRel agg = findFirstNode(phys, byClass(cls));
 
-        assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
+        assertNotNull(agg, invalidPlanErrorMessage(phys));
 
         RelDataType rowTypes = agg.getRowType();
 
@@ -343,67 +439,271 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
         assertEquals(tf.createJavaType(Double.class), 
rowTypes.getFieldList().get(7).getType());
     }
 
+
+    /**
+     * CollationPermuteMapReduce.
+     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void collationPermuteMapReduce() throws Exception {
+        TestTable tbl = createAffinityTable("TEST").addIndex("grp0_1", 3, 4);
+
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+
+        publicSchema.addTable(tbl);
+
+        String sql = "SELECT MIN(val0) FROM test GROUP BY grp1, grp0";
+
+        IgniteRel phys = physicalPlan(
+                sql,
+                publicSchema,
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+
+        IgniteReduceSortAggregate agg = findFirstNode(phys, 
byClass(IgniteReduceSortAggregate.class));
+
+        assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
+
+        assertNull(
+                findFirstNode(phys, byClass(IgniteSort.class)),
+                "Invalid plan\n" + RelOptUtil.toString(phys)
+        );
+    }
+
+    @Test
+    public void testEmptyCollationPassThroughLimit() throws Exception {
+        IgniteSchema publicSchema = createSchema(
+                createTable("TEST", IgniteDistributions.single(), "A", 
Integer.class));
+
+        assertPlan("SELECT (SELECT test.a FROM test t ORDER BY 1 LIMIT 1) FROM 
test", publicSchema,
+                hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
+                        .and(input(1, 
hasChildThat(isInstanceOf(IgniteLimit.class)
+                                .and(input(isInstanceOf(IgniteSort.class)))))))
+        );
+    }
+
+    @Test
+    public void testCollationPassThrough() throws Exception {
+        IgniteSchema publicSchema = createSchema(
+                createTable("TEST", IgniteDistributions.single(), "A", 
Integer.class, "B", Integer.class));
+
+        // Sort order equals to grouping set.
+        assertPlan("SELECT a, b, COUNT(*) FROM test GROUP BY a, b ORDER BY a, 
b", publicSchema,
+                isInstanceOf(IgniteAggregate.class)
+                        .and(input(isInstanceOf(IgniteSort.class)
+                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
+                                .and(input(isTableScan("TEST"))))),
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+
+        // Sort order equals to grouping set (permuted collation).
+        assertPlan("SELECT a, b, COUNT(*) FROM test GROUP BY a, b ORDER BY b, 
a", publicSchema,
+                isInstanceOf(IgniteAggregate.class)
+                        .and(input(isInstanceOf(IgniteSort.class)
+                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(1, 0))))
+                                .and(input(isTableScan("TEST"))))),
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+
+        // Sort order is a subset of grouping set.
+        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
a", publicSchema,
+                isInstanceOf(IgniteAggregate.class)
+                        .and(input(isInstanceOf(IgniteSort.class)
+                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
+                                .and(input(isTableScan("TEST"))))),
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+
+        // Sort order is a subset of grouping set (permuted collation).
+        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
b", publicSchema,
+                isInstanceOf(IgniteAggregate.class)
+                        .and(input(isInstanceOf(IgniteSort.class)
+                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(1, 0))))
+                                .and(input(isTableScan("TEST"))))),
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+
+        // Sort order is a superset of grouping set (additional sorting 
required).
+        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
a, b, cnt", publicSchema,
+                isInstanceOf(IgniteSort.class)
+                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1, 2))))
+                        .and(input(isInstanceOf(IgniteAggregate.class)
+                                .and(input(isInstanceOf(IgniteSort.class)
+                                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
+                                        .and(input(isTableScan("TEST"))))))),
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+
+        // Sort order is not equals to grouping set (additional sorting 
required).
+        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
cnt, b", publicSchema,
+                isInstanceOf(IgniteSort.class)
+                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(2, 1))))
+                        .and(input(isInstanceOf(IgniteAggregate.class)
+                                .and(input(isInstanceOf(IgniteSort.class)
+                                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
+                                        .and(input(isTableScan("TEST"))))))),
+                AggregateAlgorithm.SORT.rulesToDisable
+        );
+    }
+
+    /**
+     * Test simple query with aggregate and no groups.
+     */
     @ParameterizedTest
-    @EnumSource(AggregateAlgorithm.class)
-    public void colocated(AggregateAlgorithm algo) throws Exception {
-        IgniteSchema schema = createSchema(
-                createTable(
-                        "EMP", IgniteDistributions.affinity(1, 
UUID.randomUUID(), DEFAULT_ZONE_ID),
-                        "EMPID", Integer.class,
-                        "DEPTID", Integer.class,
-                        "NAME", String.class,
-                        "SALARY", Integer.class
-                ).addIndex("DEPTID", 1),
-                createTable(
-                        "DEPT", IgniteDistributions.affinity(0, 
UUID.randomUUID(), DEFAULT_ZONE_ID),
-                        "DEPTID", Integer.class,
-                        "NAME", String.class
-                ).addIndex("DEPTID", 0)
+    @EnumSource
+    public void noGroupByAggregate(AggregateAlgorithm algo) throws Exception {
+        TestTable tbl = createAffinityTable("TEST").addIndex("val0_val1", 1, 
2);
+
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+
+        publicSchema.addTable(tbl);
+
+        String sqlCount = "SELECT COUNT(*) FROM test";
+
+        IgniteRel phys = physicalPlan(
+                sqlCount,
+                publicSchema,
+                algo.rulesToDisable
         );
+        assertNotNull(phys);
 
-        String sql = "SELECT SUM(SALARY) FROM emp GROUP BY deptid";
+        IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, 
byClass(algo.reduce));
+        IgniteMapAggregateBase mapAgg = findFirstNode(phys, byClass(algo.map));
 
-        assertPlan(sql, schema, hasChildThat(isInstanceOf(algo.colocated)
-                        .and(hasDistribution(IgniteDistributions.affinity(0, 
UUID.randomUUID(), DEFAULT_ZONE_ID)))),
-                algo.rulesToDisable);
+        assertNotNull(rdcAgg, invalidPlanErrorMessage(phys));
+        assertNotNull(mapAgg, invalidPlanErrorMessage(phys));
 
-        sql = "SELECT dept.deptid, agg.cnt "
-                + "FROM dept "
-                + "JOIN (SELECT deptid, COUNT(*) AS cnt FROM emp GROUP BY 
deptid) AS agg ON dept.deptid = agg.deptid";
+        assertThat(
+                invalidPlanErrorMessage(phys).get(),
+                first(rdcAgg.getAggregateCalls()).getAggregation(),
+                IsInstanceOf.instanceOf(SqlCountAggFunction.class));
 
-        assertPlan(sql, schema, hasChildThat(isInstanceOf(Join.class)
-                        .and(input(0, 
hasDistribution(IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID))))
-                        .and(input(1, 
hasDistribution(IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID))))),
-                algo.rulesToDisable);
+        assertThat(
+                invalidPlanErrorMessage(phys).get(),
+                first(mapAgg.getAggCallList()).getAggregation(),
+                IsInstanceOf.instanceOf(SqlCountAggFunction.class));
     }
 
     /**
-     * Check that map aggregate does not contain distinct accumulator and can 
be planned at all.
+     * Test subquery with aggregate.
      *
      * @throws Exception If failed.
      */
-    @Test
-    public void mapAggregateWithoutDistinctAcc() throws Exception {
-        TestTable tbl = createAffinityTable("TEST");
+    @ParameterizedTest
+    @EnumSource
+    public void subqueryWithAggregate(AggregateAlgorithm algo) throws 
Exception {
+        IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
+
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+
+        createTable(publicSchema,
+                "EMPS",
+                new RelDataTypeFactory.Builder(f)
+                        .add("ID", f.createJavaType(Integer.class))
+                        .add("NAME", f.createJavaType(String.class))
+                        .add("SALARY", f.createJavaType(Double.class))
+                        .build(),
+                IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID)
+        );
+
+        String sql = "SELECT * FROM emps WHERE emps.salary = (SELECT 
AVG(emps.salary) FROM emps)";
+
+        IgniteRel phys = physicalPlan(
+                sql,
+                publicSchema,
+                algo.rulesToDisable
+        );
+        assertNotNull(phys);
+
+        IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, 
byClass(algo.reduce));
+        IgniteMapAggregateBase mapAgg = findFirstNode(phys, byClass(algo.map));
+
+        assertNotNull(rdcAgg, invalidPlanErrorMessage(phys));
+        assertNotNull(mapAgg, invalidPlanErrorMessage(phys));
+
+        assertThat(
+                invalidPlanErrorMessage(phys).get(),
+                first(rdcAgg.getAggregateCalls()).getAggregation(),
+                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
+
+        assertThat(
+                invalidPlanErrorMessage(phys).get(),
+                first(mapAgg.getAggCallList()).getAggregation(),
+                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
+    }
+
+    /**
+     * Check distinct aggregate with no aggregate function.
+     *
+     * @throws Exception If failed.
+     */
+    @ParameterizedTest
+    @EnumSource
+    public void mapReduceDistinctWithIndex(AggregateAlgorithm algo) throws 
Exception {
+        TestTable tbl = createAffinityTable("TEST").addIndex("val0_val1", 1, 
2);
 
         IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
 
         publicSchema.addTable(tbl);
 
-        checkDistinctInMapAggNode("SELECT COUNT(*) FROM test", publicSchema);
-        checkDistinctInMapAggNode("SELECT COUNT(DISTINCT val0) FROM test", 
publicSchema);
-        checkDistinctInMapAggNode("SELECT AVG(DISTINCT val0) FROM test", 
publicSchema);
-        checkDistinctInMapAggNode("SELECT SUM(DISTINCT val0) FROM test", 
publicSchema);
-        checkDistinctInMapAggNode("SELECT MIN(DISTINCT val0) FROM test", 
publicSchema);
-        checkDistinctInMapAggNode("SELECT MAX(DISTINCT val0) FROM test", 
publicSchema);
-
-        checkDistinctInMapAggNode("SELECT COUNT(DISTINCT val0) FROM test GROUP 
BY val1, grp0", publicSchema);
-        checkDistinctInMapAggNode("SELECT val1, COUNT(DISTINCT val0) as v1 
FROM test GROUP BY val1", publicSchema);
-        checkDistinctInMapAggNode("SELECT AVG(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema);
-        checkDistinctInMapAggNode("SELECT SUM(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema);
-        checkDistinctInMapAggNode("SELECT MIN(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema);
-        checkDistinctInMapAggNode("SELECT MAX(DISTINCT val0) FROM test GROUP 
BY val1", publicSchema);
-        checkDistinctInMapAggNode("SELECT val0 FROM test WHERE VAL1 = 
ANY(SELECT DISTINCT val1 FROM test)", publicSchema);
+        String sql = "SELECT DISTINCT val0, val1 FROM test";
+
+        IgniteRel phys = physicalPlan(
+                sql,
+                publicSchema,
+                algo.rulesToDisable
+        );
+
+        IgniteAggregate mapAgg = findFirstNode(phys, byClass(algo.map));
+        IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, 
byClass(algo.reduce));
+
+        assertNotNull(rdcAgg, invalidPlanErrorMessage(phys));
+        assertNotNull(mapAgg, invalidPlanErrorMessage(phys));
+
+        assertTrue(nullOrEmpty(rdcAgg.getAggregateCalls()), 
invalidPlanErrorMessage(phys));
+        assertTrue(nullOrEmpty(mapAgg.getAggCallList()), 
invalidPlanErrorMessage(phys));
+
+        if (algo == AggregateAlgorithm.SORT) {
+            assertNotNull(findFirstNode(phys, byClass(IgniteIndexScan.class)));
+        }
+    }
+
+    /**
+     * Checks if already sorted input exist and involved 
[Map|Reduce]SortAggregate.
+     */
+    @ParameterizedTest
+    @EnumSource
+    public void testNoSortAppendingWithCorrectCollation(AggregateAlgorithm 
algo) throws Exception {
+        RelFieldCollation coll = new RelFieldCollation(1, 
RelFieldCollation.Direction.DESCENDING);
+
+        TestTable tbl = 
createAffinityTable("TEST").addIndex(RelCollations.of(coll), "val0Idx");
+
+        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
+
+        publicSchema.addTable(tbl);
+
+        String sql = "SELECT ID FROM test WHERE VAL0 IN (SELECT VAL0 FROM 
test)";
+
+        IgniteRel phys = physicalPlan(
+                sql,
+                publicSchema,
+                ArrayUtils.concat(
+                        algo.rulesToDisable,
+                        "NestedLoopJoinConverter",
+                        "CorrelatedNestedLoopJoin",
+                        "CorrelateToNestedLoopRule"
+                )
+        );
+
+        if (algo == AggregateAlgorithm.SORT) {
+            assertNull(findFirstNode(phys, byClass(IgniteSort.class)), 
invalidPlanErrorMessage(phys));
+            assertNull(findFirstNode(phys, byClass(IgniteTableScan.class)), 
invalidPlanErrorMessage(phys));
+        } else {
+            assertNotNull(findFirstNode(phys, byClass(IgniteSort.class)), 
invalidPlanErrorMessage(phys));
+            assertNotNull(findFirstNode(phys, byClass(IgniteTableScan.class)), 
invalidPlanErrorMessage(phys));
+        }
     }
 
     /**
@@ -411,29 +711,23 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
      *
      * @param sql Request string.
      * @param publicSchema Schema.
+     * @param algo
      * @throws Exception If failed.
      */
-    private void checkDistinctInMapAggNode(String sql, IgniteSchema 
publicSchema) throws Exception {
-        List<Pair<String[], Predicate<IgniteRel>>> disabledRules = List.of(
-                new Pair<>(new String[]{"ColocatedHashAggregateConverterRule", 
"ColocatedSortAggregateConverterRule",
-                        "MapReduceSortAggregateConverterRule"}, node -> 
!findNodes(node, byClass(IgniteMapAggregateBase.class)).isEmpty()),
-                new Pair<>(new String[]{"MapReduceHashAggregateConverterRule", 
"MapReduceSortAggregateConverterRule",
-                        "ColocatedHashAggregateConverterRule"}, node -> true),
-                new Pair<>(new String[]{"MapReduceHashAggregateConverterRule", 
"MapReduceSortAggregateConverterRule",
-                        "ColocatedSortAggregateConverterRule"}, node -> true)
-        );
-
-        for (Pair<String[], Predicate<IgniteRel>> rules : disabledRules) {
-            IgniteRel phys = physicalPlan(sql, publicSchema, rules.getFirst());
+    private void checkDistinctInMapAggNode(String sql, IgniteSchema 
publicSchema, AggregateAlgorithm algo) throws Exception {
+        IgniteRel phys = physicalPlan(
+                sql,
+                publicSchema,
+                concat(algo.rulesToDisable, 
"ColocatedSortAggregateConverterRule", "ColocatedHashAggregateConverterRule"));
 
-            assertTrue(rules.getSecond().test(phys), "[" + sql + "] Failed 
with disabled rules: " + Arrays.toString(rules.getFirst()));
+        assertFalse(findNodes(phys, 
byClass(IgniteMapAggregateBase.class)).isEmpty(),
+                invalidPlanErrorMessage(phys));
 
-            assertFalse(findNodes(phys, 
byClass(IgniteMapAggregateBase.class)).stream()
-                            .anyMatch(n -> ((Aggregate) 
n).getAggCallList().stream()
-                                    .anyMatch(AggregateCall::isDistinct)
-                            ),
-                    "Invalid plan\n" + RelOptUtil.toString(phys, 
SqlExplainLevel.ALL_ATTRIBUTES));
-        }
+        assertFalse(findNodes(phys, 
byClass(IgniteMapAggregateBase.class)).stream()
+                        .anyMatch(n -> ((Aggregate) 
n).getAggCallList().stream()
+                                .anyMatch(AggregateCall::isDistinct)
+                        ),
+                invalidPlanErrorMessage(phys));
     }
 
     private static Stream<Arguments> provideAlgoAndDistribution() {
@@ -444,39 +738,4 @@ public class AggregatePlannerTest extends 
AbstractAggregatePlannerTest {
                 Arguments.of(AggregateAlgorithm.HASH, 
IgniteDistributions.random())
         );
     }
-
-    enum AggregateAlgorithm {
-        SORT(
-                IgniteColocatedSortAggregate.class,
-                IgniteMapSortAggregate.class,
-                IgniteReduceSortAggregate.class,
-                "ColocatedHashAggregateConverterRule", 
"MapReduceHashAggregateConverterRule"
-        ),
-
-        HASH(
-                IgniteColocatedHashAggregate.class,
-                IgniteMapHashAggregate.class,
-                IgniteReduceHashAggregate.class,
-                "ColocatedSortAggregateConverterRule", 
"MapReduceSortAggregateConverterRule"
-        );
-
-        public final Class<? extends IgniteColocatedAggregateBase> colocated;
-
-        public final Class<? extends IgniteMapAggregateBase> map;
-
-        public final Class<? extends IgniteReduceAggregateBase> reduce;
-
-        public final String[] rulesToDisable;
-
-        AggregateAlgorithm(
-                Class<? extends IgniteColocatedAggregateBase> colocated,
-                Class<? extends IgniteMapAggregateBase> map,
-                Class<? extends IgniteReduceAggregateBase> reduce,
-                String... rulesToDisable) {
-            this.colocated = colocated;
-            this.map = map;
-            this.reduce = reduce;
-            this.rulesToDisable = rulesToDisable;
-        }
-    }
 }
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashAggregatePlannerTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashAggregatePlannerTest.java
deleted file mode 100644
index 51b86e455c..0000000000
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/HashAggregatePlannerTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.util.CollectionUtils.first;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import java.util.UUID;
-import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.sql.fun.SqlAvgAggFunction;
-import org.apache.calcite.sql.fun.SqlCountAggFunction;
-import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapHashAggregate;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceHashAggregate;
-import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
-import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem;
-import org.hamcrest.core.IsInstanceOf;
-import org.junit.jupiter.api.Test;
-
-/**
- * HashAggregatePlannerTest.
- * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
- */
-public class HashAggregatePlannerTest extends AbstractAggregatePlannerTest {
-    /**
-     * SubqueryWithAggregate.
-     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
-     *
-     * @throws Exception If failed.
-     */
-    @Test
-    public void subqueryWithAggregate() throws Exception {
-        IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
-
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-
-        createTable(publicSchema,
-                "EMPS",
-                new RelDataTypeFactory.Builder(f)
-                        .add("ID", f.createJavaType(Integer.class))
-                        .add("NAME", f.createJavaType(String.class))
-                        .add("SALARY", f.createJavaType(Double.class))
-                        .build(),
-                IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID)
-        );
-
-        String sql = "SELECT /*+ 
DISABLE_RULE('MapReduceSortAggregateConverterRule', 
'ColocatedHashAggregateConverterRule', "
-                + "'ColocatedSortAggregateConverterRule') */ * FROM emps WHERE 
emps.salary = (SELECT AVG(emps.salary) FROM emps)";
-
-        IgniteRel phys = physicalPlan(
-                sql,
-                publicSchema
-        );
-
-        assertNotNull(phys);
-
-        IgniteReduceHashAggregate rdcAgg = findFirstNode(phys, 
byClass(IgniteReduceHashAggregate.class));
-        IgniteMapHashAggregate mapAgg = findFirstNode(phys, 
byClass(IgniteMapHashAggregate.class));
-
-        assertNotNull(rdcAgg, "Invalid plan\n" + RelOptUtil.toString(phys));
-        assertNotNull(mapAgg, "Invalid plan\n" + RelOptUtil.toString(phys));
-
-        assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
-                first(rdcAgg.getAggregateCalls()).getAggregation(),
-                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
-
-        assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
-                first(mapAgg.getAggCallList()).getAggregation(),
-                IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
-    }
-
-    /**
-     * NoGroupByAggregate.
-     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
-     */
-    @Test
-    public void noGroupByAggregate() throws Exception {
-        TestTable tbl = createAffinityTable("TEST").addIndex("val0_val1", 1, 
2);
-
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-
-        publicSchema.addTable(tbl);
-
-        String sqlCount = "SELECT /*+ 
DISABLE_RULE('MapReduceSortAggregateConverterRule', 
'ColocatedHashAggregateConverterRule', "
-                + "'ColocatedSortAggregateConverterRule') */ COUNT(*) FROM 
test";
-
-        IgniteRel phys = physicalPlan(
-                sqlCount,
-                publicSchema
-        );
-
-        IgniteMapHashAggregate mapAgg = findFirstNode(phys, 
byClass(IgniteMapHashAggregate.class));
-        IgniteReduceHashAggregate rdcAgg = findFirstNode(phys, 
byClass(IgniteReduceHashAggregate.class));
-
-        assertNotNull(rdcAgg, "Invalid plan\n" + RelOptUtil.toString(phys));
-        assertNotNull(mapAgg, "Invalid plan\n" + RelOptUtil.toString(phys));
-
-        assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
-                first(rdcAgg.getAggregateCalls()).getAggregation(),
-                IsInstanceOf.instanceOf(SqlCountAggFunction.class));
-
-        assertThat(
-                "Invalid plan\n" + RelOptUtil.toString(phys),
-                first(mapAgg.getAggCallList()).getAggregation(),
-                IsInstanceOf.instanceOf(SqlCountAggFunction.class));
-    }
-}
diff --git 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortAggregatePlannerTest.java
 
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortAggregatePlannerTest.java
deleted file mode 100644
index 8aed84b631..0000000000
--- 
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/SortAggregatePlannerTest.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.util.List;
-import java.util.UUID;
-import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.RelCollations;
-import org.apache.calcite.rel.RelFieldCollation;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.ignite.internal.sql.engine.rel.IgniteAggregate;
-import 
org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin;
-import org.apache.ignite.internal.sql.engine.rel.IgniteLimit;
-import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
-import org.apache.ignite.internal.sql.engine.rel.IgniteSort;
-import org.apache.ignite.internal.sql.engine.rel.IgniteTableScan;
-import 
org.apache.ignite.internal.sql.engine.rel.agg.IgniteColocatedSortAggregate;
-import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceSortAggregate;
-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.apache.ignite.internal.sql.engine.trait.TraitUtils;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem;
-import org.apache.ignite.internal.util.ArrayUtils;
-import org.junit.jupiter.api.Test;
-
-/**
- * SortAggregatePlannerTest.
- * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
- */
-public class SortAggregatePlannerTest extends AbstractAggregatePlannerTest {
-    /** Hash aggregate rules. */
-    private static final String[] HASH_AGG_RULES =
-            {"ColocatedHashAggregateConverterRule", 
"MapReduceHashAggregateConverterRule"};
-
-    /** Checks if already sorted input exist and involved 
[Map|Reduce]SortAggregate. */
-    @Test
-    public void testNoSortAppendingWithCorrectCollation() throws Exception {
-        RelFieldCollation coll = new RelFieldCollation(1, 
RelFieldCollation.Direction.DESCENDING);
-
-        TestTable tbl = 
createAffinityTable("TEST").addIndex(RelCollations.of(coll), "val0Idx");
-
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-
-        publicSchema.addTable(tbl);
-
-        String sql = "SELECT ID FROM test WHERE VAL0 IN (SELECT VAL0 FROM 
test)";
-
-        IgniteRel phys = physicalPlan(
-                sql,
-                publicSchema,
-                ArrayUtils.concat(
-                        HASH_AGG_RULES,
-                        "NestedLoopJoinConverter",
-                        "CorrelatedNestedLoopJoin",
-                        "CorrelateToNestedLoopRule"
-                )
-        );
-
-        assertTrue(
-                findFirstNode(phys, byClass(IgniteSort.class)) == null
-                        && findFirstNode(phys, byClass(IgniteTableScan.class)) 
== null,
-                "Invalid plan\n" + RelOptUtil.toString(phys)
-        );
-    }
-
-    /**
-     * CollationPermuteSingle.
-     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
-     *
-     * @throws Exception If failed.
-     */
-    @Test
-    public void collationPermuteSingle() throws Exception {
-        IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
-
-        TestTable tbl = new TestTable(
-                new RelDataTypeFactory.Builder(f)
-                        .add("ID", f.createJavaType(Integer.class))
-                        .add("VAL0", f.createJavaType(Integer.class))
-                        .add("VAL1", f.createJavaType(Integer.class))
-                        .add("GRP0", f.createJavaType(Integer.class))
-                        .add("GRP1", f.createJavaType(Integer.class))
-                        .build(), "TEST") {
-
-            @Override
-            public IgniteDistribution distribution() {
-                return IgniteDistributions.broadcast();
-            }
-        }
-                .addIndex("grp0_1", 3, 4);
-
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-
-        publicSchema.addTable(tbl);
-
-        String sql = "SELECT MIN(val0) FROM test GROUP BY grp1, grp0";
-
-        IgniteRel phys = physicalPlan(
-                sql,
-                publicSchema,
-                HASH_AGG_RULES
-        );
-
-        IgniteColocatedSortAggregate agg = findFirstNode(phys, 
byClass(IgniteColocatedSortAggregate.class));
-
-        assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
-
-        assertNull(
-                findFirstNode(phys, byClass(IgniteSort.class)),
-                "Invalid plan\n" + RelOptUtil.toString(phys)
-        );
-    }
-
-    /**
-     * CollationPermuteMapReduce.
-     * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
-     *
-     * @throws Exception If failed.
-     */
-    @Test
-    public void collationPermuteMapReduce() throws Exception {
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-        IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
-
-        createTable(publicSchema,
-                "TEST",
-                new RelDataTypeFactory.Builder(f)
-                        .add("ID", f.createJavaType(Integer.class))
-                        .add("VAL0", f.createJavaType(Integer.class))
-                        .add("VAL1", f.createJavaType(Integer.class))
-                        .add("GRP0", f.createJavaType(Integer.class))
-                        .add("GRP1", f.createJavaType(Integer.class))
-                        .build(),
-                IgniteDistributions.affinity(0, UUID.randomUUID(), 
DEFAULT_ZONE_ID)
-        ).addIndex("grp0_1", 3, 4);
-
-        String sql = "SELECT MIN(val0) FROM test GROUP BY grp1, grp0";
-
-        IgniteRel phys = physicalPlan(
-                sql,
-                publicSchema,
-                HASH_AGG_RULES
-        );
-
-        IgniteReduceSortAggregate agg = findFirstNode(phys, 
byClass(IgniteReduceSortAggregate.class));
-
-        assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
-
-        assertNull(
-                findFirstNode(phys, byClass(IgniteSort.class)),
-                "Invalid plan\n" + RelOptUtil.toString(phys)
-        );
-    }
-
-    @Test
-    public void testEmptyCollationPassThroughLimit() throws Exception {
-        IgniteSchema publicSchema = createSchema(
-                createTable("TEST", IgniteDistributions.single(), "A", 
Integer.class));
-
-        assertPlan("SELECT (SELECT test.a FROM test t ORDER BY 1 LIMIT 1) FROM 
test", publicSchema,
-                hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
-                        .and(input(1, 
hasChildThat(isInstanceOf(IgniteLimit.class)
-                                .and(input(isInstanceOf(IgniteSort.class)))))))
-        );
-    }
-
-    @Test
-    public void testCollationPassThrough() throws Exception {
-        IgniteSchema publicSchema = createSchema(
-                createTable("TEST", IgniteDistributions.single(), "A", 
Integer.class, "B", Integer.class));
-
-        // Sort order equals to grouping set.
-        assertPlan("SELECT a, b, COUNT(*) FROM test GROUP BY a, b ORDER BY a, 
b", publicSchema,
-                isInstanceOf(IgniteAggregate.class)
-                        .and(input(isInstanceOf(IgniteSort.class)
-                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
-                                .and(input(isTableScan("TEST"))))),
-                HASH_AGG_RULES
-        );
-
-        // Sort order equals to grouping set (permuted collation).
-        assertPlan("SELECT a, b, COUNT(*) FROM test GROUP BY a, b ORDER BY b, 
a", publicSchema,
-                isInstanceOf(IgniteAggregate.class)
-                        .and(input(isInstanceOf(IgniteSort.class)
-                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(1, 0))))
-                                .and(input(isTableScan("TEST"))))),
-                HASH_AGG_RULES
-        );
-
-        // Sort order is a subset of grouping set.
-        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
a", publicSchema,
-                isInstanceOf(IgniteAggregate.class)
-                        .and(input(isInstanceOf(IgniteSort.class)
-                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
-                                .and(input(isTableScan("TEST"))))),
-                HASH_AGG_RULES
-        );
-
-        // Sort order is a subset of grouping set (permuted collation).
-        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
b", publicSchema,
-                isInstanceOf(IgniteAggregate.class)
-                        .and(input(isInstanceOf(IgniteSort.class)
-                                .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(1, 0))))
-                                .and(input(isTableScan("TEST"))))),
-                HASH_AGG_RULES
-        );
-
-        // Sort order is a superset of grouping set (additional sorting 
required).
-        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
a, b, cnt", publicSchema,
-                isInstanceOf(IgniteSort.class)
-                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1, 2))))
-                        .and(input(isInstanceOf(IgniteAggregate.class)
-                                .and(input(isInstanceOf(IgniteSort.class)
-                                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
-                                        .and(input(isTableScan("TEST"))))))),
-                HASH_AGG_RULES
-        );
-
-        // Sort order is not equals to grouping set (additional sorting 
required).
-        assertPlan("SELECT a, b, COUNT(*) cnt FROM test GROUP BY a, b ORDER BY 
cnt, b", publicSchema,
-                isInstanceOf(IgniteSort.class)
-                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(2, 1))))
-                        .and(input(isInstanceOf(IgniteAggregate.class)
-                                .and(input(isInstanceOf(IgniteSort.class)
-                                        .and(s -> 
s.collation().equals(TraitUtils.createCollation(List.of(0, 1))))
-                                        .and(input(isTableScan("TEST"))))))),
-                HASH_AGG_RULES
-        );
-    }
-}

Reply via email to