From: Mike Bayer Date: Thu, 27 Jun 2024 22:17:47 +0000 (-0400) Subject: cache key share; support correct traverse of 'of' X-Git-Tag: rel_1_4_53~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f9d99928e6efb921c4dcd5febf810632c5521e8;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git 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 (cherry picked from commit 6d2f43e14f2fe25cdc811355b7bd6d11f8eee381) (cherry picked from commit 522baa306fc788cf02acf29bf08e86a431a7050e) --- diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index 95d2fdf245..7536665a6e 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -2831,6 +2831,7 @@ class ForUpdateArg(ClauseElement): ("nowait", InternalTraversal.dp_boolean), ("read", InternalTraversal.dp_boolean), ("skip_locked", InternalTraversal.dp_boolean), + ("key_share", InternalTraversal.dp_boolean), ] @classmethod diff --git a/lib/sqlalchemy/sql/traversals.py b/lib/sqlalchemy/sql/traversals.py index 41b960c9c3..eb4913d7c3 100644 --- a/lib/sqlalchemy/sql/traversals.py +++ b/lib/sqlalchemy/sql/traversals.py @@ -1159,6 +1159,8 @@ class TraversalComparatorStrategy(InternalTraversal, 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 0a7f0d4114..3e13174f79 100644 --- a/test/sql/test_compare.py +++ b/test/sql/test_compare.py @@ -472,6 +472,21 @@ class CoreFixtures(object): 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)