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 43a757ec3282e0..8592d3f22a0294 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 @@ -34,6 +34,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; import org.apache.doris.nereids.trees.plans.logical.LogicalApply; import org.apache.doris.nereids.trees.plans.logical.LogicalCTEConsumer; +import org.apache.doris.nereids.trees.plans.logical.LogicalCatalogRelation; 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.LogicalJoin; @@ -97,6 +98,25 @@ public Plan visit(Plan plan, Map replaceMap) { return logicalPlan; } + @Override + public Plan visitLogicalCatalogRelation(LogicalCatalogRelation relation, Map replaceMap) { + relation = (LogicalCatalogRelation) super.visit(relation, replaceMap); + relation = (LogicalCatalogRelation) relation.recomputeLogicalProperties(); + for (Slot slot : relation.getOutput()) { + replaceMap.put(slot.getExprId(), slot); + } + Optional> newVirtualColumns + = updateExpressions(relation.getVirtualColumns(), replaceMap, true); + if (!newVirtualColumns.isPresent()) { + return relation; + } + for (NamedExpression newVirtualColumn : newVirtualColumns.get()) { + replaceMap.put(newVirtualColumn.getExprId(), newVirtualColumn.toSlot()); + } + return relation.withVirtualColumns(newVirtualColumns.get()) + .recomputeLogicalProperties(); + } + @Override public Plan visitLogicalSink(LogicalSink logicalSink, Map replaceMap) { logicalSink = (LogicalSink) super.visit(logicalSink, replaceMap); diff --git a/regression-test/data/query_p0/virtual_slot_ref/adjust_virtual_slot_nullable.out b/regression-test/data/query_p0/virtual_slot_ref/adjust_virtual_slot_nullable.out new file mode 100644 index 00000000000000..ea65f366267586 --- /dev/null +++ b/regression-test/data/query_p0/virtual_slot_ref/adjust_virtual_slot_nullable.out @@ -0,0 +1,17 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !left_join_shape -- +PhysicalResultSink +--hashJoin[INNER_JOIN] hashCondition=((t1.c_int = t2.c_int)) otherCondition=() build RFs:RF0 c_int->[c_int];RF1 c_int->[c_int] +----PhysicalOlapScan[tbl_adjust_virtual_slot_nullable_1] apply RFs: RF0 RF1 +----PhysicalProject +------filter(OR[( not dayofmonth(c_date) IN (1, 3)),( not dayofmonth(c_date) IN (2, 3))]) +--------PhysicalOlapScan[tbl_adjust_virtual_slot_nullable_2] + +-- !left_join_result -- +1 2020-01-01 1 2022-02-01 +1 2020-01-01 1 2022-02-02 +1 2020-01-02 1 2022-02-01 +1 2020-01-02 1 2022-02-02 +1 2020-01-03 1 2022-02-01 +1 2020-01-03 1 2022-02-02 + diff --git a/regression-test/suites/query_p0/virtual_slot_ref/adjust_virtual_slot_nullable.groovy b/regression-test/suites/query_p0/virtual_slot_ref/adjust_virtual_slot_nullable.groovy new file mode 100644 index 00000000000000..80d4b9fd5bef15 --- /dev/null +++ b/regression-test/suites/query_p0/virtual_slot_ref/adjust_virtual_slot_nullable.groovy @@ -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. + +suite("adjust_virtual_slot_nullable") { + def tbl1 = "tbl_adjust_virtual_slot_nullable_1" + def tbl2 = "tbl_adjust_virtual_slot_nullable_2" + multi_sql """ + SET ignore_shape_nodes='PhysicalDistribute'; + drop table if exists ${tbl1} force; + drop table if exists ${tbl2} force; + create table ${tbl1} (c_int int not null, c_date date not null) properties('replication_num' = '1'); + create table ${tbl2} (c_int int not null, c_date date not null) properties('replication_num' = '1'); + insert into ${tbl1} values + (1, '2020-01-01'), + (1, '2020-01-02'), + (1, '2020-01-03'), + (2, '2021-01-01'), + (2, '2021-01-02'), + (2, '2021-01-03'); + insert into ${tbl2} values + (1, '2022-02-01'), + (1, '2022-02-02'), + (1, '2022-02-03'); + """ + + def querySql = """ + SELECT t1.*, t2.* + FROM + ${tbl1} AS t1 + LEFT JOIN ${tbl2} AS t2 + ON t1.c_int = t2.c_int + WHERE + NOT ( + day(t2.c_date) IN (1, 3) + AND + day(t2.c_date) IN (2, 3, 3) + ); + """ + + explainAndOrderResult 'left_join', querySql + explain { + sql querySql + verbose true + contains 'type=tinyint, nullable=false, isAutoIncrement=false, subColPath=null, virtualColumn=dayofmonth(c_date' + } +}