libenchao commented on code in PR #3193:
URL: https://github.com/apache/calcite/pull/3193#discussion_r1204991292
##########
core/src/main/java/org/apache/calcite/rel/rules/SubQueryRemoveRule.java:
##########
@@ -866,6 +866,8 @@ private static void matchFilter(SubQueryRemoveRule rule,
LogicVisitor.find(RelOptUtil.Logic.TRUE, ImmutableList.of(c), e);
final Set<CorrelationId> variablesSet =
RelOptUtil.getVariablesUsed(e.rel);
+ /* Only consider the correlated variables which originated from this
sub-query level*/
Review Comment:
The comment style is not Calcite style for inline comments, we use `//` for
this kind of comment.
##########
core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java:
##########
@@ -3549,7 +3549,17 @@ protected final void createAggImpl(
// implement HAVING (we have already checked that it is non-trivial)
relBuilder.push(bb.root());
if (havingExpr != null) {
- relBuilder.filter(havingExpr);
+ /* Set the correlation variables used in this sub-query to the filter
node,
+ * same logic is being used for the filter generated in where clause.
+ */
Review Comment:
Same with the comment in `SubQueryRemoveRule`.
##########
core/src/main/java/org/apache/calcite/rel/rules/SubQueryRemoveRule.java:
##########
@@ -866,6 +866,8 @@ private static void matchFilter(SubQueryRemoveRule rule,
LogicVisitor.find(RelOptUtil.Logic.TRUE, ImmutableList.of(c), e);
final Set<CorrelationId> variablesSet =
RelOptUtil.getVariablesUsed(e.rel);
+ /* Only consider the correlated variables which originated from this
sub-query level*/
+ variablesSet.retainAll(filter.getVariablesSet());
Review Comment:
This seems correct only when we have already set the variable for `Filter`
(which I believe is the right direction), however I'm not sure we can guarantee
that for now. That says, we can still handle the cases that the `Filter` is not
set the variable, and maybe this would be an regression in some sense. For
downstream projects, there may exist such usages, even we can pass all the
tests of Calcite.
##########
core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java:
##########
@@ -6823,6 +6823,48 @@ private void checkSemiJoinRuleOnAntiJoin(RelOptRule
rule) {
.checkUnchanged();
}
+ /** Test case for CALCITE-5683 for two level nested decorrelate with
standard program
+ * failing during the decorrelation phase. */
+ @Test void testTwoLevelDecorrelate() {
+ final String sql = "SELECT d1.name, d1.deptno + "
+ + " ( SELECT e1.empno "
+ + " FROM emp e1 "
+ + " WHERE d1.deptno = e1.deptno and "
+ + " e1.sal = (SELECT max(sal) "
+ + " FROM emp e2 "
+ + " WHERE e1.sal = e2.sal and"
+ + " e1.deptno = e2.deptno and"
+ + " d1.deptno < e2.deptno))"
+ + " FROM dept d1";
+
+ sql(sql)
+ .withExpand(false)
+ .withLateDecorrelate(true)
+ .withTrim(true)
+ .withRule()
+ .checkUnchanged();
Review Comment:
This seems weird that you are asserting the plan is not changed, but the
content in `RelOptRulesTest.xml` does contain `planAfter` section, and the
tests still pass.
##########
core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java:
##########
@@ -3549,7 +3549,17 @@ protected final void createAggImpl(
// implement HAVING (we have already checked that it is non-trivial)
relBuilder.push(bb.root());
if (havingExpr != null) {
- relBuilder.filter(havingExpr);
+ /* Set the correlation variables used in this sub-query to the filter
node,
+ * same logic is being used for the filter generated in where clause.
+ */
+ Set<CorrelationId> variableSet = new HashSet<>();
+ if (havingExpr instanceof RexSubQuery) {
Review Comment:
Seems that this condition can only take care of limited cases which the
`RexSubQuery` is the only condition.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]