--- /dev/null
+.. change::
+ :tags: bug, sql
+ :tickets: 12084
+
+ Fixed issue in "lambda SQL" feature where the tracking of bound parameters
+ could be corrupted if the same lambda were evaluated across multiple
+ compile phases, including when using the same lambda across multiple engine
+ instances or with statement caching disabled.
+
rec = AnalyzedFunction(
tracker, self, apply_propagate_attrs, fn
)
- rec.closure_bindparams = bindparams
+ rec.closure_bindparams = list(bindparams)
lambda_cache[key] = rec
else:
rec = lambda_cache[key]
(7, "foo"),
)
+ def test_bindparam_not_cached(self, user_address_fixture, testing_engine):
+ """test #12084"""
+
+ users, addresses = user_address_fixture
+
+ engine = testing_engine(
+ share_pool=True, options={"query_cache_size": 0}
+ )
+ with engine.begin() as conn:
+ conn.execute(
+ users.insert(),
+ [{"id": 7, "name": "bar"}, {"id": 8, "name": "foo"}],
+ )
+
+ def make_query(stmt, *criteria):
+ for crit in criteria:
+ stmt += lambda s: s.where(crit)
+
+ return stmt
+
+ for i in range(2):
+ with engine.connect() as conn:
+ stmt = lambda_stmt(lambda: select(users))
+ # create a filter criterion that will never match anything
+ stmt1 = make_query(
+ stmt,
+ users.c.name == "bar",
+ users.c.name == "foo",
+ )
+
+ assert len(conn.scalars(stmt1).all()) == 0
+
+ stmt2 = make_query(
+ stmt,
+ users.c.name == "bar",
+ users.c.name == "bar",
+ users.c.name == "foo",
+ )
+
+ assert len(conn.scalars(stmt2).all()) == 0
+
class DeferredLambdaElementTest(
fixtures.TestBase, testing.AssertsExecutionResults, AssertsCompiledSQL