This is an automated email from the ASF dual-hosted git repository.
amaliujia 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 9b27206 CALCITE-4434 fix cannot implement 'CASE row WHEN row...'
9b27206 is described below
commit 9b272069091c649935c36a6bf26204b64b18ef44
Author: zhen wang <[email protected]>
AuthorDate: Wed Dec 16 17:25:52 2020 +0800
CALCITE-4434 fix cannot implement 'CASE row WHEN row...'
---
.../calcite/sql2rel/StandardConvertletTable.java | 24 ++++++++++++
core/src/test/resources/sql/struct.iq | 44 ++++++++++++++++++++++
2 files changed, 68 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..f6987a3 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -30,6 +30,7 @@ import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexRangeRef;
import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.runtime.FlatLists;
import org.apache.calcite.runtime.SqlFunctions;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlBasicCall;
@@ -900,6 +901,29 @@ public class StandardConvertletTable extends
ReflectiveConvertletTable {
: operandTypeChecker.getConsistency();
final List<RexNode> exprs = convertOperands(cx, call, consistency);
RelDataType type = rexBuilder.deriveReturnType(op, exprs);
+
+ //generate relation for `=(Row1,Row2)`
+ if (op.kind == SqlKind.EQUALS) {
+ RexNode expr0 = RexUtil.removeCast(exprs.get(0));
+ RexNode expr1 = RexUtil.removeCast(exprs.get(1));
+ SqlKind expr0Kind = expr0.getKind();
+ SqlKind expr1Kind = expr1.getKind();
+ if (expr0Kind == SqlKind.ROW && expr1Kind == SqlKind.ROW) {
+ RexCall call0 = (RexCall) expr0;
+ RexCall call1 = (RexCall) expr1;
+ int cmpCount = call0.getOperands().size();
+ ImmutableList.Builder<RexNode> compareBuilder =
ImmutableList.builder();
+ for (int i = 0; i < cmpCount; i += 1) {
+ RexNode cmp = rexBuilder.makeCall(type, op,
+ FlatLists.of(
+ call0.getOperands().get(i),
+ call1.getOperands().get(i))
+ );
+ compareBuilder.add(cmp);
+ }
+ return rexBuilder.makeCall(type, SqlStdOperatorTable.AND,
compareBuilder.build());
+ }
+ }
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