This is an automated email from the ASF dual-hosted git repository. kxiao pushed a commit to branch branch-2.0 in repository https://gitbox.apache.org/repos/asf/doris.git
commit 8c07312ee0e4826c48016a2b4d5146bc51858b78 Author: AKIRA <33112463+kikyou1...@users.noreply.github.com> AuthorDate: Thu Sep 21 16:46:35 2023 +0900 [minor](test) Add some ut for optimizer rule (#24562) Add ut for * ExistsApplyToJoin * SimplifyDecimalV3Comparison * SimplifyArithmeticComparisonRule * SimplifyCastRule --- .../SimplifyArithmeticComparisonRuleTest.java | 55 ++++++++++ .../expression/rules/SimplifyCastRuleTest.java | 60 ++++++++++ .../rules/SimplifyDecimalV3ComparisonTest.java | 56 ++++++++++ .../rules/rewrite/ExistsApplyToJoinTest.java | 121 +++++++++++++++++++++ 4 files changed, 292 insertions(+) diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyArithmeticComparisonRuleTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyArithmeticComparisonRuleTest.java new file mode 100644 index 0000000000..5a438ded65 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyArithmeticComparisonRuleTest.java @@ -0,0 +1,55 @@ +// 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.doris.nereids.rules.expression.rules; + +import org.apache.doris.nereids.rules.expression.ExpressionRewriteTestHelper; +import org.apache.doris.nereids.rules.expression.ExpressionRuleExecutor; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.expressions.SlotReference; +import org.apache.doris.nereids.types.IntegerType; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +class SimplifyArithmeticComparisonRuleTest extends ExpressionRewriteTestHelper { + + @Test + public void testProcess() { + Map<String, Slot> nameToSlot = new HashMap<>(); + nameToSlot.put("a", new SlotReference("a", IntegerType.INSTANCE)); + executor = new ExpressionRuleExecutor(ImmutableList.of(SimplifyArithmeticComparisonRule.INSTANCE)); + assertRewriteAfterSimplify("a + 1 > 1", "a > cast((1 - 1) as INT)", nameToSlot); + assertRewriteAfterSimplify("a - 1 > 1", "a > cast((1 + 1) as INT)", nameToSlot); + assertRewriteAfterSimplify("a / -2 > 1", "cast((1 * -2) as INT) > a", nameToSlot); + } + + private void assertRewriteAfterSimplify(String expr, String expected, Map<String, Slot> slotNameToSlot) { + Expression needRewriteExpression = PARSER.parseExpression(expr); + if (slotNameToSlot != null) { + needRewriteExpression = replaceUnboundSlot(needRewriteExpression, slotNameToSlot); + } + Expression rewritten = SimplifyArithmeticComparisonRule.INSTANCE.rewrite(needRewriteExpression, context); + Expression expectedExpression = PARSER.parseExpression(expected); + Assertions.assertEquals(expectedExpression.toSql(), rewritten.toSql()); + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyCastRuleTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyCastRuleTest.java new file mode 100644 index 0000000000..8c07b3e972 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyCastRuleTest.java @@ -0,0 +1,60 @@ +// 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.doris.nereids.rules.expression.rules; + +import org.apache.doris.nereids.rules.expression.ExpressionRewriteTestHelper; +import org.apache.doris.nereids.rules.expression.ExpressionRuleExecutor; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.types.DataType; +import org.apache.doris.nereids.types.DecimalV3Type; +import org.apache.doris.nereids.types.StringType; +import org.apache.doris.nereids.types.VarcharType; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class SimplifyCastRuleTest extends ExpressionRewriteTestHelper { + + @Test + public void testSimplify() { + executor = new ExpressionRuleExecutor(ImmutableList.of(SimplifyCastRule.INSTANCE)); + assertRewriteAfterSimplify("CAST('1' AS STRING)", "'1'", + StringType.INSTANCE); + assertRewriteAfterSimplify("CAST('1' AS VARCHAR)", "'1'", + VarcharType.createVarcharType(-1)); + assertRewriteAfterSimplify("CAST(1 AS DECIMAL)", "1", + DecimalV3Type.createDecimalV3Type(9, 0)); + assertRewriteAfterSimplify("CAST(1000 AS DECIMAL)", "1000", + DecimalV3Type.createDecimalV3Type(9, 0)); + assertRewriteAfterSimplify("CAST(1 AS DECIMALV3)", "1", + DecimalV3Type.createDecimalV3Type(9, 0)); + assertRewriteAfterSimplify("CAST(1000 AS DECIMALV3)", "1000", + DecimalV3Type.createDecimalV3Type(9, 0)); + } + + private void assertRewriteAfterSimplify(String expr, String expected, DataType expectedType) { + Expression needRewriteExpression = PARSER.parseExpression(expr); + Expression rewritten = SimplifyCastRule.INSTANCE.rewrite(needRewriteExpression, context); + Expression expectedExpression = PARSER.parseExpression(expected); + Assertions.assertEquals(expectedExpression.toSql(), rewritten.toSql()); + Assertions.assertEquals(expectedType, rewritten.getDataType()); + + } + +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyDecimalV3ComparisonTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyDecimalV3ComparisonTest.java new file mode 100644 index 0000000000..ff424e4971 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyDecimalV3ComparisonTest.java @@ -0,0 +1,56 @@ +// 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.doris.nereids.rules.expression.rules; + +import org.apache.doris.common.Config; +import org.apache.doris.nereids.rules.expression.ExpressionRewriteTestHelper; +import org.apache.doris.nereids.rules.expression.ExpressionRuleExecutor; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.expressions.SlotReference; +import org.apache.doris.nereids.types.DecimalV3Type; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +class SimplifyDecimalV3ComparisonTest extends ExpressionRewriteTestHelper { + + @Test + public void testSimplifyDecimalV3Comparison() { + Config.enable_decimal_conversion = false; + Map<String, Slot> nameToSlot = new HashMap<>(); + nameToSlot.put("col1", new SlotReference("col1", DecimalV3Type.createDecimalV3Type(15, 2))); + executor = new ExpressionRuleExecutor(ImmutableList.of(SimplifyDecimalV3Comparison.INSTANCE)); + assertRewriteAfterSimplify("cast(col1 as decimalv3(27, 9)) > 0.6", "cast(col1 as decimalv3(27, 9)) > 0.6", nameToSlot); + } + + private void assertRewriteAfterSimplify(String expr, String expected, Map<String, Slot> slotNameToSlot) { + Expression needRewriteExpression = PARSER.parseExpression(expr); + if (slotNameToSlot != null) { + needRewriteExpression = replaceUnboundSlot(needRewriteExpression, slotNameToSlot); + } + Expression rewritten = SimplifyDecimalV3Comparison.INSTANCE.rewrite(needRewriteExpression, context); + Expression expectedExpression = PARSER.parseExpression(expected); + Assertions.assertEquals(expectedExpression.toSql(), rewritten.toSql()); + } + +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/ExistsApplyToJoinTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/ExistsApplyToJoinTest.java new file mode 100644 index 0000000000..eeb7a505f8 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/ExistsApplyToJoinTest.java @@ -0,0 +1,121 @@ +// 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.doris.nereids.rules.rewrite; + +import org.apache.doris.nereids.trees.expressions.EqualTo; +import org.apache.doris.nereids.trees.expressions.Exists; +import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.plans.JoinType; +import org.apache.doris.nereids.trees.plans.logical.LogicalApply; +import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan; +import org.apache.doris.nereids.util.MemoPatternMatchSupported; +import org.apache.doris.nereids.util.MemoTestUtils; +import org.apache.doris.nereids.util.PlanChecker; +import org.apache.doris.nereids.util.PlanConstructor; + +import com.google.common.collect.ImmutableList; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +class ExistsApplyToJoinTest implements MemoPatternMatchSupported { + + @Test + public void testCorrelatedExists() { + LogicalOlapScan left = PlanConstructor.newLogicalOlapScan(0, "t1", 1); + List<Slot> leftSlots = left.getOutput(); + LogicalOlapScan right = PlanConstructor.newLogicalOlapScan(0, "t2", 1); + List<Slot> rightSlots = right.getOutput(); + EqualTo equalTo = new EqualTo(leftSlots.get(0), rightSlots.get(0)); + Exists exists = new Exists(right, false); + LogicalApply<LogicalOlapScan, LogicalOlapScan> apply = + new LogicalApply<>(ImmutableList.of(leftSlots.get(0), rightSlots.get(0)), + exists, Optional.of(equalTo), Optional.empty(), + false, false, left, right); + PlanChecker.from(MemoTestUtils.createConnectContext(), apply) + .applyTopDown(new ExistsApplyToJoin()) + .matchesFromRoot(logicalJoin( + logicalOlapScan(), + logicalOlapScan() + ).when(j -> j.getJoinType().equals(JoinType.LEFT_SEMI_JOIN))); + } + + @Test + public void testUnCorrelatedExists() { + LogicalOlapScan left = PlanConstructor.newLogicalOlapScan(0, "t1", 1); + List<Slot> leftSlots = left.getOutput(); + LogicalOlapScan right = PlanConstructor.newLogicalOlapScan(0, "t2", 1); + List<Slot> rightSlots = right.getOutput(); + EqualTo equalTo = new EqualTo(leftSlots.get(0), rightSlots.get(0)); + Exists exists = new Exists(right, false); + LogicalApply<LogicalOlapScan, LogicalOlapScan> apply = + new LogicalApply<>(Collections.emptyList(), + exists, Optional.of(equalTo), Optional.empty(), + false, false, left, right); + PlanChecker.from(MemoTestUtils.createConnectContext(), apply) + .applyTopDown(new ExistsApplyToJoin()) + .matchesFromRoot(logicalJoin( + logicalOlapScan(), + logicalLimit(logicalOlapScan()) + ).when(j -> j.getJoinType().equals(JoinType.CROSS_JOIN))); + } + + @Test + public void testUnCorrelatedNotExists() { + LogicalOlapScan left = PlanConstructor.newLogicalOlapScan(0, "t1", 1); + List<Slot> leftSlots = left.getOutput(); + LogicalOlapScan right = PlanConstructor.newLogicalOlapScan(0, "t2", 1); + List<Slot> rightSlots = right.getOutput(); + EqualTo equalTo = new EqualTo(leftSlots.get(0), rightSlots.get(0)); + Exists exists = new Exists(right, true); + LogicalApply<LogicalOlapScan, LogicalOlapScan> apply = + new LogicalApply<>(Collections.emptyList(), + exists, Optional.of(equalTo), Optional.empty(), + false, false, left, right); + PlanChecker.from(MemoTestUtils.createConnectContext(), apply) + .applyTopDown(new ExistsApplyToJoin()) + .matchesFromRoot(logicalFilter(logicalJoin( + logicalOlapScan(), + logicalAggregate(logicalLimit(logicalOlapScan()))).when( + j -> j.getJoinType().equals(JoinType.CROSS_JOIN))) + ); + } + + @Test + public void testCorrelatedNotExists() { + LogicalOlapScan left = PlanConstructor.newLogicalOlapScan(0, "t1", 1); + List<Slot> leftSlots = left.getOutput(); + LogicalOlapScan right = PlanConstructor.newLogicalOlapScan(0, "t2", 1); + List<Slot> rightSlots = right.getOutput(); + EqualTo equalTo = new EqualTo(leftSlots.get(0), rightSlots.get(0)); + Exists exists = new Exists(right, true); + LogicalApply<LogicalOlapScan, LogicalOlapScan> apply = + new LogicalApply<>(ImmutableList.of(leftSlots.get(0), rightSlots.get(0)), + exists, Optional.of(equalTo), Optional.empty(), + false, false, left, right); + PlanChecker.from(MemoTestUtils.createConnectContext(), apply) + .applyTopDown(new ExistsApplyToJoin()) + .matchesFromRoot(logicalJoin( + logicalOlapScan(), + logicalOlapScan() + ).when(j -> j.getJoinType().equals(JoinType.LEFT_ANTI_JOIN))); + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org