From 5802b85aa93a81caea77073a3381ef912fdd677c Mon Sep 17 00:00:00 2001 From: Ilya Kuznetsov Date: Sat, 25 May 2019 12:39:48 +0300 Subject: [PATCH] fixed filter-by-id; added test --- src/secondaryindex.cpp | 9 ++++--- src/secondaryindex.h | 2 +- src/sphinx.cpp | 6 +++-- test/test_379/model.bin | 1 + test/test_379/test.xml | 59 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 test/test_379/model.bin create mode 100644 test/test_379/test.xml diff --git a/src/secondaryindex.cpp b/src/secondaryindex.cpp index 6d9c0ca6ec..425dc51347 100644 --- a/src/secondaryindex.cpp +++ b/src/secondaryindex.cpp @@ -1047,7 +1047,7 @@ void SelectIterators ( const CSphVector & dFilters, const CS } -RowidIterator_i * CreateFilteredIterator ( CSphVector & dFilters, const CSphVector & dFilterTree, const CSphVector & dHints, const HistogramContainer_c & tHistograms, const BYTE * pDocidLookup ) +RowidIterator_i * CreateFilteredIterator ( const CSphVector & dFilters, CSphVector & dModifiedFilters, const CSphVector & dFilterTree, const CSphVector & dHints, const HistogramContainer_c & tHistograms, const BYTE * pDocidLookup ) { // no iterators with OR queries if ( dFilterTree.GetLength() ) @@ -1065,8 +1065,11 @@ RowidIterator_i * CreateFilteredIterator ( CSphVector & dFil } dEnabledIndexes.Sort ( bind ( &SecondaryIndexInfo_t::m_iFilterId ) ); - for ( int i = dEnabledIndexes.GetLength()-1; i>=0; i-- ) - dFilters.Remove ( dEnabledIndexes[i].m_iFilterId ); + ARRAY_FOREACH ( i, dFilters ) + { + if ( !dEnabledIndexes.FindFirst ( [i] ( const SecondaryIndexInfo_t & tInfo ) { return tInfo.m_iFilterId==i; } ) ) + dModifiedFilters.Add ( dFilters[i] ); + } int nIterators = dIterators.GetLength(); if ( nIterators==1 ) diff --git a/src/secondaryindex.h b/src/secondaryindex.h index afa4e0c4cd..854dda71ae 100644 --- a/src/secondaryindex.h +++ b/src/secondaryindex.h @@ -85,7 +85,7 @@ struct SecondaryIndexInfo_t int m_iFilterId {-1}; }; -RowidIterator_i * CreateFilteredIterator ( CSphVector & dFilters, const CSphVector & dFilterTree, const CSphVector & dHints, const HistogramContainer_c & tHistograms, const BYTE * pDocidLookup ); +RowidIterator_i * CreateFilteredIterator ( const CSphVector & dFilters, CSphVector & dModifiedFilters, const CSphVector & dFilterTree, const CSphVector & dHints, const HistogramContainer_c & tHistograms, const BYTE * pDocidLookup ); ////////////////////////////////////////////////////////////////////////// diff --git a/src/sphinx.cpp b/src/sphinx.cpp index 9b1bcac90a..9ad80d08d9 100644 --- a/src/sphinx.cpp +++ b/src/sphinx.cpp @@ -13864,15 +13864,17 @@ bool CSphIndex_VLN::MultiScan ( const CSphQuery * pQuery, CSphQueryResult * pRes bool bReverse = pQuery->m_bReverseScan; // shortcut int iCutoff = ( pQuery->m_iCutoff<=0 ) ? -1 : pQuery->m_iCutoff; - CSphVector dFilters = pQuery->m_dFilters; + // we don't modify the original filters because iterators may use some data from them (to avoid copying) + CSphVector dModifiedFilters; RowidIterator_i * pIterator = nullptr; if ( m_pHistograms ) - pIterator = CreateFilteredIterator ( dFilters, pQuery->m_dFilterTree, pQuery->m_dIndexHints, *m_pHistograms, m_tDocidLookup.GetWritePtr() ); + pIterator = CreateFilteredIterator ( pQuery->m_dFilters, dModifiedFilters, pQuery->m_dFilterTree, pQuery->m_dIndexHints, *m_pHistograms, m_tDocidLookup.GetWritePtr() ); if ( pIterator ) { // one or several filters got replaced by an iterator, need to re-create the remaining filters SafeDelete ( tCtx.m_pFilter ); + tFlx.m_pFilters = &dModifiedFilters; tCtx.CreateFilters ( tFlx, pResult->m_sError, pResult->m_sWarning ); bool bStop; diff --git a/test/test_379/model.bin b/test/test_379/model.bin new file mode 100644 index 0000000000..b459127fc8 --- /dev/null +++ b/test/test_379/model.bin @@ -0,0 +1 @@ +a:1:{i:0;a:3:{i:0;a:3:{s:8:"sphinxql";s:58:"select id from test1 where id in (1,13) and gid not in (1)";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:1:{s:2:"id";s:1:"1";}i:1;a:1:{s:2:"id";s:2:"13";}}}i:1;a:3:{s:8:"sphinxql";s:74:"select id from test1 where id in (1,13) and gid not in (1) force index(id)";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:1:{s:2:"id";s:1:"1";}i:1;a:1:{s:2:"id";s:2:"13";}}}i:2;a:3:{s:8:"sphinxql";s:75:"select id from test1 where id in (1,13) and gid not in (1) ignore index(id)";s:10:"total_rows";i:2;s:4:"rows";a:2:{i:0;a:1:{s:2:"id";s:1:"1";}i:1;a:1:{s:2:"id";s:2:"13";}}}}} \ No newline at end of file diff --git a/test/test_379/test.xml b/test/test_379/test.xml new file mode 100644 index 0000000000..4400ce34eb --- /dev/null +++ b/test/test_379/test.xml @@ -0,0 +1,59 @@ + + + +id attr index + + +indexer +{ + mem_limit = 16M +} + +searchd +{ + +} + +source test1 +{ + type = mysql + + sql_query = select id, gid, title from test_table + sql_attr_uint = gid + sql_field_string = title +} + +index test1 +{ + source = test1 + path = /test1 +} + + + +create table test_table +( + id int not null, + gid int not null, + title varchar(255) not null +); + +drop table if exists test_table; + + +insert into test_table values +( 1, 11, 'test' ), +( 2, 12, 'test' ), +( 3, 13, 'test' ), +( 11, 21,'test' ), +( 12, 22, 'test' ), +( 13, 23, 'test' ) + + + +select id from test1 where id in (1,13) and gid not in (1) +select id from test1 where id in (1,13) and gid not in (1) force index(id) +select id from test1 where id in (1,13) and gid not in (1) ignore index(id) + + +