]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
pass more contextual information to PyWrapper param create
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 27 Dec 2022 17:29:38 +0000 (12:29 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 27 Dec 2022 19:05:15 +0000 (14:05 -0500)
Fixed issue in lambda SQL feature where the calculated type of a literal
value would not take into account the type coercion rules of the "compared
to type", leading to a lack of typing information for SQL expressions, such
as comparisons to :class:`.JSON` elements and similar.

Fixes: #9029
Change-Id: I381c8d7458d98ba762313dee9ec47a9c1881f74a
(cherry picked from commit f63d7e33ec785a5ea4fbc77963c537be26b8419b)

doc/build/changelog/unreleased_14/9029.rst [new file with mode: 0644]
lib/sqlalchemy/sql/coercions.py
lib/sqlalchemy/sql/lambdas.py
regen_callcounts.tox.ini
test/profiles.txt
test/sql/test_lambdas.py

diff --git a/doc/build/changelog/unreleased_14/9029.rst b/doc/build/changelog/unreleased_14/9029.rst
new file mode 100644 (file)
index 0000000..38114e9
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, sql
+    :tickets: 9029
+
+    Fixed issue in lambda SQL feature where the calculated type of a literal
+    value would not take into account the type coercion rules of the "compared
+    to type", leading to a lack of typing information for SQL expressions, such
+    as comparisons to :class:`.JSON` elements and similar.
index 8cc73cb5c5ab38dc4c56958f334abccae5ae5ec8..ede488915ec5375dea71d0a8d96a161969824de4 100644 (file)
@@ -141,7 +141,12 @@ def expect(
 
     if not isinstance(
         element,
-        (elements.ClauseElement, schema.SchemaItem, schema.FetchedValue),
+        (
+            elements.ClauseElement,
+            schema.SchemaItem,
+            schema.FetchedValue,
+            lambdas.PyWrapper,
+        ),
     ):
         resolved = None
 
@@ -190,6 +195,8 @@ def expect(
                     )
             else:
                 resolved = element
+    elif isinstance(element, lambdas.PyWrapper):
+        resolved = element._sa__py_wrapper_literal(**kw)
     else:
         resolved = element
     if (
index 584efe4c68896d0f5b5af40d91e056b3756ea03a..236427d9df6f842de5cc738385b4343fa9e5cca0 100644 (file)
@@ -18,7 +18,6 @@ from . import elements
 from . import roles
 from . import schema
 from . import traversals
-from . import type_api
 from . import visitors
 from .base import _clone
 from .base import Options
@@ -1215,11 +1214,11 @@ class PyWrapper(ColumnOperators):
             return value
 
     def operate(self, op, *other, **kwargs):
-        elem = object.__getattribute__(self, "__clause_element__")()
+        elem = object.__getattribute__(self, "_py_wrapper_literal")()
         return op(elem, *other, **kwargs)
 
     def reverse_operate(self, op, other, **kwargs):
-        elem = object.__getattribute__(self, "__clause_element__")()
+        elem = object.__getattribute__(self, "_py_wrapper_literal")()
         return op(other, elem, **kwargs)
 
     def _extract_bound_parameters(self, starting_point, result_list):
@@ -1232,16 +1231,19 @@ class PyWrapper(ColumnOperators):
             element = getter(starting_point)
             pywrapper._sa__extract_bound_parameters(element, result_list)
 
-    def __clause_element__(self):
+    def _py_wrapper_literal(self, expr=None, operator=None, **kw):
         param = object.__getattribute__(self, "_param")
         to_evaluate = object.__getattribute__(self, "_to_evaluate")
         if param is None:
             name = object.__getattribute__(self, "_name")
             self._param = param = elements.BindParameter(
-                name, required=False, unique=True
+                name,
+                required=False,
+                unique=True,
+                _compared_to_operator=operator,
+                _compared_to_type=expr.type if expr is not None else None,
             )
             self._has_param = True
-            param.type = type_api._resolve_value_to_type(to_evaluate)
         return param._with_value(to_evaluate, maintain_key=True)
 
     def __bool__(self):
@@ -1259,6 +1261,7 @@ class PyWrapper(ColumnOperators):
             "__clause_element__",
             "operate",
             "reverse_operate",
+            "_py_wrapper_literal",
             "__class__",
             "__dict__",
         ):
index 80d88aa45445323eed8d81dcdfc9425ab19d1616..0379b1cfe8d468c62bb60ce1ed845338bd8481b7 100644 (file)
@@ -21,7 +21,15 @@ commands=
     db_{oracle}: {env:BASECOMMAND} {env:ORACLE:} {posargs}
     db_{mssql}: {env:BASECOMMAND} {env:MSSQL:} {posargs}
 
-passenv=ORACLE_HOME NLS_LANG TOX_POSTGRESQL TOX_MYSQL TOX_ORACLE TOX_MSSQL TOX_SQLITE TOX_WORKERS
+passenv=
+    ORACLE_HOME
+    NLS_LANG
+    TOX_POSTGRESQL
+    TOX_MYSQL
+    TOX_ORACLE
+    TOX_MSSQL
+    TOX_SQLITE
+    TOX_WORKERS
 
 # -E     : ignore PYTHON* environment variables (such as PYTHONPATH)
 # -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE
index ab19468b37d4adeef7f0ddbee19ff6e02e7f571a..5c285f4f4535807bf3020d5d17fb6f770afbd9fb 100644 (file)
@@ -165,8 +165,8 @@ test.aaa_profiling.test_misc.EnumTest.test_create_enum_from_pep_435_w_expensive_
 
 # TEST: test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation
 
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 46635
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 56845
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 47035
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 57245
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 50335
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 61445
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 50335
@@ -174,8 +174,8 @@ test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_w_annotation x86_6
 
 # TEST: test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation
 
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 45735
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 55945
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 45835
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 56045
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 49435
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 60545
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 49435
@@ -183,8 +183,8 @@ test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_bundle_wo_annotation x86_
 
 # TEST: test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations
 
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 50835
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 58545
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 51135
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 58845
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 53935
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 62545
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 53935
@@ -192,8 +192,8 @@ test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_w_annotations x86_
 
 # TEST: test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations
 
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 49935
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 57645
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 50335
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 58045
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 53035
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 61645
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_entity_wo_annotations x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 53035
@@ -219,8 +219,8 @@ test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_w_annotations x
 
 # TEST: test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations
 
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 44335
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 52045
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 44435
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 52145
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 47435
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 56045
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_bundle_wo_annotations x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 47435
@@ -237,8 +237,8 @@ test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_w_annotations x
 
 # TEST: test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations
 
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 30905
-test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 33505
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 31005
+test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 33605
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 33705
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 36605
 test.aaa_profiling.test_orm.AnnotatedOverheadTest.test_no_entity_wo_annotations x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 33705
@@ -282,8 +282,8 @@ test.aaa_profiling.test_orm.BranchedOptionTest.test_query_opts_unbound_branching
 
 # TEST: test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline
 
-test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 15162
-test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 26175
+test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 15246
+test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 26259
 test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 15190
 test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 27207
 test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 15190
@@ -291,8 +291,8 @@ test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline x86_64_linux_cpython_
 
 # TEST: test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols
 
-test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 21303
-test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 26316
+test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 21291
+test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 26304
 test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 21344
 test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 27361
 test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 21344
@@ -300,8 +300,8 @@ test.aaa_profiling.test_orm.DeferOptionsTest.test_defer_many_cols x86_64_linux_c
 
 # TEST: test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased
 
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 9853
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 10003
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 9953
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 10153
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 10304
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 10454
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 10304
@@ -318,8 +318,8 @@ test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_aliased_select_join x8
 
 # TEST: test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain
 
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 4053
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 4203
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 4153
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 4353
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 4054
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 4204
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 4054
@@ -327,8 +327,8 @@ test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_b_plain x86_64_linux_cpy
 
 # TEST: test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d
 
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 96088
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 96238
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 99338
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 99738
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 103689
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 103839
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 103689
@@ -336,8 +336,8 @@ test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d x86_64_linux_cpython_3
 
 # TEST: test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased
 
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 94138
-test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 94288
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 97288
+test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 97688
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 102039
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 102189
 test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 102039
@@ -345,8 +345,8 @@ test.aaa_profiling.test_orm.JoinConditionTest.test_a_to_d_aliased x86_64_linux_c
 
 # TEST: test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query
 
-test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 495703
-test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 497535
+test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 497722
+test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 499549
 test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 527563
 test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 529405
 test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 527563
@@ -354,8 +354,8 @@ test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_build_query x86_64_linux_cp
 
 # TEST: test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results
 
-test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 425705
-test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 443305
+test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 425305
+test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 442905
 test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 430805
 test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 449905
 test.aaa_profiling.test_orm.JoinedEagerLoadTest.test_fetch_results x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 430205
@@ -372,8 +372,8 @@ test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_
 
 # TEST: test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity
 
-test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 103486
-test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 108243
+test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 104575
+test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 109332
 test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 107759
 test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 113767
 test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_no_identity x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 107759
@@ -381,8 +381,8 @@ test.aaa_profiling.test_orm.LoadManyToOneFromIdentityTest.test_many_to_one_load_
 
 # TEST: test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks
 
-test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 19841
-test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 20287
+test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 20043
+test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 20497
 test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 20731
 test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 21299
 test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 20731
@@ -390,8 +390,8 @@ test.aaa_profiling.test_orm.MergeBackrefsTest.test_merge_pending_with_all_pks x8
 
 # TEST: test.aaa_profiling.test_orm.MergeTest.test_merge_load
 
-test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 1396
-test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 1436
+test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 1414
+test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 1454
 test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 1460
 test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 1511
 test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 1460
@@ -399,8 +399,8 @@ test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_3.9_s
 
 # TEST: test.aaa_profiling.test_orm.MergeTest.test_merge_no_load
 
-test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 101,17
-test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 101,17
+test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 107,18
+test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 107,18
 test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 103,18
 test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 103,18
 test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 103,18
@@ -408,8 +408,8 @@ test.aaa_profiling.test_orm.MergeTest.test_merge_no_load x86_64_linux_cpython_3.
 
 # TEST: test.aaa_profiling.test_orm.QueryTest.test_query_cols
 
-test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 5842
-test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 6602
+test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 5936
+test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 6696
 test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 6150
 test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 6940
 test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 6150
@@ -417,8 +417,8 @@ test.aaa_profiling.test_orm.QueryTest.test_query_cols x86_64_linux_cpython_3.9_s
 
 # TEST: test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results
 
-test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 253005
-test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 271105
+test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 264805
+test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 282905
 test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 263605
 test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 283105
 test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64_linux_cpython_3.9_sqlite_pysqlite_dbapiunicode_cextensions 263605
@@ -426,7 +426,7 @@ test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results x86_64
 
 # TEST: test.aaa_profiling.test_orm.SessionTest.test_expire_lots
 
-test.aaa_profiling.test_orm.SessionTest.test_expire_lots x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 1141
+test.aaa_profiling.test_orm.SessionTest.test_expire_lots x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 1158
 test.aaa_profiling.test_orm.SessionTest.test_expire_lots x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 1146
 test.aaa_profiling.test_orm.SessionTest.test_expire_lots x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 1252
 test.aaa_profiling.test_orm.SessionTest.test_expire_lots x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 1256
index 29e1258efbfe8e2c94caaff9fe7738fc4c51940e..ede9702010b877a6f2789645a9145b207520e022 100644 (file)
@@ -31,6 +31,7 @@ from sqlalchemy.testing.assertsql import CompiledSQL
 from sqlalchemy.types import ARRAY
 from sqlalchemy.types import Boolean
 from sqlalchemy.types import Integer
+from sqlalchemy.types import JSON
 from sqlalchemy.types import String
 
 
@@ -1513,6 +1514,107 @@ class LambdaElementTest(
             expr, "users.name || :x_1", checkparams={"x_1": "bar"}
         )
 
+    def test_rhs_type_detection_from_left(self):
+        """test #9029"""
+        tt = table("tt", column("q", JSON))
+
+        x = {"foo": "bar"}
+
+        def mylambda():
+            return tt.c.q + x
+
+        expr = coercions.expect(roles.WhereHavingRole, mylambda)
+        is_(expr._resolved.right.type._type_affinity, JSON)
+
+    def test_rhs_type_detection_standalone(self):
+        """test related to #9029, as type coercion rule was changed"""
+
+        x = 5
+
+        def mylambda():
+            return x
+
+        expr = coercions.expect(roles.OrderByRole, mylambda)
+        is_(expr._resolved.type._type_affinity, Integer)
+
+        x = "now im a string"
+
+        # stays as int b.c. _resolved is cached
+        is_(expr._resolved.type._type_affinity, Integer)
+
+        # make a new one!  now it will be string
+        expr = coercions.expect(roles.OrderByRole, mylambda)
+        is_(expr._resolved.type._type_affinity, String)
+
+    @testing.only_on("sqlite")
+    @testing.variation("stmt_type", ["lambda_stmt", "lambda_crit"])
+    @testing.variation("callable_type", ["none", "closure", "parameter"])
+    def test_9029_integration(
+        self, metadata, connection, stmt_type, callable_type
+    ):
+        t = Table(
+            "t",
+            metadata,
+            Column("id", Integer, primary_key=True),
+            Column("data", JSON),
+        )
+
+        t.create(connection)
+
+        connection.execute(
+            t.insert(),
+            {
+                "id": 12,
+                "data": {"key": "value", "key2": {"subkey": [1, 2, 3]}},
+            },
+        )
+
+        d = {"key": "value", "key2": {"subkey": [1, 2, 3]}}
+
+        if callable_type.none:
+            if stmt_type.lambda_stmt:
+                stmt = lambda_stmt(lambda: select(t).filter(t.c.data == d))
+            elif stmt_type.lambda_crit:
+                stmt = select(t).filter(lambda: t.c.data == d)
+            else:
+                stmt_type.fail()
+
+            to_run = stmt
+
+        elif callable_type.closure:
+
+            def go():
+                if stmt_type.lambda_stmt:
+                    stmt = lambda_stmt(lambda: select(t).filter(t.c.data == d))
+                elif stmt_type.lambda_crit:
+                    stmt = select(t).filter(lambda: t.c.data == d)
+                else:
+                    stmt_type.fail()
+                return stmt
+
+            to_run = go()
+
+        elif callable_type.parameter:
+
+            def go(data):
+                if stmt_type.lambda_stmt:
+                    stmt = lambda_stmt(
+                        lambda: select(t).filter(t.c.data == data)
+                    )
+                elif stmt_type.lambda_crit:
+                    stmt = select(t).filter(lambda: t.c.data == data)
+                else:
+                    stmt_type.fail()
+
+                return stmt
+
+            to_run = go(d)
+
+        eq_(
+            connection.execute(to_run).first(),
+            (12, {"key": "value", "key2": {"subkey": [1, 2, 3]}}),
+        )
+
     def test_execute_constructed_uncached(self, user_address_fixture):
         users, addresses = user_address_fixture