suibianwanwank commented on code in PR #4637:
URL: https://github.com/apache/calcite/pull/4637#discussion_r2609532655
##########
core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java:
##########
@@ -1184,6 +1210,154 @@ private static void shiftMapping(Map<Integer, Integer>
mapping, int startIndex,
return null;
}
+ /**
+ * Given the SQL:
+ * SELECT ename,
+ * (SELECT sum(c)
+ * FROM
+ * (SELECT deptno AS c
+ * FROM dept
+ * WHERE dept.deptno = emp.deptno
+ * UNION ALL
+ * SELECT 2 AS c
+ * FROM bonus
+ * WHERE bonus.job = emp.job) AS union_subquery
+ * ) AS correlated_sum
+ * FROM emp;
+ *
+ * <p>from:
+ * LogicalUnion(all=[true])
+ * LogicalProject(C=[CAST($0):INTEGER NOT NULL])
+ * LogicalFilter(condition=[=($0, $cor0.DEPTNO)])
+ * LogicalTableScan(table=[[scott, DEPT]])
+ * LogicalProject(C=[2])
+ * LogicalFilter(condition=[=($1, $cor0.JOB)])
+ * LogicalTableScan(table=[[scott, BONUS]])
+ *
+ * <p>to:
+ * LogicalUnion(all=[true])
+ * LogicalProject(JOB=[$0], DEPTNO=[$1], C=[$2])
+ * LogicalJoin(condition=[IS NOT DISTINCT FROM($1, $3)],
joinType=[inner])
+ * LogicalAggregate(group=[{0, 1}])
+ * LogicalProject(JOB=[$2], DEPTNO=[$7])
+ * LogicalTableScan(table=[[scott, EMP]])
+ * LogicalProject(C=[CAST($0):INTEGER NOT NULL], DEPTNO=[$0])
+ * LogicalTableScan(table=[[scott, DEPT]])
+ * LogicalProject(JOB=[$0], DEPTNO=[$1], C=[$2])
+ * LogicalJoin(condition=[IS NOT DISTINCT FROM($0, $3)],
joinType=[inner])
+ * LogicalAggregate(group=[{0, 1}])
+ * LogicalProject(JOB=[$2], DEPTNO=[$7])
+ * LogicalTableScan(table=[[scott, EMP]])
+ * LogicalProject(C=[2], JOB=[$1])
+ * LogicalFilter(condition=[IS NOT NULL($1)])
+ * LogicalTableScan(table=[[scott, BONUS]])
+ */
+ public @Nullable Frame decorrelateRel(SetOp rel, boolean isCorVarDefined,
+ boolean parentPropagatesNullValues) {
+ if (!isCorVarDefined) {
+ return decorrelateRel((RelNode) rel, false, parentPropagatesNullValues);
+ }
+
+ final CorelMap localCorelMap = new CorelMapBuilder().build(rel);
+ final List<CorRef> corVarList = new
ArrayList<>(localCorelMap.mapRefRelToCorRef.values());
+ Collections.sort(corVarList);
+
+ if (corVarList.isEmpty()) {
+ return decorrelateRel((RelNode) rel, true, parentPropagatesNullValues);
+ }
+
+ final NavigableMap<CorDef, Integer> valueGenCorDefOutputs = new
TreeMap<>();
+ final RelNode valueGen =
+ createValueGenerator(corVarList, 0, valueGenCorDefOutputs);
+ requireNonNull(valueGen, "valueGen");
+
+ final int valueGenFieldCount = valueGen.getRowType().getFieldCount();
+ final List<RelNode> newInputs = new ArrayList<>();
+ final Map<Integer, Integer> setOpOldToNewOutputs = new HashMap<>();
+ final NavigableMap<CorDef, Integer> setOpCorDefOutputs = new TreeMap<>();
+ // Original SetOp payload width.
+ final int payloadFieldCount = rel.getRowType().getFieldCount();
+
+ for (int i = 0; i < rel.getInputs().size(); i++) {
+ RelNode oldInput = rel.getInput(i);
+ Frame frame = getInvoke(oldInput, true, rel, parentPropagatesNullValues);
+ if (frame == null) {
+ // If input has not been rewritten, do not rewrite this rel.
+ return null;
+ }
+
+ // Build join conditions: for each CorDef of this branch that belongs
+ // to the current outFrameCorrId, equate valueGen(col) with branch(col).
+ final List<RexNode> conditions = new ArrayList<>();
Review Comment:
Could you explain what left and right represent? Assuming one side has no
corVar, what would the join condition be in that case?
--
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]