Replace SPLIT_PART by SUBSTR and POSITION
SPLIT_PART is not a standard SQL function (it is not supported by MySQL). SUBSTR is used even if it is not standard SQL because SUBSTRING is not supported by SQLite. This will change once we will migrate to python-sql. review784002
This commit is contained in:
1 parent
3492e90308
commit
2e8ec5f5df
4 files changed
+34
-18
No files matched your search
@@ -23,6 +23,7 @@ except ImportError:
|
||||
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 @@ def split_part(text, delimiter, count):
|
||||
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 @@ class Database(DatabaseInterface):
|
||||
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 @@ class Cursor(CursorInterface):
|
||||
|
||||
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', '?')
|
||||
|
||||
@@ -144,7 +144,7 @@ class Translation(ModelSQL, ModelView):
|
||||
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()])]
|
||||
|
||||
|
||||
@@ -90,7 +90,8 @@ class Property(Function):
|
||||
#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 @@ class Property(Function):
|
||||
|
||||
#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 @@ class Property(Function):
|
||||
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
|
||||
|
||||
@@ -1269,8 +1269,9 @@ class ModelSQL(ModelStorage):
|
||||
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 @@ class ModelSQL(ModelStorage):
|
||||
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 @@ class ModelSQL(ModelStorage):
|
||||
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 @@ class ModelSQL(ModelStorage):
|
||||
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:
|
||||
|
||||
Reference in new issue
Block a user