This is an automated email from the ASF dual-hosted git repository.

huajianlan pushed a commit to branch opt_insert_into_values
in repository https://gitbox.apache.org/repos/asf/doris.git

commit d8327d9b7f3b8f4b4a2fdb0a6ebecdc470816e2d
Author: 924060929 <lanhuaj...@selectdb.com>
AuthorDate: Fri Dec 6 12:03:46 2024 +0800

    fix
---
 .../trees/plans/commands/insert/InsertUtils.java   | 42 ++++++++++++---
 .../trees/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 570011d3b7c..b09b2429941 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.trees.plans.logical.UnboundLogicalSink;
 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.Lists;
 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 class InsertUtils {
             );
         }
 
+        Boolean[] outputSlotNullables = new 
Boolean[logicalInlineTable.getConstantExprsList().get(0).size()];
+        Arrays.fill(outputSlotNullables, false);
+
         for (List<NamedExpression> values : 
logicalInlineTable.getConstantExprsList()) {
             ImmutableList.Builder<NamedExpression> 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 class InsertUtils {
                                     + "' in table '" + table.getName() + "' is 
not allowed.");
                         }
                         if (values.get(i) instanceof DefaultValueSlot) {
-                            
optimizedRowConstructor.add(generateDefaultExpression(sameNameColumn));
+                            NamedExpression defaultExpression = 
generateDefaultExpression(sameNameColumn);
+                            addColumnValue(
+                                    optimizedRowConstructor, 
outputSlotNullables, i, defaultExpression
+                            );
                         } else {
                             DataType targetType = 
DataType.fromCatalogType(sameNameColumn.getType());
                             Expression castValue = castValue(values.get(i), 
targetType);
                             castValue = rewriteContext == null
                                     ? castValue
                                     : FoldConstantRuleOnFE.evaluate(castValue, 
rewriteContext);
-                            optimizedRowConstructor.add((NamedExpression) 
castValue);
+                            addColumnValue(
+                                    optimizedRowConstructor, 
outputSlotNullables, i, (NamedExpression) castValue
+                            );
                         }
                     }
                 } else {
@@ -408,14 +422,19 @@ public class InsertUtils {
                                     + "' in table '" + table.getName() + "' is 
not allowed.");
                         }
                         if (values.get(i) instanceof DefaultValueSlot) {
-                            
optimizedRowConstructor.add(generateDefaultExpression(columns.get(i)));
+                            NamedExpression defaultExpression = 
generateDefaultExpression(columns.get(i));
+                            addColumnValue(
+                                    optimizedRowConstructor, 
outputSlotNullables, i, defaultExpression
+                            );
                         } else {
                             DataType targetType = 
DataType.fromCatalogType(columns.get(i).getType());
                             Expression castValue = castValue(values.get(i), 
targetType);
                             castValue = rewriteContext == null
                                     ? castValue
                                     : FoldConstantRuleOnFE.evaluate(castValue, 
rewriteContext);
-                            optimizedRowConstructor.add((NamedExpression) 
castValue);
+                            addColumnValue(
+                                    optimizedRowConstructor, 
outputSlotNullables, i, (NamedExpression) castValue
+                            );
                         }
                     }
                 }
@@ -423,7 +442,16 @@ public class InsertUtils {
             optimizedRowConstructors.add(optimizedRowConstructor.build());
         }
 
-        return plan.withChildren(new 
LogicalInlineTable(optimizedRowConstructors.build()));
+        return plan.withChildren(new 
LogicalInlineTable(optimizedRowConstructors.build(), Optional.of(
+                Utils.fastToImmutableList(outputSlotNullables)
+        )));
+    }
+
+    private static void addColumnValue(
+            ImmutableList.Builder<NamedExpression> 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 a229c8780ad..762ac6351d2 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 com.google.common.collect.ImmutableList;
 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<List<NamedExpression>> constantExprsList;
 
+    private final Optional<List<Boolean>> outputNullables;
+
     public LogicalInlineTable(List<List<NamedExpression>> constantExprsList) {
-        this(constantExprsList, Optional.empty(), Optional.empty());
+        this(constantExprsList, Optional.empty(), Optional.empty(), 
Optional.empty());
+    }
+
+    public LogicalInlineTable(List<List<NamedExpression>> constantExprsList, 
Optional<List<Boolean>> outputNullables) {
+        this(constantExprsList, outputNullables, Optional.empty(), 
Optional.empty());
     }
 
     public LogicalInlineTable(List<List<NamedExpression>> constantExprsList,
+            Optional<List<Boolean>> outputNullables,
             Optional<GroupExpression> groupExpression,
             Optional<LogicalProperties> 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 class LogicalInlineTable extends LogicalLeaf 
implements BlockFuncDepsProp
 
     @Override
     public Plan withGroupExpression(Optional<GroupExpression> groupExpression) 
{
-        return new LogicalInlineTable(constantExprsList, groupExpression, 
Optional.of(getLogicalProperties()));
+        return new LogicalInlineTable(
+                constantExprsList, outputNullables, groupExpression, 
Optional.of(getLogicalProperties())
+        );
     }
 
     @Override
     public Plan withGroupExprLogicalPropChildren(Optional<GroupExpression> 
groupExpression,
             Optional<LogicalProperties> logicalProperties, List<Plan> 
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<Slot> computeOutput() {
-        return constantExprsList.get(0)
-                .stream()
-                .map(NamedExpression::toSlot)
-                .collect(Collectors.toList());
+        if (outputNullables.isPresent()) {
+            List<Boolean> nullables = outputNullables.get();
+            int columnNum = constantExprsList.get(0).size();
+            List<NamedExpression> firstRow = constantExprsList.get(0);
+            ImmutableList.Builder<Slot> 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<NamedExpression> firstRow = constantExprsList.get(0);
+            ImmutableList.Builder<Slot> output = 
ImmutableList.builderWithExpectedSize(constantExprsList.size());
+            for (int i = 0; i < columnNum; i++) {
+                NamedExpression firstRowColumn = firstRow.get(i);
+                boolean nullable = false;
+                for (List<NamedExpression> row : constantExprsList) {
+                    if (row.get(i).nullable()) {
+                        nullable = true;
+                        break;
+                    }
+                }
+                output.add(new SlotReference(firstRowColumn.getName(), 
firstRowColumn.getDataType(), nullable));
+            }
+            return output.build();
+        }
     }
 
     @Override


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to