From 4fe7f08f7bf2a896f88d22d4c897916229362975 Mon Sep 17 00:00:00 2001 From: 924060929 Date: Fri, 6 Dec 2024 12:03:46 +0800 Subject: [PATCH] fix --- .../plans/commands/insert/InsertUtils.java | 42 ++++++++++--- .../plans/logical/LogicalInlineTable.java | 59 ++++++++++++++++--- 2 files changed, 85 insertions(+), 16 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertUtils.java index 570011d3b7ceb50..b09b24299414a9b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertUtils.java @@ -56,6 +56,7 @@ import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.util.RelationUtil; import org.apache.doris.nereids.util.TypeCoercionUtils; +import org.apache.doris.nereids.util.Utils; import org.apache.doris.proto.InternalService; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.InsertStreamTxnExecutor; @@ -80,6 +81,7 @@ import com.google.common.collect.Sets; import org.apache.commons.collections.CollectionUtils; +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Set; @@ -353,14 +355,21 @@ public static Plan normalizePlan(Plan plan, TableIf table, Optional values : logicalInlineTable.getConstantExprsList()) { ImmutableList.Builder optimizedRowConstructor = ImmutableList.builder(); if (values.isEmpty()) { if (CollectionUtils.isNotEmpty(unboundLogicalSink.getColNames())) { throw new AnalysisException("value list should not be empty if columns are specified"); } - for (Column column : columns) { - optimizedRowConstructor.add(generateDefaultExpression(column)); + for (int i = 0; i < columns.size(); i++) { + Column column = columns.get(i); + NamedExpression defaultExpression = generateDefaultExpression(column); + addColumnValue( + optimizedRowConstructor, outputSlotNullables, i, defaultExpression + ); } } else { if (CollectionUtils.isNotEmpty(unboundLogicalSink.getColNames())) { @@ -386,14 +395,19 @@ public static Plan normalizePlan(Plan plan, TableIf table, Optional optimizedRowConstructor, + Boolean[] nullable, int index, NamedExpression value) { + optimizedRowConstructor.add(value); + nullable[index] |= value.nullable(); } private static Expression castValue(Expression value, DataType targetType) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalInlineTable.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalInlineTable.java index a229c8780ad3b83..762ac6351d2db04 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalInlineTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalInlineTable.java @@ -17,11 +17,13 @@ package org.apache.doris.nereids.trees.plans.logical; +import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.memo.GroupExpression; import org.apache.doris.nereids.properties.LogicalProperties; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.expressions.Slot; +import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.plans.BlockFuncDepsPropagation; import org.apache.doris.nereids.trees.plans.Plan; import org.apache.doris.nereids.trees.plans.PlanType; @@ -33,7 +35,6 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; /** * represent value list such as values(1), (2), (3) will generate LogicalInlineTable((1), (2), (3)). @@ -42,15 +43,27 @@ public class LogicalInlineTable extends LogicalLeaf implements BlockFuncDepsProp private final List> constantExprsList; + private final Optional> outputNullables; + public LogicalInlineTable(List> constantExprsList) { - this(constantExprsList, Optional.empty(), Optional.empty()); + this(constantExprsList, Optional.empty(), Optional.empty(), Optional.empty()); + } + + public LogicalInlineTable(List> constantExprsList, Optional> outputNullables) { + this(constantExprsList, outputNullables, Optional.empty(), Optional.empty()); } public LogicalInlineTable(List> constantExprsList, + Optional> outputNullables, Optional groupExpression, Optional logicalProperties) { super(PlanType.LOGICAL_INLINE_TABLE, groupExpression, logicalProperties); - this.constantExprsList = ImmutableList.copyOf( + + if (constantExprsList.isEmpty()) { + throw new AnalysisException("constantExprsList should now be empty"); + } + this.outputNullables = Objects.requireNonNull(outputNullables, "outputNullables should not be null"); + this.constantExprsList = Utils.fastToImmutableList( Objects.requireNonNull(constantExprsList, "constantExprsList should not be null")); } @@ -70,21 +83,49 @@ public List getExpressions() { @Override public Plan withGroupExpression(Optional groupExpression) { - return new LogicalInlineTable(constantExprsList, groupExpression, Optional.of(getLogicalProperties())); + return new LogicalInlineTable( + constantExprsList, outputNullables, groupExpression, Optional.of(getLogicalProperties()) + ); } @Override public Plan withGroupExprLogicalPropChildren(Optional groupExpression, Optional logicalProperties, List children) { - return new LogicalInlineTable(constantExprsList, groupExpression, logicalProperties); + if (!children.isEmpty()) { + throw new AnalysisException("children should not be empty"); + } + return new LogicalInlineTable(constantExprsList, outputNullables, groupExpression, logicalProperties); } @Override public List computeOutput() { - return constantExprsList.get(0) - .stream() - .map(NamedExpression::toSlot) - .collect(Collectors.toList()); + if (outputNullables.isPresent()) { + List nullables = outputNullables.get(); + int columnNum = constantExprsList.get(0).size(); + List firstRow = constantExprsList.get(0); + ImmutableList.Builder output = ImmutableList.builderWithExpectedSize(constantExprsList.size()); + for (int i = 0; i < columnNum; i++) { + NamedExpression firstRowColumn = firstRow.get(i); + output.add(new SlotReference(firstRowColumn.getName(), firstRowColumn.getDataType(), nullables.get(i))); + } + return output.build(); + } else { + int columnNum = constantExprsList.get(0).size(); + List firstRow = constantExprsList.get(0); + ImmutableList.Builder output = ImmutableList.builderWithExpectedSize(constantExprsList.size()); + for (int i = 0; i < columnNum; i++) { + NamedExpression firstRowColumn = firstRow.get(i); + boolean nullable = false; + for (List row : constantExprsList) { + if (row.get(i).nullable()) { + nullable = true; + break; + } + } + output.add(new SlotReference(firstRowColumn.getName(), firstRowColumn.getDataType(), nullable)); + } + return output.build(); + } } @Override