@Override protected Binding computeNext() { while(bindings.hasNext()) { List<Binding> cand = bindings.next(); Binding r = null; for(Binding b : cand) { if(r == null) { r = b; } else { boolean isCompatible = Algebra.compatible(r, b); if(isCompatible) { r = Algebra.merge(r, b); } else { continue; } } } return r; } return endOfData(); } }
private static QueryIterator joinWorkerN(QueryIterator left, Table right, JoinType joinType, ExprList conditions, ExecutionContext execCxt) { List<Binding> out = new ArrayList<>() ; for ( ; left.hasNext() ; ) { Binding bindingLeft = left.next() ; int count = 0 ; for (Iterator<Binding> iter = right.rows() ; iter.hasNext();) { Binding bindingRight = iter.next() ; Binding r = Algebra.merge(bindingLeft, bindingRight) ; if ( r == null ) continue ; // This does the conditional part. Theta-join. if ( conditions == null || conditions.isSatisfied(r, execCxt) ) { count ++ ; out.add(r) ; } } if ( count == 0 && ( joinType == LEFT) ) // Conditions on left? out.add(bindingLeft) ; } return new QueryIterPlainWrapper(out.iterator(), execCxt) ; }
protected Binding moveToNextBindingOrNull() { if ( isFinished() ) return null; for ( ;; ) { // For rows from the right. if ( rowRight == null ) { if ( right.hasNext() ) { rowRight = right.next(); s_countRHS++; left = leftRows.iterator(); } else return null; } // There is a rowRight while (left.hasNext()) { Binding rowLeft = left.next(); Binding r = Algebra.merge(rowLeft, rowRight); if ( r != null ) { s_countResults++; return r; } } // Nothing more for this rowRight. rowRight = null; } }
/** Very simple, materializing version - useful for debugging. * Builds output early. Materializes left, streams right. * Does <b>not</b> scale. * No cancellation, no stats. * * @see #nestedLoopJoin */ public static QueryIterator nestedLoopJoinBasic(QueryIterator left, QueryIterator right, ExecutionContext execCxt) { List<Binding> leftRows = Iter.toList(left) ; List<Binding> output = new ArrayList<>() ; for ( ; right.hasNext() ; ) { Binding row2 = right.next() ; for ( Binding row1 : leftRows ) { Binding r = Algebra.merge(row1, row2) ; if ( r != null ) output.add(r) ; } } return new QueryIterPlainWrapper(output.iterator(), execCxt) ; }
/** Very simple, materializing version for leftjoin - useful for debugging. * Builds output early. Materializes right, streams left. * Does <b>not</b> scale. */ public static QueryIterator nestedLoopLeftJoinBasic(QueryIterator left, QueryIterator right, ExprList conditions, ExecutionContext execCxt) { // Stream from left, materialize right. List<Binding> rightRows = Iter.toList(right) ; List<Binding> output = new ArrayList<>() ; long count = 0 ; for ( ; left.hasNext() ; ) { Binding row1 = left.next() ; boolean match = false ; for ( Binding row2 : rightRows ) { Binding r = Algebra.merge(row1, row2) ; if ( r != null && applyConditions(r, conditions, execCxt)) { output.add(r) ; match = true ; } } if ( ! match ) output.add(row1) ; } return new QueryIterPlainWrapper(output.iterator(), execCxt) ; }
Binding r = Algebra.merge(rowLeft, rowRight); if ( r != null && applyConditions(r) ) { s_countResults++;
Binding r = Algebra.merge(rowCurrentProbe, rowStream) ; Binding r2 = null ;