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

Wei-hao-Li pushed a commit to branch fix-diff-order
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit dd6757534aa1aa3eb6b53f52521a5bdccffab6f7
Author: Weihao Li <[email protected]>
AuthorDate: Sat May 9 19:00:44 2026 +0800

    fix
    
    Signed-off-by: Weihao Li <[email protected]>
---
 .../relational/analyzer/StatementAnalyzer.java     |  8 ++++
 .../plan/relational/analyzer/AnalyzerTest.java     | 50 ++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 49a6c19673b..12656f0ce5e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -872,6 +872,8 @@ public class StatementAnalyzer {
 
     @Override
     public Scope visitQuery(Query node, Optional<Scope> context) {
+      boolean originalHasFillInParentScope = hasFillInParentScope;
+      boolean originalHasDiffFunctionInParentScope = 
hasDiffFunctionInParentScope;
       analysis.setQuery(true);
       Scope withScope = analyzeWith(node, context);
       hasFillInParentScope = node.getFill().isPresent() || 
hasFillInParentScope;
@@ -927,6 +929,8 @@ public class StatementAnalyzer {
               .build();
 
       analysis.setScope(node, queryScope);
+      hasFillInParentScope = originalHasFillInParentScope;
+      hasDiffFunctionInParentScope = originalHasDiffFunctionInParentScope;
       return queryScope;
     }
 
@@ -1159,6 +1163,8 @@ public class StatementAnalyzer {
 
     @Override
     public Scope visitQuerySpecification(QuerySpecification node, 
Optional<Scope> scope) {
+      boolean originalHasFillInParentScope = hasFillInParentScope;
+      boolean originalHasDiffFunctionInParentScope = 
hasDiffFunctionInParentScope;
       // TODO: extract candidate names from SELECT, WHERE, HAVING, GROUP BY 
and ORDER BY expressions
       // to pass down to analyzeFrom
       hasFillInParentScope = node.getFill().isPresent() || 
hasFillInParentScope;
@@ -1258,6 +1264,8 @@ public class StatementAnalyzer {
             orderByScope.orElseThrow(() -> new NoSuchElementException("No 
value present")));
       }
 
+      hasFillInParentScope = originalHasFillInParentScope;
+      hasDiffFunctionInParentScope = originalHasDiffFunctionInParentScope;
       return outputScope;
     }
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
index e8626735374..45599c8a981 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
@@ -65,6 +65,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.OperatorNotFoundException;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableHeaderSchemaValidator;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.PlanTester;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.SymbolAllocator;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.TableLogicalPlanner;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.TableDistributedPlanner;
@@ -108,6 +109,15 @@ import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.TEST_MATADATA;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.assertTableScanWithoutEntryOrder;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.getChildrenNode;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanAssert.assertPlan;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.aggregation;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.exchange;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.filter;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.mergeSort;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.output;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.project;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.sort;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.tableScan;
 import static 
org.apache.iotdb.db.queryengine.plan.statement.component.Ordering.ASC;
 import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN;
 import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
@@ -854,6 +864,46 @@ public class AnalyzerTest {
         filterNode.getPredicate().toString());
   }
 
+  @Test
+  public void diffWithSubqueryOrderByTest() {
+    PlanTester planTester = new PlanTester();
+    String sqlWithOuterWhere =
+        "SELECT time, tag1, s1 FROM ("
+            + "select * from table1 ORDER by time"
+            + ") WHERE diff(s1) IS NOT NULL ORDER by time DESC";
+    planTester.createPlan(sqlWithOuterWhere);
+    assertPlan(
+        planTester.getFragmentPlan(0),
+        output(sort(filter(mergeSort(exchange(), exchange(), exchange())))));
+    assertPlan(planTester.getFragmentPlan(1), 
sort(tableScan("testdb.table1")));
+    assertPlan(planTester.getFragmentPlan(2), 
sort(tableScan("testdb.table1")));
+    assertPlan(planTester.getFragmentPlan(3), 
sort(tableScan("testdb.table1")));
+
+    String sqlWithOuterHaving =
+        "SELECT time, tag1, s1 FROM ("
+            + "select * from table1 ORDER by time"
+            + ") GROUP BY time, tag1, s1 HAVING diff(s1) IS NOT NULL ORDER by 
time DESC";
+    planTester.createPlan(sqlWithOuterHaving);
+    assertPlan(
+        planTester.getFragmentPlan(0),
+        output(sort(filter(aggregation(mergeSort(exchange(), exchange(), 
exchange()))))));
+    assertPlan(planTester.getFragmentPlan(1), 
sort(tableScan("testdb.table1")));
+    assertPlan(planTester.getFragmentPlan(2), 
sort(tableScan("testdb.table1")));
+    assertPlan(planTester.getFragmentPlan(3), 
sort(tableScan("testdb.table1")));
+
+    String sqlWithOuterOrderBy =
+        "SELECT time, tag1, s1 FROM ("
+            + "select * from table1 ORDER by time"
+            + ") ORDER by coalesce(diff(s1), -1000.0) DESC, time DESC";
+    planTester.createPlan(sqlWithOuterOrderBy);
+    assertPlan(
+        planTester.getFragmentPlan(0),
+        output(project(sort(project(mergeSort(exchange(), exchange(), 
exchange()))))));
+    assertPlan(planTester.getFragmentPlan(1), 
sort(tableScan("testdb.table1")));
+    assertPlan(planTester.getFragmentPlan(2), 
sort(tableScan("testdb.table1")));
+    assertPlan(planTester.getFragmentPlan(3), 
sort(tableScan("testdb.table1")));
+  }
+
   @Test
   public void predicatePushDownTest() {
     sql =

Reply via email to