[FIX] expression: use unaccent() for translated search
authorChristophe Simonis <chs@openerp.com>
Mon, 31 Mar 2014 12:30:12 +0000 (14:30 +0200)
committerChristophe Simonis <chs@openerp.com>
Mon, 31 Mar 2014 12:30:12 +0000 (14:30 +0200)
lp bug: https://launchpad.net/bugs/1049653 fixed

bzr revid: chs@openerp.com-20140331123012-dq3hsw2bc368zvgq

openerp/osv/expression.py

index d3c2a8a..360ab49 100644 (file)
@@ -1020,6 +1020,7 @@ class expression(object):
                     push(create_substitution_leaf(leaf, (left, operator, right), working_model))
 
                 elif field.translate and right:
+                    field = left
                     need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike')
                     sql_operator = {'=like': 'like', '=ilike': 'ilike'}.get(operator, operator)
                     if need_wildcard:
@@ -1031,33 +1032,38 @@ class expression(object):
                         sql_operator = sql_operator[4:] if sql_operator[:3] == 'not' else '='
                         inselect_operator = 'not inselect'
 
-                    subselect = '( SELECT res_id'          \
-                             '    FROM ir_translation'  \
-                             '   WHERE name = %s'       \
-                             '     AND lang = %s'       \
-                             '     AND type = %s'
-                    instr = ' %s'
-                    #Covering in,not in operators with operands (%s,%s) ,etc.
                     if sql_operator == 'in':
-                        instr = ','.join(['%s'] * len(right))
-                        subselect += '     AND value ' + sql_operator + ' ' + " (" + instr + ")"   \
-                             ') UNION ('                \
-                             '  SELECT id'              \
-                             '    FROM "' + working_model._table + '"'       \
-                             '   WHERE "' + left + '" ' + sql_operator + ' ' + " (" + instr + "))"
-                    else:
-                        subselect += '     AND value ' + sql_operator + instr +   \
-                             ') UNION ('                \
-                             '  SELECT id'              \
-                             '    FROM "' + working_model._table + '"'       \
-                             '   WHERE "' + left + '" ' + sql_operator + instr + ")"
+                        right = tuple(right)
 
-                    params = [working_model._name + ',' + left,
+                    if self.has_unaccent and sql_operator.endswith('like'):
+                        trans_left = 'unaccent(value)'
+                        left = 'unaccent("%s")' % (left,)
+                        instr = 'unaccent(%s)'
+                    else:
+                        trans_left = 'value'
+                        left = '"%s"' % (left,)
+                        instr = '%s'
+
+                    subselect = """(SELECT res_id
+                                      FROM ir_translation
+                                     WHERE name = %s
+                                       AND lang = %s
+                                       AND type = %s
+                                       AND {trans_left} {operator} {right}
+                                   ) UNION (
+                                    SELECT id
+                                      FROM "{table}"
+                                     WHERE {left} {operator} {right}
+                                   )
+                                """.format(trans_left=trans_left, operator=sql_operator,
+                                           right=instr, table=working_model._table, left=left)
+
+                    params = [working_model._name + ',' + field,
                               context.get('lang', False) or 'en_US',
                               'model',
                               right,
                               right,
-                             ]
+                              ]
                     push(create_substitution_leaf(leaf, ('id', inselect_operator, (subselect, params)), working_model))
 
                 else:
@@ -1176,7 +1182,7 @@ class expression(object):
 
             if left in model._columns:
                 format = need_wildcard and '%s' or model._columns[left]._symbol_set[0]
-                if self.has_unaccent and sql_operator in ('ilike', 'not ilike'):
+                if self.has_unaccent and sql_operator.endswith('like'):
                     query = '(unaccent(%s."%s") %s unaccent(%s))' % (table_alias, left, sql_operator, format)
                 else:
                     query = '(%s."%s" %s %s)' % (table_alias, left, sql_operator, format)