This is an automated email from the ASF dual-hosted git repository. shuwenwei pushed a commit to branch table_disk_usage_statistics in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit b4711270859062881798755ea1c7dbf0c304134d Author: shuwenwei <[email protected]> AuthorDate: Tue Oct 28 11:28:39 2025 +0800 update InformationSchema --- .../PushLimitOffsetIntoTableScan.java | 44 ++++++++++++++-------- .../commons/schema/table/InformationSchema.java | 29 +++++++------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java index 2993c8f3696..b58ee1874ac 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations; +import org.apache.iotdb.commons.schema.table.InformationSchema; import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor; @@ -40,6 +41,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode; import org.apache.iotdb.db.queryengine.plan.relational.planner.node.SortNode; import org.apache.iotdb.db.queryengine.plan.relational.planner.node.StreamSortNode; import org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableFunctionProcessorNode; +import org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode; import org.apache.iotdb.db.queryengine.plan.relational.planner.node.TopKNode; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; @@ -52,7 +54,7 @@ import static org.apache.iotdb.db.queryengine.plan.relational.planner.optimizati /** * <b>Optimization phase:</b> Distributed plan planning. * - * <p>The LIMIT OFFSET condition can be pushed down to the DeviceTableScanNode, when the following + * <p>The LIMIT OFFSET condition can be pushed down to the TableScanNode, when the following * conditions are met: * <li>Time series query (not aggregation query). * <li>The query expressions are all scalar expression. @@ -104,9 +106,9 @@ public class PushLimitOffsetIntoTableScan implements PlanOptimizer { // In Filter-TableScan and Filter-Project-TableScan case, limit can not be pushed down. // In later, we need consider other case such as Filter-Values. // FilterNode in outer query can not be pushed down. - if (node.getChild() instanceof DeviceTableScanNode + if (node.getChild() instanceof TableScanNode || (node.getChild() instanceof ProjectNode - && ((ProjectNode) node.getChild()).getChild() instanceof DeviceTableScanNode)) { + && ((ProjectNode) node.getChild()).getChild() instanceof TableScanNode)) { context.enablePushDown = false; return node; } @@ -161,10 +163,10 @@ public class PushLimitOffsetIntoTableScan implements PlanOptimizer { context.enablePushDown = false; return node; } else { - DeviceTableScanNode deviceTableScanNode = subContext.deviceTableScanNode; - context.deviceTableScanNode = deviceTableScanNode; - if (deviceTableScanNode != null) { - deviceTableScanNode.setPushDownLimit(node.getCount()); + TableScanNode tableScanNode = subContext.tableScanNode; + context.tableScanNode = tableScanNode; + if (tableScanNode != null) { + tableScanNode.setPushDownLimit(node.getCount()); } return node; } @@ -182,14 +184,14 @@ public class PushLimitOffsetIntoTableScan implements PlanOptimizer { return node; } - DeviceTableScanNode deviceTableScanNode = subContext.deviceTableScanNode; - context.deviceTableScanNode = deviceTableScanNode; + TableScanNode tableScanNode = subContext.tableScanNode; + context.tableScanNode = tableScanNode; OrderingScheme orderingScheme = node.getOrderingScheme(); Map<Symbol, ColumnSchema> tableColumnSchema = - analysis.getTableColumnSchema(deviceTableScanNode.getQualifiedObjectName()); + analysis.getTableColumnSchema(tableScanNode.getQualifiedObjectName()); Set<Symbol> sortSymbols = new HashSet<>(); for (Symbol orderBy : orderingScheme.getOrderBy()) { - if (deviceTableScanNode.isTimeColumn(orderBy)) { + if (tableScanNode.isTimeColumn(orderBy)) { break; } @@ -203,6 +205,11 @@ public class PushLimitOffsetIntoTableScan implements PlanOptimizer { sortSymbols.add(orderBy); } + if (!(tableScanNode instanceof DeviceTableScanNode)) { + context.enablePushDown = false; + return node; + } + boolean pushLimitToEachDevice = false; for (Map.Entry<Symbol, ColumnSchema> entry : tableColumnSchema.entrySet()) { if (entry.getValue().getColumnCategory() == TsTableColumnCategory.TAG @@ -211,7 +218,7 @@ public class PushLimitOffsetIntoTableScan implements PlanOptimizer { break; } } - deviceTableScanNode.setPushLimitToEachDevice(pushLimitToEachDevice); + ((DeviceTableScanNode) tableScanNode).setPushLimitToEachDevice(pushLimitToEachDevice); return node; } @@ -233,14 +240,19 @@ public class PushLimitOffsetIntoTableScan implements PlanOptimizer { @Override public PlanNode visitDeviceTableScan(DeviceTableScanNode node, Context context) { - context.deviceTableScanNode = node; + context.tableScanNode = node; return node; } @Override public PlanNode visitInformationSchemaTableScan( InformationSchemaTableScanNode node, Context context) { - context.enablePushDown = false; + if (InformationSchema.supportsPushDownLimitOffset( + node.getQualifiedObjectName().getObjectName())) { + context.tableScanNode = node; + } else { + context.enablePushDown = false; + } return node; } @@ -262,9 +274,9 @@ public class PushLimitOffsetIntoTableScan implements PlanOptimizer { } private static class Context { - // means if limit and offset can be pushed down into DeviceTableScanNode + // means if limit and offset can be pushed down into TableScanNode private boolean enablePushDown = true; - private DeviceTableScanNode deviceTableScanNode; + private TableScanNode tableScanNode; private boolean existSortNode = false; private boolean existLimitNode = false; } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/InformationSchema.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/InformationSchema.java index 8ececbae9ad..a237b7c6dd5 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/InformationSchema.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/InformationSchema.java @@ -24,12 +24,11 @@ import org.apache.iotdb.commons.schema.table.column.AttributeColumnSchema; import org.apache.iotdb.commons.schema.table.column.FieldColumnSchema; import org.apache.iotdb.commons.schema.table.column.TagColumnSchema; +import org.apache.ratis.thirdparty.com.google.common.collect.ImmutableSet; import org.apache.tsfile.enums.TSDataType; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -37,6 +36,8 @@ import java.util.Set; public class InformationSchema { public static final String INFORMATION_DATABASE = "information_schema"; private static final Map<String, TsTable> schemaTables = new HashMap<>(); + private static final Map<String, Set<String>> columnsThatSupportPushDownPredicate = + new HashMap<>(); public static final String QUERIES = "queries"; public static final String DATABASES = "databases"; @@ -386,23 +387,23 @@ public class InformationSchema { schemaTables.put(TABLE_DISK_USAGE, tableDiskUsageTable); } + static { + columnsThatSupportPushDownPredicate.put( + TABLE_DISK_USAGE, + ImmutableSet.of( + ColumnHeaderConstant.DATABASE, + ColumnHeaderConstant.TABLE_NAME_TABLE_MODEL, + ColumnHeaderConstant.NODE_ID_TABLE_MODEL, + ColumnHeaderConstant.REGION_ID_TABLE_MODEL, + ColumnHeaderConstant.TIME_PARTITION_TABLE_MODEL)); + } + public static Map<String, TsTable> getSchemaTables() { return schemaTables; } public static Set<String> getColumnsSupportPushDownPredicate(String tableName) { - switch (tableName) { - case TABLE_DISK_USAGE: - return new HashSet<>( - Arrays.asList( - ColumnHeaderConstant.DATABASE, - ColumnHeaderConstant.TABLE_NAME_TABLE_MODEL, - ColumnHeaderConstant.NODE_ID_TABLE_MODEL, - ColumnHeaderConstant.REGION_ID_TABLE_MODEL, - ColumnHeaderConstant.TIME_PARTITION_TABLE_MODEL)); - default: - return Collections.emptySet(); - } + return columnsThatSupportPushDownPredicate.getOrDefault(tableName, Collections.emptySet()); } private InformationSchema() {
