github-actions[bot] commented on code in PR #67887:
URL: https://github.com/apache/doris/pull/67887#discussion_r4003463873


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ComputeSignature.java:
##########
@@ -117,6 +118,19 @@ default FunctionSignature 
computeSignature(FunctionSignature signature) {
                 .get();
     }
 
+    /**
+     * Refresh argument and return metadata that is derived directly from the 
current children after reusing a
+     * previously resolved signature. The immediate origin arguments are 
supplied with that signature so an override
+     * can distinguish an unchanged raw child from an unrelated replacement 
without eagerly recomputing either type.
+     * The default is intentionally identity: overload selection, coercion, 
and value-dependent precision decisions
+     * remain frozen across equivalent rewrites. An override must only rebuild 
metadata that the function definition
+     * derives from its children; it must not search overloads or rerun 
generic signature computation.
+     */
+    default FunctionSignature refreshDerivedSignature(
+            FunctionSignature signature, List<Expression> 
immediateOriginArguments) {
+        return signature;

Review Comment:
   [P1] Refresh unchanged complex passthrough signatures too
   
   This identity default leaves functions such as ArrayPopBack, ArrayPopFront, 
ArraySlice, ArrayConcat, and DeduplicateMap on their old reused return 
metadata. A reduced production path is:
   
   ```text
   LeftOuterJoin(other = length(to_json(array_popback(
     array(struct(l.number, r.number), struct(l.number, r.number)))))) > 0)
   ```
   
   The final AdjustNullable pass rebuilds the edited struct/array nodes with 
the right-side field nullable, but ArrayPopBack.withChildren still reaches this 
default and keeps its pre-join retArgType(0) result. ExpressionTranslator then 
emits the current argument type with that stale return, while BE derives and 
produces array_popback's result from argument 0, so return/column type 
validation can fail with the same nested-nullability mismatch this PR is 
fixing. Please audit all complex retArgType/Follow passthroughs and add an 
outer-join regression with one of them between array(struct(...)) and its 
consumer.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Array.java:
##########
@@ -131,4 +142,79 @@ public List<FunctionSignature> getSignatures() {
                 .map(dataType -> FunctionSignature.ret(ArrayType.of(new 
FollowToArgumentType(0))).varArgs(dataType))
                 .collect(ImmutableList.toImmutableList());
     }
+
+    @Override
+    public FunctionSignature computeSignature(FunctionSignature signature) {
+        if (isFullyResolved(signature.returnType)
+                && 
signature.argumentsTypes.stream().allMatch(Array::isFullyResolved)) {
+            // findWiderCommonTypeByVariable already produced the exact common 
item type. Running generic precision
+            // promotion again could use one visible nested leaf to overwrite 
independent fields inside that type.
+            return signature;
+        }
+        return ExplicitlyCastableSignature.super.computeSignature(signature);
+    }
+
+    @Override
+    public FunctionSignature deriveSignatureFromChildren(
+            FunctionSignature resolvedSignature, List<Expression> 
immediateOriginArguments) {
+        if (children.isEmpty()) {
+            if (!resolvedSignature.hasVarArgs && 
resolvedSignature.argumentsTypes.isEmpty()) {
+                return resolvedSignature;
+            }
+            throw new AnalysisException(
+                    "Cannot safely reuse a non-empty ARRAY signature for an 
empty ARRAY");
+        }
+        if (!resolvedSignature.hasVarArgs || 
resolvedSignature.argumentsTypes.isEmpty()
+                || !(resolvedSignature.returnType instanceof ArrayType)) {
+            throw new AnalysisException(
+                    "Cannot safely reuse an empty or fixed-arity ARRAY 
signature for a non-empty ARRAY");
+        }
+        List<DataType> currentTypes = children.stream()
+                .map(ExpressionTrait::getDataType)
+                .collect(Collectors.toList());
+        List<DataType> originTypes = new ArrayList<>(currentTypes.size());
+        for (int i = 0; i < currentTypes.size(); i++) {
+            DataType resolvedType = resolvedSignature.getArgType(i);
+            DataType originType = i < immediateOriginArguments.size()
+                    ? immediateOriginArguments.get(i).getDataType() : 
resolvedType;
+            ChildDerivedSignature.refreshNestedTypeMetadata(
+                    resolvedType, currentTypes.get(i), originType);
+            originTypes.add(originType);
+        }
+        DataType itemType = ChildDerivedSignature.mergeNestedTypeMetadata(

Review Comment:
   [P1] Retype typed NULL children to the refreshed array item shape
   
   A reduced path is:
   
   ```text
   LeftOuterJoin(other = length(to_json(
     array(struct(l.number, r.number), NULL)))) > 0)
   ```
   
   Initial coercion types the NULL as the original required-field struct. 
AdjustNullable then makes `r.number` nullable, and this merge publishes that 
refreshed struct as every signature argument and as the array item, but it does 
not change the typed NullLiteral child. ExpressionTranslator sends the actual 
old child type. BE consequently creates the array result with a nullable-field 
Struct while the NULL source is `ColumnNullable(ColumnStruct<required field>)`; 
array construction materializes it and recursively copies the nested payload 
even when its null bit is set, so the destination nullable field receives a 
non-nullable source column. Please retype typed-NULL children (and parallel 
multi-input constructors such as CreateMap) to the refreshed common type, and 
add an executing outer-join regression; the current FE-only typed-NULL test 
checks only the signature.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to