void QueryPlanSet::addOtherPlans( bool checkFirst ) { const char *ns = fbs_.ns(); NamespaceDetails *d = nsdetails( ns ); if ( !d ) return; // If table scan is optimal or natural order requested if ( ( fbs_.nNontrivialBounds() == 0 && order_.isEmpty() ) || ( !order_.isEmpty() && !strcmp( order_.firstElement().fieldName(), "$natural" ) ) ) { // Table scan plan addPlan( PlanPtr( new QueryPlan( fbs_, order_ ) ), checkFirst ); return; } PlanSet plans; for( int i = 0; i < d->nIndexes; ++i ) { PlanPtr p( new QueryPlan( fbs_, order_, &d->indexes[ i ] ) ); if ( p->optimal() ) { addPlan( p, checkFirst ); return; } else if ( !p->unhelpful() ) { plans.push_back( p ); } } for( PlanSet::iterator i = plans.begin(); i != plans.end(); ++i ) addPlan( *i, checkFirst ); // Table scan plan addPlan( PlanPtr( new QueryPlan( fbs_, order_ ) ), checkFirst ); }
void QueryPlanSet::addOtherPlans( bool checkFirst ) { const char *ns = _frsp->ns(); NamespaceDetails *d = nsdetails( ns ); if ( !d ) return; // If table scan is optimal or natural order requested or tailable cursor requested if ( !_frsp->matchPossible() || ( _frsp->noNontrivialRanges() && _order.isEmpty() ) || ( !_order.isEmpty() && !strcmp( _order.firstElement().fieldName(), "$natural" ) ) ) { // Table scan plan addPlan( QueryPlanPtr( new QueryPlan( d, -1, *_frsp, *_originalFrsp, _originalQuery, _order ) ), checkFirst ); return; } bool normalQuery = _hint.isEmpty() && _min.isEmpty() && _max.isEmpty(); PlanSet plans; QueryPlanPtr optimalPlan; for( int i = 0; i < d->nIndexes; ++i ) { if ( normalQuery ) { if ( !_frsp->matchPossibleForIndex( d, i, d->idx( i ).keyPattern() ) ) { // If no match is possible, only generate a trival plan that won't // scan any documents. QueryPlanPtr p( new QueryPlan( d, i, *_frsp, *_originalFrsp, _originalQuery, _order ) ); addPlan( p, checkFirst ); return; } if ( !QueryUtilIndexed::indexUseful( *_frsp, d, i, _order ) ) { continue; } } QueryPlanPtr p( new QueryPlan( d, i, *_frsp, *_originalFrsp, _originalQuery, _order ) ); if ( p->optimal() ) { if ( !optimalPlan.get() ) { optimalPlan = p; } } else if ( !p->unhelpful() ) { plans.push_back( p ); } } if ( optimalPlan.get() ) { addPlan( optimalPlan, checkFirst ); return; } for( PlanSet::iterator i = plans.begin(); i != plans.end(); ++i ) addPlan( *i, checkFirst ); // Table scan plan addPlan( QueryPlanPtr( new QueryPlan( d, -1, *_frsp, *_originalFrsp, _originalQuery, _order ) ), checkFirst ); }