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

jackietien 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 e1bd11b9d6e Fixed the issue with deeply nested Or Filter in 
NonAlignedTreeViewScan
e1bd11b9d6e is described below

commit e1bd11b9d6e9cd1109a2f16af0157cd734824666
Author: shuwenwei <[email protected]>
AuthorDate: Mon Jun 23 19:34:31 2025 +0800

    Fixed the issue with deeply nested Or Filter in NonAlignedTreeViewScan
---
 .../plan/planner/TableOperatorGenerator.java       | 20 ++++++++---
 ...nAlignedTreeDeviceViewScanOperatorTreeTest.java | 39 ++++++++++++++++++++++
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
index 2132df0af1d..8c5143833e4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
@@ -597,6 +597,19 @@ public class TableOperatorGenerator extends 
PlanVisitor<Operator, LocalExecution
               }
             }
 
+            // Using getSeriesScanOptionsBuilder to create SeriesScanBuilder 
will cause multiple
+            // calls to setTimeFilterForTableModel and generate a deeply 
nested Or filter.
+            // Therefore, a separate setting is made here
+            Filter timeFilter = null;
+            if (node.getTimePredicate().isPresent()) {
+              Expression timePredicate = node.getTimePredicate().get();
+              timeFilter = timePredicate.accept(new 
ConvertPredicateToTimeFilterVisitor(), null);
+              context
+                  .getDriverContext()
+                  .getFragmentInstanceContext()
+                  .setTimeFilterForTableModel(timeFilter);
+            }
+
             boolean canPushDownLimit = cannotPushDownConjuncts.isEmpty();
             // only use full outer time join
             boolean canPushDownLimitToAllSeriesScanOptions =
@@ -621,10 +634,9 @@ public class TableOperatorGenerator extends 
PlanVisitor<Operator, LocalExecution
                       : (pushDownPredicatesForCurrentMeasurement == null
                           ? null
                           : 
IrUtils.combineConjuncts(pushDownPredicatesForCurrentMeasurement));
-              SeriesScanOptions.Builder builder =
-                  node.getTimePredicate()
-                      .map(expression -> getSeriesScanOptionsBuilder(context, 
expression))
-                      .orElseGet(SeriesScanOptions.Builder::new);
+              SeriesScanOptions.Builder builder = new 
SeriesScanOptions.Builder();
+              // time filter may be stateful, so we need to copy it
+              builder.withGlobalTimeFilter(timeFilter == null ? null : 
timeFilter.copy());
               builder
                   .withIsTableViewForTreeModel(true)
                   .withAllSensors(new HashSet<>(measurementColumnNames));
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/NonAlignedTreeDeviceViewScanOperatorTreeTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/NonAlignedTreeDeviceViewScanOperatorTreeTest.java
index 73f957ddf78..2188a04479b 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/NonAlignedTreeDeviceViewScanOperatorTreeTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/NonAlignedTreeDeviceViewScanOperatorTreeTest.java
@@ -67,6 +67,8 @@ import org.apache.tsfile.read.common.block.TsBlock;
 import org.apache.tsfile.read.common.type.Type;
 import org.apache.tsfile.read.common.type.TypeEnum;
 import org.apache.tsfile.read.common.type.TypeFactory;
+import org.apache.tsfile.read.filter.basic.Filter;
+import org.apache.tsfile.read.filter.operator.Or;
 import org.apache.tsfile.utils.Binary;
 import org.apache.tsfile.write.schema.IMeasurementSchema;
 import org.junit.After;
@@ -86,6 +88,7 @@ import java.util.stream.Collectors;
 import static 
org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceContext.createFragmentInstanceContext;
 import static 
org.apache.iotdb.db.queryengine.execution.operator.Operator.NOT_BLOCKED;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -199,6 +202,37 @@ public class NonAlignedTreeDeviceViewScanOperatorTreeTest {
     }
   }
 
+  @Test
+  public void testScanWithPushDownPredicateAndLimitAndOffsetAndTimePredicate() 
throws Exception {
+    List<String> outputColumnList = Arrays.asList("sensor0", "sensor1", 
"sensor2", "time", "tag1");
+    TreeNonAlignedDeviceViewScanNode node = 
getTreeNonAlignedDeviceViewScanNode(outputColumnList);
+    node.setPushDownOffset(500);
+    node.setPushDownLimit(500);
+    node.setTimePredicate(
+        new ComparisonExpression(
+            ComparisonExpression.Operator.GREATER_THAN,
+            new Symbol("time").toSymbolReference(),
+            new LongLiteral("0")));
+    node.setPushDownPredicate(
+        new ComparisonExpression(
+            ComparisonExpression.Operator.GREATER_THAN,
+            new Symbol("sensor1").toSymbolReference(),
+            new LongLiteral("1000")));
+    ExecutorService instanceNotificationExecutor =
+        IoTDBThreadPoolFactory.newFixedThreadPool(1, 
"test-instance-notification");
+    Operator operator = getOperator(node, instanceNotificationExecutor);
+    assertTrue(operator instanceof DeviceIteratorScanOperator);
+    try {
+      checkResult(operator, outputColumnList, 500);
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    } finally {
+      operator.close();
+      instanceNotificationExecutor.shutdown();
+    }
+  }
+
   @Test
   public void testScanWithPushDownPredicateAndPushLimitToEachDevice() throws 
Exception {
     List<String> outputColumnList = Arrays.asList("sensor0", "sensor1", 
"sensor2", "time", "tag1");
@@ -633,6 +667,11 @@ public class NonAlignedTreeDeviceViewScanOperatorTreeTest {
       }
       count += tsBlock.getPositionCount();
     }
+    FragmentInstanceContext fragmentInstance = 
operator.getOperatorContext().getInstanceContext();
+    Filter globalTimeFilter = fragmentInstance.getGlobalTimeFilter();
+    if (globalTimeFilter != null) {
+      assertFalse(globalTimeFilter instanceof Or);
+    }
     assertEquals(expectedCount, count);
   }
 

Reply via email to