Code review comment: can array_generate accept only one argument? if not so,  node.getChildren().size() < 2

Code under review:
public Void visitFunctionCall(FunctionCallExpr node, Scope scope) {
            Type[] argumentTypes = node.getChildren().stream().map(Expr::getType).toArray(Type[]::new);

            if (node.isNondeterministicBuiltinFnName()) {
                ExprId exprId = analyzeState.getNextNondeterministicId();
                node.setNondeterministicId(exprId);
            }

            Function fn;
            String fnName = node.getFnName().getFunction();

            if (fnName.equals(FunctionSet.COUNT) && node.getParams().isDistinct()) {
                
                
                fn = Expr.getBuiltinFunction(FunctionSet.COUNT, new Type[] {argumentTypes[0]},
                        Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            } else if (fnName.equals(FunctionSet.EXCHANGE_BYTES) || fnName.equals(FunctionSet.EXCHANGE_SPEED)) {
                fn = Expr.getBuiltinFunction(fnName, argumentTypes,
                        Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
                fn.setArgsType(argumentTypes); 
                fn.setIsNullable(false);
            } else if (fnName.equals(FunctionSet.TIME_SLICE) || fnName.equals(FunctionSet.DATE_SLICE)) {
                
                if (!(node.getChild(1) instanceof IntLiteral)) {
                    throw new SemanticException(
                            fnName + " requires second parameter must be a constant interval");
                }
                if (((IntLiteral) node.getChild(1)).getValue() <= 0) {
                    throw new SemanticException(
                            fnName + " requires second parameter must be greater than 0");
                }
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            } else if (FunctionSet.decimalRoundFunctions.contains(fnName) ||
                    Arrays.stream(argumentTypes).anyMatch(Type::isDecimalV3)) {
                
                
                
                
                
                if (FunctionSet.varianceFunctions.contains(fnName)) {
                    
                    
                    
                    
                    
                    
                    
                    Type[] doubleArgTypes = Stream.of(argumentTypes).map(t -> Type.DOUBLE).toArray(Type[]::new);
                    fn = Expr.getBuiltinFunction(fnName, doubleArgTypes,
                            Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
                } else {
                    fn = getDecimalV3Function(node, argumentTypes);
                }
            } else if (Arrays.stream(argumentTypes).anyMatch(arg -> arg.matchesType(Type.TIME))) {
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
                if (fn instanceof AggregateFunction) {
                    throw new SemanticException("Time Type can not used in %s function",
                            fnName);
                }
            } else if (FunctionSet.STR_TO_DATE.equals(fnName)) {
                fn = getStrToDateFunction(node, argumentTypes);
            } else if (fnName.equals(FunctionSet.ARRAY_FILTER)) {
                if (node.getChildren().size() != 2) {
                    throw new SemanticException(fnName + " should have 2 array inputs or lambda functions.");
                }
                if (!node.getChild(0).getType().isArrayType() && !node.getChild(0).getType().isNull()) {
                    throw new SemanticException("The first input of " + fnName +
                            " should be an array or a lambda function.");
                }
                if (!node.getChild(1).getType().isArrayType() && !node.getChild(1).getType().isNull()) {
                    throw new SemanticException("The second input of " + fnName +
                            " should be an array or a lambda function.");
                }
                
                if (!Type.canCastTo(node.getChild(1).getType(), Type.ARRAY_BOOLEAN)) {
                    throw new SemanticException("The second input of array_filter " +
                            node.getChild(1).getType().toString() + "  can't cast to ARRAY<BOOL>");
                }
                node.setChild(1, new CastExpr(Type.ARRAY_BOOLEAN, node.getChild(1)));
                argumentTypes[1] = Type.ARRAY_BOOLEAN;
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            } else if (fnName.equals(FunctionSet.ARRAY_SORTBY)) {
                if (node.getChildren().size() != 2) {
                    throw new SemanticException(fnName + " should have 2 array inputs or lambda functions.");
                }
                if (!node.getChild(0).getType().isArrayType() && !node.getChild(0).getType().isNull()) {
                    throw new SemanticException("The first input of " + fnName +
                            " should be an array or a lambda function.");
                }
                if (!node.getChild(1).getType().isArrayType() && !node.getChild(1).getType().isNull()) {
                    throw new SemanticException("The second input of " + fnName +
                            " should be an array or a lambda function.");
                }
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            } else if (fnName.equals(FunctionSet.ARRAY_SLICE)) {
                
                for (int i = 1; i < argumentTypes.length; i++) {
                    argumentTypes[i] = Type.BIGINT;
                }
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_SUPERTYPE_OF);
            } else if (fnName.equals(FunctionSet.ARRAY_CONCAT)) {
                if (node.getChildren().size() < 2) {
                    throw new SemanticException(fnName + " should have at least two inputs");
                }
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            } else if (fnName.equals("array_generate")) {
                if (node.getChildren().size() < 1 || node.getChildren().size() > 3) {
                    throw new SemanticException(fnName + " has wrong input numbers");
                }
                for (Expr expr : node.getChildren()) {
                    if ((expr instanceof SlotRef) && node.getChildren().size() != 3) {
                        throw new SemanticException(fnName + " with IntColumn doesn't support default parameters");
                    }
                    if (!(expr instanceof IntLiteral) && !(expr instanceof LargeIntLiteral) &&
                            !(expr instanceof SlotRef) && !(expr instanceof NullLiteral)) {
                        throw new SemanticException(fnName + "'s parameter only support Integer");
                    }
                }
                
                if (node.getChildren().size() == 1) {
                    LiteralExpr secondParam = (LiteralExpr) node.getChild(0);
                    node.clearChildren();
                    try {
                        node.addChild(new IntLiteral("1", Type.TINYINT));
                        node.addChild(secondParam);
                    } catch (AnalysisException e) {
                        throw new SemanticException(e.getMessage());
                    }
                }
                if (node.getChildren().size() == 2) {
                    int idx = 0;
                    BigInteger[] childValues = new BigInteger[2];
                    for (Expr expr : node.getChildren()) {
                        if (expr instanceof NullLiteral) {
                            throw new SemanticException(fnName + "'s parameter only support Integer");
                        } else if (expr instanceof IntLiteral) {
                            childValues[idx++] = BigInteger.valueOf(((IntLiteral) expr).getValue());
                        } else {
                            childValues[idx++] = ((LargeIntLiteral) expr).getValue();
                        }
                    }

                    if (childValues[0].compareTo(childValues[1]) < 0) {
                        node.addChild(new IntLiteral(1));
                    } else {
                        node.addChild(new IntLiteral(-1));
                    }
                }
                argumentTypes = node.getChildren().stream().map(Expr::getType).toArray(Type[]::new);
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_SUPERTYPE_OF);
            } else {
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            }

            if (fn == null) {
                fn = AnalyzerUtils.getUdfFunction(session, node.getFnName(), argumentTypes);
            }

            if (fn == null) {
                throw new SemanticException("No matching function with signature: %s(%s).",
                        fnName,
                        node.getParams().isStar() ? "*" : Joiner.on(", ")
                                .join(Arrays.stream(argumentTypes).map(Type::toSql).collect(Collectors.toList())));
            }

            if (fn instanceof TableFunction) {
                throw unsupportedException("Table function cannot be used in expression");
            }

            
            for (int i = 0; i < fn.getNumArgs(); i++) {
                if (!argumentTypes[i].matchesType(fn.getArgs()[i]) &&
                        !Type.canCastToAsFunctionParameter(argumentTypes[i], fn.getArgs()[i])) {
                    throw new SemanticException("No matching function with signature: %s(%s).", fnName,
                            node.getParams().isStar() ? "*" : Joiner.on(", ")
                                    .join(Arrays.stream(argumentTypes).map(Type::toSql).collect(Collectors.toList())));
                }
            }

            node.setFn(fn);
            node.setType(fn.getReturnType());
            FunctionAnalyzer.analyze(node);
            return null;
        }

Line commented on: if (node.getChildren().size() < 1 || node.getChildren().size() > 3) {

Revised code:
public Void visitFunctionCall(FunctionCallExpr node, Scope scope) {
            Type[] argumentTypes = node.getChildren().stream().map(Expr::getType).toArray(Type[]::new);

            if (node.isNondeterministicBuiltinFnName()) {
                ExprId exprId = analyzeState.getNextNondeterministicId();
                node.setNondeterministicId(exprId);
            }

            Function fn;
            String fnName = node.getFnName().getFunction();

            
            checkFunction(fnName, node);

            if (fnName.equals(FunctionSet.COUNT) && node.getParams().isDistinct()) {
                
                
                fn = Expr.getBuiltinFunction(FunctionSet.COUNT, new Type[] {argumentTypes[0]},
                        Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            } else if (fnName.equals(FunctionSet.EXCHANGE_BYTES) || fnName.equals(FunctionSet.EXCHANGE_SPEED)) {
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
                fn.setArgsType(argumentTypes); 
                fn.setIsNullable(false);
            } else if (DecimalV3FunctionAnalyzer.argumentTypeContainDecimalV3(fnName, argumentTypes)) {
                
                
                
                
                
                fn = DecimalV3FunctionAnalyzer.getDecimalV3Function(session, node, argumentTypes);
            } else if (Arrays.stream(argumentTypes).anyMatch(arg -> arg.matchesType(Type.TIME))) {
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
                if (fn instanceof AggregateFunction) {
                    throw new SemanticException("Time Type can not used in" + fnName + " function", node.getPos());
                }
            } else if (FunctionSet.STR_TO_DATE.equals(fnName)) {
                fn = getStrToDateFunction(node, argumentTypes);
            } else if (FunctionSet.ARRAY_GENERATE.equals(fnName)) {
                fn = getArrayGenerateFunction(node);
                argumentTypes = node.getChildren().stream().map(Expr::getType).toArray(Type[]::new);
            } else {
                fn = Expr.getBuiltinFunction(fnName, argumentTypes, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
            }

            if (fn == null) {
                fn = AnalyzerUtils.getUdfFunction(session, node.getFnName(), argumentTypes);
            }

            if (fn == null) {
                String msg = String.format("No matching function with signature: %s(%s)",
                        fnName,
                        node.getParams().isStar() ? "*" : Joiner.on(", ")
                                .join(Arrays.stream(argumentTypes).map(Type::toSql).collect(Collectors.toList())));
                throw new SemanticException(msg, node.getPos());
            }

            if (fn instanceof TableFunction) {
                throw new SemanticException("Table function cannot be used in expression", node.getPos());
            }

            for (int i = 0; i < fn.getNumArgs(); i++) {
                if (!argumentTypes[i].matchesType(fn.getArgs()[i]) &&
                        !Type.canCastToAsFunctionParameter(argumentTypes[i], fn.getArgs()[i])) {
                    String msg = String.format("No matching function with signature: %s(%s)", fnName,
                            node.getParams().isStar() ? "*" :
                                    Arrays.stream(argumentTypes).map(Type::toSql).collect(Collectors.joining(", ")));
                    throw new SemanticException(msg, node.getPos());
                }
            }

            if (fn.hasVarArgs()) {
                Type varType = fn.getArgs()[fn.getNumArgs() - 1];
                for (int i = fn.getNumArgs(); i < argumentTypes.length; i++) {
                    if (!argumentTypes[i].matchesType(varType) &&
                            !Type.canCastToAsFunctionParameter(argumentTypes[i], varType)) {
                        String msg = String.format("Variadic function %s(%s) can't support type: %s", fnName,
                                Arrays.stream(fn.getArgs()).map(Type::toSql).collect(Collectors.joining(", ")),
                                argumentTypes[i]);
                        throw new SemanticException(msg, node.getPos());
                    }
                }
            }

            node.setFn(fn);
            node.setType(fn.getReturnType());
            FunctionAnalyzer.analyze(node);
            return null;
        }