From 3c2ad425871de7d37f6bd05a62143ed6fec9709d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 18 Jun 2026 15:49:10 +0200 Subject: [PATCH] Do not convert select query value into list when searching on char with in operator Closes #14898 (grafted from f62e20c70717ed0a40ad86a7dd5672577f73626b) --HG-- branch : 8.0 --- trytond/trytond/model/fields/char.py | 11 ++++++----- trytond/trytond/tests/test_field_char.py | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/trytond/trytond/model/fields/char.py b/trytond/trytond/model/fields/char.py index 4a9c654e59..4998a8bb93 100644 --- a/trytond/trytond/model/fields/char.py +++ b/trytond/trytond/model/fields/char.py @@ -3,7 +3,7 @@ import string import warnings -from sql import Column, Expression, Query +from sql import Column, CombiningQuery, Expression, Query, Select from sql.conditionals import Coalesce, NullIf from sql.functions import Trim from sql.operators import Not @@ -121,10 +121,11 @@ class Char(FieldTranslate): return column def _domain_value(self, operator, value): - if operator in {'in', 'not in'}: - value = [v if v is not None else '' for v in value] - elif value is None: - value = '' + if not isinstance(value, (Select, CombiningQuery)): + if operator in {'in', 'not in'}: + value = [v if v is not None else '' for v in value] + elif value is None: + value = '' value = super()._domain_value(operator, value) if self.search_unaccented and operator.endswith('ilike'): database = Transaction().database diff --git a/trytond/trytond/tests/test_field_char.py b/trytond/trytond/tests/test_field_char.py index ea9b8abfb4..afc19ac908 100644 --- a/trytond/trytond/tests/test_field_char.py +++ b/trytond/trytond/tests/test_field_char.py @@ -3,7 +3,7 @@ # this repository contains the full copyright notices and license terms. import unittest -from sql import Literal +from sql import Literal, Select from trytond import backend from trytond.model.exceptions import ( @@ -55,9 +55,17 @@ class CommonTestCaseMixin: chars_bar = Char.search([ ('char', '=', "Bar"), ]) + chars_select_foo = Char.search([ + ('char', '=', Select([Literal('Foo')])), + ]) + chars_select_bar = Char.search([ + ('char', '=', Select([Literal('Bar')])), + ]) self.assertListEqual(chars_foo, [char]) self.assertListEqual(chars_bar, []) + self.assertListEqual(chars_select_foo, [char]) + self.assertListEqual(chars_select_bar, []) @with_transaction() def test_search_equals_none(self): @@ -178,10 +186,18 @@ class CommonTestCaseMixin: chars_empty = Char.search([ ('char', 'in', []), ]) + chars_select_foo = Char.search([ + ('char', 'in', Select([Literal('Foo')])), + ]) + chars_select_bar = Char.search([ + ('char', 'in', Select([Literal('Bar')])), + ]) self.assertListEqual(chars_foo, [char]) self.assertListEqual(chars_bar, []) self.assertListEqual(chars_empty, []) + self.assertListEqual(chars_select_foo, [char]) + self.assertListEqual(chars_select_bar, []) @with_transaction() def test_search_in_none(self):