blob: 1945dabaed39ae0c48a84592b6542fc187af24b7 [file] [log] [blame]
/*
* 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.calcite.test.enumerable;
import org.apache.calcite.adapter.enumerable.EnumerableRules;
import org.apache.calcite.adapter.java.ReflectiveSchema;
import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.config.Lex;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.test.CalciteAssert;
import org.apache.calcite.test.schemata.hr.HrSchema;
import org.junit.jupiter.api.Test;
import java.util.function.Consumer;
/** Test for
* {@link org.apache.calcite.adapter.enumerable.EnumerableSortedAggregate}. */
public class EnumerableSortedAggregateTest {
@Test void sortedAgg() {
tester(false, new HrSchema())
.query("select deptno, "
+ "max(salary) as max_salary, count(name) as num_employee "
+ "from emps group by deptno")
.withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
planner.removeRule(EnumerableRules.ENUMERABLE_AGGREGATE_RULE);
planner.addRule(EnumerableRules.ENUMERABLE_SORTED_AGGREGATE_RULE);
})
.explainContains(
"EnumerableSortedAggregate(group=[{1}], max_salary=[MAX($3)], num_employee=[COUNT($2)])\n"
+ " EnumerableSort(sort0=[$1], dir0=[ASC])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsOrdered(
"deptno=10; max_salary=11500.0; num_employee=3",
"deptno=20; max_salary=8000.0; num_employee=1");
}
@Test void sortedAggTwoGroupKeys() {
tester(false, new HrSchema())
.query(
"select deptno, commission, "
+ "max(salary) as max_salary, count(name) as num_employee "
+ "from emps group by deptno, commission")
.withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
planner.removeRule(EnumerableRules.ENUMERABLE_AGGREGATE_RULE);
planner.addRule(EnumerableRules.ENUMERABLE_SORTED_AGGREGATE_RULE);
})
.explainContains(
"EnumerableSortedAggregate(group=[{1, 4}], max_salary=[MAX($3)], num_employee=[COUNT($2)])\n"
+ " EnumerableSort(sort0=[$1], sort1=[$4], dir0=[ASC], dir1=[ASC])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsOrdered(
"deptno=10; commission=250; max_salary=11500.0; num_employee=1",
"deptno=10; commission=1000; max_salary=10000.0; num_employee=1",
"deptno=10; commission=null; max_salary=7000.0; num_employee=1",
"deptno=20; commission=500; max_salary=8000.0; num_employee=1");
}
// Outer sort is expected to be pushed through aggregation.
@Test void sortedAggGroupbyXOrderbyX() {
tester(false, new HrSchema())
.query(
"select deptno, "
+ "max(salary) as max_salary, count(name) as num_employee "
+ "from emps group by deptno order by deptno")
.withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
planner.removeRule(EnumerableRules.ENUMERABLE_AGGREGATE_RULE);
planner.addRule(EnumerableRules.ENUMERABLE_SORTED_AGGREGATE_RULE);
})
.explainContains(
"EnumerableSortedAggregate(group=[{1}], max_salary=[MAX($3)], num_employee=[COUNT($2)])\n"
+ " EnumerableSort(sort0=[$1], dir0=[ASC])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsOrdered(
"deptno=10; max_salary=11500.0; num_employee=3",
"deptno=20; max_salary=8000.0; num_employee=1");
}
// Outer sort is not expected to be pushed through aggregation.
@Test void sortedAggGroupbyXOrderbyY() {
tester(false, new HrSchema())
.query(
"select deptno, "
+ "max(salary) as max_salary, count(name) as num_employee "
+ "from emps group by deptno order by num_employee desc")
.withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
planner.removeRule(EnumerableRules.ENUMERABLE_AGGREGATE_RULE);
planner.addRule(EnumerableRules.ENUMERABLE_SORTED_AGGREGATE_RULE);
})
.explainContains(
"EnumerableSort(sort0=[$2], dir0=[DESC])\n"
+ " EnumerableSortedAggregate(group=[{1}], max_salary=[MAX($3)], num_employee=[COUNT($2)])\n"
+ " EnumerableSort(sort0=[$1], dir0=[ASC])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsOrdered(
"deptno=10; max_salary=11500.0; num_employee=3",
"deptno=20; max_salary=8000.0; num_employee=1");
}
@Test void sortedAggNullValueInSortedGroupByKeys() {
tester(false, new HrSchema())
.query(
"select commission, "
+ "count(deptno) as num_dept "
+ "from emps group by commission")
.withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
planner.removeRule(EnumerableRules.ENUMERABLE_AGGREGATE_RULE);
planner.addRule(EnumerableRules.ENUMERABLE_SORTED_AGGREGATE_RULE);
})
.explainContains(
"EnumerableSortedAggregate(group=[{4}], num_dept=[COUNT()])\n"
+ " EnumerableSort(sort0=[$4], dir0=[ASC])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsOrdered(
"commission=250; num_dept=1",
"commission=500; num_dept=1",
"commission=1000; num_dept=1",
"commission=null; num_dept=1");
}
private CalciteAssert.AssertThat tester(boolean forceDecorrelate,
Object schema) {
return CalciteAssert.that()
.with(CalciteConnectionProperty.LEX, Lex.JAVA)
.with(CalciteConnectionProperty.FORCE_DECORRELATE, forceDecorrelate)
.withSchema("s", new ReflectiveSchema(schema));
}
}