morrySnow commented on code in PR #23598:
URL: https://github.com/apache/doris/pull/23598#discussion_r1316695492


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java:
##########
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.LambdaType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Lambda includes lambda arguments and function body
+ * Before bind, x -> x : arguments("x") -> children: Expression(x)
+ * After bind, x -> x : arguments("x") -> children: Expression(x) 
ArrayItemReference(x)
+ */
+public class Lambda extends Expression {
+    final List<String> argumentNames;
+
+    /**
+     * constructor
+     */
+    public Lambda(List<String> argumentNames, Expression lambdaFunction) {
+        super(lambdaFunction);
+        this.argumentNames = argumentNames;

Review Comment:
   ```suggestion
           this.argumentNames = 
ImmutableList.copyOf(Objects.requreNonNull(argumentNames, "argumentNames should 
not null"));
   ```



##########
fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4:
##########
@@ -331,6 +331,15 @@ namedExpressionSeq
 
 expression
     : booleanExpression
+    | lambdaExpression
+    ;
+
+lambdaExpression
+    : args+=errorCapturingIdentifier ARROW body=booleanExpression

Review Comment:
   ```suggestion
       : args+=errorCapturingIdentifier ARROW body=expression
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java:
##########
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.LambdaType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Lambda includes lambda arguments and function body
+ * Before bind, x -> x : arguments("x") -> children: Expression(x)
+ * After bind, x -> x : arguments("x") -> children: Expression(x) 
ArrayItemReference(x)
+ */
+public class Lambda extends Expression {
+    final List<String> argumentNames;
+
+    /**
+     * constructor
+     */
+    public Lambda(List<String> argumentNames, Expression lambdaFunction) {
+        super(lambdaFunction);
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, Expression lambdaFunction, 
List<ArrayItemReference> arguments) {
+        
super(ImmutableList.<Expression>builder().add(lambdaFunction).addAll(arguments).build());
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, List<Expression> children) {
+        super(children);
+        this.argumentNames = argumentNames;
+    }
+
+    /**
+     * make slot according array expression
+     * @param arrays array expression
+     * @return item slots of array expression
+     */
+    public ImmutableList<ArrayItemReference> makeArguments(List<Expression> 
arrays) {
+        Builder<ArrayItemReference> builder = new ImmutableList.Builder<>();
+        for (int i = 0; i < arrays.size(); i++) {
+            Expression array = arrays.get(i);
+            String name = argumentNames.get(i);
+            Preconditions.checkArgument(array.getDataType() instanceof 
ArrayType, "lambda must receive array");
+            builder.add(new ArrayItemReference(name, array));
+        }
+        return builder.build();
+    }
+
+    public String getLambdaArgumentName(int i) {
+        return argumentNames.get(i);
+    }
+
+    public ArrayItemReference getLambdaArgument(int i) {
+        return (ArrayItemReference) children.get(i + 1);
+    }
+
+    public List<ArrayItemReference> getLambdaArguments() {
+        return children.stream()
+                .skip(1)
+                .map(e -> (ArrayItemReference) e)
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getLambdaArgumentNames() {
+        return argumentNames;
+    }
+
+    public Expression getLambdaFunction() {
+        return child(0);
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitLambda(this, context);
+    }
+
+    public Lambda withLambdaFunctionArguments(Expression lambdaFunction, 
List<ArrayItemReference> arguments) {
+        return new Lambda(argumentNames, lambdaFunction, arguments);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Lambda that = (Lambda) o;
+        return argumentNames.equals(that.argumentNames)
+                && Objects.equals(children(), that.children());
+    }
+
+    @Override
+    public String toSql() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(String.format("%s -> %s", argumentNames,

Review Comment:
   argumentNames is List, List toString use '[]' instead of '()' as container. 
so i think u should use string join to generate right sql string



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java:
##########
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.LambdaType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Lambda includes lambda arguments and function body
+ * Before bind, x -> x : arguments("x") -> children: Expression(x)
+ * After bind, x -> x : arguments("x") -> children: Expression(x) 
ArrayItemReference(x)
+ */
+public class Lambda extends Expression {
+    final List<String> argumentNames;
+
+    /**
+     * constructor
+     */
+    public Lambda(List<String> argumentNames, Expression lambdaFunction) {
+        super(lambdaFunction);
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, Expression lambdaFunction, 
List<ArrayItemReference> arguments) {
+        
super(ImmutableList.<Expression>builder().add(lambdaFunction).addAll(arguments).build());
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, List<Expression> children) {
+        super(children);
+        this.argumentNames = argumentNames;
+    }
+
+    /**
+     * make slot according array expression
+     * @param arrays array expression
+     * @return item slots of array expression
+     */
+    public ImmutableList<ArrayItemReference> makeArguments(List<Expression> 
arrays) {
+        Builder<ArrayItemReference> builder = new ImmutableList.Builder<>();
+        for (int i = 0; i < arrays.size(); i++) {
+            Expression array = arrays.get(i);
+            String name = argumentNames.get(i);
+            Preconditions.checkArgument(array.getDataType() instanceof 
ArrayType, "lambda must receive array");
+            builder.add(new ArrayItemReference(name, array));
+        }
+        return builder.build();
+    }
+
+    public String getLambdaArgumentName(int i) {
+        return argumentNames.get(i);
+    }
+
+    public ArrayItemReference getLambdaArgument(int i) {
+        return (ArrayItemReference) children.get(i + 1);
+    }
+
+    public List<ArrayItemReference> getLambdaArguments() {
+        return children.stream()
+                .skip(1)
+                .map(e -> (ArrayItemReference) e)
+                .collect(Collectors.toList());
+    }
+
+    public List<String> getLambdaArgumentNames() {
+        return argumentNames;
+    }
+
+    public Expression getLambdaFunction() {
+        return child(0);
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitLambda(this, context);
+    }
+
+    public Lambda withLambdaFunctionArguments(Expression lambdaFunction, 
List<ArrayItemReference> arguments) {
+        return new Lambda(argumentNames, lambdaFunction, arguments);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Lambda that = (Lambda) o;
+        return argumentNames.equals(that.argumentNames)
+                && Objects.equals(children(), that.children());
+    }
+
+    @Override
+    public String toSql() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(String.format("%s -> %s", argumentNames,
+                getLambdaFunction().toSql()));
+        for (int i = 1; i < getArguments().size(); i++) {
+            builder.append(", ").append(getArgument(i).toSql());
+        }
+        return builder.toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(String.format("%s -> %s", argumentNames,

Review Comment:
   ditto



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ArrayItemReference.java:
##########
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions;
+
+import 
org.apache.doris.nereids.trees.expressions.typecoercion.ExpectsInputTypes;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.coercion.AnyDataType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * it is item from array, which used in lambda function
+ */
+public class ArrayItemReference extends NamedExpression implements 
ExpectsInputTypes {
+    protected final String name;
+    protected final ExprId exprId;
+
+    /** ArrayItemReference */
+    public ArrayItemReference(String name, Expression arrayExpression) {
+        this(StatementScopeIdGenerator.newExprId(), name, arrayExpression);
+    }
+
+    public ArrayItemReference(ExprId exprId, String name, Expression 
arrayExpression) {
+        super(ImmutableList.of(arrayExpression));
+        Preconditions.checkArgument(arrayExpression.getDataType() instanceof 
ArrayType,
+                "ArrayItemReference' child must return array");
+        this.name = name;
+        this.exprId = exprId;
+    }
+
+    public Expression getArrayExpression() {
+        return children.get(0);
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitArrayItemReference(this, context);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public ExprId getExprId() {
+        return exprId;
+    }
+
+    @Override
+    public List<String> getQualifier() {
+        return ImmutableList.of(name);
+    }
+
+    @Override
+    public boolean nullable() {
+        return ((ArrayType) 
(this.children.get(0).getDataType())).containsNull();
+    }
+
+    @Override
+    public ArrayItemReference withChildren(List<Expression> expressions) {
+        return new ArrayItemReference(exprId, name, expressions.get(0));
+    }
+
+    @Override
+    public DataType getDataType() {
+        return ((ArrayType) 
(this.children.get(0).getDataType())).getItemType();
+    }
+
+    @Override
+    public String toSql() {
+        String str = getName() + "#" + getExprId();
+        str += " of " + child(0).toSql();
+        return str;
+    }
+
+    @Override
+    public Slot toSlot() {
+        return new ArrayItemSlot(exprId, name, getDataType(), nullable());
+    }
+
+    @Override
+    public String toString() {
+        String str = getName() + "#" + getExprId();
+        str += " of " + child(0).toString();
+        return str;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        ArrayItemReference that = (ArrayItemReference) o;
+        return Objects.equals(child(0), that.child(0));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(children, getExprId());

Review Comment:
   i think just use exprid is ok?



##########
fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4:
##########
@@ -331,6 +331,15 @@ namedExpressionSeq
 
 expression
     : booleanExpression
+    | lambdaExpression
+    ;
+
+lambdaExpression
+    : args+=errorCapturingIdentifier ARROW body=booleanExpression
+    | LEFT_PAREN
+        args+=errorCapturingIdentifier (COMMA args+=errorCapturingIdentifier)+
+      RIGHT_PAREN
+        ARROW body=booleanExpression

Review Comment:
   ```suggestion
           ARROW body=expression
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java:
##########
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.LambdaType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Lambda includes lambda arguments and function body
+ * Before bind, x -> x : arguments("x") -> children: Expression(x)
+ * After bind, x -> x : arguments("x") -> children: Expression(x) 
ArrayItemReference(x)
+ */
+public class Lambda extends Expression {
+    final List<String> argumentNames;

Review Comment:
   ```suggestion
   public class Lambda extends Expression {
   
       private final List<String> argumentNames;
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java:
##########
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.LambdaType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Lambda includes lambda arguments and function body
+ * Before bind, x -> x : arguments("x") -> children: Expression(x)
+ * After bind, x -> x : arguments("x") -> children: Expression(x) 
ArrayItemReference(x)
+ */
+public class Lambda extends Expression {
+    final List<String> argumentNames;
+
+    /**
+     * constructor
+     */
+    public Lambda(List<String> argumentNames, Expression lambdaFunction) {
+        super(lambdaFunction);
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, Expression lambdaFunction, 
List<ArrayItemReference> arguments) {
+        
super(ImmutableList.<Expression>builder().add(lambdaFunction).addAll(arguments).build());
+        this.argumentNames = argumentNames;

Review Comment:
   ditto



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ArrayItemReference.java:
##########
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions;
+
+import 
org.apache.doris.nereids.trees.expressions.typecoercion.ExpectsInputTypes;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.coercion.AnyDataType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * it is item from array, which used in lambda function
+ */
+public class ArrayItemReference extends NamedExpression implements 
ExpectsInputTypes {
+    protected final String name;
+    protected final ExprId exprId;
+

Review Comment:
   ```suggestion
   public class ArrayItemReference extends NamedExpression implements 
ExpectsInputTypes {
       
       protected final ExprId exprId;
       protected final String name;
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java:
##########
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.LambdaType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Lambda includes lambda arguments and function body
+ * Before bind, x -> x : arguments("x") -> children: Expression(x)
+ * After bind, x -> x : arguments("x") -> children: Expression(x) 
ArrayItemReference(x)
+ */
+public class Lambda extends Expression {
+    final List<String> argumentNames;
+
+    /**
+     * constructor
+     */
+    public Lambda(List<String> argumentNames, Expression lambdaFunction) {
+        super(lambdaFunction);
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, Expression lambdaFunction, 
List<ArrayItemReference> arguments) {
+        
super(ImmutableList.<Expression>builder().add(lambdaFunction).addAll(arguments).build());
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, List<Expression> children) {
+        super(children);
+        this.argumentNames = argumentNames;
+    }
+
+    /**
+     * make slot according array expression
+     * @param arrays array expression
+     * @return item slots of array expression
+     */
+    public ImmutableList<ArrayItemReference> makeArguments(List<Expression> 
arrays) {
+        Builder<ArrayItemReference> builder = new ImmutableList.Builder<>();
+        for (int i = 0; i < arrays.size(); i++) {
+            Expression array = arrays.get(i);
+            String name = argumentNames.get(i);
+            Preconditions.checkArgument(array.getDataType() instanceof 
ArrayType, "lambda must receive array");

Review Comment:
   throw new AnalysisException(). and print the original expression for user



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java:
##########
@@ -0,0 +1,162 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.LambdaType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Lambda includes lambda arguments and function body
+ * Before bind, x -> x : arguments("x") -> children: Expression(x)
+ * After bind, x -> x : arguments("x") -> children: Expression(x) 
ArrayItemReference(x)
+ */
+public class Lambda extends Expression {
+    final List<String> argumentNames;
+
+    /**
+     * constructor
+     */
+    public Lambda(List<String> argumentNames, Expression lambdaFunction) {
+        super(lambdaFunction);
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, Expression lambdaFunction, 
List<ArrayItemReference> arguments) {
+        
super(ImmutableList.<Expression>builder().add(lambdaFunction).addAll(arguments).build());
+        this.argumentNames = argumentNames;
+    }
+
+    public Lambda(List<String> argumentNames, List<Expression> children) {
+        super(children);
+        this.argumentNames = argumentNames;

Review Comment:
   ditto



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ArrayItemReference.java:
##########
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions;
+
+import 
org.apache.doris.nereids.trees.expressions.typecoercion.ExpectsInputTypes;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.coercion.AnyDataType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * it is item from array, which used in lambda function
+ */
+public class ArrayItemReference extends NamedExpression implements 
ExpectsInputTypes {
+    protected final String name;
+    protected final ExprId exprId;
+
+    /** ArrayItemReference */
+    public ArrayItemReference(String name, Expression arrayExpression) {
+        this(StatementScopeIdGenerator.newExprId(), name, arrayExpression);
+    }
+
+    public ArrayItemReference(ExprId exprId, String name, Expression 
arrayExpression) {
+        super(ImmutableList.of(arrayExpression));
+        Preconditions.checkArgument(arrayExpression.getDataType() instanceof 
ArrayType,
+                "ArrayItemReference' child must return array");
+        this.name = name;
+        this.exprId = exprId;

Review Comment:
   ```suggestion
           this.exprId = exprId;
           this.name = name;
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ArrayItemReference.java:
##########
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions;
+
+import 
org.apache.doris.nereids.trees.expressions.typecoercion.ExpectsInputTypes;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.coercion.AnyDataType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * it is item from array, which used in lambda function
+ */
+public class ArrayItemReference extends NamedExpression implements 
ExpectsInputTypes {
+    protected final String name;
+    protected final ExprId exprId;
+
+    /** ArrayItemReference */
+    public ArrayItemReference(String name, Expression arrayExpression) {
+        this(StatementScopeIdGenerator.newExprId(), name, arrayExpression);
+    }
+
+    public ArrayItemReference(ExprId exprId, String name, Expression 
arrayExpression) {
+        super(ImmutableList.of(arrayExpression));
+        Preconditions.checkArgument(arrayExpression.getDataType() instanceof 
ArrayType,
+                "ArrayItemReference' child must return array");

Review Comment:
   print arrayExpression for easy debuging



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayMap.java:
##########


Review Comment:
   add all lambda signature of functions: 
https://doris.apache.org/docs/dev/sql-manual/sql-functions/array-functions/array



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PlanTranslatorContext.java:
##########
@@ -155,6 +161,10 @@ public void addExprIdSlotRefPair(ExprId exprId, SlotRef 
slotRef) {
         slotIdToExprId.put(slotRef.getDesc().getId(), exprId);
     }
 
+    public void addExprIdColumnRef(ExprId exprId, ColumnRefExpr columnRefExpr) 
{

Review Comment:
   ```suggestion
       public void addExprIdColumnRefPair(ExprId exprId, ColumnRefExpr 
columnRefExpr) {
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PlanTranslatorContext.java:
##########
@@ -75,6 +76,11 @@ public class PlanTranslatorContext {
      */
     private final Map<SlotId, ExprId> slotIdToExprId = Maps.newHashMap();
 
+    /**
+     * index from Nereids' slot to legacy slot.
+     */

Review Comment:
   The comments need to be clearer to explain it is used for lambda function



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ArrayItemReference.java:
##########
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions;
+
+import 
org.apache.doris.nereids.trees.expressions.typecoercion.ExpectsInputTypes;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.coercion.AnyDataType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * it is item from array, which used in lambda function
+ */
+public class ArrayItemReference extends NamedExpression implements 
ExpectsInputTypes {
+    protected final String name;
+    protected final ExprId exprId;
+
+    /** ArrayItemReference */
+    public ArrayItemReference(String name, Expression arrayExpression) {
+        this(StatementScopeIdGenerator.newExprId(), name, arrayExpression);
+    }
+
+    public ArrayItemReference(ExprId exprId, String name, Expression 
arrayExpression) {
+        super(ImmutableList.of(arrayExpression));
+        Preconditions.checkArgument(arrayExpression.getDataType() instanceof 
ArrayType,
+                "ArrayItemReference' child must return array");
+        this.name = name;
+        this.exprId = exprId;
+    }
+
+    public Expression getArrayExpression() {
+        return children.get(0);
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitArrayItemReference(this, context);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public ExprId getExprId() {
+        return exprId;
+    }
+
+    @Override
+    public List<String> getQualifier() {
+        return ImmutableList.of(name);
+    }
+
+    @Override
+    public boolean nullable() {
+        return ((ArrayType) 
(this.children.get(0).getDataType())).containsNull();
+    }
+
+    @Override
+    public ArrayItemReference withChildren(List<Expression> expressions) {
+        return new ArrayItemReference(exprId, name, expressions.get(0));
+    }
+
+    @Override
+    public DataType getDataType() {
+        return ((ArrayType) 
(this.children.get(0).getDataType())).getItemType();
+    }
+
+    @Override
+    public String toSql() {
+        String str = getName() + "#" + getExprId();
+        str += " of " + child(0).toSql();
+        return str;

Review Comment:
   to sql should return valid sql to ensure lamdba.toSql could return valid sql



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ArrayItemReference.java:
##########
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions;
+
+import 
org.apache.doris.nereids.trees.expressions.typecoercion.ExpectsInputTypes;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.coercion.AnyDataType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * it is item from array, which used in lambda function
+ */
+public class ArrayItemReference extends NamedExpression implements 
ExpectsInputTypes {
+    protected final String name;
+    protected final ExprId exprId;
+
+    /** ArrayItemReference */
+    public ArrayItemReference(String name, Expression arrayExpression) {
+        this(StatementScopeIdGenerator.newExprId(), name, arrayExpression);
+    }
+
+    public ArrayItemReference(ExprId exprId, String name, Expression 
arrayExpression) {
+        super(ImmutableList.of(arrayExpression));
+        Preconditions.checkArgument(arrayExpression.getDataType() instanceof 
ArrayType,
+                "ArrayItemReference' child must return array");
+        this.name = name;
+        this.exprId = exprId;
+    }
+
+    public Expression getArrayExpression() {
+        return children.get(0);
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitArrayItemReference(this, context);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public ExprId getExprId() {
+        return exprId;
+    }
+
+    @Override
+    public List<String> getQualifier() {
+        return ImmutableList.of(name);
+    }
+
+    @Override
+    public boolean nullable() {
+        return ((ArrayType) 
(this.children.get(0).getDataType())).containsNull();
+    }
+
+    @Override
+    public ArrayItemReference withChildren(List<Expression> expressions) {
+        return new ArrayItemReference(exprId, name, expressions.get(0));
+    }
+
+    @Override
+    public DataType getDataType() {
+        return ((ArrayType) 
(this.children.get(0).getDataType())).getItemType();
+    }
+
+    @Override
+    public String toSql() {
+        String str = getName() + "#" + getExprId();
+        str += " of " + child(0).toSql();
+        return str;
+    }
+
+    @Override
+    public Slot toSlot() {
+        return new ArrayItemSlot(exprId, name, getDataType(), nullable());
+    }
+
+    @Override
+    public String toString() {
+        String str = getName() + "#" + getExprId();
+        str += " of " + child(0).toString();
+        return str;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        ArrayItemReference that = (ArrayItemReference) o;
+        return Objects.equals(child(0), that.child(0));

Review Comment:
   why not only compare exprid?



-- 
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: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


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


Reply via email to