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 29, 2024
1 parent 75511b8 commit ae5feaf
Show file tree
Hide file tree
Showing 4 changed files with 479 additions and 310 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,7 @@

import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -225,7 +215,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 +247,48 @@ 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;
}
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(Objects.requireNonNull(node));
}
}
List<SqlNode> selectList = new ArrayList<>();
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 ae5feaf

Please sign in to comment.