2
// $Id: sphinxquery.cpp 2968 2011-09-23 16:31:11Z shodan $
2
// $Id: sphinxquery.cpp 3114 2012-02-21 14:52:21Z klirichek $
6
// Copyright (c) 2001-2011, Andrew Aksyonoff
7
// Copyright (c) 2008-2011, Sphinx Technologies Inc
6
// Copyright (c) 2001-2012, Andrew Aksyonoff
7
// Copyright (c) 2008-2012, Sphinx Technologies Inc
8
8
// All rights reserved
10
10
// This program is free software; you can redistribute it and/or modify
54
54
XQNode_t * SweepNulls ( XQNode_t * pNode );
55
55
bool FixupNots ( XQNode_t * pNode );
57
inline void SetFieldSpec ( const CSphSmallBitvec& uMask, int iMaxPos )
59
m_dStateSpec.SetFieldSpec ( uMask, iMaxPos );
61
inline void SetZoneVec ( int iZoneVec )
63
m_dStateSpec.SetZoneSpec ( m_dZoneVecs[iZoneVec] );
58
67
const CSphVector<int> & GetZoneVec ( int iZoneVec ) const
113
123
//////////////////////////////////////////////////////////////////////////
125
void XQLimitSpec_t::SetFieldSpec ( const CSphSmallBitvec& uMask, int iMaxPos )
128
m_dFieldMask = uMask;
129
m_iFieldMaxPos = iMaxPos;
115
134
void XQNode_t::SetFieldSpec ( const CSphSmallBitvec& uMask, int iMaxPos )
117
136
// set it, if we do not yet have one
121
m_dFieldMask = uMask;
122
m_iFieldMaxPos = iMaxPos;
137
if ( !m_dSpec.m_bFieldSpec )
138
m_dSpec.SetFieldSpec ( uMask, iMaxPos );
125
140
// some of the children might not yet have a spec, even if the node itself has
126
141
// eg. 'hello @title world' (whole node has '@title' spec but 'hello' node does not have any!)
128
143
m_dChildren[i]->SetFieldSpec ( uMask, iMaxPos );
146
void XQLimitSpec_t::SetZoneSpec ( const CSphVector<int> & dZones )
131
152
void XQNode_t::SetZoneSpec ( const CSphVector<int> & dZones )
133
154
// set it, if we do not yet have one
134
if ( !m_dZones.GetLength() )
155
if ( !m_dSpec.m_dZones.GetLength() )
156
m_dSpec.SetZoneSpec ( dZones );
137
158
// some of the children might not yet have a spec, even if the node itself has
138
159
ARRAY_FOREACH ( i, m_dChildren )
147
if ( pSpecs->m_bFieldSpec )
148
SetFieldSpec ( pSpecs->m_dFieldMask, pSpecs->m_iFieldMaxPos );
168
if ( !m_dSpec.m_bFieldSpec )
169
m_dSpec.SetFieldSpec ( pSpecs->m_dSpec.m_dFieldMask, pSpecs->m_dSpec.m_iFieldMaxPos );
150
if ( pSpecs->m_dZones.GetLength() )
151
SetZoneSpec ( pSpecs->m_dZones );
171
if ( !m_dSpec.m_dZones.GetLength() )
172
m_dSpec.SetZoneSpec ( pSpecs->m_dSpec.m_dZones );
155
176
void XQNode_t::ClearFieldMask ()
178
m_dSpec.m_dFieldMask.Set();
159
180
ARRAY_FOREACH ( i, m_dChildren )
160
181
m_dChildren[i]->ClearFieldMask();
791
812
XQKeyword_t tAW ( sKeyword, m_iAtomPos );
792
813
tAW.m_uStarPosition = uStarPosition;
794
XQNode_t * pNode = new XQNode_t();
815
XQNode_t * pNode = new XQNode_t ( m_dStateSpec );
795
816
pNode->m_dWords.Add ( tAW );
797
818
m_dSpawned.Add ( pNode );
823
844
if ( eOp==SPH_QUERY_NOT )
825
XQNode_t * pNode = new XQNode_t();
846
XQNode_t * pNode = new XQNode_t ( m_dStateSpec );
826
847
pNode->SetOp ( SPH_QUERY_NOT, pLeft );
827
848
m_dSpawned.Add ( pNode );
839
860
// eg. '@title hello' vs 'world'
840
861
pRight->CopySpecs ( pLeft );
863
XQNode_t * pDonor = pRight;
864
if ( pRight->m_dSpec.m_bInvisible )
867
m_dStateSpec = pDonor->m_dSpec;
842
869
// build a new node
843
870
XQNode_t * pResult = NULL;
844
871
if ( pLeft->m_dChildren.GetLength() && pLeft->GetOp()==eOp && pLeft->m_iOpArg==iOpArg )
846
873
pLeft->m_dChildren.Add ( pRight );
875
if ( pRight->m_dSpec.m_bFieldSpec )
876
pResult->m_dSpec.SetFieldSpec ( pRight->m_dSpec.m_dFieldMask, pRight->m_dSpec.m_iFieldMaxPos );
878
if ( pRight->m_dSpec.m_dZones.GetLength() )
879
pResult->m_dSpec.SetZoneSpec ( pRight->m_dSpec.m_dZones );
850
XQNode_t * pNode = new XQNode_t();
882
// however, it's right (!) spec which is chosen for the resulting node,
883
// eg. '@title hello' + 'world @body program'
884
XQNode_t * pNode = new XQNode_t ( pDonor->m_dSpec );
851
885
pNode->SetOp ( eOp, pLeft, pRight );
852
886
pNode->m_iOpArg = iOpArg;
853
887
m_dSpawned.Add ( pNode );
857
// however, it's right (!) spec which is chosen for the resulting node,
858
// eg. '@title hello' + 'world @body program'
859
if ( pRight->m_bFieldSpec )
861
pResult->m_bFieldSpec = true;
862
pResult->m_dFieldMask = pRight->m_dFieldMask;
863
pResult->m_iFieldMaxPos = pRight->m_iFieldMaxPos;
968
992
// must be some NOTs within AND at this point, convert this node to ANDNOT
969
993
assert ( pNode->GetOp()==SPH_QUERY_AND && pNode->m_dChildren.GetLength() && dNots.GetLength() );
971
XQNode_t * pAnd = new XQNode_t();
995
XQNode_t * pAnd = new XQNode_t ( pNode->m_dSpec );
972
996
pAnd->SetOp ( SPH_QUERY_AND, pNode->m_dChildren );
973
997
m_dSpawned.Add ( pAnd );
996
1020
for ( int i = 0; i < pNode->m_dChildren.GetLength (); )
998
if ( pNode->m_dChildren[i]->m_dFieldMask.TestAll() )
1022
if ( pNode->m_dChildren[i]->m_dSpec.m_dFieldMask.TestAll() )
1000
1024
// this should be a leaf node
1001
1025
assert ( pNode->m_dChildren[i]->m_dChildren.GetLength()==0 );
1063
1087
const int OPTION_RELAXED_LEN = strlen ( OPTION_RELAXED );
1065
1089
m_bStopOnInvalid = true;
1066
if ( strncmp ( sQuery, OPTION_RELAXED, OPTION_RELAXED_LEN )==0 && !sphIsAlpha ( sQuery[OPTION_RELAXED_LEN] ) )
1090
if ( sQuery && strncmp ( sQuery, OPTION_RELAXED, OPTION_RELAXED_LEN )==0 && !sphIsAlpha ( sQuery[OPTION_RELAXED_LEN] ) )
1068
1092
sQuery += OPTION_RELAXED_LEN;
1069
1093
m_bStopOnInvalid = false;
1520
1544
XQNode_t * pNode;
1521
1545
if ( !hBranches.Exists(j) )
1523
pNode = new XQNode_t;
1547
pNode = new XQNode_t ( pTree->m_dSpec );
1524
1548
pNode->SetOp ( m_eOp, pTree->m_dChildren[i] );
1525
1549
hBranches.Add ( pNode, j );
1540
1564
if ( !pOtherChildren )
1542
pOtherChildren = new XQNode_t;
1566
pOtherChildren = new XQNode_t ( pTree->m_dSpec );
1543
1567
pOtherChildren->SetOp ( m_eOp, pTree->m_dChildren[i] );
1545
1569
pOtherChildren->m_dChildren.Add ( pTree->m_dChildren[i] );