JackieTien97 commented on code in PR #13136:
URL: https://github.com/apache/iotdb/pull/13136#discussion_r1718077935


##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/Concat2ColumnTransformer.java:
##########
@@ -0,0 +1,62 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class Concat2ColumnTransformer extends BinaryColumnTransformer {
+
+  public Concat2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        
columnBuilder.writeBinary(BytesUtils.valueOf(leftValue.concat(rightValue)));

Review Comment:
   directly call getValues in Binary and new byte[left.length + right.length], 
then copy them into new byte array
   
   Then use the new byte[] array to construct Binary, write it into 
columnBuilder



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTreeRewriter.java:
##########
@@ -421,6 +424,26 @@ public Expression visitFunctionCall(FunctionCall node, 
Context<C> context) {
       return node;
     }
 
+    @Override
+    public Expression visitTrim(Trim node, Context<C> context) {
+      if (!context.isDefaultRewrite()) {
+        Expression result = rewriter.rewriteTrim(node, context.get(), 
ExpressionTreeRewriter.this);
+        if (result != null) {
+          return result;
+        }
+      }
+
+      List<Expression> ExpectedArguments = new ArrayList<>();

Review Comment:
   ```suggestion
         List<Expression> expectedArguments = new ArrayList<>();
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/Concat2ColumnTransformer.java:
##########
@@ -0,0 +1,62 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class Concat2ColumnTransformer extends BinaryColumnTransformer {
+
+  public Concat2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        
columnBuilder.writeBinary(BytesUtils.valueOf(leftValue.concat(rightValue)));
+      } else if (!leftColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBinary(BytesUtils.valueOf(leftValue));
+      } else if (!rightColumn.isNull(i)) {
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBinary(BytesUtils.valueOf(rightValue));

Review Comment:
   ```suggestion
           columnBuilder.writeBinary(rightColumn.getBinary(i));
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTreeRewriter.java:
##########
@@ -421,6 +424,26 @@ public Expression visitFunctionCall(FunctionCall node, 
Context<C> context) {
       return node;
     }
 
+    @Override
+    public Expression visitTrim(Trim node, Context<C> context) {
+      if (!context.isDefaultRewrite()) {
+        Expression result = rewriter.rewriteTrim(node, context.get(), 
ExpressionTreeRewriter.this);
+        if (result != null) {
+          return result;
+        }
+      }
+
+      List<Expression> ExpectedArguments = new ArrayList<>();
+      ExpectedArguments.add(node.getTrimSource());
+      node.getTrimCharacter().ifPresent(ExpectedArguments::add);
+      List<Expression> ActualArguments = rewrite(ExpectedArguments, context);

Review Comment:
   ```suggestion
         List<Expression> actualArguments = rewrite(expectedArguments, context);
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/ConcatMultiColumnTransformer.java:
##########
@@ -0,0 +1,65 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.MultiColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+import java.util.List;
+
+public class ConcatMultiColumnTransformer extends MultiColumnTransformer {
+
+  public ConcatMultiColumnTransformer(
+      Type returnType, List<ColumnTransformer> columnTransformerList) {
+    super(returnType, columnTransformerList);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing because the type is checked in tableMetaDataImpl
+  }
+
+  @Override
+  protected void doTransform(
+      List<Column> childrenColumns, ColumnBuilder builder, int positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      boolean isNull = true;
+      StringBuilder result = new StringBuilder();
+      for (int j = 0; j < childrenColumns.size(); j++) {
+        if (!childrenColumns.get(j).isNull(i)) {
+          isNull = false;
+          result.append(
+              
childrenColumns.get(j).getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET));
+        }
+      }

Review Comment:
   calculate total length first and then use that new a byte[], then copy each 
nonNull element into it.



##########
integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionRelationalIT.java:
##########
@@ -236,6 +236,8 @@ public void insertRelationalSqlTest()
                 row, "id:" + row, "attr:" + row, row * 1.0));
       }
 
+      // 在这里加上transform的操作
+

Review Comment:
   ```suggestion
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RTrimColumnTransformer.java:
##########
@@ -0,0 +1,67 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class RTrimColumnTransformer extends UnaryColumnTransformer {
+  private final String character;
+
+  public RTrimColumnTransformer(
+      Type returnType, ColumnTransformer childColumnTransformer, String 
character) {
+    super(returnType, childColumnTransformer);
+    this.character = character;
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        String currentValue = 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBinary(BytesUtils.valueOf(rtrim(currentValue)));
+      } else {
+        columnBuilder.appendNull();
+      }
+    }
+  }
+
+  private String rtrim(String value) {
+    if (value.isEmpty() || character.isEmpty()) {
+      return value;
+    }
+
+    int end = value.length() - 1;
+
+    while (end >= 0 && character.indexOf(value.charAt(end)) >= 0) end--;
+
+    if (end < 0) {
+      return "";
+    }
+
+    return value.substring(0, end + 1);
+  }

Review Comment:
   same as ltrim



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/LTrimColumnTransformer.java:
##########
@@ -0,0 +1,67 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class LTrimColumnTransformer extends UnaryColumnTransformer {
+  private final String character;
+
+  public LTrimColumnTransformer(
+      Type returnType, ColumnTransformer childColumnTransformer, String 
character) {
+    super(returnType, childColumnTransformer);
+    this.character = character;
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        String currentValue = 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBinary(BytesUtils.valueOf(ltrim(currentValue)));
+      } else {
+        columnBuilder.appendNull();
+      }
+    }
+  }
+
+  private String ltrim(String value) {
+    if (value.isEmpty() || character.isEmpty()) {
+      return value;
+    }
+
+    int start = 0;
+
+    while (start < value.length() && character.indexOf(value.charAt(start)) >= 
0) start++;
+
+    if (start >= value.length()) {
+      return "";
+    } else {
+      return value.substring(start);
+    }
+  }

Review Comment:
   duplicated code



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/SignColumnTransformer.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.type.Type;
+
+public class SignColumnTransformer extends UnaryColumnTransformer {
+  public SignColumnTransformer(Type returnType, ColumnTransformer 
childColumnTransformer) {
+    super(returnType, childColumnTransformer);
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        if (TSDataType.DOUBLE.equals(column.getDataType())) {
+          columnBuilder.writeInt((int) Math.signum(column.getDouble(i)));
+        } else if (TSDataType.FLOAT.equals(column.getDataType())) {
+          columnBuilder.writeInt((int) Math.signum(column.getFloat(i)));

Review Comment:
   ```suggestion
             columnBuilder.writeFloat(Math.signum(column.getFloat(i)));
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java:
##########
@@ -188,6 +193,278 @@ && isIntegerNumber(argumentTypes.get(2)))) {
                 + " only accepts two or three arguments and first must be text 
or string data type, second and third must be numeric data types [INT32, 
INT64]");
       }
       return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.LENGTH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be text or string 
data type.");
+      }
+      return INT32;
+    } else if 
(TableBuiltinScalarFunction.UPPER.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be text or string 
data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.LOWER.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be text or string 
data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.TRIM.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))
+          && !(argumentTypes.size() == 2 && isTwoCharType(argumentTypes))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one or two arguments and they must be text or 
string data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.LTRIM.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))
+          && !(argumentTypes.size() == 2 && isTwoCharType(argumentTypes))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one or two arguments and they must be text or 
string data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.RTRIM.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))
+          && !(argumentTypes.size() == 2 && isTwoCharType(argumentTypes))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one or two arguments and they must be text or 
string data type.");
+      }
+      return argumentTypes.get(0);
+    } else if (TableBuiltinScalarFunction.STRING_CONTAINS
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if (TableBuiltinScalarFunction.REGEXP_LIKE
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if 
(TableBuiltinScalarFunction.STRPOS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return INT32;
+    } else if (TableBuiltinScalarFunction.STARTS_WITH
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if (TableBuiltinScalarFunction.ENDS_WITH
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if 
(TableBuiltinScalarFunction.CONCAT.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() >= 2
+          && argumentTypes.stream().allMatch(TableMetadataImpl::isCharType))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two or more arguments and they must be text 
or string data type.");
+      }
+      return STRING;
+    } else if 
(TableBuiltinScalarFunction.STRCMP.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return INT32;
+    } else if 
(TableBuiltinScalarFunction.SIN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.COS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.TAN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ASIN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ACOS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ATAN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.SINH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.COSH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.TANH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if (TableBuiltinScalarFunction.DEGREES
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if (TableBuiltinScalarFunction.RADIANS
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ABS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.SIGN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return INT32;

Review Comment:
   return type should same as 
input(https://trino.io/docs/current/functions/math.html#sign)
   <img width="479" alt="image" 
src="https://github.com/user-attachments/assets/fe9f55ff-4a36-4f2d-ab48-9edcb6a033b8";>
   
   return argumentTypes.get(0);
   



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/StartsWithColumnTransformer.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class StartsWithColumnTransformer extends UnaryColumnTransformer {
+  private final String prefix;
+
+  public StartsWithColumnTransformer(
+      Type returnType, ColumnTransformer childColumnTransformer, String 
prefix) {
+    super(returnType, childColumnTransformer);
+    this.prefix = prefix;
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        String currentValue = 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBoolean(currentValue.startsWith(prefix));

Review Comment:
   same as ends_with, using byte[] to compare directly.



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/Strcmp2ColumnTransformer.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class Strcmp2ColumnTransformer extends BinaryColumnTransformer {
+  public Strcmp2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        
columnBuilder.writeInt(Integer.compare(leftValue.compareTo(rightValue), 0));

Review Comment:
   no need to transform Bianry to String and then compare, you can directly use 
`compareTo` method in `Binary` class



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java:
##########
@@ -188,6 +193,278 @@ && isIntegerNumber(argumentTypes.get(2)))) {
                 + " only accepts two or three arguments and first must be text 
or string data type, second and third must be numeric data types [INT32, 
INT64]");
       }
       return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.LENGTH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be text or string 
data type.");
+      }
+      return INT32;
+    } else if 
(TableBuiltinScalarFunction.UPPER.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be text or string 
data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.LOWER.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be text or string 
data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.TRIM.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))
+          && !(argumentTypes.size() == 2 && isTwoCharType(argumentTypes))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one or two arguments and they must be text or 
string data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.LTRIM.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))
+          && !(argumentTypes.size() == 2 && isTwoCharType(argumentTypes))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one or two arguments and they must be text or 
string data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.RTRIM.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isCharType(argumentTypes.get(0)))
+          && !(argumentTypes.size() == 2 && isTwoCharType(argumentTypes))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one or two arguments and they must be text or 
string data type.");
+      }
+      return argumentTypes.get(0);
+    } else if (TableBuiltinScalarFunction.STRING_CONTAINS
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if (TableBuiltinScalarFunction.REGEXP_LIKE
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if 
(TableBuiltinScalarFunction.STRPOS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return INT32;
+    } else if (TableBuiltinScalarFunction.STARTS_WITH
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if (TableBuiltinScalarFunction.ENDS_WITH
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return BOOLEAN;
+    } else if 
(TableBuiltinScalarFunction.CONCAT.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() >= 2
+          && argumentTypes.stream().allMatch(TableMetadataImpl::isCharType))) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two or more arguments and they must be text 
or string data type.");
+      }
+      return STRING;
+    } else if 
(TableBuiltinScalarFunction.STRCMP.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!isTwoCharType(argumentTypes)) {
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts two arguments and they must be text or string 
data type.");
+      }
+      return INT32;
+    } else if 
(TableBuiltinScalarFunction.SIN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.COS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.TAN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ASIN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ACOS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ATAN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.SINH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.COSH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.TANH.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if (TableBuiltinScalarFunction.DEGREES
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if (TableBuiltinScalarFunction.RADIANS
+        .getFunctionName()
+        .equalsIgnoreCase(functionName)) {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return DOUBLE;
+    } else if 
(TableBuiltinScalarFunction.ABS.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return argumentTypes.get(0);
+    } else if 
(TableBuiltinScalarFunction.SIGN.getFunctionName().equalsIgnoreCase(functionName))
 {
+      if (!(argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0)))) 
{
+        throw new SemanticException(
+            "Scalar function "
+                + functionName.toLowerCase(Locale.ENGLISH)
+                + " only accepts one argument and it must be TimeStamp, 
Double, Float, Int32 or Int64 data type.");
+      }
+      return INT32;

Review Comment:
   for timestamp dataType, its return type should also be long



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/ConcatColumnTransformer.java:
##########
@@ -0,0 +1,57 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class ConcatColumnTransformer extends UnaryColumnTransformer {
+  private final String str;

Review Comment:
   init it as byte[], and then copy byte[] in doTransform method



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/EndsWith2ColumnTransformer.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class EndsWith2ColumnTransformer extends BinaryColumnTransformer {
+  public EndsWith2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBoolean(leftValue.endsWith(rightValue));

Review Comment:
   directly compare with underlying byte[]



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/EndsWithColumnTransformer.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class EndsWithColumnTransformer extends UnaryColumnTransformer {
+  private final String suffix;
+
+  public EndsWithColumnTransformer(
+      Type returnType, ColumnTransformer childColumnTransformer, String 
suffix) {
+    super(returnType, childColumnTransformer);
+    this.suffix = suffix;
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        String currentValue = 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBoolean(currentValue.endsWith(suffix));

Review Comment:
   directly compare with underlying byte[]



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/EndsWithColumnTransformer.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class EndsWithColumnTransformer extends UnaryColumnTransformer {
+  private final String suffix;

Review Comment:
   init it using byte[]



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/Concat2ColumnTransformer.java:
##########
@@ -0,0 +1,62 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class Concat2ColumnTransformer extends BinaryColumnTransformer {
+
+  public Concat2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        
columnBuilder.writeBinary(BytesUtils.valueOf(leftValue.concat(rightValue)));
+      } else if (!leftColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBinary(BytesUtils.valueOf(leftValue));

Review Comment:
   ```suggestion
           columnBuilder.writeBinary(leftColumn.getBinary(i));
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RTrim2ColumnTransformer.java:
##########
@@ -0,0 +1,67 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class RTrim2ColumnTransformer extends BinaryColumnTransformer {
+  public RTrim2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBinary(BytesUtils.valueOf(rtrim(leftValue, 
rightValue)));
+      } else {
+        columnBuilder.appendNull();
+      }
+    }
+  }
+
+  private String rtrim(String source, String character) {

Review Comment:
   same as ltrim



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/LTrim2ColumnTransformer.java:
##########
@@ -0,0 +1,70 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.BytesUtils;
+
+public class LTrim2ColumnTransformer extends BinaryColumnTransformer {
+  public LTrim2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBinary(BytesUtils.valueOf(ltrim(leftValue, 
rightValue)));
+      } else {
+        columnBuilder.appendNull();
+      }
+    }
+  }
+
+  private String ltrim(String source, String character) {

Review Comment:
   make it as public static method and then call this method in another LTrim 
to avoid duplicated codes.



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/SignColumnTransformer.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.type.Type;
+
+public class SignColumnTransformer extends UnaryColumnTransformer {
+  public SignColumnTransformer(Type returnType, ColumnTransformer 
childColumnTransformer) {
+    super(returnType, childColumnTransformer);
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        if (TSDataType.DOUBLE.equals(column.getDataType())) {
+          columnBuilder.writeInt((int) Math.signum(column.getDouble(i)));
+        } else if (TSDataType.FLOAT.equals(column.getDataType())) {
+          columnBuilder.writeInt((int) Math.signum(column.getFloat(i)));
+        } else if (TSDataType.INT32.equals(column.getDataType())) {
+          columnBuilder.writeInt((int) Math.signum(column.getInt(i)));
+        } else if (TSDataType.INT64.equals(column.getDataType())
+            || TSDataType.TIMESTAMP.equals(column.getDataType())) {
+          columnBuilder.writeInt((int) Math.signum(column.getLong(i)));

Review Comment:
   ```suggestion
             columnBuilder.writeLong((long) Math.signum(column.getLong(i)));
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RegexpLikeColumnTransformer.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class RegexpLikeColumnTransformer extends UnaryColumnTransformer {
+  private final String regex;

Review Comment:
           Pattern p = Pattern.compile(regex);
   



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/RegexpLikeColumnTransformer.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class RegexpLikeColumnTransformer extends UnaryColumnTransformer {
+  private final String regex;
+
+  public RegexpLikeColumnTransformer(
+      Type returnType, ColumnTransformer childColumnTransformer, String regex) 
{
+    super(returnType, childColumnTransformer);
+    this.regex = regex;
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        String currentValue = 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBoolean(currentValue.matches(regex));

Review Comment:
   ```suggestion
           columnBuilder.writeBoolean(p.matcher(currentValue).matches());
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/StartsWith2ColumnTransformer.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class StartsWith2ColumnTransformer extends BinaryColumnTransformer {
+  public StartsWith2ColumnTransformer(
+      Type returnType, ColumnTransformer leftTransformer, ColumnTransformer 
rightTransformer) {
+    super(returnType, leftTransformer, rightTransformer);
+  }
+
+  @Override
+  protected void checkType() {
+    // do nothing
+  }
+
+  @Override
+  protected void doTransform(
+      Column leftColumn, Column rightColumn, ColumnBuilder columnBuilder, int 
positionCount) {
+    for (int i = 0; i < positionCount; i++) {
+      if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+        String leftValue = 
leftColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        String rightValue = 
rightColumn.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET);
+        columnBuilder.writeBoolean(leftValue.startsWith(rightValue));

Review Comment:
   same as ends_with, using byte[] to compare directly.



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/SignColumnTransformer.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.type.Type;
+
+public class SignColumnTransformer extends UnaryColumnTransformer {
+  public SignColumnTransformer(Type returnType, ColumnTransformer 
childColumnTransformer) {
+    super(returnType, childColumnTransformer);
+  }
+
+  @Override
+  protected void doTransform(Column column, ColumnBuilder columnBuilder) {
+    for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+      if (!column.isNull(i)) {
+        if (TSDataType.DOUBLE.equals(column.getDataType())) {
+          columnBuilder.writeInt((int) Math.signum(column.getDouble(i)));

Review Comment:
   ```suggestion
             columnBuilder.writeDouble(Math.signum(column.getDouble(i)));
   ```



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/StringContainsColumnTransformer.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class StringContainsColumnTransformer extends UnaryColumnTransformer {

Review Comment:
   remove?



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/StringContains2ColumnTransformer.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.BinaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class StringContains2ColumnTransformer extends BinaryColumnTransformer {

Review Comment:
   remove?



##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/StrcmpColumnTransformer.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * 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.iotdb.db.queryengine.transformation.dag.column.unary.scalar;
+
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import 
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.UnaryColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.read.common.type.Type;
+
+public class StrcmpColumnTransformer extends UnaryColumnTransformer {
+  private final String str;

Review Comment:
   init it as Binary and then use Binary.compareTo in doTransform method



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to