Skip to content

Commit

Permalink
[CALCITE-6221] JDBC adapter generates invalid query when the same tab…
Browse files Browse the repository at this point in the history
…le is joined multiple times
  • Loading branch information
kramerul committed Jan 30, 2024
1 parent 75511b8 commit 951b324
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ public Result visit(Join e) {
break;
}
final Result leftResult = visitInput(e, 0).resetAlias();
final Result rightResult = visitInput(e, 1).resetAlias();
Result rightResult = maybeFixRenamedFields(visitInput(e, 1).resetAlias(), e);
final Context leftContext = leftResult.qualifiedContext();
final Context rightContext = rightResult.qualifiedContext();
final SqlNode sqlCondition;
Expand Down Expand Up @@ -257,6 +257,53 @@ public Result visit(Join e) {
return result(join, leftResult, rightResult);
}

private Result maybeFixRenamedFields(Result rightResult, Join e) {
Frame last = stack.peekLast();
if (last != null && last.r instanceof TableModify) {
return rightResult;
}
if (stack.stream().noneMatch(it -> it.r instanceof Filter)) {
return rightResult;
}
List<String> rightFieldNames = e.getRight().getRowType().getFieldNames();
List<String> fieldNames = e.getRowType().getFieldNames();
int offset = e.getLeft().getRowType().getFieldCount();
boolean hasFieldNameCollision = false;
for (int i = 0; i < rightFieldNames.size(); i++) {
if (!rightFieldNames.get(i).equals(fieldNames.get(offset + i))) {
hasFieldNameCollision = true;
}
}
if (!hasFieldNameCollision) {
return rightResult;
}
Builder builder = rightResult.builder(e);
List<SqlNode> oldSelectList = new ArrayList<>();
if (builder.select.getSelectList() == SqlNodeList.SINGLETON_STAR) {
for (int i = 0; i < rightFieldNames.size(); i++) {
oldSelectList.add(new SqlIdentifier(rightFieldNames.get(i), POS));
}
} else {
for (SqlNode node : builder.select.getSelectList().getList()) {
oldSelectList.add(requireNonNull(node, "node"));
}
}
List<SqlNode> selectList = new ArrayList<>();
// The entries in fieldNames are unique, since they have been generated
// using SqlValidatorUtil.deriveJoinRowType
for (int i = 0; i < rightFieldNames.size(); i++) {
SqlNode column = oldSelectList.get(i);
if (!rightFieldNames.get(i).equals(fieldNames.get(offset + i))) {
column =
SqlStdOperatorTable.AS.createCall(POS, SqlUtil.stripAs(column),
new SqlIdentifier(fieldNames.get(offset + i), POS));
}
selectList.add(column);
}
builder.setSelect(new SqlNodeList(selectList, POS));
return builder.result();
}

protected Result visitAntiOrSemiJoin(Join e) {
final Result leftResult = visitInput(e, 0).resetAlias();
final Result rightResult = visitInput(e, 1).resetAlias();
Expand Down
Loading

0 comments on commit 951b324

Please sign in to comment.