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()));
}