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 =
