windows-nt/Source/XPSP1/NT/inetsrv/query/xpr/parse.cxx
2020-09-26 16:20:57 +08:00

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;
}
}