Merge "ensure correlate_except is checked for empty tuple" into main

This commit is contained in:
mike bayer
2022-01-04 19:36:30 +00:00
committed by Gerrit Code Review
4 changed files with 50 additions and 2 deletions
+9
View File
@@ -0,0 +1,9 @@
.. change::
:tags: bug, orm
:tickets: 7514
Fixed issue where :meth:`_sql.Select.correlate_except` method, when passed
either the ``None`` value or no arguments, would not correlate any elements
when used in an ORM context (that is, passing ORM entities as FROM
clauses), rather than causing all FROM elements to be considered as
"correlated" in the same way which occurs when using Core-only constructs.
+2 -2
View File
@@ -774,7 +774,7 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
for s in query._correlate
)
)
elif query._correlate_except:
elif query._correlate_except is not None:
self.correlate_except = tuple(
util.flatten_iterator(
sql_util.surface_selectables(s) if s is not None else None
@@ -1192,7 +1192,7 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
if correlate:
statement.correlate.non_generative(statement, *correlate)
if correlate_except:
if correlate_except is not None:
statement.correlate_except.non_generative(
statement, *correlate_except
)
+31
View File
@@ -1,8 +1,10 @@
from sqlalchemy import bindparam
from sqlalchemy import Column
from sqlalchemy import exc
from sqlalchemy import func
from sqlalchemy import insert
from sqlalchemy import inspect
from sqlalchemy import Integer
from sqlalchemy import literal_column
from sqlalchemy import null
from sqlalchemy import or_
@@ -31,12 +33,15 @@ from sqlalchemy.sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing import AssertsCompiledSQL
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
from sqlalchemy.testing import is_
from sqlalchemy.testing.assertions import expect_raises_message
from sqlalchemy.testing.fixtures import fixture_session
from sqlalchemy.testing.util import resolve_lambda
from sqlalchemy.util.langhelpers import hybridproperty
from .inheritance import _poly_fixtures
from .test_query import QueryTest
from ..sql.test_compiler import CorrelateTest as _CoreCorrelateTest
# TODO:
# composites / unions, etc.
@@ -2320,3 +2325,29 @@ class RawSelectTest(QueryTest, AssertsCompiledSQL):
)
self.assert_compile(stmt1, expected)
self.assert_compile(stmt2, expected)
class CorrelateTest(fixtures.DeclarativeMappedTest, _CoreCorrelateTest):
@classmethod
def setup_classes(cls):
Base = cls.DeclarativeBasic
class T1(Base):
__tablename__ = "t1"
a = Column(Integer, primary_key=True)
@hybridproperty
def c(self):
return self
class T2(Base):
__tablename__ = "t2"
a = Column(Integer, primary_key=True)
@hybridproperty
def c(self):
return self
def _fixture(self):
t1, t2 = self.classes("T1", "T2")
return t1, t2, select(t1).where(t1.c.a == t2.c.a)
+8
View File
@@ -5920,6 +5920,14 @@ class CorrelateTest(fixtures.TestBase, AssertsCompiledSQL):
)
)
def test_correlate_except_empty(self):
t1, t2, s1 = self._fixture()
self._assert_where_all_correlated(
select(t1, t2).where(
t2.c.a == s1.correlate_except().scalar_subquery()
)
)
def test_correlate_except_having(self):
t1, t2, s1 = self._fixture()
self._assert_having_correlated(