Skip to content

Commit 75d00aa

Browse files
committed
add shadow expression for ComparisonExpression
1 parent 639b884 commit 75d00aa

File tree

4 files changed

+85
-13
lines changed

4 files changed

+85
-13
lines changed

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/QueryPlanner.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.iotdb.db.queryengine.plan.relational.analyzer.NodeRef;
3131
import org.apache.iotdb.db.queryengine.plan.relational.analyzer.RelationType;
3232
import org.apache.iotdb.db.queryengine.plan.relational.planner.ir.GapFillStartAndEndTimeExtractVisitor;
33+
import org.apache.iotdb.db.queryengine.plan.relational.planner.ir.PredicateWithUncorrelatedScalarSubqueryReconstructor;
3334
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.AggregationNode;
3435
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.AggregationNode.Aggregation;
3536
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.FilterNode;
@@ -763,9 +764,13 @@ private PlanBuilder filter(PlanBuilder subPlan, Expression predicate, Node node)
763764
}
764765

765766
subPlan = subqueryPlanner.handleSubqueries(subPlan, predicate, analysis.getSubqueries(node));
766-
return subPlan.withNewRoot(
767-
new FilterNode(
768-
queryIdAllocator.genPlanNodeId(), subPlan.getRoot(), subPlan.rewrite(predicate)));
767+
PlanBuilder planBuilder =
768+
subPlan.withNewRoot(
769+
new FilterNode(
770+
queryIdAllocator.genPlanNodeId(), subPlan.getRoot(), subPlan.rewrite(predicate)));
771+
PredicateWithUncorrelatedScalarSubqueryReconstructor.getInstance()
772+
.clearShadowExpression(predicate);
773+
return planBuilder;
769774
}
770775

771776
private PlanBuilder aggregate(PlanBuilder subPlan, QuerySpecification node) {

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/PredicateWithUncorrelatedScalarSubqueryReconstructor.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression;
3535
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral;
3636
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
37+
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall;
3738
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Identifier;
3839
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal;
3940
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LogicalExpression;
@@ -79,21 +80,19 @@ public void reconstructPredicateWithUncorrelatedScalarSubquery(
7980
ComparisonExpression comparisonExpression = (ComparisonExpression) expression;
8081
Expression left = comparisonExpression.getLeft();
8182
Expression right = comparisonExpression.getRight();
82-
if (left instanceof Identifier && right instanceof SubqueryExpression) {
83+
if ((left instanceof Identifier || left instanceof FunctionCall)
84+
&& right instanceof SubqueryExpression) {
8385
Optional<Literal> result =
8486
fetchUncorrelatedSubqueryResultForPredicate(
8587
context, (SubqueryExpression) right, analysis.getWith());
8688
// If the subquery result is not present, we cannot reconstruct the predicate.
87-
if (result.isPresent()) {
88-
right = result.get();
89-
}
90-
} else if (right instanceof Identifier && left instanceof SubqueryExpression) {
89+
result.ifPresent(comparisonExpression::setShadowRight);
90+
} else if ((right instanceof Identifier || right instanceof FunctionCall)
91+
&& left instanceof SubqueryExpression) {
9192
Optional<Literal> result =
9293
fetchUncorrelatedSubqueryResultForPredicate(
9394
context, (SubqueryExpression) left, analysis.getWith());
94-
if (result.isPresent()) {
95-
left = result.get();
96-
}
95+
result.ifPresent(comparisonExpression::setShadowLeft);
9796
}
9897
comparisonExpression.setLeft(left);
9998
comparisonExpression.setRight(right);
@@ -215,6 +214,23 @@ public Optional<Literal> fetchUncorrelatedSubqueryResultForPredicate(
215214
return Optional.empty();
216215
}
217216

217+
public void clearShadowExpression(Expression expression) {
218+
if (expression instanceof LogicalExpression) {
219+
LogicalExpression logicalExpression = (LogicalExpression) expression;
220+
for (Expression term : logicalExpression.getTerms()) {
221+
clearShadowExpression(term);
222+
}
223+
} else if (expression instanceof NotExpression) {
224+
NotExpression notExpression = (NotExpression) expression;
225+
clearShadowExpression(notExpression.getValue());
226+
} else if (expression instanceof ComparisonExpression) {
227+
ComparisonExpression comparisonExpression = (ComparisonExpression) expression;
228+
comparisonExpression.clearShadow();
229+
clearShadowExpression(comparisonExpression.getLeft());
230+
clearShadowExpression(comparisonExpression.getRight());
231+
}
232+
}
233+
218234
private static class PredicateWithUncorrelatedScalarSubqueryReconstructorHolder {
219235
private static PredicateWithUncorrelatedScalarSubqueryReconstructor INSTANCE =
220236
new PredicateWithUncorrelatedScalarSubqueryReconstructor();

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ComparisonExpression.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ public Operator negate() {
9797

9898
private final Operator operator;
9999
private Expression left;
100+
private Expression shadowLeft;
100101
private Expression right;
102+
private Expression shadowRight;
101103

102104
public ComparisonExpression(Operator operator, Expression left, Expression right) {
103105
super(null);
@@ -127,11 +129,11 @@ public Operator getOperator() {
127129
}
128130

129131
public Expression getLeft() {
130-
return left;
132+
return shadowLeft != null ? shadowLeft : left;
131133
}
132134

133135
public Expression getRight() {
134-
return right;
136+
return shadowRight != null ? shadowRight : right;
135137
}
136138

137139
public void setLeft(Expression left) {
@@ -152,6 +154,22 @@ public List<Node> getChildren() {
152154
return ImmutableList.of(left, right);
153155
}
154156

157+
// set by unfold of subquery
158+
public void setShadowLeft(Expression shadowLeft) {
159+
this.shadowLeft = shadowLeft;
160+
}
161+
162+
// set by unfold of subquery
163+
public void setShadowRight(Expression shadowRight) {
164+
this.shadowRight = shadowRight;
165+
}
166+
167+
// called after the stage is finished
168+
public void clearShadow() {
169+
this.shadowLeft = null;
170+
this.shadowRight = null;
171+
}
172+
155173
@Override
156174
public boolean equals(Object o) {
157175
if (this == o) {

iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/UncorrelatedSubqueryTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,4 +500,37 @@ public void testUncorrelatedNotExistsSubquery() {
500500
SINGLE,
501501
tableScan2)))))));
502502
}
503+
504+
@Test
505+
public void testUncorrelatedHavingSubquery() {
506+
String sql =
507+
"SELECT min(time) as min FROM table1 group by s1 having min(time) > (select max(time) from table2)";
508+
LogicalQueryPlan logicalQueryPlan = planTester.createPlan(sql);
509+
510+
PlanMatchPattern tableScan =
511+
tableScan("testdb.table1", ImmutableList.of("time", "s1"), ImmutableSet.of("time", "s1"));
512+
PlanMatchPattern agg =
513+
aggregation(
514+
singleGroupingSet("s1"),
515+
ImmutableMap.of(
516+
Optional.of("min"), aggregationFunction("min", ImmutableList.of("time"))),
517+
ImmutableList.of(),
518+
Optional.empty(),
519+
SINGLE,
520+
tableScan);
521+
522+
Expression filterPredicate =
523+
new ComparisonExpression(GREATER_THAN, new SymbolReference("min"), new LongLiteral("1"));
524+
525+
// Verify full LogicalPlan
526+
/*
527+
* └──OutputNode
528+
* └──FilterNode
529+
* ├──ProjectNode
530+
* └──Aggregation
531+
* └──TableScanNode
532+
*/
533+
534+
assertPlan(logicalQueryPlan, output(filter(filterPredicate, project(agg))));
535+
}
503536
}

0 commit comments

Comments
 (0)