From 6d2f43e14f2fe25cdc811355b7bd6d11f8eee381 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 27 Jun 2024 18:17:47 -0400 Subject: [PATCH] cache key share; support correct traverse of 'of' Fixed caching issue where the :paramref:`_sql.Select.with_for_update.key_share` element of :meth:`_sql.Select.with_for_update` was not considered as part of the cache key, leading to incorrect caching if different variations of this parameter were used with an otherwise identical statement. Also repairs a traversal issue where the ``of`` element of ``ForUpdateArg`` when set to ``None`` cannot be compared against a non-None element because the traversal defines it as a clauselist. Traversal in this case is adjusted to accommodate for this case so that we dont need to create a risky-to-backport change to ``ForUpdateArg`` itself. Fixes: #11544 Change-Id: Ie8a50716df06977af58b0c22a8c10e1b64d972b9 --- lib/sqlalchemy/sql/selectable.py | 1 + lib/sqlalchemy/sql/traversals.py | 2 ++ test/sql/test_compare.py | 15 +++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index 1e06754e6f..a9ef7fd030 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -3086,6 +3086,7 @@ class ForUpdateArg(ClauseElement): ("nowait", InternalTraversal.dp_boolean), ("read", InternalTraversal.dp_boolean), ("skip_locked", InternalTraversal.dp_boolean), + ("key_share", InternalTraversal.dp_boolean), ] of: Optional[Sequence[ClauseElement]] diff --git a/lib/sqlalchemy/sql/traversals.py b/lib/sqlalchemy/sql/traversals.py index 3ca3caf9e2..8bb2939cb3 100644 --- a/lib/sqlalchemy/sql/traversals.py +++ b/lib/sqlalchemy/sql/traversals.py @@ -562,6 +562,8 @@ class TraversalComparatorStrategy(HasTraversalDispatch, util.MemoizedSlots): return False else: continue + elif right_child is None: + return False comparison = dispatch( left_attrname, left, left_child, right, right_child, **kw diff --git a/test/sql/test_compare.py b/test/sql/test_compare.py index d8947ab67b..a43ea70e10 100644 --- a/test/sql/test_compare.py +++ b/test/sql/test_compare.py @@ -478,6 +478,21 @@ class CoreFixtures: select(table_a.c.a) .where(table_a.c.b == 5) .with_for_update(nowait=True), + select(table_a.c.a) + .where(table_a.c.b == 5) + .with_for_update(nowait=True, skip_locked=True), + select(table_a.c.a) + .where(table_a.c.b == 5) + .with_for_update(nowait=True, read=True), + select(table_a.c.a) + .where(table_a.c.b == 5) + .with_for_update(of=table_a.c.a), + select(table_a.c.a) + .where(table_a.c.b == 5) + .with_for_update(of=table_a.c.b), + select(table_a.c.a) + .where(table_a.c.b == 5) + .with_for_update(nowait=True, key_share=True), select(table_a.c.a).where(table_a.c.b == 5).correlate(table_b), select(table_a.c.a) .where(table_a.c.b == 5) -- 2.47.2