Skip to content

Commit cee63d5

Browse files
author
Dongsheng He
committed
[CALCITE-7502] RelToSqlConverter creates invalid sql when converting nested window contains SqlCaseWhen
1 parent b2e1ab3 commit cee63d5

2 files changed

Lines changed: 45 additions & 15 deletions

File tree

core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
100100
import org.apache.calcite.sql.type.SqlTypeFamily;
101101
import org.apache.calcite.sql.type.SqlTypeName;
102+
import org.apache.calcite.sql.util.SqlBasicVisitor;
102103
import org.apache.calcite.sql.util.SqlShuttle;
103104
import org.apache.calcite.sql.validate.SqlValidatorUtil;
104105
import org.apache.calcite.util.DateString;
@@ -2177,24 +2178,25 @@ private boolean containsOver(@UnknownInitialization Result this,
21772178
if (node == null) {
21782179
return false;
21792180
}
2180-
if (node.getKind() == SqlKind.WINDOW) {
2181-
return true;
2182-
}
2183-
if (node instanceof SqlSelect) {
2184-
final SqlNodeList selectList = ((SqlSelect) node).getSelectList();
2185-
for (SqlNode child : selectList) {
2186-
if (containsOver(child)) {
2187-
return true;
2181+
final boolean[] result = {false};
2182+
node.accept(new SqlBasicVisitor<Void>() {
2183+
@Override public Void visit(SqlCall call) {
2184+
if (result[0]) {
2185+
return null;
21882186
}
2189-
}
2190-
} else if (node instanceof SqlBasicCall) {
2191-
for (SqlNode operand : ((SqlBasicCall) node).getOperandList()) {
2192-
if (containsOver(operand)) {
2193-
return true;
2187+
if (call.getKind() == SqlKind.WINDOW) {
2188+
result[0] = true;
2189+
return null;
2190+
}
2191+
for (SqlNode operand : call.getOperandList()) {
2192+
if (operand != null) {
2193+
operand.accept(this);
2194+
}
21942195
}
2196+
return null;
21952197
}
2196-
}
2197-
return false;
2198+
});
2199+
return result[0];
21982200
}
21992201

22002202
/** Returns whether an {@link Aggregate} contains nested operands that

core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5960,6 +5960,34 @@ private void checkLiteral2(String expression, String expected) {
59605960
+ "FROM \"foodmart\".\"product\"";
59615961
sql(query1).optimize(rules, null).ok(expected10);
59625962
sql(query1).ok(expected11);
5963+
5964+
String query2 = " SELECT "
5965+
+ "SUM (\"daily_sales\") OVER (PARTITION BY \"product_name\") AS \"sales\" "
5966+
+ "FROM ( SELECT \"product_name\", "
5967+
+ "CASE WHEN SUM(\"product_id\") OVER (PARTITION BY \"product_name\") > 0 "
5968+
+ "THEN 1 ELSE 0 END AS \"daily_sales\" "
5969+
+ "FROM \"product\" ) subquery";
5970+
String expected20 = "SELECT "
5971+
+ "SUM(\"daily_sales\") "
5972+
+ "OVER (PARTITION BY \"product_name\" "
5973+
+ "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS \"sales\"\n"
5974+
+ "FROM (SELECT \"product_name\", "
5975+
+ "CASE WHEN (SUM(\"product_id\") OVER (PARTITION BY \"product_name\" "
5976+
+ "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) > 0 THEN 1 ELSE 0 END "
5977+
+ "AS \"daily_sales\"\n"
5978+
+ "FROM \"foodmart\".\"product\") AS \"t1\"";
5979+
String expected21 = "SELECT "
5980+
+ "SUM(\"daily_sales\") "
5981+
+ "OVER (PARTITION BY \"product_name\" "
5982+
+ "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS \"sales\"\n"
5983+
+ "FROM (SELECT \"product_name\", "
5984+
+ "CASE WHEN (SUM(\"product_id\") "
5985+
+ "OVER (PARTITION BY \"product_name\" "
5986+
+ "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) > 0 THEN 1 ELSE 0 END "
5987+
+ "AS \"daily_sales\"\n"
5988+
+ "FROM \"foodmart\".\"product\") AS \"t\"";
5989+
sql(query2).optimize(rules, null).ok(expected20);
5990+
sql(query2).ok(expected21);
59635991
}
59645992

59655993
/** Test case for

0 commit comments

Comments
 (0)