Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,84 @@ public void testCaseInSensitive() {
retArray,
DATABASE_NAME);
}

@Test
public void testDiffWithOrderBySubquery() {
String[] expectedHeader = new String[] {"time", "device_id", "s1", "_col3"};
String[] retArray =
new String[] {
"1970-02-27T20:53:20.001Z,d1,8,3.0,",
"1970-02-27T20:53:20.000Z,d1,null,null,",
"1970-01-01T00:00:00.006Z,d1,null,null,",
"1970-01-01T00:00:00.005Z,d1,5,1.0,",
"1970-01-01T00:00:00.004Z,d1,4,2.0,",
"1970-01-01T00:00:00.003Z,d1,null,null,",
"1970-01-01T00:00:00.002Z,d1,2,1.0,",
"1970-01-01T00:00:00.001Z,d1,1,null,"
};
tableResultSetEqualTest(
"SELECT time, device_id, s1, diff(s1) FROM ("
+ "select * "
+ "from table1 where device_id='d1' ORDER by time"
+ ") "
+ "ORDER by time DESC",
expectedHeader,
retArray,
DATABASE_NAME);
}

@Test
public void testDiffInOuterWhereHavingOrderBy() {
String[] expectedHeader = new String[] {"time", "device_id", "s1"};
String[] expectedRowsFilteredByDiff =
new String[] {
"1970-02-27T20:53:20.001Z,d1,8,",
"1970-01-01T00:00:00.005Z,d1,5,",
"1970-01-01T00:00:00.004Z,d1,4,",
"1970-01-01T00:00:00.002Z,d1,2,"
};
tableResultSetEqualTest(
"SELECT time, device_id, s1 FROM ("
+ "select * "
+ "from table1 where device_id='d1' ORDER by time"
+ ") "
+ "WHERE diff(s1) IS NOT NULL "
+ "ORDER by time DESC",
expectedHeader,
expectedRowsFilteredByDiff,
DATABASE_NAME);

tableResultSetEqualTest(
"SELECT time, device_id, s1 FROM ("
+ "select * "
+ "from table1 where device_id='d1' ORDER by time"
+ ") "
+ "GROUP BY time, device_id, s1 "
+ "HAVING diff(s1) IS NOT NULL "
+ "ORDER by time DESC",
expectedHeader,
expectedRowsFilteredByDiff,
DATABASE_NAME);

String[] expectedRowsOrderedByDiff =
new String[] {
"1970-02-27T20:53:20.001Z,d1,8,",
"1970-01-01T00:00:00.004Z,d1,4,",
"1970-01-01T00:00:00.005Z,d1,5,",
"1970-01-01T00:00:00.002Z,d1,2,",
"1970-02-27T20:53:20.000Z,d1,null,",
"1970-01-01T00:00:00.006Z,d1,null,",
"1970-01-01T00:00:00.003Z,d1,null,",
"1970-01-01T00:00:00.001Z,d1,1,"
};
tableResultSetEqualTest(
"SELECT time, device_id, s1 FROM ("
+ "select * "
+ "from table1 where device_id='d1' ORDER by time"
+ ") "
+ "ORDER BY coalesce(diff(s1), -1000.0) DESC, time DESC",
expectedHeader,
expectedRowsOrderedByDiff,
DATABASE_NAME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@
import static org.apache.iotdb.db.queryengine.plan.relational.analyzer.Scope.BasisType.TABLE;
import static org.apache.iotdb.db.queryengine.plan.relational.metadata.MetadataUtil.createQualifiedObjectName;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.IrExpressionInterpreter.evaluateConstantExpression;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.PushPredicateIntoTableScan.containsDiffFunction;
import static org.apache.iotdb.db.queryengine.plan.relational.sql.util.AstUtil.preOrder;
import static org.apache.iotdb.db.queryengine.plan.relational.utils.NodeUtils.getSortItemsFromOrderBy;
import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN;
Expand All @@ -303,6 +304,7 @@
private final Analysis analysis;

private boolean hasFillInParentScope = false;
private boolean hasDiffFunctionInParentScope = false;
private final MPPQueryContext queryContext;

private final AccessControl accessControl;
Expand Down Expand Up @@ -870,9 +872,13 @@

@Override
public Scope visitQuery(Query node, Optional<Scope> context) {
boolean originalHasFillInParentScope = hasFillInParentScope;

Check warning on line 875 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Distance between variable 'originalHasFillInParentScope' declaration and its first usage is 11, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRQ&open=AZ4McTZIBOAiju0VcqRQ&pullRequest=17629
boolean originalHasDiffFunctionInParentScope = hasDiffFunctionInParentScope;

Check warning on line 876 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Distance between variable 'originalHasDiffFunctionInParentScope' declaration and its first usage is 12, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRR&open=AZ4McTZIBOAiju0VcqRR&pullRequest=17629
analysis.setQuery(true);
Scope withScope = analyzeWith(node, context);
hasFillInParentScope = node.getFill().isPresent() || hasFillInParentScope;
hasDiffFunctionInParentScope =
containsDiffFunctionInQuery(node) || hasDiffFunctionInParentScope;
Scope queryBodyScope = process(node.getQueryBody(), withScope);

if (node.getFill().isPresent()) {
Expand All @@ -887,7 +893,8 @@
if ((queryBodyScope.getOuterQueryParent().isPresent() || !isTopLevel)
&& !node.getLimit().isPresent()
&& !node.getOffset().isPresent()
&& !hasFillInParentScope) {
&& !hasFillInParentScope
&& !hasDiffFunctionInParentScope) {
// not the root scope and ORDER BY is ineffective
analysis.markRedundantOrderBy(node.getOrderBy().get());
warningCollector.add(
Expand Down Expand Up @@ -922,6 +929,8 @@
.build();

analysis.setScope(node, queryScope);
hasFillInParentScope = originalHasFillInParentScope;
hasDiffFunctionInParentScope = originalHasDiffFunctionInParentScope;
return queryScope;
}

Expand Down Expand Up @@ -1144,6 +1153,7 @@
statementAnalyzerFactory.createStatementAnalyzer(
analysis, queryContext, sessionContext, warningCollector, CorrelationSupport.ALLOWED);
analyzer.hasFillInParentScope = hasFillInParentScope;
analyzer.hasDiffFunctionInParentScope = hasDiffFunctionInParentScope;
Scope queryScope =
analyzer.analyze(
node.getQuery(),
Expand All @@ -1153,9 +1163,13 @@

@Override
public Scope visitQuerySpecification(QuerySpecification node, Optional<Scope> scope) {
boolean originalHasFillInParentScope = hasFillInParentScope;

Check warning on line 1166 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Distance between variable 'originalHasFillInParentScope' declaration and its first usage is 19, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRS&open=AZ4McTZIBOAiju0VcqRS&pullRequest=17629
boolean originalHasDiffFunctionInParentScope = hasDiffFunctionInParentScope;

Check warning on line 1167 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Distance between variable 'originalHasDiffFunctionInParentScope' declaration and its first usage is 20, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRT&open=AZ4McTZIBOAiju0VcqRT&pullRequest=17629
// TODO: extract candidate names from SELECT, WHERE, HAVING, GROUP BY and ORDER BY expressions
// to pass down to analyzeFrom
hasFillInParentScope = node.getFill().isPresent() || hasFillInParentScope;
hasDiffFunctionInParentScope =
containsDiffFunctionInQuerySpecification(node) || hasDiffFunctionInParentScope;

Scope sourceScope = analyzeFrom(node, scope);
analyzeWindowDefinitions(node, sourceScope);
Expand Down Expand Up @@ -1188,7 +1202,8 @@
if ((sourceScope.getOuterQueryParent().isPresent() || !isTopLevel)
&& !node.getLimit().isPresent()
&& !node.getOffset().isPresent()
&& !hasFillInParentScope) {
&& !hasFillInParentScope
&& !hasDiffFunctionInParentScope) {
// not the root scope and ORDER BY is ineffective
analysis.markRedundantOrderBy(orderBy);
warningCollector.add(
Expand Down Expand Up @@ -1249,6 +1264,8 @@
orderByScope.orElseThrow(() -> new NoSuchElementException("No value present")));
}

hasFillInParentScope = originalHasFillInParentScope;
hasDiffFunctionInParentScope = originalHasDiffFunctionInParentScope;
return outputScope;
}

Expand Down Expand Up @@ -1301,6 +1318,37 @@
return windowFunctions;
}

// cover case: (query1) UNION (query2) order by ...
private boolean containsDiffFunctionInQuery(Query node) {
return getSortItemsFromOrderBy(node.getOrderBy()).stream()
.map(SortItem::getSortKey)
.anyMatch(expression -> containsDiffFunction(expression));
}

private boolean containsDiffFunctionInQuerySpecification(QuerySpecification node) {
for (SelectItem selectItem : node.getSelect().getSelectItems()) {
if (selectItem instanceof AllColumns) {
Optional<Expression> target = ((AllColumns) selectItem).getTarget();
if (target.isPresent() && containsDiffFunction(target.get())) {
return true;
}
} else if (selectItem instanceof SingleColumn
&& containsDiffFunction(((SingleColumn) selectItem).getExpression())) {
return true;
}
}

if (node.getWhere().isPresent() && containsDiffFunction(node.getWhere().get())) {

Check warning on line 1341 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Call "Optional#isPresent()" before accessing the value.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRK&open=AZ4McTZIBOAiju0VcqRK&pullRequest=17629
return true;
}
if (node.getHaving().isPresent() && containsDiffFunction(node.getHaving().get())) {

Check warning on line 1344 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Call "Optional#isPresent()" before accessing the value.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRL&open=AZ4McTZIBOAiju0VcqRL&pullRequest=17629
return true;
}
return getSortItemsFromOrderBy(node.getOrderBy()).stream()
.map(SortItem::getSortKey)
.anyMatch(expression -> containsDiffFunction(expression));
}

private void resolveFunctionCallAndMeasureWindows(QuerySpecification querySpecification) {
ImmutableList.Builder<Expression> expressions = ImmutableList.builder();

Expand Down Expand Up @@ -2600,7 +2648,7 @@
}
}

private Analysis.GroupingSetAnalysis analyzeGroupBy(

Check warning on line 2651 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 110 to 64, Complexity from 22 to 14, Nesting Level from 6 to 2, Number of Variables from 22 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRM&open=AZ4McTZIBOAiju0VcqRM&pullRequest=17629
QuerySpecification node, Scope scope, List<Expression> outputExpressions) {
if (node.getGroupBy().isPresent()) {
ImmutableList.Builder<List<Set<FieldId>>> cubes = ImmutableList.builder();
Expand Down Expand Up @@ -2996,7 +3044,7 @@
}

@Override
public Scope visitSetOperation(SetOperation node, Optional<Scope> scope) {

Check warning on line 3047 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 82 to 64, Complexity from 16 to 14, Nesting Level from 3 to 2, Number of Variables from 25 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRO&open=AZ4McTZIBOAiju0VcqRO&pullRequest=17629
checkState(node.getRelations().size() >= 2);

List<RelationType> childrenTypes =
Expand Down Expand Up @@ -3287,7 +3335,7 @@
// accessControlScope, filter));
// }

public Scope visitPatternRecognitionRelation(

Check warning on line 3338 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 120 to 64, Complexity from 18 to 14, Nesting Level from 3 to 2, Number of Variables from 35 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRN&open=AZ4McTZIBOAiju0VcqRN&pullRequest=17629
PatternRecognitionRelation relation, Optional<Scope> scope) {
Scope inputScope = process(relation.getInput(), scope);

Expand Down Expand Up @@ -4926,7 +4974,7 @@
return null;
}

private ArgumentsAnalysis analyzeArguments(

Check warning on line 4977 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 79 to 64, Complexity from 15 to 14, Nesting Level from 3 to 2, Number of Variables from 25 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTZIBOAiju0VcqRP&open=AZ4McTZIBOAiju0VcqRP&pullRequest=17629
List<ParameterSpecification> parameterSpecifications,
List<TableFunctionArgument> arguments,
Optional<Scope> scope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.TableDeviceQueryCountNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.TableDeviceQueryScanNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.DataNodeLocationSupplierFactory;
import org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.PushPredicateIntoTableScan;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Insert;
import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
Expand Down Expand Up @@ -320,8 +319,23 @@
}

@Override
public List<PlanNode> visitProject(ProjectNode node, PlanContext context) {

Check warning on line 322 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 77 to 64, Complexity from 18 to 14, Nesting Level from 5 to 2, Number of Variables from 18 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTVbBOAiju0VcqRH&open=AZ4McTVbBOAiju0VcqRH&pullRequest=17629
boolean containsDiff =
node.getAssignments().getMap().values().stream()
.anyMatch(expression -> containsDiffFunction(expression));
OrderingScheme originalExpectedOrdering = context.expectedOrderingScheme;
boolean originalHasSortProperty = context.hasSortProperty;
if (containsDiff) {
context.clearExpectedOrderingScheme();
}
List<PlanNode> childrenNodes = node.getChild().accept(this, context);
if (containsDiff) {
if (originalHasSortProperty) {
context.setExpectedOrderingScheme(originalExpectedOrdering);
} else {
context.clearExpectedOrderingScheme();
}
}
OrderingScheme childOrdering = nodeOrderingMap.get(childrenNodes.get(0).getPlanNodeId());
boolean containAllSortItem = false;
if (childOrdering != null) {
Expand Down Expand Up @@ -378,9 +392,6 @@
return Collections.singletonList(node);
}

boolean containsDiff =
node.getAssignments().getMap().values().stream()
.anyMatch(PushPredicateIntoTableScan::containsDiffFunction);
if (containsDiff) {
if (containAllSortItem) {
nodeOrderingMap.put(node.getPlanNodeId(), childOrdering);
Expand Down Expand Up @@ -583,7 +594,20 @@

@Override
public List<PlanNode> visitFilter(FilterNode node, PlanContext context) {
boolean containsDiff = containsDiffFunction(node.getPredicate());
OrderingScheme originalExpectedOrdering = context.expectedOrderingScheme;
boolean originalHasSortProperty = context.hasSortProperty;
if (containsDiff) {
context.clearExpectedOrderingScheme();
}
List<PlanNode> childrenNodes = node.getChild().accept(this, context);
if (containsDiff) {
if (originalHasSortProperty) {
context.setExpectedOrderingScheme(originalExpectedOrdering);
} else {
context.clearExpectedOrderingScheme();
}
}
OrderingScheme childOrdering = nodeOrderingMap.get(childrenNodes.get(0).getPlanNodeId());
if (childOrdering != null) {
nodeOrderingMap.put(node.getPlanNodeId(), childOrdering);
Expand All @@ -594,7 +618,7 @@
return Collections.singletonList(node);
}

if (containsDiffFunction(node.getPredicate())) {
if (containsDiff) {
node.setChild(mergeChildrenViaCollectOrMergeSort(childOrdering, childrenNodes));
return Collections.singletonList(node);
}
Expand Down Expand Up @@ -883,7 +907,7 @@
}

@Override
public List<PlanNode> visitTreeDeviceViewScan(TreeDeviceViewScanNode node, PlanContext context) {

Check warning on line 910 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 121 to 64, Complexity from 20 to 14, Nesting Level from 3 to 2, Number of Variables from 21 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTVbBOAiju0VcqRI&open=AZ4McTVbBOAiju0VcqRI&pullRequest=17629
DataPartition dataPartition = analysis.getDataPartitionInfo();
if (dataPartition == null || node.getTreeDBName() == null) {
node.setRegionReplicaSet(NOT_ASSIGNED);
Expand Down Expand Up @@ -1327,7 +1351,7 @@
}

@Override
public List<PlanNode> visitAggregationTreeDeviceViewScan(

Check warning on line 1354 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 161 to 64, Complexity from 21 to 14, Nesting Level from 3 to 2, Number of Variables from 26 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTVbBOAiju0VcqRF&open=AZ4McTVbBOAiju0VcqRF&pullRequest=17629
AggregationTreeDeviceViewScanNode node, PlanContext context) {
String dbName = node.getTreeDBName();
DataPartition dataPartition = analysis.getDataPartitionInfo();
Expand Down Expand Up @@ -1770,7 +1794,7 @@
return collectNode;
}

private void processSortProperty(

Check warning on line 1797 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

A "Brain Method" was detected. Refactor it to reduce at least one of the following metrics: LOC from 111 to 64, Complexity from 19 to 14, Nesting Level from 4 to 2, Number of Variables from 22 to 6.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ4McTVbBOAiju0VcqRG&open=AZ4McTVbBOAiju0VcqRG&pullRequest=17629
final DeviceTableScanNode deviceTableScanNode,
final List<PlanNode> resultTableScanNodeList,
final PlanContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
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;
Expand Down Expand Up @@ -108,6 +109,15 @@
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;
Expand Down Expand Up @@ -854,6 +864,46 @@ public void diffTest() {
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 =
Expand Down
Loading