Commit 100812e5 authored by Vincent Pelletier's avatar Vincent Pelletier

Strenghten a bit SearchText detector: a word followed by a colon is not enough...

Strenghten a bit SearchText detector: a word followed by a colon is not enough to qulify as a COLUMN token, tha word must also be in a set of valid column names.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@25940 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent ca6b0902
...@@ -109,7 +109,7 @@ class ISearchKey(Interface): ...@@ -109,7 +109,7 @@ class ISearchKey(Interface):
If given, expresses the comparison between column and value. If given, expresses the comparison between column and value.
""" """
def parseSearchText(value): def parseSearchText(value, column_id_set):
""" """
Parse given value to generate an Abstract Syntax Tree representing its Parse given value to generate an Abstract Syntax Tree representing its
logical structure, or None if there is no obvious structure in given logical structure, or None if there is no obvious structure in given
...@@ -118,6 +118,9 @@ class ISearchKey(Interface): ...@@ -118,6 +118,9 @@ class ISearchKey(Interface):
value (string) value (string)
The string to parse. The string to parse.
column_id_set (set)
A list of valid column names. This is used when deciding wether value
should really be parsed or remain a bare string.
Returns: (None, AbstratSyntaxNode) Returns: (None, AbstratSyntaxNode)
AbstratSyntaxNode complies with the IAbstractSyntaxNode interface. AbstratSyntaxNode complies with the IAbstractSyntaxNode interface.
......
...@@ -1981,6 +1981,9 @@ class Catalog(Folder, ...@@ -1981,6 +1981,9 @@ class Catalog(Folder,
# column names with empty values. This is for backward compatibility. See # column names with empty values. This is for backward compatibility. See
# comment about empty values. # comment about empty values.
implicit_table_list = [] implicit_table_list = []
# It's not a problem to use a dict instead of a set here, and saves a
# cast.
column_id_set = self.getColumnMap()
for key, value in kw.iteritems(): for key, value in kw.iteritems():
result = None result = None
if isinstance(value, dict_type_list): if isinstance(value, dict_type_list):
...@@ -2014,7 +2017,7 @@ class Catalog(Folder, ...@@ -2014,7 +2017,7 @@ class Catalog(Folder,
# String: parse using key's default search key. # String: parse using key's default search key.
search_key = self.getColumnDefaultSearchKey(key) search_key = self.getColumnDefaultSearchKey(key)
if search_key is not None: if search_key is not None:
abstract_syntax_tree = search_key.parseSearchText(value) abstract_syntax_tree = search_key.parseSearchText(value, column_id_set)
if abstract_syntax_tree is None: if abstract_syntax_tree is None:
# Parsing failed, create a query from the bare string. # Parsing failed, create a query from the bare string.
result = self.buildSingleQuery(key, value) result = self.buildSingleQuery(key, value)
......
...@@ -42,8 +42,8 @@ class DefaultKey(SearchKey): ...@@ -42,8 +42,8 @@ class DefaultKey(SearchKey):
default_comparison_operator = '=' default_comparison_operator = '='
get_operator_from_value = True get_operator_from_value = True
def parseSearchText(self, value): def parseSearchText(self, value, column_id_set):
return parse(value) return parse(value, column_id_set)
def _guessComparisonOperator(self, value): def _guessComparisonOperator(self, value):
if isinstance(value, basestring) and '%' in value: if isinstance(value, basestring) and '%' in value:
......
...@@ -40,8 +40,8 @@ class FullTextKey(SearchKey): ...@@ -40,8 +40,8 @@ class FullTextKey(SearchKey):
default_comparison_operator = 'match' default_comparison_operator = 'match'
get_operator_from_value = False get_operator_from_value = False
def parseSearchText(self, value): def parseSearchText(self, value, column_id_set):
return parse(value) return parse(value, column_id_set)
verifyClass(ISearchKey, FullTextKey) verifyClass(ISearchKey, FullTextKey)
...@@ -42,8 +42,8 @@ class KeywordKey(SearchKey): ...@@ -42,8 +42,8 @@ class KeywordKey(SearchKey):
default_comparison_operator = 'like' default_comparison_operator = 'like'
get_operator_from_value = True get_operator_from_value = True
def parseSearchText(self, value): def parseSearchText(self, value, column_id_set):
return parse(value) return parse(value, column_id_set)
def _buildQuery(self, operator_value_dict, logical_operator, parsed, group): def _buildQuery(self, operator_value_dict, logical_operator, parsed, group):
""" """
......
...@@ -341,7 +341,7 @@ class SearchKey(object): ...@@ -341,7 +341,7 @@ class SearchKey(object):
query = ComplexQuery(query_list, operator=logical_operator) query = ComplexQuery(query_list, operator=logical_operator)
return query return query
def parseSearchText(self, value): def parseSearchText(self, value, column_id_set):
return None return None
verifyClass(ISearchKey, SearchKey) verifyClass(ISearchKey, SearchKey)
......
...@@ -47,7 +47,7 @@ class AdvancedSearchTextDetector(lexer): ...@@ -47,7 +47,7 @@ class AdvancedSearchTextDetector(lexer):
return t return t
def t_COLUMN(self, t): def t_COLUMN(self, t):
self.found = True self.found = t.value[:-1] in self.column_id_set
t.type = 'WORD' t.type = 'WORD'
return t return t
...@@ -89,7 +89,8 @@ class AdvancedSearchTextDetector(lexer): ...@@ -89,7 +89,8 @@ class AdvancedSearchTextDetector(lexer):
def token(self): def token(self):
return self.token_list.pop(0) return self.token_list.pop(0)
def __call__(self, input): def __call__(self, input, column_id_set):
self.column_id_set = column_id_set
self.found = False self.found = False
check_grammar = False check_grammar = False
self.token_list = token_list = [] self.token_list = token_list = []
......
...@@ -66,8 +66,8 @@ def getAdvancedSearchTextParser(): ...@@ -66,8 +66,8 @@ def getAdvancedSearchTextParser():
return parser return parser
@profiler_decorator @profiler_decorator
def _parse(input, *args, **kw): def _parse(input, column_id_set, *args, **kw):
if getAdvancedSearchTextDetector()(input): if getAdvancedSearchTextDetector()(input, column_id_set):
result = getAdvancedSearchTextParser()(input, *args, **kw) result = getAdvancedSearchTextParser()(input, *args, **kw)
else: else:
result = None result = None
...@@ -274,12 +274,13 @@ if __name__ == '__main__': ...@@ -274,12 +274,13 @@ if __name__ == '__main__':
return result return result
original_parse = _parse original_parse = _parse
fake_column_id_set = set(['a', 'b', 'c', 'd', 'title', 'toto', 'titi', 'foo', 'bar'])
def parse(input, *args, **kw): def parse(input, *args, **kw):
""" """
Parse input and walk generated AST. Parse input and walk generated AST.
""" """
result = original_parse(input, *args, **kw) result = original_parse(input, fake_column_id_set, *args, **kw)
if result is not None: if result is not None:
#print repr(result) #print repr(result)
result = walk(result) result = walk(result)
...@@ -309,7 +310,7 @@ if __name__ == '__main__': ...@@ -309,7 +310,7 @@ if __name__ == '__main__':
print repr(input) print repr(input)
try: try:
try: try:
detector_result = getAdvancedSearchTextDetector()(input) detector_result = getAdvancedSearchTextDetector()(input, fake_column_id_set)
except ParserOrLexerError, message: except ParserOrLexerError, message:
print ' Detector raise: %r' % (message, ) print ' Detector raise: %r' % (message, )
detector_result = False detector_result = False
......
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