This is an automated email from the ASF dual-hosted git repository.

jt2594838 pushed a commit to branch remove_swtich_type
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit ade03e2d1fd93807431adc8f3029650e92d9e891
Author: Tian Jiang <[email protected]>
AuthorDate: Thu Aug 27 18:29:07 2026 +0800

    multiple refactors
---
 .../iotdb/commons/udf/builtin/TypeServices.java    | 206 +++++++++++++++++++++
 .../commons/udf/builtin/UDTFCommonDerivative.java  |  41 +---
 .../udf/builtin/UDTFCommonValueDifference.java     |  42 +----
 .../iotdb/commons/udf/builtin/UDTFDerivative.java  |  11 ++
 .../udf/builtin/UDTFNonNegativeDerivative.java     |  48 +----
 .../builtin/UDTFNonNegativeValueDifference.java    |  49 +----
 .../commons/udf/builtin/UDTFValueDifference.java   |  12 ++
 .../iotdb/commons/udf/builtin/UDTFValueTrend.java  |  42 ++---
 8 files changed, 259 insertions(+), 192 deletions(-)

diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/TypeServices.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/TypeServices.java
new file mode 100644
index 00000000000..f663171abae
--- /dev/null
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/TypeServices.java
@@ -0,0 +1,206 @@
+/*
+ * 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.commons.udf.builtin;
+
+import org.apache.iotdb.udf.api.access.Row;
+import org.apache.iotdb.udf.api.collector.PointCollector;
+import 
org.apache.iotdb.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
+
+import org.apache.tsfile.read.common.type.service.TypeService;
+
+import java.io.IOException;
+
+/** Type-specific operations used by numeric built-in UDFs. */
+final class TypeServices {
+
+  // Select the primitive Row accessor once per UDF instance instead of 
switching for every row.
+  static final TypeService<PreviousValueReader> VALUE_TREND_READER_SERVICE =
+      type ->
+          switch (type.getTypeEnum()) {
+            case INT32 -> (target, row) -> target.previousInt = row.getInt(0);
+            case INT64 -> (target, row) -> target.previousLong = 
row.getLong(0);
+            case FLOAT -> (target, row) -> target.previousFloat = 
row.getFloat(0);
+            case DOUBLE -> (target, row) -> target.previousDouble = 
row.getDouble(0);
+            case BOOLEAN, DATE, TIMESTAMP, TEXT, STRING, BLOB, OBJECT, ROW, 
UNKNOWN, VECTOR ->
+                (target, row) -> {
+                  throw target.invalidDataType();
+                };
+          };
+
+  static final TypeService<ValueDifferenceOperator> 
VALUE_DIFFERENCE_OPERATOR_SERVICE =
+      type ->
+          switch (type.getTypeEnum()) {
+            case INT32 ->
+                (target, time, row, collector) -> {
+                  int current = row.getInt(0);
+                  collector.putInt(time, current - target.previousInt);
+                  target.previousInt = current;
+                };
+            case INT64 ->
+                (target, time, row, collector) -> {
+                  long current = row.getLong(0);
+                  collector.putLong(time, current - target.previousLong);
+                  target.previousLong = current;
+                };
+            case FLOAT ->
+                (target, time, row, collector) -> {
+                  float current = row.getFloat(0);
+                  collector.putFloat(time, current - target.previousFloat);
+                  target.previousFloat = current;
+                };
+            case DOUBLE ->
+                (target, time, row, collector) -> {
+                  double current = row.getDouble(0);
+                  collector.putDouble(time, current - target.previousDouble);
+                  target.previousDouble = current;
+                };
+            case BOOLEAN, DATE, TIMESTAMP, TEXT, STRING, BLOB, OBJECT, ROW, 
UNKNOWN, VECTOR ->
+                (target, time, row, collector) -> {
+                  throw target.invalidDataType();
+                };
+          };
+
+  static final TypeService<ValueDifferenceOperator> 
NON_NEGATIVE_VALUE_DIFFERENCE_OPERATOR_SERVICE =
+      type ->
+          switch (type.getTypeEnum()) {
+            case INT32 ->
+                (target, time, row, collector) -> {
+                  int current = row.getInt(0);
+                  collector.putInt(time, Math.abs(current - 
target.previousInt));
+                  target.previousInt = current;
+                };
+            case INT64 ->
+                (target, time, row, collector) -> {
+                  long current = row.getLong(0);
+                  collector.putLong(time, Math.abs(current - 
target.previousLong));
+                  target.previousLong = current;
+                };
+            case FLOAT ->
+                (target, time, row, collector) -> {
+                  float current = row.getFloat(0);
+                  collector.putFloat(time, Math.abs(current - 
target.previousFloat));
+                  target.previousFloat = current;
+                };
+            case DOUBLE ->
+                (target, time, row, collector) -> {
+                  double current = row.getDouble(0);
+                  collector.putDouble(time, Math.abs(current - 
target.previousDouble));
+                  target.previousDouble = current;
+                };
+            case BOOLEAN, DATE, TIMESTAMP, TEXT, STRING, BLOB, OBJECT, ROW, 
UNKNOWN, VECTOR ->
+                (target, time, row, collector) -> {
+                  throw target.invalidDataType();
+                };
+          };
+
+  static final TypeService<DerivativeOperator> DERIVATIVE_OPERATOR_SERVICE =
+      type ->
+          switch (type.getTypeEnum()) {
+            case INT32 ->
+                (target, time, row, collector, timeDelta) -> {
+                  int current = row.getInt(0);
+                  collector.putDouble(time, (current - target.previousInt) / 
timeDelta);
+                  target.previousInt = current;
+                };
+            case INT64 ->
+                (target, time, row, collector, timeDelta) -> {
+                  long current = row.getLong(0);
+                  collector.putDouble(time, (current - target.previousLong) / 
timeDelta);
+                  target.previousLong = current;
+                };
+            case FLOAT ->
+                (target, time, row, collector, timeDelta) -> {
+                  float current = row.getFloat(0);
+                  collector.putDouble(time, (current - target.previousFloat) / 
timeDelta);
+                  target.previousFloat = current;
+                };
+            case DOUBLE ->
+                (target, time, row, collector, timeDelta) -> {
+                  double current = row.getDouble(0);
+                  collector.putDouble(time, (current - target.previousDouble) 
/ timeDelta);
+                  target.previousDouble = current;
+                };
+            case BOOLEAN, DATE, TIMESTAMP, TEXT, STRING, BLOB, OBJECT, ROW, 
UNKNOWN, VECTOR ->
+                (target, time, row, collector, timeDelta) -> {
+                  throw target.invalidDataType();
+                };
+          };
+
+  static final TypeService<DerivativeOperator> 
NON_NEGATIVE_DERIVATIVE_OPERATOR_SERVICE =
+      type ->
+          switch (type.getTypeEnum()) {
+            case INT32 ->
+                (target, time, row, collector, timeDelta) -> {
+                  int current = row.getInt(0);
+                  collector.putDouble(time, Math.abs(current - 
target.previousInt) / timeDelta);
+                  target.previousInt = current;
+                };
+            case INT64 ->
+                (target, time, row, collector, timeDelta) -> {
+                  long current = row.getLong(0);
+                  collector.putDouble(time, Math.abs(current - 
target.previousLong) / timeDelta);
+                  target.previousLong = current;
+                };
+            case FLOAT ->
+                (target, time, row, collector, timeDelta) -> {
+                  float current = row.getFloat(0);
+                  collector.putDouble(time, Math.abs(current - 
target.previousFloat) / timeDelta);
+                  target.previousFloat = current;
+                };
+            case DOUBLE ->
+                (target, time, row, collector, timeDelta) -> {
+                  double current = row.getDouble(0);
+                  collector.putDouble(time, Math.abs(current - 
target.previousDouble) / timeDelta);
+                  target.previousDouble = current;
+                };
+            case BOOLEAN, DATE, TIMESTAMP, TEXT, STRING, BLOB, OBJECT, ROW, 
UNKNOWN, VECTOR ->
+                (target, time, row, collector, timeDelta) -> {
+                  throw target.invalidDataType();
+                };
+          };
+
+  static {
+    VALUE_TREND_READER_SERVICE.check();
+    VALUE_DIFFERENCE_OPERATOR_SERVICE.check();
+    NON_NEGATIVE_VALUE_DIFFERENCE_OPERATOR_SERVICE.check();
+    DERIVATIVE_OPERATOR_SERVICE.check();
+    NON_NEGATIVE_DERIVATIVE_OPERATOR_SERVICE.check();
+  }
+
+  private TypeServices() {}
+
+  @FunctionalInterface
+  interface PreviousValueReader {
+    void read(UDTFValueTrend target, Row row)
+        throws UDFInputSeriesDataTypeNotValidException, IOException;
+  }
+
+  @FunctionalInterface
+  interface ValueDifferenceOperator {
+    void apply(UDTFValueTrend target, long time, Row row, PointCollector 
collector)
+        throws UDFInputSeriesDataTypeNotValidException, IOException;
+  }
+
+  @FunctionalInterface
+  interface DerivativeOperator {
+    void apply(
+        UDTFValueTrend target, long time, Row row, PointCollector collector, 
double timeDelta)
+        throws UDFInputSeriesDataTypeNotValidException, IOException;
+  }
+}
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonDerivative.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonDerivative.java
index cb5cbcc0486..0a80ad2de28 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonDerivative.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonDerivative.java
@@ -19,11 +19,9 @@
 
 package org.apache.iotdb.commons.udf.builtin;
 
-import org.apache.iotdb.commons.udf.utils.UDFDataTypeTransformer;
 import org.apache.iotdb.udf.api.access.Row;
 import org.apache.iotdb.udf.api.collector.PointCollector;
 import 
org.apache.iotdb.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
-import org.apache.iotdb.udf.api.type.Type;
 
 import java.io.IOException;
 
@@ -34,44 +32,7 @@ public class UDTFCommonDerivative extends UDTFDerivative {
       throws UDFInputSeriesDataTypeNotValidException, IOException {
     long currentTime = row.getTime();
     double timeDelta = (double) currentTime - previousTime;
-    switch (dataType) {
-      case INT32:
-        int currentInt = row.getInt(0);
-        collector.putDouble(currentTime, (currentInt - previousInt) / 
timeDelta);
-        previousInt = currentInt;
-        break;
-      case INT64:
-        long currentLong = row.getLong(0);
-        collector.putDouble(currentTime, (currentLong - previousLong) / 
timeDelta);
-        previousLong = currentLong;
-        break;
-      case FLOAT:
-        float currentFloat = row.getFloat(0);
-        collector.putDouble(currentTime, (currentFloat - previousFloat) / 
timeDelta);
-        previousFloat = currentFloat;
-        break;
-      case DOUBLE:
-        double currentDouble = row.getDouble(0);
-        collector.putDouble(currentTime, (currentDouble - previousDouble) / 
timeDelta);
-        previousDouble = currentDouble;
-        break;
-      case DATE:
-      case BOOLEAN:
-      case TIMESTAMP:
-      case TEXT:
-      case STRING:
-      case BLOB:
-      case OBJECT:
-      default:
-        // This will not happen.
-        throw new UDFInputSeriesDataTypeNotValidException(
-            0,
-            UDFDataTypeTransformer.transformToUDFDataType(dataType),
-            Type.INT32,
-            Type.INT64,
-            Type.FLOAT,
-            Type.DOUBLE);
-    }
+    derivativeOperator.apply(this, currentTime, row, collector, timeDelta);
     previousTime = currentTime;
   }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonValueDifference.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonValueDifference.java
index 7f8d81f6b82..0a4deac2024 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonValueDifference.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFCommonValueDifference.java
@@ -19,11 +19,9 @@
 
 package org.apache.iotdb.commons.udf.builtin;
 
-import org.apache.iotdb.commons.udf.utils.UDFDataTypeTransformer;
 import org.apache.iotdb.udf.api.access.Row;
 import org.apache.iotdb.udf.api.collector.PointCollector;
 import 
org.apache.iotdb.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
-import org.apache.iotdb.udf.api.type.Type;
 
 import java.io.IOException;
 
@@ -32,44 +30,6 @@ public class UDTFCommonValueDifference extends 
UDTFValueDifference {
   @Override
   protected void doTransform(Row row, PointCollector collector)
       throws UDFInputSeriesDataTypeNotValidException, IOException {
-    long time = row.getTime();
-    switch (dataType) {
-      case INT32:
-        int currentInt = row.getInt(0);
-        collector.putInt(time, currentInt - previousInt);
-        previousInt = currentInt;
-        break;
-      case INT64:
-        long currentLong = row.getLong(0);
-        collector.putLong(time, currentLong - previousLong);
-        previousLong = currentLong;
-        break;
-      case FLOAT:
-        float currentFloat = row.getFloat(0);
-        collector.putFloat(time, currentFloat - previousFloat);
-        previousFloat = currentFloat;
-        break;
-      case DOUBLE:
-        double currentDouble = row.getDouble(0);
-        collector.putDouble(time, currentDouble - previousDouble);
-        previousDouble = currentDouble;
-        break;
-      case STRING:
-      case BLOB:
-      case OBJECT:
-      case TIMESTAMP:
-      case TEXT:
-      case BOOLEAN:
-      case DATE:
-      default:
-        // This will not happen.
-        throw new UDFInputSeriesDataTypeNotValidException(
-            0,
-            UDFDataTypeTransformer.transformToUDFDataType(dataType),
-            Type.INT32,
-            Type.INT64,
-            Type.FLOAT,
-            Type.DOUBLE);
-    }
+    valueDifferenceOperator.apply(this, row.getTime(), row, collector);
   }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFDerivative.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFDerivative.java
index 81645d47787..2457ed89811 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFDerivative.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFDerivative.java
@@ -29,16 +29,27 @@ import 
org.apache.iotdb.udf.api.customizer.strategy.RowByRowAccessStrategy;
 import 
org.apache.iotdb.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
 import org.apache.iotdb.udf.api.type.Type;
 
+import org.apache.tsfile.read.common.type.service.TypeService;
+
 import java.io.IOException;
 
 public abstract class UDTFDerivative extends UDTFValueTrend {
 
   protected long previousTime;
+  protected TypeServices.DerivativeOperator derivativeOperator;
+
+  protected TypeService<TypeServices.DerivativeOperator> 
derivativeOperatorService() {
+    return TypeServices.DERIVATIVE_OPERATOR_SERVICE;
+  }
 
   @Override
   public void beforeStart(UDFParameters parameters, UDTFConfigurations 
configurations)
       throws MetadataException {
     dataType = 
UDFDataTypeTransformer.transformToTsDataType(parameters.getDataType(0));
+    org.apache.tsfile.read.common.type.Type type =
+        org.apache.tsfile.read.common.type.Type.fromTsDataType(dataType);
+    previousValueReader = TypeServices.VALUE_TREND_READER_SERVICE.call(type);
+    derivativeOperator = derivativeOperatorService().call(type);
     configurations.setAccessStrategy(new 
RowByRowAccessStrategy()).setOutputDataType(Type.DOUBLE);
   }
 
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeDerivative.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeDerivative.java
index 077db957f6e..3847e8638b4 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeDerivative.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeDerivative.java
@@ -19,59 +19,27 @@
 
 package org.apache.iotdb.commons.udf.builtin;
 
-import org.apache.iotdb.commons.udf.utils.UDFDataTypeTransformer;
 import org.apache.iotdb.udf.api.access.Row;
 import org.apache.iotdb.udf.api.collector.PointCollector;
 import 
org.apache.iotdb.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
-import org.apache.iotdb.udf.api.type.Type;
+
+import org.apache.tsfile.read.common.type.service.TypeService;
 
 import java.io.IOException;
 
 public class UDTFNonNegativeDerivative extends UDTFDerivative {
 
+  @Override
+  protected TypeService<TypeServices.DerivativeOperator> 
derivativeOperatorService() {
+    return TypeServices.NON_NEGATIVE_DERIVATIVE_OPERATOR_SERVICE;
+  }
+
   @Override
   protected void doTransform(Row row, PointCollector collector)
       throws UDFInputSeriesDataTypeNotValidException, IOException {
     long currentTime = row.getTime();
     double timeDelta = (double) currentTime - previousTime;
-    switch (dataType) {
-      case INT32:
-        int currentInt = row.getInt(0);
-        collector.putDouble(currentTime, Math.abs(currentInt - previousInt) / 
timeDelta);
-        previousInt = currentInt;
-        break;
-      case INT64:
-        long currentLong = row.getLong(0);
-        collector.putDouble(currentTime, Math.abs(currentLong - previousLong) 
/ timeDelta);
-        previousLong = currentLong;
-        break;
-      case FLOAT:
-        float currentFloat = row.getFloat(0);
-        collector.putDouble(currentTime, Math.abs(currentFloat - 
previousFloat) / timeDelta);
-        previousFloat = currentFloat;
-        break;
-      case DOUBLE:
-        double currentDouble = row.getDouble(0);
-        collector.putDouble(currentTime, Math.abs(currentDouble - 
previousDouble) / timeDelta);
-        previousDouble = currentDouble;
-        break;
-      case DATE:
-      case BLOB:
-      case OBJECT:
-      case STRING:
-      case TIMESTAMP:
-      case BOOLEAN:
-      case TEXT:
-      default:
-        // This will not happen.
-        throw new UDFInputSeriesDataTypeNotValidException(
-            0,
-            UDFDataTypeTransformer.transformToUDFDataType(dataType),
-            Type.INT32,
-            Type.INT64,
-            Type.FLOAT,
-            Type.DOUBLE);
-    }
+    derivativeOperator.apply(this, currentTime, row, collector, timeDelta);
     previousTime = currentTime;
   }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeValueDifference.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeValueDifference.java
index fcb68817f15..2cafcf446c3 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeValueDifference.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFNonNegativeValueDifference.java
@@ -19,57 +19,24 @@
 
 package org.apache.iotdb.commons.udf.builtin;
 
-import org.apache.iotdb.commons.udf.utils.UDFDataTypeTransformer;
 import org.apache.iotdb.udf.api.access.Row;
 import org.apache.iotdb.udf.api.collector.PointCollector;
 import 
org.apache.iotdb.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
-import org.apache.iotdb.udf.api.type.Type;
+
+import org.apache.tsfile.read.common.type.service.TypeService;
 
 import java.io.IOException;
 
 public class UDTFNonNegativeValueDifference extends UDTFValueDifference {
 
+  @Override
+  protected TypeService<TypeServices.ValueDifferenceOperator> 
valueDifferenceOperatorService() {
+    return TypeServices.NON_NEGATIVE_VALUE_DIFFERENCE_OPERATOR_SERVICE;
+  }
+
   @Override
   protected void doTransform(Row row, PointCollector collector)
       throws UDFInputSeriesDataTypeNotValidException, IOException {
-    long time = row.getTime();
-    switch (dataType) {
-      case INT32:
-        int currentInt = row.getInt(0);
-        collector.putInt(time, Math.abs(currentInt - previousInt));
-        previousInt = currentInt;
-        break;
-      case INT64:
-        long currentLong = row.getLong(0);
-        collector.putLong(time, Math.abs(currentLong - previousLong));
-        previousLong = currentLong;
-        break;
-      case FLOAT:
-        float currentFloat = row.getFloat(0);
-        collector.putFloat(time, Math.abs(currentFloat - previousFloat));
-        previousFloat = currentFloat;
-        break;
-      case DOUBLE:
-        double currentDouble = row.getDouble(0);
-        collector.putDouble(time, Math.abs(currentDouble - previousDouble));
-        previousDouble = currentDouble;
-        break;
-      case BOOLEAN:
-      case TEXT:
-      case STRING:
-      case TIMESTAMP:
-      case BLOB:
-      case OBJECT:
-      case DATE:
-      default:
-        // This will not happen.
-        throw new UDFInputSeriesDataTypeNotValidException(
-            0,
-            UDFDataTypeTransformer.transformToUDFDataType(dataType),
-            Type.INT32,
-            Type.INT64,
-            Type.FLOAT,
-            Type.DOUBLE);
-    }
+    valueDifferenceOperator.apply(this, row.getTime(), row, collector);
   }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueDifference.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueDifference.java
index 9804e1ce374..81d8cc78aa7 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueDifference.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueDifference.java
@@ -28,14 +28,26 @@ import 
org.apache.iotdb.udf.api.customizer.parameter.UDFParameters;
 import org.apache.iotdb.udf.api.customizer.strategy.RowByRowAccessStrategy;
 import 
org.apache.iotdb.udf.api.exception.UDFInputSeriesDataTypeNotValidException;
 
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.read.common.type.service.TypeService;
+
 import java.io.IOException;
 
 public abstract class UDTFValueDifference extends UDTFValueTrend {
 
+  protected TypeServices.ValueDifferenceOperator valueDifferenceOperator;
+
+  protected TypeService<TypeServices.ValueDifferenceOperator> 
valueDifferenceOperatorService() {
+    return TypeServices.VALUE_DIFFERENCE_OPERATOR_SERVICE;
+  }
+
   @Override
   public void beforeStart(UDFParameters parameters, UDTFConfigurations 
configurations)
       throws MetadataException {
     dataType = 
UDFDataTypeTransformer.transformToTsDataType(parameters.getDataType(0));
+    Type type = Type.fromTsDataType(dataType);
+    previousValueReader = TypeServices.VALUE_TREND_READER_SERVICE.call(type);
+    valueDifferenceOperator = valueDifferenceOperatorService().call(type);
     configurations
         .setAccessStrategy(new RowByRowAccessStrategy())
         
.setOutputDataType(UDFDataTypeTransformer.transformToUDFDataType(dataType));
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueTrend.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueTrend.java
index d4487fdfd95..1f8a7718822 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueTrend.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFValueTrend.java
@@ -42,6 +42,7 @@ public abstract class UDTFValueTrend implements UDTF {
   protected double previousDouble = 0;
 
   protected TSDataType dataType;
+  protected TypeServices.PreviousValueReader previousValueReader;
 
   @Override
   public void validate(UDFParameterValidator validator) throws UDFException {
@@ -52,36 +53,17 @@ public abstract class UDTFValueTrend implements UDTF {
 
   protected void updatePreviousValue(Row row)
       throws UDFInputSeriesDataTypeNotValidException, IOException {
-    switch (dataType) {
-      case INT32:
-        previousInt = row.getInt(0);
-        break;
-      case INT64:
-        previousLong = row.getLong(0);
-        break;
-      case FLOAT:
-        previousFloat = row.getFloat(0);
-        break;
-      case DOUBLE:
-        previousDouble = row.getDouble(0);
-        break;
-      case TEXT:
-      case BOOLEAN:
-      case TIMESTAMP:
-      case STRING:
-      case DATE:
-      case BLOB:
-      case OBJECT:
-      default:
-        // This will not happen.
-        throw new UDFInputSeriesDataTypeNotValidException(
-            0,
-            UDFDataTypeTransformer.transformToUDFDataType(dataType),
-            Type.INT32,
-            Type.INT64,
-            Type.FLOAT,
-            Type.DOUBLE);
-    }
+    previousValueReader.read(this, row);
+  }
+
+  protected UDFInputSeriesDataTypeNotValidException invalidDataType() {
+    return new UDFInputSeriesDataTypeNotValidException(
+        0,
+        UDFDataTypeTransformer.transformToUDFDataType(dataType),
+        Type.INT32,
+        Type.INT64,
+        Type.FLOAT,
+        Type.DOUBLE);
   }
 
   protected abstract void doTransform(Row row, PointCollector collector)

Reply via email to