You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2021/01/05 20:22:26 UTC
[calcite] branch master updated: [CALCITE-4434] Cannot implement
'CASE row WHEN row ...'
This is an automated email from the ASF dual-hosted git repository.
jhyde pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 1dd27f7 [CALCITE-4434] Cannot implement 'CASE row WHEN row ...'
1dd27f7 is described below
commit 1dd27f7ee6eaabd44ecda148bff7db9926dbf201
Author: zhen wang <zi...@gmail.com>
AuthorDate: Thu Dec 31 13:36:31 2020 +0800
[CALCITE-4434] Cannot implement 'CASE row WHEN row ...'
Fix by expanding
ROW (x0, x1, ...) = ROW (y0, y1, ...)
inside a CASE expression to
x0 = y0 AND x1 = y1 AND ...
Close apache/calcite#2309
---
.../calcite/sql2rel/StandardConvertletTable.java | 15 ++++++++
core/src/test/resources/sql/struct.iq | 44 ++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
index aec9007..640b37f 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -900,6 +900,21 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
: operandTypeChecker.getConsistency();
final List<RexNode> exprs = convertOperands(cx, call, consistency);
RelDataType type = rexBuilder.deriveReturnType(op, exprs);
+
+ // Expand 'ROW (x0, x1, ...) = ROW (y0, y1, ...)'
+ // to 'x0 = y0 AND x1 = y1 AND ...'
+ if (op.kind == SqlKind.EQUALS) {
+ final RexNode expr0 = RexUtil.removeCast(exprs.get(0));
+ final RexNode expr1 = RexUtil.removeCast(exprs.get(1));
+ if (expr0.getKind() == SqlKind.ROW && expr1.getKind() == SqlKind.ROW) {
+ final RexCall call0 = (RexCall) expr0;
+ final RexCall call1 = (RexCall) expr1;
+ final List<RexNode> eqList = new ArrayList<>();
+ Pair.forEach(call0.getOperands(), call1.getOperands(), (x, y) ->
+ eqList.add(rexBuilder.makeCall(op, x, y)));
+ return RexUtil.composeConjunction(rexBuilder, eqList);
+ }
+ }
return rexBuilder.makeCall(type, op, RexUtil.flatten(exprs, op));
}
diff --git a/core/src/test/resources/sql/struct.iq b/core/src/test/resources/sql/struct.iq
index 651b388..eaa429e 100644
--- a/core/src/test/resources/sql/struct.iq
+++ b/core/src/test/resources/sql/struct.iq
@@ -83,4 +83,48 @@ where t.struct = ROW(2, ROW(3,4));
!ok
+!use scott
+
+# [CALCITE-4434] Cannot implement 'CASE row WHEN row ...'
+SELECT deptno, job,
+ CASE (deptno, job)
+ WHEN (20, 'CLERK') THEN 1
+ WHEN (30, 'SALESMAN') THEN 2
+ ELSE 3
+ END AS x
+FROM "scott".emp
+WHERE empno < 7600;
++--------+----------+---+
+| DEPTNO | JOB | X |
++--------+----------+---+
+| 20 | CLERK | 1 |
+| 20 | MANAGER | 3 |
+| 30 | SALESMAN | 2 |
+| 30 | SALESMAN | 2 |
++--------+----------+---+
+(4 rows)
+
+!ok
+
+# Equivalent to previous
+SELECT deptno, job,
+ CASE
+ WHEN deptno = 20 AND job = 'CLERK' THEN 1
+ WHEN deptno = 30 AND job = 'SALESMAN' THEN 2
+ ELSE 3
+ END AS x
+FROM "scott".emp
+WHERE empno < 7600;
++--------+----------+---+
+| DEPTNO | JOB | X |
++--------+----------+---+
+| 20 | CLERK | 1 |
+| 20 | MANAGER | 3 |
+| 30 | SALESMAN | 2 |
+| 30 | SALESMAN | 2 |
++--------+----------+---+
+(4 rows)
+
+!ok
+
# End struct.iq