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

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


The following commit(s) were added to refs/heads/master by this push:
     new 012026f0358 Add DEVICE_METADATA_INFO_SWAP_THRESHOLD parameter to 
read_tsfile table function (#18146)
012026f0358 is described below

commit 012026f0358cc05f983188efc9fb6552008d4269
Author: shuwenwei <[email protected]>
AuthorDate: Wed Jul 8 16:13:56 2026 +0800

    Add DEVICE_METADATA_INFO_SWAP_THRESHOLD parameter to read_tsfile table 
function (#18146)
---
 .../iotdb/db/i18n/DataNodeQueryMessages.java       |  2 +
 .../iotdb/db/i18n/DataNodeQueryMessages.java       |  2 +
 .../db/queryengine/common/MPPQueryContext.java     |  8 ++-
 .../read_tsfile/ExternalTsFileQueryResource.java   |  9 ++--
 .../tvf/read_tsfile/ReadTsFileTableFunction.java   | 60 ++++++++++++++++++++--
 .../plan/relational/planner/RelationPlanner.java   |  5 +-
 .../ExternalTsFileQueryResourceTest.java           |  7 ++-
 7 files changed, 81 insertions(+), 12 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
index 7978fce5113..f32079208fd 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
@@ -868,6 +868,8 @@ public final class DataNodeQueryMessages {
       "Invalid scalar argument: ";
   public static final String ARGUMENT_SHOULD_BE_A_STRING =
       "Argument %s should be a string";
+  public static final String ARGUMENT_SHOULD_BE_A_NUMBER =
+      "Argument %s should be a number";
   public static final String ARGUMENT_SHOULD_CONTAIN_AT_LEAST_ONE_PATH =
       "Argument %s should contain at least one path";
   public static final String READ_TSFILE_PATH_IS_NOT_ALLOWED =
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
index 34a7fa084bf..9e4a0188a11 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
@@ -852,6 +852,8 @@ public final class DataNodeQueryMessages {
       "无效的标量参数:";
   public static final String ARGUMENT_SHOULD_BE_A_STRING =
       "参数 %s 应为字符串";
+  public static final String ARGUMENT_SHOULD_BE_A_NUMBER =
+      "参数 %s 应为数字";
   public static final String ARGUMENT_SHOULD_CONTAIN_AT_LEAST_ONE_PATH =
       "参数 %s 应至少包含一个路径";
   public static final String READ_TSFILE_PATH_IS_NOT_ALLOWED =
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java
index 6412d334903..d3926bcac79 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java
@@ -291,7 +291,10 @@ public class MPPQueryContext implements IAuditEntity {
   }
 
   public ExternalTsFileQueryResource createExternalTsFileQueryResource(
-      String tableName, List<String> tsFilePaths, Map<Symbol, ColumnSchema> 
tableColumnSchema) {
+      String tableName,
+      List<String> tsFilePaths,
+      Map<Symbol, ColumnSchema> tableColumnSchema,
+      long deviceMetadataInfoSwapThreshold) {
     int resourceIndex = externalTsFileQueryResourceIndex.getAndIncrement();
     ExternalTsFileQueryResource externalTsFileQueryResource =
         new ExternalTsFileQueryResource(
@@ -302,7 +305,8 @@ public class MPPQueryContext implements IAuditEntity {
                 .resolve(String.valueOf(resourceIndex)),
             tableName,
             tsFilePaths,
-            tableColumnSchema);
+            tableColumnSchema,
+            deviceMetadataInfoSwapThreshold);
     externalTsFileQueryResources.add(externalTsFileQueryResource);
     return externalTsFileQueryResource;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResource.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResource.java
index 75249c1c1fa..d16e602e3d2 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResource.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResource.java
@@ -88,6 +88,7 @@ public class ExternalTsFileQueryResource {
   private final String tableName;
   private final List<String> tsFilePaths;
   private final Map<Symbol, ColumnSchema> tableColumnSchema;
+  private final long deviceMetadataInfoSwapThreshold;
   private final List<TsFileResource> sharedTsFileResources;
   private final List<DeviceEntry> sharedDeviceEntries = new ArrayList<>();
   private final List<DeviceTaskPartition> deviceTaskPartitions = new 
ArrayList<>();
@@ -105,7 +106,8 @@ public class ExternalTsFileQueryResource {
       Path tempRoot,
       String tableName,
       List<String> tsFilePaths,
-      Map<Symbol, ColumnSchema> tableColumnSchema) {
+      Map<Symbol, ColumnSchema> tableColumnSchema,
+      long deviceMetadataInfoSwapThreshold) {
     this.queryContext = requireNonNull(queryContext, "queryContext is null");
     this.queryId = queryContext.getQueryId();
     this.externalTsFileResourceMemoryReservationManager =
@@ -115,6 +117,7 @@ public class ExternalTsFileQueryResource {
     this.tableName = tableName;
     this.tsFilePaths = requireNonNull(tsFilePaths, "tsFilePaths");
     this.tableColumnSchema = tableColumnSchema;
+    this.deviceMetadataInfoSwapThreshold = deviceMetadataInfoSwapThreshold;
     this.sharedTsFileResources = createTsFileResources(this.tsFilePaths);
     for (String tsFilePath : tsFilePaths) {
       
FileReaderManager.getInstance().increaseExternalFileReaderReference(tsFilePath);
@@ -280,7 +283,6 @@ public class ExternalTsFileQueryResource {
 
   public class DeviceTaskPartition {
 
-    private static final long DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES = 8L * 
1024 * 1024;
     private static final long MEMORY_RESERVE_BATCH_SIZE_IN_BYTES = 1024 * 1024;
 
     private final int partitionIndex;
@@ -341,7 +343,8 @@ public class ExternalTsFileQueryResource {
     }
 
     private boolean shouldFlush() {
-      if (getPendingMemoryBytes() >= DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES) {
+      if (getPendingMemoryBytes()
+          >= ExternalTsFileQueryResource.this.deviceMetadataInfoSwapThreshold) 
{
         return true;
       }
       if (unreservedBytes < MEMORY_RESERVE_BATCH_SIZE_IN_BYTES) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ReadTsFileTableFunction.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ReadTsFileTableFunction.java
index d141d0112c8..71ee6aa267f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ReadTsFileTableFunction.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ReadTsFileTableFunction.java
@@ -53,8 +53,11 @@ import java.util.stream.Collectors;
 
 /** Reads one or more TsFiles as a table function source. */
 public class ReadTsFileTableFunction implements TableFunction {
+  static final long DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES = 8L * 1024 * 1024;
   private static final String TABLE_NAME_PARAMETER_NAME = "TABLE_NAME";
   private static final String PATHS_PARAMETER_NAME = "PATHS";
+  private static final String 
DEVICE_METADATA_INFO_SWAP_THRESHOLD_PARAMETER_NAME =
+      "DEVICE_METADATA_INFO_SWAP_THRESHOLD";
 
   private MPPQueryContext mppQueryContext;
 
@@ -70,6 +73,11 @@ public class ReadTsFileTableFunction implements 
TableFunction {
             .name(TABLE_NAME_PARAMETER_NAME)
             .type(Type.STRING)
             .defaultValue("")
+            .build(),
+        ScalarParameterSpecification.builder()
+            .name(DEVICE_METADATA_INFO_SWAP_THRESHOLD_PARAMETER_NAME)
+            .type(Type.INT64)
+            .defaultValue(DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES)
             .build());
   }
 
@@ -92,6 +100,15 @@ public class ReadTsFileTableFunction implements 
TableFunction {
     }
     DescribedSchema outputSchema = convertToDescribedSchema(mergedTableSchema);
 
+    long deviceMetadataInfoSwapThreshold =
+        getOptionalLongArgument(
+            arguments,
+            DEVICE_METADATA_INFO_SWAP_THRESHOLD_PARAMETER_NAME,
+            DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES);
+    if (deviceMetadataInfoSwapThreshold <= 0) {
+      deviceMetadataInfoSwapThreshold = 
DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES;
+    }
+
     ReadTsFileTableFunctionHandle handle =
         new ReadTsFileTableFunctionHandle(
             schemaCollector.getTableName(),
@@ -101,7 +118,8 @@ public class ReadTsFileTableFunction implements 
TableFunction {
             mergedTableSchema.getColumnTypes().stream()
                 .map(TsTableColumnCategory::fromTsFileColumnCategory)
                 .collect(Collectors.toList()),
-            outputSchema);
+            outputSchema,
+            deviceMetadataInfoSwapThreshold);
 
     return 
TableFunctionAnalysis.builder().properColumnSchema(outputSchema).handle(handle).build();
   }
@@ -147,6 +165,26 @@ public class ReadTsFileTableFunction implements 
TableFunction {
     return ((String) value).trim();
   }
 
+  private static long getOptionalLongArgument(
+      Map<String, Argument> arguments, String name, long defaultValue) {
+    Argument argument = arguments.get(name);
+    if (argument == null) {
+      return defaultValue;
+    }
+    if (!(argument instanceof ScalarArgument)) {
+      throw new 
UDFArgumentNotValidException(DataNodeQueryMessages.INVALID_SCALAR_ARGUMENT + 
name);
+    }
+    Object value = ((ScalarArgument) argument).getValue();
+    if (value instanceof Long) {
+      return (Long) value;
+    }
+    if (value instanceof Integer) {
+      return ((Integer) value).longValue();
+    }
+    throw new UDFArgumentNotValidException(
+        String.format(DataNodeQueryMessages.ARGUMENT_SHOULD_BE_A_NUMBER, 
name));
+  }
+
   private static List<String> parseTsFilePaths(String tsFilePaths) {
     List<String> paths =
         Arrays.stream(tsFilePaths.split(","))
@@ -204,6 +242,7 @@ public class ReadTsFileTableFunction implements 
TableFunction {
     private List<String> outputColumnNames;
     private List<Type> outputColumnTypes;
     private List<TsTableColumnCategory> outputColumnCategories;
+    private long deviceMetadataInfoSwapThreshold;
 
     public ReadTsFileTableFunctionHandle() {
       this(
@@ -211,14 +250,16 @@ public class ReadTsFileTableFunction implements 
TableFunction {
           Collections.emptyList(),
           Collections.emptyList(),
           Collections.emptyList(),
-          Collections.emptyList());
+          Collections.emptyList(),
+          DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES);
     }
 
     public ReadTsFileTableFunctionHandle(
         String tableName,
         List<String> tsFilePaths,
         List<TsTableColumnCategory> outputColumnCategories,
-        DescribedSchema outputSchema) {
+        DescribedSchema outputSchema,
+        long deviceMetadataInfoSwapThreshold) {
       this(
           tableName,
           tsFilePaths,
@@ -228,7 +269,8 @@ public class ReadTsFileTableFunction implements 
TableFunction {
           outputSchema.getFields().stream()
               .map(DescribedSchema.Field::getType)
               .collect(Collectors.toList()),
-          outputColumnCategories);
+          outputColumnCategories,
+          deviceMetadataInfoSwapThreshold);
     }
 
     private ReadTsFileTableFunctionHandle(
@@ -236,7 +278,8 @@ public class ReadTsFileTableFunction implements 
TableFunction {
         List<String> tsFilePaths,
         List<String> outputColumnNames,
         List<Type> outputColumnTypes,
-        List<TsTableColumnCategory> outputColumnCategories) {
+        List<TsTableColumnCategory> outputColumnCategories,
+        long deviceMetadataInfoSwapThreshold) {
       if (outputColumnNames.size() != outputColumnTypes.size()) {
         throw new IllegalArgumentException(
             DataNodeQueryMessages.OUTPUT_COLUMN_NAMES_AND_TYPES_SIZE_MISMATCH);
@@ -251,6 +294,7 @@ public class ReadTsFileTableFunction implements 
TableFunction {
       this.outputColumnTypes = Collections.unmodifiableList(new 
ArrayList<>(outputColumnTypes));
       this.outputColumnCategories =
           Collections.unmodifiableList(new 
ArrayList<>(outputColumnCategories));
+      this.deviceMetadataInfoSwapThreshold = deviceMetadataInfoSwapThreshold;
     }
 
     public String getTableName() {
@@ -273,6 +317,10 @@ public class ReadTsFileTableFunction implements 
TableFunction {
       return outputColumnCategories;
     }
 
+    public long getDeviceMetadataInfoSwapThreshold() {
+      return deviceMetadataInfoSwapThreshold;
+    }
+
     @Override
     public byte[] serialize() {
       throw new UnsupportedOperationException(
@@ -299,6 +347,8 @@ public class ReadTsFileTableFunction implements 
TableFunction {
           + outputColumnTypes
           + ", outputColumnCategories="
           + outputColumnCategories
+          + ", deviceMetadataInfoSwapThreshold="
+          + deviceMetadataInfoSwapThreshold
           + '}';
     }
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
index f64f3d20b8f..117d5db4e5c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
@@ -1655,7 +1655,10 @@ public class RelationPlanner implements 
AstVisitor<RelationPlan, Void> {
             assignments,
             tagAndAttributeIndexMap,
             queryContext.createExternalTsFileQueryResource(
-                handle.getTableName(), handle.getTsFilePaths(), assignments));
+                handle.getTableName(),
+                handle.getTsFilePaths(),
+                assignments,
+                handle.getDeviceMetadataInfoSwapThreshold()));
 
     return new RelationPlan(scanNode, scope, outputSymbols, outerContext);
   }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResourceTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResourceTest.java
index fb0031546c9..6c7919eb6fb 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResourceTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/read_tsfile/ExternalTsFileQueryResourceTest.java
@@ -152,7 +152,12 @@ public class ExternalTsFileQueryResourceTest {
     queryContext.setStartTime(System.currentTimeMillis());
     queryContext.setTimeOut(Long.MAX_VALUE);
     return new ExternalTsFileQueryResource(
-        queryContext, root.toPath().resolve("tmp"), "table1", tsFilePaths, 
Collections.emptyMap());
+        queryContext,
+        root.toPath().resolve("tmp"),
+        "table1",
+        tsFilePaths,
+        Collections.emptyMap(),
+        ReadTsFileTableFunction.DEVICE_TASK_BUCKET_TARGET_SIZE_IN_BYTES);
   }
 
   private DeviceTaskRunReader newReader(DeviceTaskPartition partition) {

Reply via email to