//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1991 - 2000. // // File: Parse.cxx // // Contents: Converts restrictions into expressions // // Functions: Parse // // History: 15-Oct-91 KyleP Created // //-------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include "notxpr.hxx" //+--------------------------------------------------------------------------- // // Function: Parse, public // // Synopsis: Convert a restriction into an expression // // Arguments: [prst] -- Restriction to convert // [timeLimit] -- Execution time limit // // Returns: A pointer to the expression which will resolve [prst] // // History: 15-Oct-91 KyleP Created. // 27-Nov-93 KyleP Added RTNot // //---------------------------------------------------------------------------- CXpr * Parse( CRestriction const * prst, CTimeLimit& timeLimit ) { XXpr pxp; CNodeXpr * pnxpr; int cres; switch ( prst->Type() ) { case RTNot: { CNotRestriction * pnRst = (CNotRestriction *)prst; XXpr pTemp( Parse( pnRst->GetChild(), timeLimit ) ); pxp.Set( new CNotXpr( pTemp.Acquire() ) ); break; } case RTAnd: case RTOr: { CNodeRestriction * pnRst = prst->CastToNode(); CXpr::NodeType nt = (prst->Type() == RTAnd) ? CXpr::NTAnd : CXpr::NTOr; cres = pnRst->Count(); pnxpr = new CNodeXpr( nt, cres ); pxp.Set( pnxpr ); vqDebugOut(( DEB_ITRACE, "Parse: %s node, %d restrictions\n", (prst->Type() == RTAnd) ? "AND" : "OR", cres )); for ( cres--; cres >= 0; cres-- ) { pnxpr->AddChild( Parse( pnRst->GetChild(cres), timeLimit ) ); } break; } case RTInternalProp: { CInternalPropertyRestriction * pRst = (CInternalPropertyRestriction *)prst; #if CIDBG == 1 vqDebugOut(( DEB_ITRACE, "Parse: PROPERTY, prop = %d, op = %ld, value = ", pRst->Pid(), pRst->Relation() )); pRst->Value().DisplayVariant(DEB_ITRACE | DEB_NOCOMPNAME, 0); vqDebugOut(( DEB_ITRACE | DEB_NOCOMPNAME, "\n" )); #endif // DBG == 1 if ( pRst->Relation() == PRRE ) pxp.Set( new CRegXpr( pRst, timeLimit ) ); else { pxp.Set( new CXprPropertyRelation( pRst->Pid(), pRst->Relation(), pRst->Value(), pRst->AcquireContentHelper() ) ); } break; } default: vqDebugOut(( DEB_ERROR, "Unhandled expression type %d\n", prst->Type() )); //Win4Assert( !"Unhandled expression type" ); THROW( CException( QUERY_E_INVALIDRESTRICTION ) ); break; } return( pxp.Acquire() ); } //+------------------------------------------------------------------------- // // Function: MoveFullyIndexableNode, public // // Effects: Splits out any components of [pnrSource] which are // *completely* resolved by content index. In practice, // this is boolean trees of CONTENT nodes. // // Arguments: [pnrSource] -- Original restriction // [pnrFullyResolvable] -- Fully resolvable portions of // [pnrSource] // // Modifies: Nodes may be removed from [pnrSource] // // History: 10-Feb-92 KyleP Created // //-------------------------------------------------------------------------- void MoveFullyIndexable( CNodeRestriction & pnrSource, CNodeRestriction & pnrFullyResolvable ) { for ( int i = pnrSource.Count()-1; i >= 0; i-- ) { if ( IsFullyIndexable( pnrSource.GetChild(i) ) ) { unsigned pos; pnrFullyResolvable.AddChild( pnrSource.RemoveChild(i), pos ); } } } //+------------------------------------------------------------------------- // // Function: IsFullyIndexable, public // // Synopsis: Determines of node (or tree) is fully resolved by content // index. // // Arguments: [pRst] -- Restriction to test // // Returns: TRUE if node is fully indexable // // History: 10-Feb-93 KyleP Created // //-------------------------------------------------------------------------- BOOL IsFullyIndexable( CRestriction * pRst ) { switch ( pRst->Type() ) { case RTContent: case RTWord: case RTSynonym: case RTPhrase: case RTRange: case RTProperty: case RTNone: // null-node from noise word in vector query return( TRUE ); case RTAnd: case RTOr: case RTProximity: case RTVector: { CNodeRestriction * pnRst = pRst->CastToNode(); for( int i = pnRst->Count()-1; i >= 0; i-- ) { if ( !IsFullyIndexable( pnRst->GetChild(i) ) ) return FALSE; } return( TRUE ); } case RTNot: { CNotRestriction * pnRst = (CNotRestriction *)pRst; return( IsFullyIndexable( pnRst->GetChild() ) ); break; } default: vqDebugOut(( DEB_ITRACE, "Restriction type %d is not fully indexable\n", pRst->Type() )); return FALSE; } }