~ubuntu-branches/ubuntu/vivid/sphinxsearch/vivid

« back to all changes in this revision

Viewing changes to src/sphinxquery.cpp

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-04-05 09:25:55 UTC
  • mfrom: (1.2.1) (7.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20120405092555-65tc91rowhls3kob
Tags: 2.0.4-0ubuntu1
* New upstream release (LP: #930747)
* Remove explicit depends on libmysqlcient16 (LP: #974427)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//
2
 
// $Id: sphinxquery.cpp 2968 2011-09-23 16:31:11Z shodan $
 
2
// $Id: sphinxquery.cpp 3114 2012-02-21 14:52:21Z klirichek $
3
3
//
4
4
 
5
5
//
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
9
9
//
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 );
56
56
 
 
57
        inline void SetFieldSpec ( const CSphSmallBitvec& uMask, int iMaxPos )
 
58
        {
 
59
                m_dStateSpec.SetFieldSpec ( uMask, iMaxPos );
 
60
        }
 
61
        inline void SetZoneVec ( int iZoneVec )
 
62
        {
 
63
                m_dStateSpec.SetZoneSpec ( m_dZoneVecs[iZoneVec] );
 
64
        }
 
65
 
57
66
public:
58
67
        const CSphVector<int> & GetZoneVec ( int iZoneVec ) const
59
68
        {
93
102
        CSphVector<CSphString>  m_dIntTokens;
94
103
 
95
104
        CSphVector < CSphVector<int> >  m_dZoneVecs;
 
105
        XQLimitSpec_t                   m_dStateSpec;
96
106
};
97
107
 
98
108
//////////////////////////////////////////////////////////////////////////
112
122
 
113
123
//////////////////////////////////////////////////////////////////////////
114
124
 
 
125
void XQLimitSpec_t::SetFieldSpec ( const CSphSmallBitvec& uMask, int iMaxPos )
 
126
{
 
127
        m_bFieldSpec = true;
 
128
        m_dFieldMask = uMask;
 
129
        m_iFieldMaxPos = iMaxPos;
 
130
}
 
131
 
 
132
 
 
133
 
115
134
void XQNode_t::SetFieldSpec ( const CSphSmallBitvec& uMask, int iMaxPos )
116
135
{
117
136
        // set it, if we do not yet have one
118
 
        if ( !m_bFieldSpec )
119
 
        {
120
 
                m_bFieldSpec = true;
121
 
                m_dFieldMask = uMask;
122
 
                m_iFieldMaxPos = iMaxPos;
123
 
        }
 
137
        if ( !m_dSpec.m_bFieldSpec )
 
138
                m_dSpec.SetFieldSpec ( uMask, iMaxPos );
124
139
 
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 );
129
144
}
130
145
 
 
146
void XQLimitSpec_t::SetZoneSpec ( const CSphVector<int> & dZones )
 
147
{
 
148
        m_dZones = dZones;
 
149
}
 
150
 
 
151
 
131
152
void XQNode_t::SetZoneSpec ( const CSphVector<int> & dZones )
132
153
{
133
154
        // set it, if we do not yet have one
134
 
        if ( !m_dZones.GetLength() )
135
 
                m_dZones = dZones;
 
155
        if ( !m_dSpec.m_dZones.GetLength() )
 
156
                m_dSpec.SetZoneSpec ( dZones );
136
157
 
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 )
144
165
        if ( !pSpecs )
145
166
                return;
146
167
 
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 );
149
170
 
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 );
152
173
}
153
174
 
154
175
 
155
176
void XQNode_t::ClearFieldMask ()
156
177
{
157
 
        m_dFieldMask.Set();
 
178
        m_dSpec.m_dFieldMask.Set();
158
179
 
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;
793
814
 
794
 
        XQNode_t * pNode = new XQNode_t();
 
815
        XQNode_t * pNode = new XQNode_t ( m_dStateSpec );
795
816
        pNode->m_dWords.Add ( tAW );
796
817
 
797
818
        m_dSpawned.Add ( pNode );
822
843
 
823
844
        if ( eOp==SPH_QUERY_NOT )
824
845
        {
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 );
828
849
                return pNode;
839
860
        // eg. '@title hello' vs 'world'
840
861
        pRight->CopySpecs ( pLeft );
841
862
 
 
863
        XQNode_t * pDonor = pRight;
 
864
        if ( pRight->m_dSpec.m_bInvisible )
 
865
                pDonor = pLeft;
 
866
 
 
867
        m_dStateSpec = pDonor->m_dSpec;
 
868
 
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 )
845
872
        {
846
873
                pLeft->m_dChildren.Add ( pRight );
847
874
                pResult = pLeft;
 
875
                if ( pRight->m_dSpec.m_bFieldSpec )
 
876
                        pResult->m_dSpec.SetFieldSpec ( pRight->m_dSpec.m_dFieldMask, pRight->m_dSpec.m_iFieldMaxPos );
 
877
 
 
878
                if ( pRight->m_dSpec.m_dZones.GetLength() )
 
879
                        pResult->m_dSpec.SetZoneSpec ( pRight->m_dSpec.m_dZones );
848
880
        } else
849
881
        {
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 );
854
888
                pResult = pNode;
855
889
        }
856
 
 
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 )
860
 
        {
861
 
                pResult->m_bFieldSpec = true;
862
 
                pResult->m_dFieldMask = pRight->m_dFieldMask;
863
 
                pResult->m_iFieldMaxPos = pRight->m_iFieldMaxPos;
864
 
        }
865
 
 
866
890
        return pResult;
867
891
}
868
892
 
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() );
970
994
 
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 );
974
998
 
978
1002
                pNot = dNots[0];
979
1003
        } else
980
1004
        {
981
 
                pNot = new XQNode_t();
 
1005
                pNot = new XQNode_t ( pNode->m_dSpec );
982
1006
                pNot->SetOp ( SPH_QUERY_OR, dNots );
983
1007
                m_dSpawned.Add ( pNot );
984
1008
        }
995
1019
 
996
1020
        for ( int i = 0; i < pNode->m_dChildren.GetLength (); )
997
1021
        {
998
 
                if ( pNode->m_dChildren[i]->m_dFieldMask.TestAll() )
 
1022
                if ( pNode->m_dChildren[i]->m_dSpec.m_dFieldMask.TestAll() )
999
1023
                {
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 );
1064
1088
 
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] ) )
1067
1091
        {
1068
1092
                sQuery += OPTION_RELAXED_LEN;
1069
1093
                m_bStopOnInvalid = false;
1072
1096
        // setup parser
1073
1097
        m_pParsed = &tParsed;
1074
1098
        m_sQuery = (BYTE*) sQuery;
1075
 
        m_iQueryLen = strlen(sQuery);
 
1099
        m_iQueryLen = sQuery ? strlen(sQuery) : 0;
1076
1100
        m_pTokenizer = pMyTokenizer.Ptr();
1077
1101
        m_pSchema = pSchema;
1078
1102
        m_pDict = pDict;
1118
1142
 
1119
1143
        // all ok; might want to create a dummy node to indicate that
1120
1144
        m_dSpawned.Reset();
1121
 
        tParsed.m_pRoot = m_pRoot ? m_pRoot : new XQNode_t ();
 
1145
        tParsed.m_pRoot = m_pRoot ? m_pRoot : new XQNode_t ( m_dStateSpec );
1122
1146
        return true;
1123
1147
}
1124
1148
 
1520
1544
                                                        XQNode_t * pNode;
1521
1545
                                                        if ( !hBranches.Exists(j) )
1522
1546
                                                        {
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 );
1526
1550
                                                        } else
1539
1563
                                {
1540
1564
                                        if ( !pOtherChildren )
1541
1565
                                        {
1542
 
                                                pOtherChildren = new XQNode_t;
 
1566
                                                pOtherChildren = new XQNode_t ( pTree->m_dSpec );
1543
1567
                                                pOtherChildren->SetOp ( m_eOp, pTree->m_dChildren[i] );
1544
1568
                                        } else
1545
1569
                                                pOtherChildren->m_dChildren.Add ( pTree->m_dChildren[i] );
1735
1759
}
1736
1760
 
1737
1761
//
1738
 
// $Id: sphinxquery.cpp 2968 2011-09-23 16:31:11Z shodan $
 
1762
// $Id: sphinxquery.cpp 3114 2012-02-21 14:52:21Z klirichek $
1739
1763
//