diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommand.java index 0c976506a8..f6bd39ac83 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommand.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommand.java @@ -31,10 +31,12 @@ import org.apache.doris.nereids.parser.NereidsParser; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.GreaterThanEqual; import org.apache.doris.nereids.trees.expressions.InPredicate; +import org.apache.doris.nereids.trees.expressions.IsNull; import org.apache.doris.nereids.trees.expressions.LessThan; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral; import org.apache.doris.nereids.trees.expressions.literal.Literal; +import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.algebra.Sink; import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; @@ -54,6 +56,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; /** * Update mv by partition @@ -123,7 +126,21 @@ public class UpdateMvByPartitionCommand extends InsertOverwriteTableCommand { List inValues = ((ListPartitionItem) item).getItems().stream() .map(UpdateMvByPartitionCommand::convertPartitionKeyToLiteral) .collect(ImmutableList.toImmutableList()); - return new InPredicate(col, inValues); + List predicates = new ArrayList<>(); + if (inValues.stream().anyMatch(NullLiteral.class::isInstance)) { + inValues = inValues.stream() + .filter(e -> !(e instanceof NullLiteral)) + .collect(Collectors.toList()); + Expression isNullPredicate = new IsNull(col); + predicates.add(isNullPredicate); + } + if (!inValues.isEmpty()) { + predicates.add(new InPredicate(col, inValues)); + } + if (predicates.isEmpty()) { + return BooleanLiteral.of(true); + } + return ExpressionUtils.or(predicates); } else { Range range = item.getItems(); List exprs = new ArrayList<>(); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommandTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommandTest.java index af00d8ae46..b7374565da 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommandTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/UpdateMvByPartitionCommandTest.java @@ -19,6 +19,7 @@ package org.apache.doris.nereids.trees.plans.commands; import org.apache.doris.analysis.PartitionValue; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.ListPartitionItem; import org.apache.doris.catalog.PartitionItem; import org.apache.doris.catalog.PartitionKey; import org.apache.doris.catalog.PrimitiveType; @@ -26,6 +27,7 @@ import org.apache.doris.catalog.RangePartitionItem; import org.apache.doris.common.AnalysisException; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.GreaterThanEqual; +import org.apache.doris.nereids.trees.expressions.IsNull; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.types.IntegerType; @@ -53,4 +55,23 @@ class UpdateMvByPartitionCommandTest { Expression expr = (Expression) m.invoke(null, rangePartitionItem, new SlotReference("s", IntegerType.INSTANCE)); Assertions.assertTrue(expr instanceof GreaterThanEqual); } + + @Test + void testNull() throws AnalysisException, NoSuchMethodException, InvocationTargetException, + IllegalAccessException { + Method m = UpdateMvByPartitionCommand.class.getDeclaredMethod("convertPartitionItemToPredicate", PartitionItem.class, + Slot.class); + m.setAccessible(true); + Column column = new Column("a", PrimitiveType.INT); + PartitionKey v = PartitionKey.createListPartitionKeyWithTypes(ImmutableList.of(new PartitionValue("NULL", true)), ImmutableList.of(column.getType()), false); + ListPartitionItem listPartitionItem = new ListPartitionItem(ImmutableList.of(v)); + Expression expr = (Expression) m.invoke(null, listPartitionItem, new SlotReference("s", IntegerType.INSTANCE)); + Assertions.assertTrue(expr instanceof IsNull); + + PartitionKey v1 = PartitionKey.createListPartitionKeyWithTypes(ImmutableList.of(new PartitionValue("NULL", true)), ImmutableList.of(column.getType()), false); + PartitionKey v2 = PartitionKey.createListPartitionKeyWithTypes(ImmutableList.of(new PartitionValue("1", false)), ImmutableList.of(column.getType()), false); + listPartitionItem = new ListPartitionItem(ImmutableList.of(v1, v2)); + expr = (Expression) m.invoke(null, listPartitionItem, new SlotReference("s", IntegerType.INSTANCE)); + Assertions.assertEquals("(s IS NULL OR s IN (1))", expr.toSql()); + } }