Commit b5351b64 authored by Vincent Pelletier's avatar Vincent Pelletier

Add FullText bolean mode detection heuristic.

Add a test.
FullText operators have no SearchText representation, so disable it explicitely.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@27335 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 815c5258
......@@ -100,7 +100,7 @@ verifyClass(IOperator, MultivaluedComparisonOperator)
class MatchComparisonOperator(MonovaluedComparisonOperator):
def __init__(self, operator, mode=''):
MonovaluedComparisonOperator.__init__(self, operator)
MonovaluedComparisonOperator.__init__(self, operator, '')
self.where_expression_format_string = 'MATCH (%%(column)s) AGAINST (%%(value_list)s%s)' % (mode, )
@profiler_decorator
......
......@@ -34,6 +34,9 @@ from Products.ZSQLCatalog.SearchText import parse
from Products.ZSQLCatalog.interfaces.search_key import ISearchKey
from Interface.Verify import verifyClass
from Products.ZSQLCatalog.SQLCatalog import profiler_decorator
import re
FULLTEXT_BOLLEAN_DETECTOR = re.compile(r'.*[\+\-<>\(\)\~\*]')
class FullTextKey(SearchKey):
"""
......@@ -45,6 +48,29 @@ class FullTextKey(SearchKey):
def parseSearchText(self, value, is_column):
return parse(value, is_column)
@profiler_decorator
def _processSearchValue(self, search_value, logical_operator,
comparison_operator):
"""
Special SearchValue processor for FullText queries: if a searched value
from 'match' operator group contains an operator recognised in boolean
mode, make the operator for that value be 'match_boolean'.
"""
operator_value_dict, logical_operator, parsed = \
SearchKey._processSearchValue(self, search_value, logical_operator,
comparison_operator)
new_value_list = []
append = new_value_list.append
for value in operator_value_dict.pop('match', []):
if isinstance(value, basestring) and \
FULLTEXT_BOLLEAN_DETECTOR.match(value) is not None:
operator_value_dict.setdefault('match_boolean', []).append(value)
else:
append(value)
if len(new_value_list):
operator_value_dict['match'] = new_value_list
return operator_value_dict, logical_operator, parsed
@profiler_decorator
def _buildQuery(self, operator_value_dict, logical_operator, parsed, group):
"""
......
......@@ -422,6 +422,14 @@ class TestSQLCatalog(unittest.TestCase):
self.assertRaises(ValueError, SimpleQuery, default=None, comparison_operator='>=')
self.assertRaises(ValueError, SimpleQuery, default=1, comparison_operator='is')
def test_FullTextBooleanMode(self):
"""
Fulltext searches must switch automatically to boolean mode if boolean
operators are found in search value.
"""
self.catalog(ReferenceQuery(ReferenceQuery(operator='match_boolean', fulltext='a+b'), operator='and'),
{'fulltext': 'a+b'})
##return catalog(title=Query(title='a', operator='not'))
#return catalog(title={'query': 'a', 'operator': 'not'})
#return catalog(title={'query': ['a', 'b'], 'operator': 'not'})
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment