diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-04-14 18:53:25 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-04-14 19:41:02 -0400 |
commit | 60b0a693c97e7ab504a0d36497b71ccba24ac8e8 (patch) | |
tree | bd5fe1486ed8b50e4f2dba966bd3bbc16c5eee8f /lib/sqlalchemy/sql/base.py | |
parent | cee6d12a69af38915316d6db8ca59c54325904ea (diff) | |
download | sqlalchemy-60b0a693c97e7ab504a0d36497b71ccba24ac8e8.tar.gz |
Fix with_expression() cache leak; don't adapt singletons
Fixed a cache leak involving the :func:`_orm.with_expression` loader
option, where the given SQL expression would not be correctly considered as
part of the cache key.
Additionally, fixed regression involving the corresponding
:func:`_orm.query_expression` feature. While the bug technically exists in
1.3 as well, it was not exposed until 1.4. The "default expr" value of
``null()`` would be rendered when not needed, and additionally was also not
adapted correctly when the ORM rewrites statements such as when using
joined eager loading. The fix ensures "singleton" expressions like ``NULL``
and ``true`` aren't "adapted" to refer to columns in ORM statements, and
additionally ensures that a :func:`_orm.query_expression` with no default
expression doesn't render in the statement if a
:func:`_orm.with_expression` isn't used.
Fixes: #6259
Change-Id: I5a70bc12dadad125bbc4324b64048c8d4a18916c
Diffstat (limited to 'lib/sqlalchemy/sql/base.py')
-rw-r--r-- | lib/sqlalchemy/sql/base.py | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/sqlalchemy/sql/base.py b/lib/sqlalchemy/sql/base.py index 81685dfe0..d9f05e823 100644 --- a/lib/sqlalchemy/sql/base.py +++ b/lib/sqlalchemy/sql/base.py @@ -54,6 +54,8 @@ class Immutable(object): class SingletonConstant(Immutable): + """Represent SQL constants like NULL, TRUE, FALSE""" + def __new__(cls, *arg, **kw): return cls._singleton @@ -63,6 +65,13 @@ class SingletonConstant(Immutable): obj.__init__() cls._singleton = obj + # don't proxy singletons. this means that a SingletonConstant + # will never be a "corresponding column" in a statement; the constant + # can be named directly and as it is often/usually compared against using + # "IS", it can't be adapted to a subquery column in any case. + # see :ticket:`6259`. + proxy_set = frozenset() + def _from_objects(*elements): return itertools.chain.from_iterable( |