private Expression parseFunctionExpression(
      IoTDBSqlParser.ExpressionContext functionClause, boolean canUseFullPath) {
    FunctionExpression functionExpression =
        new FunctionExpression(parseIdentifier(functionClause.functionName().getText()));

    // expressions
    boolean hasNonPureConstantSubExpression = false;
    for (IoTDBSqlParser.ExpressionContext expression : functionClause.expression()) {
      Expression subexpression = parseExpression(expression, canUseFullPath);
      if (!subexpression.isConstantOperand()) {
        hasNonPureConstantSubExpression = true;
      }
      if (subexpression instanceof EqualToExpression) {
        Expression subLeftExpression = ((EqualToExpression) subexpression).getLeftExpression();
        Expression subRightExpression = ((EqualToExpression) subexpression).getRightExpression();
        if (subLeftExpression.isConstantOperand()
            && (!(subRightExpression.isConstantOperand()
                && ((ConstantOperand) subRightExpression).getDataType().equals(TSDataType.TEXT)))) {
          throw new SemanticException("Attributes of functions should be quoted with '' or \"\"");
        }
        if (subLeftExpression.isConstantOperand() && subRightExpression.isConstantOperand()) {
          // parse attribute
          functionExpression.addAttribute(
              ((ConstantOperand) subLeftExpression).getValueString(),
              ((ConstantOperand) subRightExpression).getValueString());
        } else {
          functionExpression.addExpression(subexpression);
        }
      } else {
        functionExpression.addExpression(subexpression);
      }
    }

    // It is not allowed to have function expressions like F(1, 1.0). There should be at least one
    // non-pure-constant sub-expression, otherwise the timestamp of the row cannot be inferred.
    if (!hasNonPureConstantSubExpression) {
      throw new SemanticException(
          "Invalid function expression, all the arguments are constant operands: "
              + functionClause.getText());
    }

    // check size of input expressions
    // type check of input expressions is put in ExpressionTypeAnalyzer
    if (functionExpression.isBuiltInAggregationFunctionExpression()) {
      checkAggregationFunctionInput(functionExpression);
    } else if (functionExpression.isBuiltInScalarFunctionExpression()) {
      checkBuiltInScalarFunctionInput(functionExpression);
    }
    return functionExpression;
  }
function for parsing file path used by LOAD statement.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java