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


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ElementAt.java:
##########
@@ -85,19 +91,65 @@ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C 
context) {
     }
 
     @Override
-    public List<FunctionSignature> getSignatures() {
-        if (child(0).getDataType() instanceof StructType) {
-            return new StructElement(child(0), child(1)).getSignatures();
+    public boolean foldable() {
+        // A map may legitimately contain a null key, so element_at(map, NULL) 
must be evaluated by
+        // the BE (which looks up the null key) rather than being folded to 
NULL on the FE through
+        // PropagateNullLiteral. Marking it non-foldable here skips that fold 
for the map null-key
+        // case only; a null container (element_at(NULL, ...)) or a null 
array/struct index still
+        // folds to NULL as before.
+        if (child(0).getDataType() instanceof MapType && child(1) instanceof 
NullLiteral) {
+            return false;
         }
-        return SIGNATURES;
+        return true;
     }
 
     @Override
-    public Expression rewriteWhenAnalyze() {
+    public void checkLegalityBeforeTypeCoercion() {
+        // Struct field access (the former struct_element) only accepts a 
constant int/string index,
+        // since the selected field — and therefore the result type — must be 
known at analysis time.
         if (child(0).getDataType() instanceof StructType) {
-            return new StructElement(child(0), child(1));
+            Expression field = getArgument(1);
+            if (!(field instanceof StringLikeLiteral || field instanceof 
IntegerLikeLiteral)) {
+                throw new AnalysisException("element_at over a struct only 
allows a constant int or"
+                        + " string second parameter: " + this.toSql());
+            }
+        }
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        DataType arg0Type = child(0).getDataType();
+        if (arg0Type instanceof NullType) {
+            return ImmutableList.of(
+                    
FunctionSignature.ret(NullType.INSTANCE).args(NullType.INSTANCE, 
child(1).getDataType()));
+        }
+        if (arg0Type instanceof StructType) {
+            return 
ImmutableList.of(FunctionSignature.ret(structFieldType((StructType) arg0Type))
+                    .args(arg0Type, child(1).getDataType()));
+        }
+        return SIGNATURES;
+    }
+
+    // Resolve the type of the struct field selected by the constant 
int/string index.
+    private DataType structFieldType(StructType structType) {
+        Expression field = getArgument(1);
+        if (field instanceof IntegerLikeLiteral) {
+            int offset = ((IntegerLikeLiteral) field).getIntValue();

Review Comment:
   This truncates wider integer literals before doing the bounds check and 
selecting the return type. For example, `element_at(named_struct('a', 1), 
4294967297)` reaches this path as an `IntegerLikeLiteral`; `getIntValue()` 
wraps it to `1`, so FE infers field 1 instead of rejecting the out-of-range 
index. BE resolves the same struct index from the constant column as an 
`int64_t` in `get_struct_element_index()` and rejects the real value, so the 
plan can pass FE analysis with the wrong return type and then fail in BE 
return-type/runtime validation. Please validate using the non-truncated integer 
value (and add a regression for an index larger than `Integer.MAX_VALUE`) 
before indexing into `structType.getFields()`.



-- 
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