trytond-patches/issue4421002_20001.diff

282 lines
11 KiB
Diff

Index: trytond/trytond/model/fields/field.py
===================================================================
--- a/trytond/trytond/model/fields/field.py
+++ b/trytond/trytond/model/fields/field.py
@@ -222,6 +222,9 @@
def sql_type(self):
raise NotImplementedError
+ def sql_column(self, table):
+ return Column(table, self.name)
+
def _domain_value(self, operator, value):
if isinstance(value, (Select, CombiningQuery)):
return value
@@ -244,8 +247,9 @@
"Return a SQL expression for the domain using tables"
table, _ = tables[None]
name, operator, value = domain
+ assert name == self.name
Operator = SQL_OPERATORS[operator]
- column = Column(table, name)
+ column = self.sql_column(table)
expression = Operator(column, self._domain_value(operator, value))
if isinstance(expression, operators.In) and not expression.right:
expression = Literal(False)
@@ -256,12 +260,13 @@
def convert_order(self, name, tables, Model):
"Return a SQL expression to order"
+ assert name == self.name
table, _ = tables[None]
method = getattr(Model, 'order_%s' % name, None)
if method:
return method(tables)
else:
- return [Column(table, name)]
+ return [self.sql_column(table)]
class FieldTranslate(Field):
@@ -313,8 +318,9 @@
join = self._get_translation_join(Model, name,
translation, model, table)
Operator = SQL_OPERATORS[operator]
+ assert name == self.name
column = Coalesce(NullIf(translation.value, ''),
- Column(table, name))
+ self.sql_column(table))
where = Operator(column, self._domain_value(operator, value))
if isinstance(where, operators.In) and not where.right:
where = Literal(False)
@@ -330,6 +336,7 @@
if not self.translate:
return super(FieldTranslate, self).convert_order(name, tables,
Model)
+ assert name == self.name
table, _ = tables[None]
key = name + '.translation'
@@ -344,6 +351,7 @@
else:
translation, _ = tables[key][None]
- return [Coalesce(NullIf(translation.value, ''), Column(table, name))]
+ return [Coalesce(NullIf(translation.value, ''),
+ self.sql_column(table))]
SQLType = namedtuple('SQLType', 'base type')
Index: trytond/trytond/model/fields/many2many.py
===================================================================
--- a/trytond/trytond/model/fields/many2many.py
+++ b/trytond/trytond/model/fields/many2many.py
@@ -1,7 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from itertools import chain
-from sql import Cast, Literal, Column
+from sql import Cast, Literal
from sql.functions import Substring, Position
from .field import Field, size_validate
@@ -269,7 +269,7 @@
name, operator, value = domain[:3]
origin_field = Relation._fields[self.origin]
- origin = Column(relation, self.origin)
+ origin = getattr(Relation, self.origin).sql_column(relation)
origin_where = None
if origin_field._type == 'reference':
origin_where = origin.like(Model.__name__ + ',%')
@@ -277,13 +277,13 @@
Position(',', origin) + Literal(1)),
Relation.id.sql_type().base)
+ target = getattr(Relation, self.target).sql_column(relation)
if '.' not in name:
if operator in ('child_of', 'not child_of'):
if Target != Model:
query = Target.search([(domain[3], 'child_of', value)],
order=[], query=True)
- where = (Column(relation, self.target).in_(query)
- & (Column(relation, self.origin) != None))
+ where = (target.in_(query) & (origin != None))
if origin_where:
where &= origin_where
query = relation.select(origin, where=where)
@@ -326,7 +326,7 @@
_, target_name = name.split('.', 1)
target_domain = [(target_name,) + tuple(domain[1:])]
query = Target.search(target_domain, order=[], query=True)
- where = Column(relation, self.target).in_(query)
+ where = target.in_(query)
if origin_where:
where &= origin_where
query = relation.select(origin, where=where)
Index: trytond/trytond/model/fields/many2one.py
===================================================================
--- a/trytond/trytond/model/fields/many2one.py
+++ b/trytond/trytond/model/fields/many2one.py
@@ -1,7 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from types import NoneType
-from sql import Column, Query, Expression
+from sql import Query, Expression
from sql.operators import Or
from .field import Field, SQLType
@@ -99,8 +99,9 @@
table, _ = tables[None]
name, operator, ids = domain
red_sql = reduce_ids(table.id, ids)
- left = Column(table, self.left)
- right = Column(table, self.right)
+ Target = self.get_target()
+ left = getattr(Target, self.left).sql_column(table)
+ right = getattr(Target, self.right).sql_column(table)
cursor.execute(*table.select(left, right, where=red_sql))
where = Or()
for l, r in cursor.fetchall():
@@ -133,7 +134,7 @@
Target = self.get_target()
table, _ = tables[None]
name, operator, value = domain[:3]
- column = Column(table, name.split('.', 1)[0])
+ column = self.sql_column(table)
if '.' not in name:
if operator in ('child_of', 'not child_of'):
if Target != Model:
@@ -180,6 +181,7 @@
def convert_order(self, name, tables, Model):
if getattr(Model, 'order_%s' % name, None):
return super(Many2One, self).convert_order(name, tables, Model)
+ assert name == self.name
Target = self.get_target()
@@ -195,7 +197,7 @@
if target_tables is None:
target = Target.__table__()
target_tables = {
- None: (target, target.id == Column(table, name)),
+ None: (target, target.id == self.sql_column(table)),
}
tables[name] = target_tables
return ofield.convert_order(oname, target_tables, Target)
Index: trytond/trytond/model/fields/numeric.py
===================================================================
--- a/trytond/trytond/model/fields/numeric.py
+++ b/trytond/trytond/model/fields/numeric.py
@@ -1,7 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from decimal import Decimal
-from sql import Query, Expression
+from sql import Query, Expression, Cast, Literal, Select, CombiningQuery
from ...config import CONFIG
from .field import SQLType
@@ -30,3 +30,25 @@
if db_type == 'mysql':
return SQLType('DECIMAL', 'DECIMAL(65, 30)')
return SQLType('NUMERIC', 'NUMERIC')
+
+ def sql_column(self, table):
+ column = super(Numeric, self).sql_column(table)
+ db_type = CONFIG['db_type']
+ if db_type == 'sqlite':
+ # Must be casted as Decimal is stored as bytes
+ column = Cast(column, self.sql_type().base)
+ return column
+
+ def _domain_value(self, operator, value):
+ value = super(Numeric, self)._domain_value(operator, value)
+ db_type = CONFIG['db_type']
+ if db_type == 'sqlite':
+ if isinstance(value, (Select, CombiningQuery)):
+ return value
+ # Must be casted as Decimal is adapted to bytes
+ type_ = self.sql_type().base
+ if operator in ('in', 'not in'):
+ return [Cast(Literal(v), type_) for v in value]
+ else:
+ return Cast(Literal(value), type_)
+ return value
Index: trytond/trytond/model/fields/one2many.py
===================================================================
--- a/trytond/trytond/model/fields/one2many.py
+++ b/trytond/trytond/model/fields/one2many.py
@@ -1,7 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from itertools import chain
-from sql import Cast, Literal, Column
+from sql import Cast, Literal
from sql.functions import Substring, Position
from .field import Field, size_validate
@@ -231,7 +231,7 @@
name, operator, value = domain[:3]
origin_field = Target._fields[self.field]
- origin = Column(target, self.field)
+ origin = getattr(Target, self.field).sql_column(target)
origin_where = None
if origin_field._type == 'reference':
origin_where = origin.like(Model.__name__ + ',%')
Index: trytond/trytond/model/fields/reference.py
===================================================================
--- a/trytond/trytond/model/fields/reference.py
+++ b/trytond/trytond/model/fields/reference.py
@@ -1,7 +1,7 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from types import NoneType
-from sql import Cast, Literal, Column, Query, Expression
+from sql import Cast, Literal, Query, Expression
from sql.functions import Substring, Position
from .field import Field, SQLType
@@ -119,7 +119,8 @@
Target = pool.get(target)
table, _ = tables[None]
name, target_name = name.split('.', 1)
- column = Column(table, name)
+ assert name == self.name
+ column = self.sql_column(table)
target_domain = [(target_name,) + tuple(domain[1:3])
+ tuple(domain[4:])]
if 'active' in Target._fields:
Index: trytond/trytond/model/fields/selection.py
===================================================================
--- a/trytond/trytond/model/fields/selection.py
+++ b/trytond/trytond/model/fields/selection.py
@@ -54,11 +53,12 @@
if getattr(Model, 'order_%s' % name, None):
return super(Selection, self).convert_order(name, tables, Model)
+ assert name == self.name
table, _ = tables[None]
selections = Model.fields_get([name])[name]['selection']
if not isinstance(selections, (tuple, list)):
selections = getattr(Model, selections)()
- column = Column(table, name)
+ column = self.sql_column(table)
whens = []
for key, value in selections:
whens.append((column == key, value))