This is an automated email from the ASF dual-hosted git repository.
iwanttobepowerful pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 2df193e496 [CALCITE-7887] SubQueryRemoveRule fails for a sub-query
inside a window function
2df193e496 is described below
commit 2df193e496c7eecaf774b678ef2f4a63d087c444
Author: Weihua Zhang <[email protected]>
AuthorDate: Sun Oct 25 12:36:33 2026 +0800
[CALCITE-7887] SubQueryRemoveRule fails for a sub-query inside a window
function
---
.../java/org/apache/calcite/rex/LogicVisitor.java | 15 ++
core/src/test/resources/sql/sub-query.iq | 165 +++++++++++++++++++++
2 files changed, 180 insertions(+)
diff --git a/core/src/main/java/org/apache/calcite/rex/LogicVisitor.java
b/core/src/main/java/org/apache/calcite/rex/LogicVisitor.java
index b18613b104..d9e467a28e 100644
--- a/core/src/main/java/org/apache/calcite/rex/LogicVisitor.java
+++ b/core/src/main/java/org/apache/calcite/rex/LogicVisitor.java
@@ -150,6 +150,21 @@ public static void collect(RexNode node, RexNode seek,
Logic logic,
}
@Override public @Nullable Logic visitOver(RexOver over, @Nullable Logic
arg) {
+ // The value, not just the truth, of the operands and of the window
+ // matters, so visit them with TRUE_FALSE_UNKNOWN.
+ final Logic logic = Logic.TRUE_FALSE_UNKNOWN;
+ for (RexNode operand : over.getOperands()) {
+ operand.accept(this, logic);
+ }
+ final RexWindow window = over.getWindow();
+ for (RexNode partitionKey : window.partitionKeys) {
+ partitionKey.accept(this, logic);
+ }
+ for (RexFieldCollation orderKey : window.orderKeys) {
+ orderKey.left.accept(this, logic);
+ }
+ window.getLowerBound().accept(this, logic);
+ window.getUpperBound().accept(this, logic);
return end(over, arg);
}
diff --git a/core/src/test/resources/sql/sub-query.iq
b/core/src/test/resources/sql/sub-query.iq
index 6ea6492808..5df47b92f3 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -11003,3 +11003,168 @@ from t;
(2 rows)
!ok
+
+# [CALCITE-7887] SubQueryRemoveRule fails for a sub-query inside a window
function
+# IN sub-query inside the argument of a windowed aggregate.
+# The result of this query was validated using Postgres.
+SELECT empno,
+ SUM(CASE WHEN deptno IN (SELECT deptno FROM dept WHERE deptno < 30) THEN 1
ELSE 0 END)
+ OVER (ORDER BY empno) AS s
+FROM emp
+WHERE empno < 7600;
++-------+---+
+| EMPNO | S |
++-------+---+
+| 7369 | 1 |
+| 7499 | 1 |
+| 7521 | 1 |
+| 7566 | 2 |
++-------+---+
+(4 rows)
+
+!ok
+
+# Correlated EXISTS sub-query inside the argument of a windowed aggregate that
has a PARTITION BY.
+SELECT empno, deptno,
+ COUNT(CASE WHEN EXISTS (SELECT 1 FROM emp AS e2 WHERE e2.mgr = e.empno) THEN
1 END)
+ OVER (PARTITION BY deptno) AS c
+FROM emp AS e
+ORDER BY empno;
++-------+--------+---+
+| EMPNO | DEPTNO | C |
++-------+--------+---+
+| 7369 | 20 | 3 |
+| 7499 | 30 | 1 |
+| 7521 | 30 | 1 |
+| 7566 | 20 | 3 |
+| 7654 | 30 | 1 |
+| 7698 | 30 | 1 |
+| 7782 | 10 | 2 |
+| 7788 | 20 | 3 |
+| 7839 | 10 | 2 |
+| 7844 | 30 | 1 |
+| 7876 | 20 | 3 |
+| 7900 | 30 | 1 |
+| 7902 | 20 | 3 |
+| 7934 | 10 | 2 |
++-------+--------+---+
+(14 rows)
+
+!ok
+
+# Correlated scalar sub-query as the argument of a windowed aggregate.
+SELECT empno,
+ SUM((SELECT COUNT(*) FROM emp AS e2 WHERE e2.mgr = e.empno))
+ OVER (ORDER BY empno) AS s
+FROM emp AS e
+WHERE deptno = 20
+ORDER BY empno;
++-------+---+
+| EMPNO | S |
++-------+---+
+| 7369 | 0 |
+| 7566 | 2 |
+| 7788 | 3 |
+| 7876 | 3 |
+| 7902 | 4 |
++-------+---+
+(5 rows)
+
+!ok
+
+# IN sub-query in the PARTITION BY clause of a window.
+SELECT empno, deptno,
+ COUNT(*) OVER (PARTITION BY deptno IN (SELECT deptno FROM dept WHERE dname =
'SALES')) AS c
+FROM emp
+ORDER BY empno;
++-------+--------+---+
+| EMPNO | DEPTNO | C |
++-------+--------+---+
+| 7369 | 20 | 8 |
+| 7499 | 30 | 6 |
+| 7521 | 30 | 6 |
+| 7566 | 20 | 8 |
+| 7654 | 30 | 6 |
+| 7698 | 30 | 6 |
+| 7782 | 10 | 8 |
+| 7788 | 20 | 8 |
+| 7839 | 10 | 8 |
+| 7844 | 30 | 6 |
+| 7876 | 20 | 8 |
+| 7900 | 30 | 6 |
+| 7902 | 20 | 8 |
+| 7934 | 10 | 8 |
++-------+--------+---+
+(14 rows)
+
+!ok
+
+# Correlated EXISTS sub-query in the ORDER BY clause of a window.
+SELECT empno,
+ ROW_NUMBER() OVER (ORDER BY EXISTS (SELECT 1 FROM emp AS e2 WHERE e2.mgr =
e.empno) DESC,
+ empno) AS rn
+FROM emp AS e
+WHERE deptno = 20
+ORDER BY empno;
++-------+----+
+| EMPNO | RN |
++-------+----+
+| 7369 | 4 |
+| 7566 | 1 |
+| 7788 | 2 |
+| 7876 | 5 |
+| 7902 | 3 |
++-------+----+
+(5 rows)
+
+!ok
+
+# NOT IN sub-query whose result is UNKNOWN (the sub-query
+# returns a NULL) inside a windowed COUNT. COUNT ignores UNKNOWN values,
+# so the sub-query must be expanded using three-valued logic.
+SELECT empno,
+ COUNT(deptno NOT IN (SELECT mgr FROM emp)) OVER () AS c1,
+ COUNT(*) OVER () AS c2
+FROM emp
+WHERE deptno = 10
+ORDER BY empno;
++-------+----+----+
+| EMPNO | C1 | C2 |
++-------+----+----+
+| 7782 | 0 | 3 |
+| 7839 | 0 | 3 |
+| 7934 | 0 | 3 |
++-------+----+----+
+(3 rows)
+
+!ok
+
+# Two sub-queries in the same window: one in the argument of
+# the aggregate, one in the PARTITION BY clause.
+SELECT empno,
+ SUM(CASE WHEN EXISTS (SELECT 1 FROM emp AS e2 WHERE e2.mgr = e.empno) THEN 1
ELSE 0 END)
+ OVER (PARTITION BY deptno IN (SELECT deptno FROM dept WHERE loc = 'DALLAS')
+ ORDER BY empno) AS s
+FROM emp AS e
+ORDER BY empno;
++-------+---+
+| EMPNO | S |
++-------+---+
+| 7369 | 0 |
+| 7499 | 0 |
+| 7521 | 0 |
+| 7566 | 1 |
+| 7654 | 0 |
+| 7698 | 1 |
+| 7782 | 2 |
+| 7788 | 2 |
+| 7839 | 3 |
+| 7844 | 3 |
+| 7876 | 2 |
+| 7900 | 3 |
+| 7902 | 3 |
+| 7934 | 3 |
++-------+---+
+(14 rows)
+
+!ok