Skip to content
Permalink
Browse files
fixed #275 crash at multi-query with OR filters; added regression to …
…test 323
  • Loading branch information
tomatolog committed May 23, 2018
1 parent c3a5e4a commit 1ad8a07dbfc1131913a8d92c261fbb48f934e8b7
Showing with 50 additions and 17 deletions.
  1. +6 −3 src/searchd.cpp
  2. +0 −8 src/sphinx.cpp
  3. +4 −5 src/sphinx.h
  4. +1 −1 test/test_323/model.bin
  5. +39 −0 test/test_323/test.xml
@@ -9926,10 +9926,13 @@ struct QueryItemProxy_t
static void CreateFilterTree ( const CSphVector<FilterTreeItem_t> & dOps, int iStart, int iCount, CSphQuery & tQuery )
{
bool bHasOr = false;
CSphVector<FilterTreeItem_t> dTree ( iCount );
for ( int i = 0; i<iCount; i++ )
int iTreeCount = iCount - iStart;
CSphVector<FilterTreeItem_t> dTree ( iTreeCount );
for ( int i = 0; i<iTreeCount; i++ )
{
const FilterTreeItem_t & tItem = dOps[iStart + i];
FilterTreeItem_t tItem = dOps[iStart + i];
tItem.m_iLeft = ( tItem.m_iLeft==-1 ? -1 : tItem.m_iLeft - iStart );
tItem.m_iRight = ( tItem.m_iRight==-1 ? -1 : tItem.m_iRight - iStart );
dTree[i] = tItem;
bHasOr |= ( tItem.m_iFilterItem==-1 && tItem.m_bOr );
}
@@ -5490,14 +5490,6 @@ uint64_t CSphFilterSettings::GetHash() const
return h;
}

FilterTreeItem_t::FilterTreeItem_t ()
: m_iLeft ( -1 )
, m_iRight ( -1 )
, m_iFilterItem ( -1 )
, m_bOr ( false )
{
}

bool FilterTreeItem_t::operator == ( const FilterTreeItem_t & rhs ) const
{
return ( m_iLeft==rhs.m_iLeft && m_iRight==rhs.m_iRight && m_iFilterItem==rhs.m_iFilterItem && m_bOr==rhs.m_bOr );
@@ -2655,12 +2655,11 @@ struct CSphQueryItem
/// search query complex filter tree
struct FilterTreeItem_t
{
int m_iLeft;
int m_iRight;
int m_iFilterItem;
bool m_bOr;
int m_iLeft = -1; // left node at parser filter operations
int m_iRight = -1; // right node at parser filter operations
int m_iFilterItem = -1; // index into query filters
bool m_bOr = false;

FilterTreeItem_t ();
bool operator == ( const FilterTreeItem_t & rhs ) const;
bool operator != ( const FilterTreeItem_t & rhs ) const { return !( (*this)==rhs ); }
uint64_t GetHash() const;
@@ -1 +1 @@
a:1:{i:0;a:13:{i:0;a:2:{s:8:"sphinxql";s:116:"INSERT into rt VALUES (60, 'test', 70, 1100), (61, 'test', 71, 1101), (62, 'test', 72, 1102), (63, 'test', 73, 1103)";s:14:"total_affected";i:4;}i:1;a:3:{s:8:"sphinxql";s:36:"select * from rt where match('test')";s:10:"total_rows";i:4;s:4:"rows";a:4:{i:0;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:1;a:3:{s:2:"id";s:2:"61";s:3:"gid";s:2:"71";s:3:"pid";s:4:"1101";}i:2;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}i:3;a:3:{s:2:"id";s:2:"63";s:3:"gid";s:2:"73";s:3:"pid";s:4:"1103";}}}i:2;a:3:{s:8:"sphinxql";s:63:"select * from rt where match('test') and gid > 72 OR pid < 1101";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:1;a:3:{s:2:"id";s:2:"63";s:3:"gid";s:2:"73";s:3:"pid";s:4:"1103";}}}i:3;a:2:{s:8:"sphinxql";s:68:"delete from rt where id > 62 OR ( gid < 72 AND pid IN (1101, 1102) )";s:14:"total_affected";i:2;}i:4;a:3:{s:8:"sphinxql";s:16:"select * from rt";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:1;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:5;a:3:{s:8:"sphinxql";s:64:"select * from test1 where MATCH('test') AND gid > 22 OR gid < 12";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:4:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";s:5:"title";s:4:"test";}i:1;a:4:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";s:5:"title";s:4:"test";}}}i:6;a:3:{s:8:"sphinxql";s:64:"select * from test1 where ( gid > 12 AND pid < 1012 ) OR id > 10";s:10:"total_rows";i:4;s:4:"rows";a:4:{i:0;a:4:{s:2:"id";s:1:"3";s:3:"gid";s:2:"13";s:3:"pid";s:3:"303";s:5:"title";s:4:"test";}i:1;a:4:{s:2:"id";s:2:"11";s:3:"gid";s:2:"21";s:3:"pid";s:4:"1011";s:5:"title";s:4:"test";}i:2;a:4:{s:2:"id";s:2:"12";s:3:"gid";s:2:"22";s:3:"pid";s:4:"1012";s:5:"title";s:4:"test";}i:3;a:4:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";s:5:"title";s:4:"test";}}}i:7;a:3:{s:8:"sphinxql";s:38:"select * from dist where MATCH('test')";s:10:"total_rows";i:8;s:4:"rows";a:8:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}i:1;a:3:{s:2:"id";s:1:"2";s:3:"gid";s:2:"12";s:3:"pid";s:3:"202";}i:2;a:3:{s:2:"id";s:1:"3";s:3:"gid";s:2:"13";s:3:"pid";s:3:"303";}i:3;a:3:{s:2:"id";s:2:"11";s:3:"gid";s:2:"21";s:3:"pid";s:4:"1011";}i:4;a:3:{s:2:"id";s:2:"12";s:3:"gid";s:2:"22";s:3:"pid";s:4:"1012";}i:5;a:3:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";}i:6;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:7;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:8;a:3:{s:8:"sphinxql";s:63:"select * from dist where MATCH('test') AND gid > 22 OR gid < 12";s:10:"total_rows";i:4;s:4:"rows";a:4:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}i:1;a:3:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";}i:2;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:3;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:9;a:3:{s:8:"sphinxql";s:63:"select * from dist where ( gid > 12 AND pid < 1012 ) OR id > 60";s:10:"total_rows";i:3;s:4:"rows";a:3:{i:0;a:3:{s:2:"id";s:1:"3";s:3:"gid";s:2:"13";s:3:"pid";s:3:"303";}i:1;a:3:{s:2:"id";s:2:"11";s:3:"gid";s:2:"21";s:3:"pid";s:4:"1011";}i:2;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:10;a:3:{s:8:"sphinxql";s:51:"select * from dist where MATCH('test') AND gid < 12";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}}}i:11;a:3:{s:8:"sphinxql";s:51:"select * from dist where gid < 12 AND MATCH('test')";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}}}i:12;a:3:{s:8:"sphinxql";s:64:"select * from dist where gid > 10 AND MATCH('test') AND gid < 12";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}}}}}
a:1:{i:0;a:15:{i:0;a:2:{s:8:"sphinxql";s:116:"INSERT into rt VALUES (60, 'test', 70, 1100), (61, 'test', 71, 1101), (62, 'test', 72, 1102), (63, 'test', 73, 1103)";s:14:"total_affected";i:4;}i:1;a:3:{s:8:"sphinxql";s:36:"select * from rt where match('test')";s:10:"total_rows";i:4;s:4:"rows";a:4:{i:0;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:1;a:3:{s:2:"id";s:2:"61";s:3:"gid";s:2:"71";s:3:"pid";s:4:"1101";}i:2;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}i:3;a:3:{s:2:"id";s:2:"63";s:3:"gid";s:2:"73";s:3:"pid";s:4:"1103";}}}i:2;a:3:{s:8:"sphinxql";s:63:"select * from rt where match('test') and gid > 72 OR pid < 1101";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:1;a:3:{s:2:"id";s:2:"63";s:3:"gid";s:2:"73";s:3:"pid";s:4:"1103";}}}i:3;a:2:{s:8:"sphinxql";s:68:"delete from rt where id > 62 OR ( gid < 72 AND pid IN (1101, 1102) )";s:14:"total_affected";i:2;}i:4;a:3:{s:8:"sphinxql";s:16:"select * from rt";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:1;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:5;a:3:{s:8:"sphinxql";s:64:"select * from test1 where MATCH('test') AND gid > 22 OR gid < 12";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:4:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";s:5:"title";s:4:"test";}i:1;a:4:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";s:5:"title";s:4:"test";}}}i:6;a:3:{s:8:"sphinxql";s:64:"select * from test1 where ( gid > 12 AND pid < 1012 ) OR id > 10";s:10:"total_rows";i:4;s:4:"rows";a:4:{i:0;a:4:{s:2:"id";s:1:"3";s:3:"gid";s:2:"13";s:3:"pid";s:3:"303";s:5:"title";s:4:"test";}i:1;a:4:{s:2:"id";s:2:"11";s:3:"gid";s:2:"21";s:3:"pid";s:4:"1011";s:5:"title";s:4:"test";}i:2;a:4:{s:2:"id";s:2:"12";s:3:"gid";s:2:"22";s:3:"pid";s:4:"1012";s:5:"title";s:4:"test";}i:3;a:4:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";s:5:"title";s:4:"test";}}}i:7;a:3:{s:8:"sphinxql";s:38:"select * from dist where MATCH('test')";s:10:"total_rows";i:8;s:4:"rows";a:8:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}i:1;a:3:{s:2:"id";s:1:"2";s:3:"gid";s:2:"12";s:3:"pid";s:3:"202";}i:2;a:3:{s:2:"id";s:1:"3";s:3:"gid";s:2:"13";s:3:"pid";s:3:"303";}i:3;a:3:{s:2:"id";s:2:"11";s:3:"gid";s:2:"21";s:3:"pid";s:4:"1011";}i:4;a:3:{s:2:"id";s:2:"12";s:3:"gid";s:2:"22";s:3:"pid";s:4:"1012";}i:5;a:3:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";}i:6;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:7;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:8;a:3:{s:8:"sphinxql";s:63:"select * from dist where MATCH('test') AND gid > 22 OR gid < 12";s:10:"total_rows";i:4;s:4:"rows";a:4:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}i:1;a:3:{s:2:"id";s:2:"13";s:3:"gid";s:2:"23";s:3:"pid";s:4:"1013";}i:2;a:3:{s:2:"id";s:2:"60";s:3:"gid";s:2:"70";s:3:"pid";s:4:"1100";}i:3;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:9;a:3:{s:8:"sphinxql";s:63:"select * from dist where ( gid > 12 AND pid < 1012 ) OR id > 60";s:10:"total_rows";i:3;s:4:"rows";a:3:{i:0;a:3:{s:2:"id";s:1:"3";s:3:"gid";s:2:"13";s:3:"pid";s:3:"303";}i:1;a:3:{s:2:"id";s:2:"11";s:3:"gid";s:2:"21";s:3:"pid";s:4:"1011";}i:2;a:3:{s:2:"id";s:2:"62";s:3:"gid";s:2:"72";s:3:"pid";s:4:"1102";}}}i:10;a:3:{s:8:"sphinxql";s:51:"select * from dist where MATCH('test') AND gid < 12";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}}}i:11;a:3:{s:8:"sphinxql";s:51:"select * from dist where gid < 12 AND MATCH('test')";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}}}i:12;a:3:{s:8:"sphinxql";s:64:"select * from dist where gid > 10 AND MATCH('test') AND gid < 12";s:10:"total_rows";i:1;s:4:"rows";a:1:{i:0;a:3:{s:2:"id";s:1:"1";s:3:"gid";s:2:"11";s:3:"pid";s:3:"101";}}}i:13;a:3:{s:10:"total_rows";i:3;s:4:"rows";a:3:{i:0;a:3:{s:2:"id";s:1:"1";s:5:"price";s:1:"5";s:8:"brand_id";s:1:"1";}i:1;a:3:{s:2:"id";s:1:"3";s:5:"price";s:3:"103";s:8:"brand_id";s:2:"13";}i:2;a:3:{s:2:"id";s:2:"11";s:5:"price";s:3:"109";s:8:"brand_id";s:3:"101";}}s:8:"sphinxql";s:191:"SELECT * FROM facet1 WHERE (price >= 0 AND price < 10) OR (price >= 100 AND price < 110); SELECT * FROM facet1 WHERE (brand_id >= 0 AND brand_id < 10) OR (brand_id >= 100 AND brand_id < 110)";}i:14;a:3:{s:10:"total_rows";i:4;s:4:"rows";a:4:{i:0;a:3:{s:2:"id";s:1:"1";s:5:"price";s:1:"5";s:8:"brand_id";s:1:"1";}i:1;a:3:{s:2:"id";s:1:"2";s:5:"price";s:2:"12";s:8:"brand_id";s:1:"2";}i:2;a:3:{s:2:"id";s:2:"11";s:5:"price";s:3:"109";s:8:"brand_id";s:3:"101";}i:3;a:3:{s:2:"id";s:2:"12";s:5:"price";s:3:"122";s:8:"brand_id";s:3:"109";}}s:8:"sphinxql";s:143:" SELECT * FROM facet1 WHERE (brand_id >= 0 AND brand_id < 10) OR (brand_id >= 100 AND brand_id < 110) /* result 2 of previous multistatement */";}}}
@@ -71,6 +71,21 @@ index dist
agent = 127.0.0.1:<my_port />:rt
}

source facet1
{
type = mysql
<sql_settings/>
sql_query = select id, price, brand_id, title from facet_table
sql_attr_uint = price
sql_attr_uint = brand_id
}

index facet1
{
source = facet1
path = <data_path/>/facet1
}

</config>

<db_create>
@@ -94,6 +109,27 @@ insert into test_table values
( 13, 23, 1013, 'test' )
</db_insert>

<db_create>
create table facet_table
(
id int not null,
price int not null,
brand_id int not null,
title varchar(255) not null
);
</db_create>
<db_drop>drop table if exists facet_table</db_drop>

<db_insert>
insert into facet_table values
( 1, 5, 1, 'test' ),
( 2, 12, 2, 'test' ),
( 3, 103, 13, 'test' ),
( 11, 109, 101, 'test' ),
( 12, 122, 109, 'test' ),
( 13, 123, 113, 'test' )
</db_insert>

<sphqueries>
<sphinxql>INSERT into rt VALUES (60, 'test', 70, 1100), (61, 'test', 71, 1101), (62, 'test', 72, 1102), (63, 'test', 73, 1103)</sphinxql>
<sphinxql>select * from rt where match('test')</sphinxql>
@@ -110,6 +146,9 @@ insert into test_table values
<sphinxql>select * from dist where MATCH('test') AND gid &lt; 12</sphinxql>
<sphinxql>select * from dist where gid &lt; 12 AND MATCH('test')</sphinxql>
<sphinxql>select * from dist where gid &gt; 10 AND MATCH('test') AND gid &lt; 12</sphinxql>

<!-- crash at multi query with OR -->
<sphinxql>SELECT * FROM facet1 WHERE (price &gt;= 0 AND price &lt; 10) OR (price &gt;= 100 AND price &lt; 110); SELECT * FROM facet1 WHERE (brand_id &gt;= 0 AND brand_id &lt; 10) OR (brand_id &gt;= 100 AND brand_id &lt; 110)</sphinxql>
</sphqueries>

</test>

0 comments on commit 1ad8a07

Please sign in to comment.