void CTSP::interswap() { int a,b; int numSwaps=0; while (intersectSet(&a,&b) && numSwaps<100) { swap(a,b); numSwaps++; if (debug) printf("%f\n",getLength()); } }
Join* MultiJoin::splitSubset(const JBBSubset & leftSet, const JBBSubset & rightSet, NABoolean reUseMJ) const { // At this point assert that none of the subsets has a group by member CMPASSERT ( (jbbSubset_.getGB() == NULL_CA_ID) && (leftSet.getGB() == NULL_CA_ID) && (rightSet.getGB() == NULL_CA_ID) ); #ifndef NDEBUG // assert that left + right == subSet_ // and left intersect right = phi CANodeIdSet unionSet(leftSet.getJBBCs()); CANodeIdSet intersectSet(leftSet.getJBBCs()); unionSet += rightSet.getJBBCs(); intersectSet.intersectSet(rightSet.getJBBCs()); CMPASSERT ( (unionSet == jbbSubset_.getJBBCs()) && (intersectSet.entries() == 0 )); #endif // Note: Joins including left, semi, anti semi are only created when // a single jbbc connected via one of them is split as a single right // child. InnerNonSemi joins can be created for any split i.e. any // number of jbbcs on the left and the right of the join, but special // joins (i.e. left, semi and anti semi joins) are only created when // there is a single right child i.e. the rightSet contains only one // jbbc that is connected via a special join. This is enforced as follows // // * The leftSet should be legal: This means that for every jbbc in the // leftSet any predecessor jbbcs should be present in the leftSet. // * The rightSet is either a single jbbc or if the rightSet has more // than one jbbc then it should be legal, note that a jbbc connected // via a special join is not a legal set by itself but we allow // creation of special joins assuming the predecessors are present // in the leftSet. // // An implicit assumption here is that 'this' MultiJoin is legal, which // is fair since apart from the top level multijoin, rest of the multijoins // are produced by splitting the top level multijoin. This method should // not produce illegal multijoins, since we check both leftSet and rightSet // for legality. Only time we don't check for legality is when the rightChild // is a single jbbc, and a single jbbc does not result in a multijoin. if(!leftSet.legal()) return NULL; if((rightSet.getJBBCs().entries() > 1) && (!rightSet.legal())) return NULL; // everything here goes to statement heap CollHeap* outHeap = CmpCommon::statementHeap(); RelExpr* child0 = generateSubsetExpr(leftSet, reUseMJ); RelExpr* child1 = generateSubsetExpr(rightSet, reUseMJ); // Flag to remember to pass on the derivedFromRoutineJoin flag if needed. NABoolean derivedFromRoutineJoin(FALSE); // now form a JoinExpr with these left and right children. Join * result = NULL; // if the rightSet is a single jbbc, then it could be connected via // a special join. In such a case we have to create the appropriate // join operator if(rightSet.getJBBCs().entries() == 1){ JBBC * rightChild = rightSet.getJBBCs().getFirst().getNodeAnalysis() ->getJBBC(); Join * rightChildParentJoin = rightChild->getOriginalParentJoin(); // If rightChildParentJoin is NULL, then the child is the left // child of the left most join and is considered to be connected // via a InnerNonSemi join. if(rightChildParentJoin) { if(rightChildParentJoin->derivedFromRoutineJoin()) derivedFromRoutineJoin = TRUE; if(rightChildParentJoin->isSemiJoin()) result = new (outHeap) Join(child0, child1, REL_SEMIJOIN, NULL); if(rightChildParentJoin->isAntiSemiJoin()) result = new (outHeap) Join(child0, child1, REL_ANTI_SEMIJOIN, NULL); if(rightChildParentJoin->isLeftJoin()) { // left joins can have filter preds, i.e. predicates that // are applied as filters after applying the join predicate. // We need to set them here. result = new (outHeap) Join(child0, child1, REL_LEFT_JOIN, NULL); result->setSelectionPredicates(rightChild->getLeftJoinFilterPreds()); } if(rightChildParentJoin->isRoutineJoin()) { derivedFromRoutineJoin = TRUE; result = new (outHeap) Join(child0, child1, REL_ROUTINE_JOIN, NULL); ValueIdSet routineJoinFilterPreds = rightChild->getRoutineJoinFilterPreds(); ValueIdSet predsToAddToRoutineJoin; // add covered filter preds for (ValueId filterPred= routineJoinFilterPreds.init(); routineJoinFilterPreds.next(filterPred); routineJoinFilterPreds.advance(filterPred) ) { if(jbbSubset_.coversExpr(filterPred)) predsToAddToRoutineJoin += filterPred; } result->setSelectionPredicates(predsToAddToRoutineJoin); } if(result) { // set the join predicate for special joins, note predicates // for regular InnerNonSemi joins are set as selection predicates // in the join relexpr. result->setJoinPred(rightChild->getPredsWithPredecessors()); result->nullInstantiatedOutput().insert(rightChild-> nullInstantiatedOutput()); } } } // The join to be created is a regular InnerNonSemi join if (!result) result = new (outHeap) Join(child0, child1, REL_JOIN, NULL); // Make sure we carry the derivedFromRoutineJoin flag with us if (derivedFromRoutineJoin) result->setDerivedFromRoutineJoin(); // Share my groupAttr with result result->setGroupAttr(getGroupAttr()); // get inner join predicates ValueIdSet selPreds = rightSet.joinPredsWithOther(leftSet); // get left join filter preds if any selPreds += result->getSelectionPredicates(); result->setSelectionPredicates(selPreds); result->findEquiJoinPredicates(); // May be I could save a little if i pushdown only to the child(ren) // that are not already JBBCs, i.e. multijoins result->pushdownCoveredExpr (result->getGroupAttr()->getCharacteristicOutputs(), result->getGroupAttr()->getCharacteristicInputs(), result->selectionPred()); // We used CutOp as children, to avoid pushing predicates to JBBCs. // Now put the actual expression back in case the child is a JBBCs if(leftSet.getJBBCs().entries() == 1) result->setChild(0, getJBBCRelExpr(leftSet.getJBBCs().getFirst())); // We used CutOp as children, to avoid pushing predicates to JBBCs. // Now put the actual expression back in case the child is a JBBCs if(rightSet.getJBBCs().entries() == 1) result->setChild(1, getJBBCRelExpr(rightSet.getJBBCs().getFirst())); // Temp fixup. We need to take the selectionPred out of MultiJoin // for now to prevent that pushed expr from being there. selectionPred // is not being used now in MultiJoin xxx. if (leftSet.getJBBCs().entries() > 1) result->child(0)->selectionPred().clear(); if (rightSet.getJBBCs().entries() > 1) result->child(1)->selectionPred().clear(); return result; }