73 lines
2.9 KiB
Diff
73 lines
2.9 KiB
Diff
diff -r 5619f54a9d36 trytond/model/fields/many2one.py
|
|
--- a/trytond/trytond/model/fields/many2one.py Tue Jan 22 22:14:35 2019 +0100
|
|
+++ b/trytond/trytond/model/fields/many2one.py Fri Feb 08 09:49:22 2019 +0100
|
|
@@ -1,6 +1,6 @@
|
|
# 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 sql import Literal, Column
|
|
+from sql import Literal, Column, With
|
|
from sql.aggregate import Max
|
|
from sql.conditionals import Coalesce
|
|
from sql.operators import Or
|
|
@@ -116,7 +116,7 @@
|
|
cursor = Transaction().connection.cursor()
|
|
table, _ = tables[None]
|
|
name, operator, ids = domain
|
|
- red_sql = reduce_ids(table.id, ids)
|
|
+ red_sql = reduce_ids(table.id, (i for i in ids if i is not None))
|
|
Target = self.get_target()
|
|
left = getattr(Target, self.left).sql_column(table)
|
|
right = getattr(Target, self.right).sql_column(table)
|
|
@@ -135,35 +135,27 @@
|
|
|
|
def convert_domain_tree(self, domain, tables):
|
|
Target = self.get_target()
|
|
+ target = Target.__table__()
|
|
table, _ = tables[None]
|
|
name, operator, ids = domain
|
|
- ids = set(ids) # Ensure it is a set for concatenation
|
|
-
|
|
- def get_child(ids):
|
|
- if not ids:
|
|
- return set()
|
|
- children = Target.search([
|
|
- (name, 'in', ids),
|
|
- (name, '!=', None),
|
|
- ], order=[])
|
|
- child_ids = get_child(set(c.id for c in children))
|
|
- return ids | child_ids
|
|
-
|
|
- def get_parent(ids):
|
|
- if not ids:
|
|
- return set()
|
|
- parent_ids = set(getattr(p, name).id
|
|
- for p in Target.browse(ids) if getattr(p, name))
|
|
- return ids | get_parent(parent_ids)
|
|
+ red_sql = reduce_ids(target.id, (i for i in ids if i is not None))
|
|
|
|
if operator.endswith('child_of'):
|
|
- ids = list(get_child(ids))
|
|
+ tree = With('id', recursive=True)
|
|
+ tree.query = target.select(target.id, where=red_sql)
|
|
+ tree.query |= (target
|
|
+ .join(tree, condition=Column(target, name) == tree.id)
|
|
+ .select(target.id))
|
|
else:
|
|
- ids = list(get_parent(ids))
|
|
- if not ids:
|
|
- expression = Literal(False)
|
|
- else:
|
|
- expression = table.id.in_(ids)
|
|
+ tree = With('id', name, recursive=True)
|
|
+ tree.query = target.select(
|
|
+ target.id, Column(target, name), where=red_sql)
|
|
+ tree.query |= (target
|
|
+ .join(tree, condition=target.id == Column(tree, name))
|
|
+ .select(target.id, Column(target, name)))
|
|
+
|
|
+ expression = table.id.in_(tree.select(tree.id, with_=[tree]))
|
|
+
|
|
if operator.startswith('not'):
|
|
return ~expression
|
|
return expression
|