rubenada commented on a change in pull request #1156: [CALCITE-2973] Allow 
theta joins that have equi conditions to be exec…
URL: https://github.com/apache/calcite/pull/1156#discussion_r316699416
 
 

 ##########
 File path: 
linq4j/src/main/java/org/apache/calcite/linq4j/EnumerableDefaults.java
 ##########
 @@ -1091,38 +1125,44 @@ public boolean moveNext() {
                 return true;
               }
               if (!outers.moveNext()) {
-                if (unmatchedKeys != null) {
-                  // We've seen everything else. If we are doing a RIGHT or 
FULL
-                  // join (leftNull = true) there are any keys which right but
-                  // not the left.
-                  List<TInner> list = new ArrayList<>();
-                  for (TKey key : unmatchedKeys) {
-                    for (TInner tInner : innerLookup.get(key)) {
-                      list.add(tInner);
-                    }
-                  }
-                  inners = Linq4j.enumerator(list);
+                if (innersUnmatched != null) {
+                  inners = Linq4j.enumerator(new ArrayList<>(innersUnmatched));
                   outers.close();
                   outers = Linq4j.singletonNullEnumerator();
                   outers.moveNext();
-                  unmatchedKeys = null; // don't do the 'leftovers' again
+                  innersUnmatched = null; // don't do the 'leftovers' again
                   continue;
                 }
                 return false;
               }
               final TSource outer = outers.current();
-              final Enumerable<TInner> innerEnumerable;
+              Enumerable<TInner> innerEnumerable;
               if (outer == null) {
                 innerEnumerable = null;
               } else {
                 final TKey outerKey = outerKeySelector.apply(outer);
                 if (outerKey == null) {
                   innerEnumerable = null;
                 } else {
-                  if (unmatchedKeys != null) {
-                    unmatchedKeys.remove(outerKey);
-                  }
                   innerEnumerable = innerLookup.get(outerKey);
+                  //apply predicate to filter per-row
+                  if (innerEnumerable != null && innerEnumerable.any()) {
 
 Review comment:
   @LaiZhou I think this new piece of code could be refactored to avoid using 
`innerEnumerable.any()` (which internally creates an extra enumerator), and the 
local variable `innersToFilter`. I haven't tested the following code, but I 
think it should achieve the same result:
   ```
     if (innerEnumerable != null) {
        final List<TInner> matchedInners;
        if (predicate == null) {
          matchedInners = innerEnumerable.toList();
        }
        else {
          matchedInners = new ArrayList<>();
          try (Enumerator<TInner> innerEnumerator = 
innerEnumerable.enumerator()) {
                while (innerEnumerator.moveNext()) {
                  final TInner inner = innerEnumerator.current();
                  if (predicate.apply(outer, inner)) {
                        matchedInners.add(inner);
                  }
                }
          }
          innerEnumerable = Linq4j.asEnumerable(matchedInners);
        }
        if (innersUnmatched != null) {
          innersUnmatched.removeAll(matchedInners);
        }
     }
   ```

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


With regards,
Apache Git Services

Reply via email to