This is an automated email from the ASF dual-hosted git repository. amashenkov pushed a commit to branch ignite-21580 in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit 9f9af65ff67234e0690152dc0d49b0c527ef82f8 Author: amashenkov <andrey.mashen...@gmail.com> AuthorDate: Thu Apr 4 14:00:34 2024 +0300 Add TPC-H planner test --- .../planner/AbstractAggregatePlannerTest.java | 30 ------ .../sql/engine/planner/AbstractPlannerTest.java | 36 ++++++- .../sql/engine/planner/TpchQueryPlannerTest.java | 110 +++++++++++++++++++++ 3 files changed, 144 insertions(+), 32 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 288e662f77..c8ac94287d 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 @@ -29,10 +29,8 @@ import java.util.Objects; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.UnaryOperator; -import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.AggregateCall; -import org.apache.calcite.util.ImmutableBitSet; import org.apache.ignite.internal.sql.engine.framework.TestBuilders.TableBuilder; import org.apache.ignite.internal.sql.engine.rel.IgniteAggregate; import org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceAggregateBase; @@ -40,7 +38,6 @@ 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.apache.ignite.internal.sql.engine.trait.TraitUtils; import org.apache.ignite.internal.type.NativeTypes; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterAll; @@ -1066,31 +1063,4 @@ public abstract class AbstractAggregatePlannerTest extends AbstractPlannerTest { return true; }; } - - <T> Predicate<T> hasGroupSets(Function<T, List<ImmutableBitSet>> groupSets, int groupKey) { - return (node) -> { - List<ImmutableBitSet> allGroupSets = groupSets.apply(node); - ImmutableBitSet firstGroupSet = allGroupSets.get(0); - - boolean groupSetsMatch = allGroupSets.equals(List.of(ImmutableBitSet.of(groupKey))); - boolean groupSetMatches = firstGroupSet.equals(ImmutableBitSet.of(groupKey)); - - return groupSetMatches && groupSetsMatch; - }; - } - - <T> Predicate<T> hasNoGroupSets(Function<T, List<ImmutableBitSet>> groupSets) { - return (node) -> { - List<ImmutableBitSet> allGroupSets = groupSets.apply(node); - List<ImmutableBitSet> emptyGroupSets = List.of(ImmutableBitSet.of()); - return emptyGroupSets.equals(allGroupSets); - }; - } - - <T extends RelNode> Predicate<T> hasCollation(RelCollation expected) { - return (node) -> { - RelCollation collation = TraitUtils.collation(node); - return expected.equals(collation); - }; - } } diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java index 0bd79a619c..55b02e4101 100644 --- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java +++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/AbstractPlannerTest.java @@ -54,6 +54,7 @@ import org.apache.calcite.plan.RelOptTable; import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.AbstractRelNode; +import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelDistribution; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.RelVisitor; @@ -102,6 +103,7 @@ import org.apache.ignite.internal.sql.engine.schema.IgniteTable; import org.apache.ignite.internal.sql.engine.schema.TableDescriptor; 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.util.BaseQueryContext; import org.apache.ignite.internal.sql.engine.util.Commons; @@ -113,8 +115,7 @@ import org.apache.ignite.internal.util.Pair; import org.jetbrains.annotations.Nullable; /** - * AbstractPlannerTest. - * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859 + * Base test class for planner tests. */ public abstract class AbstractPlannerTest extends IgniteAbstractTest { protected static final String[] DISABLE_KEY_VALUE_MODIFY_RULES = { @@ -135,6 +136,37 @@ public abstract class AbstractPlannerTest extends IgniteAbstractTest { /** Last error message. */ String lastErrorMsg; + <T> Predicate<T> hasGroupSets(Function<T, List<ImmutableBitSet>> groupSets, int groupKey) { + return hasGroupSets(groupSets, List.of(groupKey)); + } + + <T> Predicate<T> hasGroupSets(Function<T, List<ImmutableBitSet>> groupSets, List<Integer> groupKeys) { + return (node) -> { + List<ImmutableBitSet> allGroupSets = groupSets.apply(node); + ImmutableBitSet firstGroupSet = allGroupSets.get(0); + + boolean groupSetsMatch = allGroupSets.equals(List.of(ImmutableBitSet.of(groupKeys))); + boolean groupSetMatches = firstGroupSet.equals(ImmutableBitSet.of(groupKeys)); + + return groupSetMatches && groupSetsMatch; + }; + } + + <T> Predicate<T> hasNoGroupSets(Function<T, List<ImmutableBitSet>> groupSets) { + return (node) -> { + List<ImmutableBitSet> allGroupSets = groupSets.apply(node); + List<ImmutableBitSet> emptyGroupSets = List.of(ImmutableBitSet.of()); + return emptyGroupSets.equals(allGroupSets); + }; + } + + <T extends RelNode> Predicate<T> hasCollation(RelCollation expected) { + return (node) -> { + RelCollation collation = TraitUtils.collation(node); + return expected.equals(collation); + }; + } + interface TestVisitor { void visit(RelNode node, int ordinal, RelNode parent); } diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/TpchQueryPlannerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/TpchQueryPlannerTest.java new file mode 100644 index 0000000000..519d6829ba --- /dev/null +++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/TpchQueryPlannerTest.java @@ -0,0 +1,110 @@ +/* + * 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 java.util.List; +import org.apache.ignite.internal.sql.engine.framework.TestBuilders; +import org.apache.ignite.internal.sql.engine.rel.IgniteExchange; +import org.apache.ignite.internal.sql.engine.rel.IgniteSort; +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.IgniteIndex.Collation; +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.trait.TraitUtils; +import org.apache.ignite.internal.type.NativeTypes; +import org.junit.jupiter.api.Test; + +/** + * Planner tests for TPC-H queries. + */ +public class TpchQueryPlannerTest extends AbstractPlannerTest { + @Test + public void tpchTest_q1() throws Exception { + IgniteSchema publicSchema = createSchema(TestBuilders.table() + .name("LINEITEM") + .addKeyColumn("L_ORDERKEY", NativeTypes.INT32) + .addColumn("L_PARTKEY", NativeTypes.INT32) + .addColumn("L_SUPPKEY", NativeTypes.INT32) + .addKeyColumn("L_LINENUMBER", NativeTypes.INT32) + .addColumn("L_QUANTITY", NativeTypes.decimalOf(15, 2)) + .addColumn("L_EXTENDEDPRICE", NativeTypes.decimalOf(15, 2)) + .addColumn("L_DISCOUNT", NativeTypes.decimalOf(15, 2)) + .addColumn("L_TAX", NativeTypes.decimalOf(15, 2)) + .addColumn("L_RETURNFLAG", NativeTypes.stringOf(1)) + .addColumn("L_LINESTATUS", NativeTypes.stringOf(1)) + .addColumn("L_SHIPDATE", NativeTypes.DATE) + .addColumn("L_COMMITDATE", NativeTypes.DATE) + .addColumn("L_RECEIPTDATE", NativeTypes.DATE) + .addColumn("L_SHIPINSTRUCT", NativeTypes.stringOf(25)) + .addColumn("L_SHIPMODE", NativeTypes.stringOf(10)) + .addColumn("L_COMMENT", NativeTypes.STRING) + .distribution(IgniteDistributions.hash(List.of(0, 3))) + .hashIndex() + .name("LINEITEM_PK") + .addColumn("L_ORDERKEY") + .addColumn("L_LINENUMBER") + .end() + .sortedIndex() + .name("IDX_SHIPDATE") + .addColumn("L_SHIPDATE", Collation.ASC_NULLS_LAST) + .end() + .build()); + + String sql = "" + + "SELECT\n" + + "/*+ DISABLE_RULE(" + + "'ColocatedHashAggregateConverterRule'," + + "'ColocatedSortAggregateConverterRule'" + + "'MapReduceSortAggregateConverterRule'" + + ") */" + + " l_returnflag,\n" + + " l_linestatus,\n" + + " sum(l_quantity) AS sum_qty,\n" + + " sum(l_extendedprice) AS sum_base_price,\n" + + " sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,\n" + + " sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,\n" + + " avg(l_quantity) AS avg_qty,\n" + + " avg(l_extendedprice) AS avg_price,\n" + + " avg(l_discount) AS avg_disc,\n" + + " count(*) AS count_order\n" + + "FROM\n" + + " lineitem \n" + + "WHERE\n" + + " l_shipdate <= DATE '1998-12-01' - INTERVAL '90' DAY\n" + + "GROUP BY\n" + + " l_returnflag,\n" + + " l_linestatus\n" + + "ORDER BY\n" + + " l_returnflag,\n" + + " l_linestatus\n"; + + assertPlan(sql, publicSchema, + nodeOrAnyChild(isInstanceOf(IgniteSort.class) + .and(hasCollation(TraitUtils.createCollation(List.of(0, 1)))) + .and(nodeOrAnyChild(isInstanceOf(IgniteReduceHashAggregate.class) + .and(nodeOrAnyChild(isInstanceOf(IgniteExchange.class) + .and(nodeOrAnyChild(isInstanceOf(IgniteMapHashAggregate.class) + .and(hasGroupSets(IgniteMapHashAggregate::getGroupSets, List.of(0, 1))) + .and(input(isIndexScan("LINEITEM", "IDX_SHIPDATE")))) + )) + )) + )) + ); + } +}