You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ignite.apache.org by GitBox <gi...@apache.org> on 2021/08/23 12:03:13 UTC

[GitHub] [ignite] zstan commented on a change in pull request #9143: IGNITE-14808 RIGHT|FULL Join operations are lost nulls sort ordering.

zstan commented on a change in pull request #9143:
URL: https://github.com/apache/ignite/pull/9143#discussion_r693909452



##########
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:
       +1




-- 
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: notifications-unsubscribe@ignite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org