amaliujia commented on a change in pull request #1995:
URL: https://github.com/apache/calcite/pull/1995#discussion_r436301143
##########
File path:
core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableNestedLoopJoin.java
##########
@@ -118,6 +129,104 @@ public static EnumerableNestedLoopJoin create(
return cost;
}
+ @Override public Pair<RelTraitSet, List<RelTraitSet>> passThroughTraits(
+ final RelTraitSet required) {
+ RelCollation collation = required.getCollation();
+ if (collation == null
+ || collation == RelCollations.EMPTY
+ || joinType == JoinRelType.FULL
+ || joinType == JoinRelType.RIGHT) {
+ return null;
+ }
+
+ // EnumerableNestedLoopJoin traits passdown shall only pass through
collation to left input.
+ // It is because for EnumerableNestedLoopJoin always uses left input as
the outer loop,
+ // thus only left input can preserve ordering.
+ // Push sort both to left and right inputs does not help right outer join.
It's because in
+ // implementation, EnumerableNestedLoopJoin produces (null,
right_unmatched) all together,
+ // which does not preserve ordering from right side.
+
+
+ Set<Integer> fields = extractTrivialFieldOfLeftInputFromJoinCondition();
+ for (RelFieldCollation fc : collation.getFieldCollations()) {
+ if (!fields.contains(fc.getFieldIndex())) {
+ return null;
+ }
+ }
+
+ RelTraitSet passthroughTraitSet = traitSet.replace(collation);
+ return Pair.of(passthroughTraitSet,
+ ImmutableList.of(
+ passthroughTraitSet,
+ passthroughTraitSet.replace(RelCollations.EMPTY)));
+ }
+
+ @Override public Pair<RelTraitSet, List<RelTraitSet>> deriveTraits(
+ final RelTraitSet childTraits, final int childId) {
+ // should only derive traits (limited to collation for now) from left join
input.
+ assert childId == 0;
+
+ RelCollation collation = childTraits.getCollation();
+ if (collation == null
+ || collation == RelCollations.EMPTY
+ || joinType == JoinRelType.FULL
+ || joinType == JoinRelType.RIGHT) {
+ return null;
+ }
+
+ Set<Integer> fields = extractTrivialFieldOfLeftInputFromJoinCondition();
+ for (RelFieldCollation fc : collation.getFieldCollations()) {
+ if (!fields.contains(fc.getFieldIndex())) {
+ return null;
+ }
+ }
+
+ List<RelFieldCollation> collationFieldsToDerive = new ArrayList<>();
+ for (RelFieldCollation fc : collation.getFieldCollations()) {
+ if (fields.contains(fc.getFieldIndex())) {
+ collationFieldsToDerive.add(fc);
+ } else {
+ break;
+ }
+ }
+
+ if (collationFieldsToDerive.size() > 0) {
+ final RelCollation newCollation = RelCollations
+ .of(collationFieldsToDerive);
+ return Pair.of(getTraitSet().replace(newCollation),
+ ImmutableList.of(childTraits, right.getTraitSet()));
+ } else {
+ return null;
+ }
+ }
+
+ @Override public DeriveMode getDeriveMode() {
+ if (joinType == JoinRelType.FULL || joinType == JoinRelType.RIGHT) {
+ return DeriveMode.PROHIBITED;
+ }
+
+ return DeriveMode.LEFT_FIRST;
+ }
+
+ private Set<Integer> extractTrivialFieldOfLeftInputFromJoinCondition() {
Review comment:
Done. Updated NestedLoopJoin with several extra tests.
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
[email protected]