alex-plekhanov commented on a change in pull request #9143:
URL: https://github.com/apache/ignite/pull/9143#discussion_r691058170



##########
File path: 
modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteMergeJoin.java
##########
@@ -162,74 +166,82 @@ else if (isPrefix(rightCollation.getKeys(), 
joinInfo.rightKeys))// preserve righ
 
     /** {@inheritDoc} */
     @Override public Pair<RelTraitSet, List<RelTraitSet>> passThroughCollation(
-        RelTraitSet nodeTraits,
+        RelTraitSet required,
         List<RelTraitSet> inputTraits
     ) {
-        RelCollation collation = TraitUtils.collation(nodeTraits);
-        RelTraitSet left = inputTraits.get(0), right = inputTraits.get(1);
-
-        int rightOff = this.left.getRowType().getFieldCount();
-
-        Map<Integer, Integer> rightToLeft = joinInfo.pairs().stream()
-            .collect(Collectors.toMap(p -> p.target, p -> p.source));
+        RelCollation collation = TraitUtils.collation(required);
+        RelTraitSet left = inputTraits.get(0);
+        RelTraitSet right = inputTraits.get(1);
 
-        List<Integer> collationLeftPrj = new ArrayList<>();
-
-        for (Integer c : collation.getKeys()) {
-            collationLeftPrj.add(
-                c >= rightOff ? rightToLeft.get(c - rightOff) : c
-            );
-        }
+        if (joinType == FULL)
+            return passThroughDefaultCollation(required, left, right);
 
-        boolean preserveNodeCollation = false;
+        int leftInputFieldCount = this.left.getRowType().getFieldCount();
 
-        List<Integer> newLeftCollation, newRightCollation;
+        List<Integer> reqKeys = RelCollations.ordinals(collation);
+        List<Integer> leftKeys = joinInfo.leftKeys.toIntegerList();
+        List<Integer> rightKeys = 
joinInfo.rightKeys.incr(leftInputFieldCount).toIntegerList();
 
-        Map<Integer, Integer> leftToRight = joinInfo.pairs().stream()
-            .collect(Collectors.toMap(p -> p.source, p -> p.target));
+        ImmutableBitSet reqKeySet = ImmutableBitSet.of(reqKeys);
+        ImmutableBitSet leftKeySet = ImmutableBitSet.of(joinInfo.leftKeys);
+        ImmutableBitSet rightKeySet = ImmutableBitSet.of(rightKeys);
 
-        if (isPrefix(collationLeftPrj, joinInfo.leftKeys)) { // preserve 
collation
-            newLeftCollation = new ArrayList<>();
-            newRightCollation = new ArrayList<>();
+        RelCollation nodeCollation;
+        RelCollation leftCollation;
+        RelCollation rightCollation;
 
-            int ind = 0;
-            for (Integer c : collation.getKeys()) {
-                if (c < rightOff) {
-                    newLeftCollation.add(c);
+        if (reqKeySet.equals(leftKeySet)) {
+            if (joinType == RIGHT)
+                return passThroughDefaultCollation(required, left, right);
 
-                    if (ind < joinInfo.leftKeys.size())
-                        newRightCollation.add(leftToRight.get(c));
-                }
-                else {
-                    c -= rightOff;
-                    newRightCollation.add(c);
-
-                    if (ind < joinInfo.leftKeys.size())
-                        newLeftCollation.add(rightToLeft.get(c));
-                }
-
-                ind++;
-            }
-
-            preserveNodeCollation = true;
+            nodeCollation = collation;
+            leftCollation = collation;
+            rightCollation = collation.apply(buildTransposeMapping(true));
         }
-        else { // generate new collations
-            newLeftCollation = maxPrefix(collationLeftPrj, joinInfo.leftKeys);
-
-            Set<Integer> tail = new HashSet<>(joinInfo.leftKeys);
-
-            tail.removeAll(newLeftCollation);
-
-            newLeftCollation.addAll(tail);
+        else if (containsOrderless(leftKeys, collation)) {
+            if (joinType == RIGHT)
+                return passThroughDefaultCollation(required, left, right);
+
+            // if sort keys are subset of left join keys, we can extend 
collations to make sure all join
+            // keys are sorted.
+            nodeCollation = collation;
+            leftCollation = extendCollation(collation, leftKeys);
+            rightCollation = leftCollation.apply(buildTransposeMapping(true));
+        }
+        else if (containsOrderless(collation, leftKeys) && 
reqKeys.stream().allMatch(i -> i < leftInputFieldCount)) {
+            if (joinType == RIGHT)
+                return passThroughDefaultCollation(required, left, right);
+
+            // if sort keys are superset of left join keys, and left join keys 
is prefix of sort keys
+            // (order not matter), also sort keys are all from left join input.
+            nodeCollation = collation;
+            leftCollation = collation;
+            rightCollation = leftCollation.apply(buildTransposeMapping(true));
+        }
+        else if (reqKeySet.equals(rightKeySet)) {
+            if (joinType == LEFT)
+                return passThroughDefaultCollation(required, left, right);
 
-            newRightCollation = 
newLeftCollation.stream().map(leftToRight::get).collect(Collectors.toList());
+            nodeCollation = collation;
+            rightCollation = RelCollations.shift(collation, 
-leftInputFieldCount);
+            leftCollation = rightCollation.apply(buildTransposeMapping(false));
         }
+        else if (containsOrderless(rightKeys, collation)) {
+            if (joinType == LEFT)
+                return passThroughDefaultCollation(required, left, right);
 
-        RelCollation leftCollation = createCollation(newLeftCollation);
-        RelCollation rightCollation = createCollation(newRightCollation);
+            nodeCollation = collation;
+            rightCollation = RelCollations.shift(extendCollation(collation, 
rightKeys), -leftInputFieldCount);
+            leftCollation = rightCollation.apply(buildTransposeMapping(false));
+        }
+        else {
+            nodeCollation = EMPTY;

Review comment:
       `return passThroughDefaultCollation(...)`?




-- 
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]


Reply via email to