diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java index c4a27b9748d7c9..73ff74066887ec 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java @@ -31,9 +31,12 @@ import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; import org.apache.doris.nereids.trees.plans.logical.LogicalCTEConsumer; +import org.apache.doris.nereids.trees.plans.logical.LogicalEsScan; import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; import org.apache.doris.nereids.trees.plans.logical.LogicalGenerate; +import org.apache.doris.nereids.trees.plans.logical.LogicalJdbcScan; import org.apache.doris.nereids.trees.plans.logical.LogicalJoin; +import org.apache.doris.nereids.trees.plans.logical.LogicalOdbcScan; import org.apache.doris.nereids.trees.plans.logical.LogicalPartitionTopN; import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; import org.apache.doris.nereids.trees.plans.logical.LogicalProject; @@ -253,6 +256,39 @@ public Plan visitLogicalCTEConsumer(LogicalCTEConsumer cteConsumer, Map replaceMap) { + if (!scan.getConjuncts().isEmpty()) { + scan.getOutputSet().forEach(s -> replaceMap.put(s.getExprId(), s)); + Set conjuncts = updateExpressions(scan.getConjuncts(), replaceMap); + return scan.withConjuncts(conjuncts).recomputeLogicalProperties(); + } else { + return scan; + } + } + + @Override + public Plan visitLogicalJdbcScan(LogicalJdbcScan scan, Map replaceMap) { + if (!scan.getConjuncts().isEmpty()) { + scan.getOutputSet().forEach(s -> replaceMap.put(s.getExprId(), s)); + Set conjuncts = updateExpressions(scan.getConjuncts(), replaceMap); + return scan.withConjuncts(conjuncts).recomputeLogicalProperties(); + } else { + return scan; + } + } + + @Override + public Plan visitLogicalOdbcScan(LogicalOdbcScan scan, Map replaceMap) { + if (!scan.getConjuncts().isEmpty()) { + scan.getOutputSet().forEach(s -> replaceMap.put(s.getExprId(), s)); + Set conjuncts = updateExpressions(scan.getConjuncts(), replaceMap); + return scan.withConjuncts(conjuncts).recomputeLogicalProperties(); + } else { + return scan; + } + } + private T updateExpression(T input, Map replaceMap) { return (T) input.rewriteDownShortCircuit(e -> e.accept(SlotReferenceReplacer.INSTANCE, replaceMap)); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/AdjustNullableTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/AdjustNullableTest.java new file mode 100644 index 00000000000000..5a6b7ac1b46497 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/AdjustNullableTest.java @@ -0,0 +1,75 @@ +// 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.ExprId; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.GreaterThan; +import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.expressions.SlotReference; +import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.nereids.trees.plans.RelationId; +import org.apache.doris.nereids.trees.plans.logical.LogicalJdbcScan; +import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan; +import org.apache.doris.nereids.types.IntegerType; +import org.apache.doris.nereids.util.MemoPatternMatchSupported; +import org.apache.doris.nereids.util.PlanConstructor; + +import mockit.Mock; +import mockit.MockUp; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +/** + * Tests for {@link AdjustNullableTest}. + */ +class AdjustNullableTest implements MemoPatternMatchSupported { + private final LogicalOlapScan scan = PlanConstructor.newLogicalOlapScan(0, "t1", 0); + + @Test + void testLogicalExternalRelation() { + new MockUp() { + @Mock + public Set getOutputSet() { + Set output = new HashSet<>(); + output.add(new SlotReference(new ExprId(1), "id", IntegerType.INSTANCE, false, + new ArrayList<>())); + return output; + } + + }; + + GreaterThan gt = new GreaterThan(new SlotReference(new ExprId(1), "id", + IntegerType.INSTANCE, true, new ArrayList<>()), Literal.of("1")); + Set conjuncts = new HashSet<>(); + conjuncts.add(gt); + Assertions.assertTrue(conjuncts.iterator().next().nullable()); + LogicalJdbcScan jdbcScan = + new LogicalJdbcScan(new RelationId(1), PlanConstructor.newOlapTable(0, "t1", 0), + new ArrayList<>(), Optional.empty(), Optional.empty(), conjuncts); + AdjustNullable adjustNullable = new AdjustNullable(); + LogicalJdbcScan newJdbcScan = (LogicalJdbcScan) adjustNullable.rewriteRoot(jdbcScan, null); + conjuncts = newJdbcScan.getConjuncts(); + Assertions.assertFalse(conjuncts.iterator().next().nullable()); + } +}