This is an automated email from the ASF dual-hosted git repository. starocean999 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 7b6d2e21226 [fix](nereids)canInferNotNullForMarkSlot method get wrong result if fold constant rule is disabled (#49428) 7b6d2e21226 is described below commit 7b6d2e21226be3df22a6f5be0e69c4b631802267 Author: starocean999 <li...@selectdb.com> AuthorDate: Wed Mar 26 09:59:38 2025 +0800 [fix](nereids)canInferNotNullForMarkSlot method get wrong result if fold constant rule is disabled (#49428) canInferNotNullForMarkSlot will get wrong result if the expression can't be fold to boolean literal or null. After this pr, the mark slot can be set as not null only if meets one of the following conditions: 1. conjunct is fold to True literal in all conditions. 2. conjunct is fold to Null or False literal in all conditions. --- .../apache/doris/nereids/util/ExpressionUtils.java | 7 +- .../util/CanInferNotNullForMarkSlotTest.java | 100 +++++++++++++++++++++ 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java index 8ac422d3b64..64fe3791072 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java @@ -665,7 +665,7 @@ public class ExpressionUtils { * markSlotSize = 3 -> loopCount = 8 ---- 000, 001, 010, 011, 100, 101, 110, 111 * markSlotSize = 4 -> loopCount = 16 ---- 0000, 0001, ... 1111 */ - int loopCount = 2 << markSlotSize; + int loopCount = 1 << markSlotSize; for (int i = 0; i < loopCount; ++i) { replaceMap.clear(); /* @@ -693,10 +693,13 @@ public class ExpressionUtils { } else { meetNullOrFalse = true; } + } else { + return false; } } + return true; } - return true; + return false; } private static boolean isNullOrFalse(Expression expression) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/CanInferNotNullForMarkSlotTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/CanInferNotNullForMarkSlotTest.java new file mode 100644 index 00000000000..20066bbc33b --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/CanInferNotNullForMarkSlotTest.java @@ -0,0 +1,100 @@ +// 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.util; + +import org.apache.doris.nereids.rules.expression.ExpressionRewriteTestHelper; +import org.apache.doris.nereids.trees.expressions.And; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.IsNull; +import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference; +import org.apache.doris.nereids.trees.expressions.Or; +import org.apache.doris.nereids.trees.expressions.SlotReference; +import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral; +import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; +import org.apache.doris.nereids.types.BooleanType; + +import com.google.common.collect.Lists; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +/** + * CanInferNotNullForMarkSlotTest. + */ +public class CanInferNotNullForMarkSlotTest extends ExpressionRewriteTestHelper { + + @Test + public void test() { + SlotReference slot = new SlotReference("slot", BooleanType.INSTANCE); + MarkJoinSlotReference markSlot1 = new MarkJoinSlotReference("markSlot1"); + MarkJoinSlotReference markSlot2 = new MarkJoinSlotReference("markSlot2"); + MarkJoinSlotReference markSlot3 = new MarkJoinSlotReference("markSlot1"); + MarkJoinSlotReference markSlot4 = new MarkJoinSlotReference("markSlot2"); + MarkJoinSlotReference markSlot5 = new MarkJoinSlotReference("markSlot1"); + + List<Expression> markJoinSlotReferenceList1 = Lists.newArrayList(markSlot1, markSlot2, markSlot3, markSlot4); + List<Expression> markJoinSlotReferenceList2 = Lists.newArrayList(markSlot1, markSlot2, markSlot3, markSlot4, + markSlot5); + + Assertions.assertTrue( + ExpressionUtils.canInferNotNullForMarkSlot(new And(BooleanLiteral.TRUE, markSlot1), context)); + Assertions.assertTrue( + ExpressionUtils.canInferNotNullForMarkSlot(new And(BooleanLiteral.FALSE, markSlot1), context)); + Assertions.assertTrue( + ExpressionUtils.canInferNotNullForMarkSlot(new And(NullLiteral.INSTANCE, markSlot1), context)); + Assertions.assertTrue( + ExpressionUtils.canInferNotNullForMarkSlot(new Or(BooleanLiteral.TRUE, markSlot1), context)); + Assertions.assertTrue( + ExpressionUtils.canInferNotNullForMarkSlot(new Or(BooleanLiteral.FALSE, markSlot1), context)); + Assertions.assertTrue( + ExpressionUtils.canInferNotNullForMarkSlot(new Or(NullLiteral.INSTANCE, markSlot1), context)); + Assertions.assertTrue(ExpressionUtils + .canInferNotNullForMarkSlot(new And(new Or(BooleanLiteral.TRUE, markSlot2), markSlot1), context)); + Assertions.assertTrue(ExpressionUtils + .canInferNotNullForMarkSlot(new And(new Or(BooleanLiteral.FALSE, markSlot2), markSlot1), context)); + Assertions.assertTrue(ExpressionUtils + .canInferNotNullForMarkSlot(new And(new Or(NullLiteral.INSTANCE, markSlot2), markSlot1), context)); + Assertions.assertTrue(ExpressionUtils + .canInferNotNullForMarkSlot(new Or(new And(BooleanLiteral.TRUE, markSlot2), markSlot1), context)); + Assertions.assertTrue(ExpressionUtils + .canInferNotNullForMarkSlot(new Or(new And(BooleanLiteral.FALSE, markSlot2), markSlot1), context)); + Assertions.assertTrue(ExpressionUtils + .canInferNotNullForMarkSlot(new Or(new And(NullLiteral.INSTANCE, markSlot2), markSlot1), context)); + Assertions.assertTrue(ExpressionUtils.canInferNotNullForMarkSlot( + new And(new Or(BooleanLiteral.FALSE, markSlot2), new IsNull(markSlot1)), context)); + Assertions.assertTrue(ExpressionUtils.canInferNotNullForMarkSlot( + new And(new Or(NullLiteral.INSTANCE, markSlot2), new IsNull(markSlot1)), context)); + Assertions.assertTrue( + ExpressionUtils.canInferNotNullForMarkSlot(new And(new IsNull(markSlot2), markSlot1), context)); + Assertions.assertTrue(ExpressionUtils.canInferNotNullForMarkSlot(new Or(markJoinSlotReferenceList1), context)); + + Assertions.assertFalse( + ExpressionUtils.canInferNotNullForMarkSlot(new Or(new IsNull(markSlot2), markSlot1), context)); + Assertions.assertFalse(ExpressionUtils.canInferNotNullForMarkSlot( + new And(new Or(BooleanLiteral.TRUE, markSlot2), new IsNull(markSlot1)), context)); + Assertions.assertFalse(ExpressionUtils.canInferNotNullForMarkSlot( + new Or(new And(BooleanLiteral.TRUE, markSlot2), new IsNull(markSlot1)), context)); + Assertions.assertFalse(ExpressionUtils.canInferNotNullForMarkSlot( + new Or(new And(BooleanLiteral.FALSE, markSlot2), new IsNull(markSlot1)), context)); + Assertions.assertFalse(ExpressionUtils.canInferNotNullForMarkSlot( + new Or(new And(NullLiteral.INSTANCE, markSlot2), new IsNull(markSlot1)), context)); + Assertions.assertFalse(ExpressionUtils.canInferNotNullForMarkSlot(new And(slot, markSlot1), context)); + Assertions.assertFalse(ExpressionUtils.canInferNotNullForMarkSlot(new Or(markJoinSlotReferenceList2), context)); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org