void IntersectQP::applyConversionRules(unsigned int maxAlternatives, OptimizationContext &opt, QueryPlans &alternatives) { XPath2MemoryManager *mm = opt.getMemoryManager(); removeSupersets(opt); // Return if we only have one argument if(args_.size() == 1) { alternatives.push_back(args_[0]); return; } // TBD remove the need for QueryExecutionContext here - jpcs QueryExecutionContext qec(GET_CONFIGURATION(opt.getContext())->getQueryContext(), /*debugging*/false); qec.setContainerBase(opt.getContainerBase()); qec.setDynamicContext(opt.getContext()); // Sort the arguments based on how many keys we think they'll return sort(args_.begin(), args_.end(), keys_compare_less(opt.getOperationContext(), qec)); alternatives.push_back(this); for(Vector::const_iterator it = args_.begin(); it != args_.end(); ++it) { for(Vector::const_iterator it2 = it + 1; it2 != args_.end(); ++it2) { QueryPlans alts; applyConversionRules2Args(maxAlternatives, *it, *it2, opt, alts); for(QueryPlans::iterator it3 = alts.begin(); it3 != alts.end(); ++it3) { IntersectQP *newIntersect = new (mm) IntersectQP(flags_, mm); newIntersect->setLocationInfo(this); Vector::const_iterator it4; // Copy args before "it" for(it4 = args_.begin(); it4 != it; ++it4) { newIntersect->addArg((*it4)->copy(mm)); } // Add new alternative newIntersect->addArg(*it3); // Copy args from after "it" to before "it2" for(++it4; it4 != it2; ++it4) { newIntersect->addArg((*it4)->copy(mm)); } // Copy args from after "it2" for(++it4; it4 != args_.end(); ++it4) { newIntersect->addArg((*it4)->copy(mm)); } newIntersect->applyConversionRules(maxAlternatives, opt, alternatives); } } } }