private ColumnTransformer getFunctionColumnTransformer()

in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java [626:1019]


  private ColumnTransformer getFunctionColumnTransformer(
      String functionName, List<Expression> children, Context context) {
    // builtin scalar function
    if (TableBuiltinScalarFunction.DIFF.getFunctionName().equalsIgnoreCase(functionName)) {
      boolean ignoreNull = true;
      if (children.size() > 1) {
        if (isBooleanLiteral(children.get(1))) {
          ignoreNull = ((BooleanLiteral) children.get(1)).getValue();
        } else {
          return new DiffColumnTransformer(
              DOUBLE,
              this.process(children.get(0), context),
              this.process(children.get(1), context));
        }
      }
      return new DiffFunctionColumnTransformer(
          DOUBLE, this.process(children.get(0), context), ignoreNull);
    } else if (TableBuiltinScalarFunction.ROUND.getFunctionName().equalsIgnoreCase(functionName)) {
      int places = 0;
      if (children.size() > 1) {
        if (isLongLiteral(children.get(1))) {
          places = (int) ((LongLiteral) children.get(1)).getParsedValue();
        } else {
          return new RoundColumnTransformer(
              DOUBLE,
              this.process(children.get(0), context),
              this.process(children.get(1), context));
        }
      }
      return new RoundFunctionColumnTransformer(
          DOUBLE, this.process(children.get(0), context), places);
    } else if (TableBuiltinScalarFunction.REPLACE
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 2) {
        if (isStringLiteral(children.get(1))) {
          return new ReplaceFunctionColumnTransformer(
              STRING, first, ((StringLiteral) children.get(1)).getValue(), "");
        } else {
          return new Replace2ColumnTransformer(
              STRING, first, this.process(children.get(1), context));
        }
      } else {
        // size == 3
        if (isStringLiteral(children.get(1)) && isStringLiteral(children.get(2))) {
          return new ReplaceFunctionColumnTransformer(
              STRING,
              first,
              ((StringLiteral) children.get(1)).getValue(),
              ((StringLiteral) children.get(2)).getValue());
        } else {
          return new Replace3ColumnTransformer(
              STRING,
              first,
              this.process(children.get(1), context),
              this.process(children.get(2), context));
        }
      }
    } else if (TableBuiltinScalarFunction.SUBSTRING
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 2) {
        if (isLongLiteral(children.get(1))) {
          int startIndex = (int) ((LongLiteral) children.get(1)).getParsedValue();
          return new SubStringColumnTransformer(STRING, first, startIndex, Integer.MAX_VALUE);
        } else {
          return new SubString2ColumnTransformer(
              STRING, first, this.process(children.get(1), context));
        }
      } else {
        // size == 3
        if (isLongLiteral(children.get(1)) && isLongLiteral(children.get(2))) {
          int startIndex = (int) ((LongLiteral) children.get(1)).getParsedValue();
          int length = (int) ((LongLiteral) children.get(2)).getParsedValue();
          return new SubStringColumnTransformer(STRING, first, startIndex, length);
        } else {
          return new SubString3ColumnTransformer(
              STRING,
              first,
              this.process(children.get(1), context),
              this.process(children.get(2), context));
        }
      }
    } else if (TableBuiltinScalarFunction.LENGTH.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new LengthColumnTransformer(INT32, first);
      }
    } else if (TableBuiltinScalarFunction.UPPER.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new UpperColumnTransformer(STRING, first);
      }
    } else if (TableBuiltinScalarFunction.LOWER.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new LowerColumnTransformer(STRING, first);
      }
    } else if (TableBuiltinScalarFunction.TRIM.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new TrimColumnTransformer(STRING, first, " ");
      } else {
        // children.size() == 2
        if (isStringLiteral(children.get(1))) {
          return new TrimColumnTransformer(
              STRING, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new Trim2ColumnTransformer(STRING, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.LTRIM.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new LTrimColumnTransformer(STRING, first, " ");
      } else {
        // children.size() == 2
        if (isStringLiteral(children.get(1))) {
          return new LTrimColumnTransformer(
              STRING, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new LTrim2ColumnTransformer(STRING, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.RTRIM.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new RTrimColumnTransformer(STRING, first, " ");
      } else {
        // children.size() == 2
        if (isStringLiteral(children.get(1))) {
          return new RTrimColumnTransformer(
              STRING, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new RTrim2ColumnTransformer(STRING, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.REGEXP_LIKE
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 2) {
        if (isStringLiteral(children.get(1))) {
          return new RegexpLikeColumnTransformer(
              BOOLEAN, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new RegexpLike2ColumnTransformer(
              BOOLEAN, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.STRPOS.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 2) {
        if (isStringLiteral(children.get(1))) {
          return new StrposColumnTransformer(
              INT32, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new Strpos2ColumnTransformer(INT32, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.STARTS_WITH
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 2) {
        if (isStringLiteral(children.get(1))) {
          return new StartsWithColumnTransformer(
              BOOLEAN, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new StartsWith2ColumnTransformer(
              BOOLEAN, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.ENDS_WITH
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 2) {
        if (isStringLiteral(children.get(1))) {
          return new EndsWithColumnTransformer(
              BOOLEAN, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new EndsWith2ColumnTransformer(
              BOOLEAN, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.CONCAT.getFunctionName().equalsIgnoreCase(functionName)) {
      if (children.size() == 2) {
        if (isStringLiteral(children.get(1)) && !isStringLiteral(children.get(0))) {
          return new ConcatColumnTransformer(
              STRING,
              this.process(children.get(0), context),
              ((StringLiteral) children.get(1)).getValue(),
              true);
        } else if (isStringLiteral(children.get(0)) && !isStringLiteral(children.get(1))) {
          return new ConcatColumnTransformer(
              STRING,
              this.process(children.get(1), context),
              ((StringLiteral) children.get(0)).getValue(),
              false);
        } else {
          return new Concat2ColumnTransformer(
              STRING,
              this.process(children.get(0), context),
              this.process(children.get(1), context));
        }
      } else {
        List<ColumnTransformer> columnTransformers = new ArrayList<>();
        for (Expression child : children) {
          columnTransformers.add(this.process(child, context));
        }
        return new ConcatMultiColumnTransformer(STRING, columnTransformers);
      }
    } else if (TableBuiltinScalarFunction.STRCMP.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 2) {
        if (isStringLiteral(children.get(1))) {
          return new StrcmpColumnTransformer(
              INT32, first, ((StringLiteral) children.get(1)).getValue());
        } else {
          return new Strcmp2ColumnTransformer(INT32, first, this.process(children.get(1), context));
        }
      }
    } else if (TableBuiltinScalarFunction.SIN.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new SinColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.COS.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new CosColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.TAN.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new TanColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.ASIN.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new AsinColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.ACOS.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new AcosColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.ATAN.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new AtanColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.SINH.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new SinhColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.COSH.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new CoshColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.TANH.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new TanhColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.DEGREES
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new DegreesColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.RADIANS
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new RadiansColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.ABS.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new AbsColumnTransformer(first.getType(), first);
      }
    } else if (TableBuiltinScalarFunction.SIGN.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new SignColumnTransformer(first.getType(), first);
      }
    } else if (TableBuiltinScalarFunction.CEIL.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new CeilColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.FLOOR.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new FloorColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.EXP.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new ExpColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.LN.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new LnColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.LOG10.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new Log10ColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.SQRT.getFunctionName().equalsIgnoreCase(functionName)) {
      ColumnTransformer first = this.process(children.get(0), context);
      if (children.size() == 1) {
        return new SqrtColumnTransformer(DOUBLE, first);
      }
    } else if (TableBuiltinScalarFunction.PI.getFunctionName().equalsIgnoreCase(functionName)) {
      ConstantColumnTransformer piColumnTransformer =
          new ConstantColumnTransformer(
              DOUBLE, new DoubleColumn(1, Optional.empty(), new double[] {Math.PI}));
      context.leafList.add(piColumnTransformer);
      return piColumnTransformer;
    } else if (TableBuiltinScalarFunction.E.getFunctionName().equalsIgnoreCase(functionName)) {
      ConstantColumnTransformer eColumnTransformer =
          new ConstantColumnTransformer(
              DOUBLE, new DoubleColumn(1, Optional.empty(), new double[] {Math.E}));
      context.leafList.add(eColumnTransformer);
      return eColumnTransformer;
    } else if (TableBuiltinScalarFunction.DATE_BIN
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      ColumnTransformer source = this.process(children.get(2), context);
      return new DateBinFunctionColumnTransformer(
          source.getType(),
          ((LongLiteral) children.get(0)).getParsedValue(),
          ((LongLiteral) children.get(1)).getParsedValue(),
          source,
          ((LongLiteral) children.get(3)).getParsedValue(),
          context.sessionInfo.getZoneId());
    } else if (TableBuiltinScalarFunction.FORMAT.getFunctionName().equalsIgnoreCase(functionName)) {
      List<ColumnTransformer> columnTransformers = new ArrayList<>();
      //      String pattern = this.process(children.get(0), context).;
      for (int i = 0; i < children.size(); i++) {
        columnTransformers.add(this.process(children.get(i), context));
      }
      return new FormatColumnTransformer(
          STRING, columnTransformers, context.sessionInfo.getZoneId());
    } else if (TableBuiltinScalarFunction.GREATEST
        .getFunctionName()
        .equalsIgnoreCase(functionName)) {
      List<ColumnTransformer> columnTransformers =
          children.stream().map(child -> this.process(child, context)).collect(Collectors.toList());
      Type returnType = columnTransformers.get(0).getType();
      return AbstractGreatestLeastColumnTransformer.getGreatestColumnTransformer(
          returnType, columnTransformers);
    } else if (TableBuiltinScalarFunction.LEAST.getFunctionName().equalsIgnoreCase(functionName)) {
      List<ColumnTransformer> columnTransformers =
          children.stream().map(child -> this.process(child, context)).collect(Collectors.toList());
      Type returnType = columnTransformers.get(0).getType();
      return AbstractGreatestLeastColumnTransformer.getLeastColumnTransformer(
          returnType, columnTransformers);
    } else {
      // user defined function
      if (TableUDFUtils.isScalarFunction(functionName)) {
        ScalarFunction scalarFunction = TableUDFUtils.getScalarFunction(functionName);
        List<ColumnTransformer> childrenColumnTransformer =
            children.stream().map(child -> process(child, context)).collect(Collectors.toList());
        FunctionArguments parameters =
            new FunctionArguments(
                childrenColumnTransformer.stream()
                    .map(i -> UDFDataTypeTransformer.transformReadTypeToUDFDataType(i.getType()))
                    .collect(Collectors.toList()),
                Collections.emptyMap());
        ScalarFunctionAnalysis analysis = scalarFunction.analyze(parameters);
        scalarFunction.beforeStart(parameters);
        Type returnType =
            UDFDataTypeTransformer.transformUDFDataTypeToReadType(analysis.getOutputDataType());
        return new UserDefineScalarFunctionTransformer(
            returnType, scalarFunction, childrenColumnTransformer);
      }
    }
    throw new IllegalArgumentException(
        String.format(
            "Unknown function %s on DataNode: %d.",
            functionName, IoTDBDescriptor.getInstance().getConfig().getDataNodeId()));
  }