//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1995 - 2000. // // File: QOptimiz.hxx // // Contents: Query optimizer. Chooses indexes and table implementations. // // Classes: CQueryOptimizer // // History: 21-Jun-95 KyleP Created // //---------------------------------------------------------------------------- #pragma once #include #include #include #include #include #include #include #include #include class CPidRemapper; DECLARE_SMARTP( Columns ); DECLARE_SMARTP( Sort ); class CGenericCursor; class CSingletonCursor; const MAX_HITS_FOR_FAST_SORT_BY_RANK_OPT = 2000; // Internal cutoff on # results for // sorted-by-rank optimization //+--------------------------------------------------------------------------- // // Class: CQueryOptimizer // // Purpose: Chooses indexes and table strategies. // // History: 21-Jun-95 KyleP Created. // //---------------------------------------------------------------------------- class CQueryOptimizer { public: CQueryOptimizer( XInterface& xQuerySession, ICiCDocStore *pDocStore, XRestriction & rst, CColumnSet const & cols, CSortSet const * psort, CPidRemapper const & pidmap, CRowsetProperties const & rProps, DWORD dwQueryStatus ); ~CQueryOptimizer(); // // Table choices. // inline BOOL IsMultiCursor() const; inline BOOL IsFullySorted() const; inline BOOL IsPositionable() const; // // Cursor retrieval // inline BOOL RequiresCI() const; inline void GetCurrentComponentIndex( unsigned & iCurrent, unsigned & cTotal ) const; inline BOOL CQueryOptimizer::IsWorkidUnique() { // // If we have a null catalog, we do not have wids in a // persistent store. So we have to return FALSE here to cause // the bigtable to associate wids with the matching docs and // use them wherever wids are needed. // return !_fNullCatalog; } CGenericCursor * QueryNextCursor( ULONG & status, BOOL& fAbort ); CSingletonCursor * QuerySingletonCursor( BOOL& fAbort ); CTimeLimit & GetTimeLimit(); // // Singleton support // inline void EnableSingletonCursors(); # ifdef CIEXTMODE void CiExtDump(void *ciExtSelf); # endif ULONG MaxResults() const { return _cMaxResults; } ULONG FirstRows() const { return _cFirstRows; } BOOL FetchDeferredValue( WORKID wid, CFullPropSpec const & ps, PROPVARIANT & var ); BOOL CanPartialDefer() { // We cannot partial defer if: // We have a null catalog OR // enumOption == CI_ENUM_MUST_NEVER_DEFER if ( _fNullCatalog ) { return FALSE; } CI_ENUM_OPTIONS enumOption; SCODE sc = _xQuerySession->GetEnumOption( &enumOption ); if ( FAILED( sc ) ) { vqDebugOut(( DEB_ERROR, "CanPartialDefer - GetEnumOption returned 0x%x\n", sc )); return FALSE; } return ( enumOption != CI_ENUM_MUST_NEVER_DEFER ); } private: // // Validation // BOOL Validate(); // // Query optimization // void ChooseIndexStrategy( CSortSet const * psort, CColumnSet const & cols ); CGenericCursor * ApplyIndexStrategy( ULONG & status, BOOL& fAbort ); ACCESS_MASK _AccessMask() const; BOOL _fMulti; // TRUE if query requires > 1 cursor. BOOL _fAtEnd; // TRUE if out of cursors. BOOL _fFullySorted; // TRUE if current component will iterate // in sorted order. DWORD _dwQueryStatus; // The original status XInterface _xQuerySession; // Query session object XInterface _xDefPropRetriever; // Deferred property retriever XInterface _xCiManager; // Content index CCiFrameworkParams _frameworkParams; // Admin parameters BOOL _fSortedByRankOpt; // TRUE if can use CSortedByRankCursor BOOL _fRankVectorProp; // TRUE if rank vector is in the output column ULONG _cMaxResults; // Limit on # query results ULONG _cFirstRows; // only sort and return the first _cFristRows rows # if CIDBG == 1 XRestriction _xrstOriginal; // For debugging only. # endif CPidRemapper const & _pidmap; // VPID/PID/PROPSPEC translations CTimeLimit _TimeLimit; // execution time limit (must precede _xXpr) XXpr _xXpr; // Expression (test against object) XRestriction _xFullyResolvableRst; // Content query // _TimeLimit must be before _qRstIterator CQueryRstIterator _qRstIterator; // Iterator over various components of OR query XColumnSet _xcols; // Used for multi-part queries. XSortSet _xsort; // Used for multi-part queries. // // Singleton support. // BOOL _fNeedSingleton; // TRUE if QuerySingletonCursor may be called. XXpr _xxprSingleton; // Copy of current expression for singleton. // // Content queries // BOOL _fUseCI; // If TRUE, always use CI value index for property queries. BOOL _fDeferTrimming; // If TRUE, sorted rank cursor will trim results *after* full fetch from CI BOOL _fCIRequiredGlobal; // Does the any component of query require a CI ? BOOL _fCIRequired; // Does the current component of OR query require a CI ? ACCESS_MASK _am; CMutexSem _mtxSem; // To serialize when creating deferred prop retriever BOOL _fNullCatalog; // Do we have a null catalog? }; inline BOOL CQueryOptimizer::IsMultiCursor() const { return _fMulti; } inline BOOL CQueryOptimizer::IsFullySorted() const { return _fFullySorted || _fSortedByRankOpt; } inline BOOL CQueryOptimizer::IsPositionable() const { return FALSE; } inline void CQueryOptimizer::EnableSingletonCursors() { _fNeedSingleton = TRUE; } inline BOOL CQueryOptimizer::RequiresCI() const { return _fCIRequiredGlobal || _fUseCI; } inline void CQueryOptimizer::GetCurrentComponentIndex( unsigned & iCurrent, unsigned & cTotal ) const { _qRstIterator.GetCurComponentIndex( iCurrent, cTotal ); // // If we're not done, then there is a component waiting inside CQueryOptimizer. // if ( !_fAtEnd ) { Win4Assert( iCurrent >= 2 ); iCurrent--; } } //+------------------------------------------------------------------------- // // Member: CQueryOptimizer::_AccessMask, private // // Returns: Access mask appropriate given properties in query // // History: 23-Oct-95 dlee Created // //-------------------------------------------------------------------------- inline ACCESS_MASK CQueryOptimizer::_AccessMask() const { return _am; } inline CTimeLimit & CQueryOptimizer::GetTimeLimit() { return _TimeLimit; } DECLARE_SMARTP( QueryOptimizer )