summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/base.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-04-14 18:53:25 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2021-04-14 19:41:02 -0400
commit60b0a693c97e7ab504a0d36497b71ccba24ac8e8 (patch)
treebd5fe1486ed8b50e4f2dba966bd3bbc16c5eee8f /lib/sqlalchemy/sql/base.py
parentcee6d12a69af38915316d6db8ca59c54325904ea (diff)
downloadsqlalchemy-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.py9
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(