212 lines
5.5 KiB
C++
212 lines
5.5 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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 <pch.cxx>
|
|
#pragma hdrstop
|
|
|
|
#include <parse.hxx>
|
|
#include <fa.hxx>
|
|
|
|
#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;
|
|
}
|
|
}
|