Reviewers: ,


Please review this at http://codereview.tryton.org/784002/

Affected files:
  M trytond/backend/sqlite/database.py
  M trytond/ir/translation.py
  M trytond/model/fields/property.py
  M trytond/model/modelsql.py


Index: trytond/backend/sqlite/database.py
===================================================================

--- a/trytond/backend/sqlite/database.py
+++ b/trytond/backend/sqlite/database.py
@@ -23,6 +23,7 @@
     from sqlite3 import OperationalError as DatabaseOperationalError
 QUOTE_SEPARATION = re.compile(r"(.*?)('.*?')", re.DOTALL)
 EXTRACT_PATTERN = re.compile(r'EXTRACT\s*\(\s*(\S*)\s+FROM', re.I)
+POSITION_PATTERN = re.compile(r'POSITION\s*\(([^\)]*)\s+IN', re.I)


 def extract(lookup_type, date):
@@ -87,6 +88,15 @@
     return (text.split(delimiter) + [''] * (count - 1))[count - 1]


+def position(substring, string):
+    if string is None:
+        return
+    try:
+        return string.index(substring) + 1
+    except ValueError:
+        return 0
+
+
 def replace(text, pattern, replacement):
     return str(text).replace(pattern, replacement)

@@ -122,6 +132,7 @@
         self._conn.create_function('extract', 2, extract)
         self._conn.create_function('date_trunc', 2, date_trunc)
         self._conn.create_function('split_part', 3, split_part)
+        self._conn.create_function('position', 2, position)
         if sqlite.sqlite_version_info < (3, 3, 14):
             self._conn.create_function('replace', 3, replace)
         return self
@@ -278,6 +289,7 @@

     def execute(self, sql, params=None):
         buf = ""
+        sql = re.sub(POSITION_PATTERN, r'POSITION(\1,', sql)
         for nquote, quote in QUOTE_SEPARATION.findall(sql + "''"):
             nquote = nquote.replace('?', '??')
             nquote = nquote.replace('%s', '?')

Index: trytond/ir/translation.py
===================================================================

--- a/trytond/ir/translation.py
+++ b/trytond/ir/translation.py
@@ -144,7 +144,7 @@
     def search_model(cls, name, clause):
         cursor = Transaction().cursor
         cursor.execute('SELECT id FROM "%s" '
-            'WHERE split_part(name, \',\', 1) %s %%s' %
+            'WHERE SUBSTR(name, 1, POSITION(\',\' IN name) - 1) %s %%s' %
             (cls._table, clause[1]), (clause[2],))
         return [('id', 'in', [x[0] for x in cursor.fetchall()])]


Index: trytond/model/fields/property.py
===================================================================

--- a/trytond/model/fields/property.py
+++ b/trytond/model/fields/property.py
@@ -90,7 +90,8 @@
         #Fetch res ids that comply with the domain
         cursor.execute(
             'SELECT CAST('
-                'SPLIT_PART("' + Property._table + '".res,\',\',2) '
+                'SUBSTR("' + Property._table + '".res, '
+ 'POSITION(\',\' IN "' + Property._table + '".res) + 1) '
                     'AS INTEGER), '
                 '"' + Property._table + '".id '
             'FROM "' + Property._table + '" '
@@ -135,7 +136,7 @@

         #Fetch the res ids that doesn't use the default value
         cursor.execute(
-            "SELECT cast(split_part(res,',',2) as integer) "
+ "SELECT CAST(SUBSTR(res, POSITION(',' IN res) + 1) AS integer) "
             'FROM "' + Property._table + '"'
             'WHERE ' + property_query + ' AND res is not null',
             property_val)
@@ -160,23 +161,22 @@
         if sql_type == 'NUMERIC':
             operator = 'CAST(%s AS NUMERIC)'

+        value = "SUBSTR(value, POSITION(',' IN value) + 1)"
         # All negative clauses will be negated later
         if clause[1] in ('in', 'not in'):
             operator = operator % '%%s'
-            return ("(CAST(SPLIT_PART(value,',',2) AS %s) IN ("
+            return ("(CAST(" + value + " AS %s) IN ("
+ ",".join((operator,) * len(clause[2])) + ")) ") % sql_type
         elif ((clause[2] is False or clause[2] is None)
                 and clause[1] in ['=', '!=']):
-            return "((cast(split_part(value,',',2) as %s) IS NULL " \
-                ") = %%s) " % sql_type
+ return "((CAST(" + value + " AS %s) IS NULL) = %%s) " % sql_type
         elif clause[1] in ['not like', 'not ilike']:
-            return "(cast(split_part(value,',',2) as %s) %s %s) " % \
+            return "(CAST(" + value + " AS %s) %s %s) " % \
                 (sql_type, clause[1].split()[1], operator)
         elif clause[1] == '!=':
-            return "(cast(split_part(value,',',2) as %s) = %s) " % \
-                (sql_type, operator)
+ return "(CAST(" + value + " AS %s) = %s) " % (sql_type, operator)
         else:
-            return "(cast(split_part(value,',',2) as %s) %s %s) " % \
+            return "(CAST(" + value + " AS %s) %s %s) " % \
                 (sql_type, clause[1], operator)

     @staticmethod

Index: trytond/model/modelsql.py
===================================================================

--- a/trytond/model/modelsql.py
+++ b/trytond/model/modelsql.py
@@ -1269,8 +1269,9 @@
                             sql_type = FIELDS[
                                 cls.id._type].sql_type(cls.id)[0]
                             query = ('SELECT id FROM "' + cls._table + '" '
-                                'WHERE CAST(SPLIT_PART('
-                                        '"' + fargs[0] + '", \',\', 2) '
+                                'WHERE CAST(SUBSTR("' + fargs[0] + '", '
+ 'POSITION(\',\' IN "' + fargs[0] + '")'
+                                        + '+ 1) '
                                     'AS ' + sql_type + ') '
                                 'IN (' + in_query[0] + ') '
                                 'AND "' + fargs[0] + '" ilike %s')
@@ -1295,8 +1296,9 @@
                             cls.id._type].sql_type(cls.id)[0]
                         where = ' AND "' + origin + '" LIKE %s'
                         where_args = [cls.__name__ + ',%']
-                        origin = ('CAST(SPLIT_PART("%s", \',\', 2) AS %s)'
-                            % (origin, sql_type))
+                        origin = ('CAST(SUBSTR("%s", '
+                            'POSITION(\',\' IN "%s") + 1) AS %s)'
+                            % (origin, origin, sql_type))
                     else:
                         origin = '"%s"' % origin
                         where = ''
@@ -1336,8 +1338,9 @@
                 rev_field = Field._fields[field.field]
                 if rev_field._type == 'reference':
                     sql_type = FIELDS[cls.id._type].sql_type(cls.id)[0]
-                    select = ('CAST(SPLIT_PART("%s", \',\', 2) AS %s)'
-                        % (field.field, sql_type))
+                    select = ('CAST(SUBSTR("%s", '
+                        'POSITION(\',\' IN "%s") + 1) AS %s)'
+                        % (field.field, field.field, sql_type))
                     where = ' AND "' + field.field + '" LIKE %s'
                     where_args = [cls.__name__ + ',%']
                 else:
@@ -1431,8 +1434,9 @@
                     origin_field = Relation._fields[field.origin]
                     if origin_field._type == 'reference':
                         sql_type = FIELDS[cls.id._type].sql_type(cls.id)[0]
-                        select = ('CAST(SPLIT_PART("%s", \',\', 2) AS %s)'
-                            % (field.origin, sql_type))
+                        select = ('CAST(SUBSTR("%s", '
+                            'POSITION(\',\' IN "%s") + 1) AS %s)'
+                            % (field.origin, field.origin, sql_type))
                         where = ' AND "' + field.origin + '" LIKE %s'
                         where_args = [cls.__name__ + ',%']
                     else:



Reply via email to