mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-21 16:12:03 -04:00
66e88d30a8
This affects mostly docstrings, except in orm/events.py::dispose_collection()
where one parameter gets renamed: given that the method is
empty, it seemed reasonable to me to fix that too.
Closes: #4440
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4440
Pull-request-sha: 779ed75acb
Change-Id: Ic0553fe97853054b09c2453af76d96363de6eb0e
721 lines
23 KiB
Python
721 lines
23 KiB
Python
"""These tests are all about the "join rewriting" feature built
|
|
to support SQLite's lack of right-nested joins. SQLite as of
|
|
version 3.7.16 no longer has this limitation.
|
|
|
|
"""
|
|
from sqlalchemy import Column
|
|
from sqlalchemy import exists
|
|
from sqlalchemy import ForeignKey
|
|
from sqlalchemy import Integer
|
|
from sqlalchemy import MetaData
|
|
from sqlalchemy import select
|
|
from sqlalchemy import Table
|
|
from sqlalchemy import testing
|
|
from sqlalchemy import union
|
|
from sqlalchemy import util
|
|
from sqlalchemy.engine import default
|
|
from sqlalchemy.testing import AssertsCompiledSQL
|
|
from sqlalchemy.testing import fixtures
|
|
|
|
|
|
m = MetaData()
|
|
|
|
|
|
a = Table("a", m, Column("id", Integer, primary_key=True))
|
|
|
|
b = Table(
|
|
"b",
|
|
m,
|
|
Column("id", Integer, primary_key=True),
|
|
Column("a_id", Integer, ForeignKey("a.id")),
|
|
)
|
|
|
|
b_a = Table("b_a", m, Column("id", Integer, primary_key=True))
|
|
|
|
b1 = Table(
|
|
"b1",
|
|
m,
|
|
Column("id", Integer, primary_key=True),
|
|
Column("a_id", Integer, ForeignKey("a.id")),
|
|
)
|
|
|
|
b2 = Table(
|
|
"b2",
|
|
m,
|
|
Column("id", Integer, primary_key=True),
|
|
Column("a_id", Integer, ForeignKey("a.id")),
|
|
)
|
|
|
|
a_to_b = Table(
|
|
"a_to_b",
|
|
m,
|
|
Column("a_id", Integer, ForeignKey("a.id")),
|
|
Column("b_id", Integer, ForeignKey("b.id")),
|
|
)
|
|
|
|
c = Table(
|
|
"c",
|
|
m,
|
|
Column("id", Integer, primary_key=True),
|
|
Column("b_id", Integer, ForeignKey("b.id")),
|
|
)
|
|
|
|
d = Table(
|
|
"d",
|
|
m,
|
|
Column("id", Integer, primary_key=True),
|
|
Column("c_id", Integer, ForeignKey("c.id")),
|
|
)
|
|
|
|
e = Table("e", m, Column("id", Integer, primary_key=True))
|
|
|
|
f = Table(
|
|
"f",
|
|
m,
|
|
Column("id", Integer, primary_key=True),
|
|
Column("a_id", ForeignKey("a.id")),
|
|
)
|
|
|
|
b_key = Table("b_key", m, Column("id", Integer, primary_key=True, key="bid"))
|
|
|
|
a_to_b_key = Table(
|
|
"a_to_b_key",
|
|
m,
|
|
Column("aid", Integer, ForeignKey("a.id")),
|
|
Column("bid", Integer, ForeignKey("b_key.bid")),
|
|
)
|
|
|
|
|
|
class _JoinRewriteTestBase(AssertsCompiledSQL):
|
|
def _test(self, s, assert_):
|
|
self.assert_compile(s, assert_)
|
|
|
|
compiled = s.compile(dialect=self.__dialect__)
|
|
|
|
# column name should be in result map, as we never render
|
|
# .key in SQL
|
|
for key, col in zip([c.name for c in s.c], s.inner_columns):
|
|
key = key % compiled.anon_map
|
|
assert col in compiled._create_result_map()[key][1]
|
|
|
|
_a_bkeyselect_bkey = ""
|
|
|
|
def test_a_bkeyselect_bkey(self):
|
|
assoc = a_to_b_key.select().alias()
|
|
j1 = assoc.join(b_key)
|
|
j2 = a.join(j1)
|
|
|
|
s = select([a, b_key], use_labels=True).select_from(j2)
|
|
self._test(s, self._a_bkeyselect_bkey)
|
|
|
|
def test_a_bc(self):
|
|
j1 = b.join(c)
|
|
j2 = a.join(j1)
|
|
|
|
# TODO: if we remove 'b' or 'c', shouldn't we get just
|
|
# the subset of cols from anon_1 ?
|
|
|
|
# TODO: do this test also with individual cols, things change
|
|
# lots based on how you go with this
|
|
|
|
s = (
|
|
select([a, b, c], use_labels=True)
|
|
.select_from(j2)
|
|
.where(b.c.id == 2)
|
|
.where(c.c.id == 3)
|
|
.order_by(a.c.id, b.c.id, c.c.id)
|
|
)
|
|
|
|
self._test(s, self._a_bc)
|
|
|
|
def test_a_bkeyassoc(self):
|
|
j1 = b_key.join(a_to_b_key)
|
|
j2 = a.join(j1)
|
|
|
|
s = select([a, b_key.c.bid], use_labels=True).select_from(j2)
|
|
|
|
self._test(s, self._a_bkeyassoc)
|
|
|
|
def test_a_bkeyassoc_aliased(self):
|
|
bkey_alias = b_key.alias()
|
|
a_to_b_key_alias = a_to_b_key.alias()
|
|
|
|
j1 = bkey_alias.join(a_to_b_key_alias)
|
|
j2 = a.join(j1)
|
|
|
|
s = select([a, bkey_alias.c.bid], use_labels=True).select_from(j2)
|
|
|
|
self._test(s, self._a_bkeyassoc_aliased)
|
|
|
|
def test_a__b_dc(self):
|
|
j1 = c.join(d)
|
|
j2 = b.join(j1)
|
|
j3 = a.join(j2)
|
|
|
|
s = (
|
|
select([a, b, c, d], use_labels=True)
|
|
.select_from(j3)
|
|
.where(b.c.id == 2)
|
|
.where(c.c.id == 3)
|
|
.where(d.c.id == 4)
|
|
.order_by(a.c.id, b.c.id, c.c.id, d.c.id)
|
|
)
|
|
|
|
self._test(s, self._a__b_dc)
|
|
|
|
def test_a_bc_comma_a1_selbc(self):
|
|
# test here we're emulating is
|
|
# test.orm.inheritance.test_polymorphic_rel:
|
|
# PolymorphicJoinsTest.test_multi_join
|
|
j1 = b.join(c)
|
|
j2 = b.join(c).select(use_labels=True).alias()
|
|
j3 = a.join(j1)
|
|
a_a = a.alias()
|
|
j4 = a_a.join(j2)
|
|
|
|
s = (
|
|
select([a, a_a, b, c, j2], use_labels=True)
|
|
.select_from(j3)
|
|
.select_from(j4)
|
|
.order_by(j2.c.b_id)
|
|
)
|
|
|
|
self._test(s, self._a_bc_comma_a1_selbc)
|
|
|
|
def test_a_atobalias_balias_c_w_exists(self):
|
|
a_to_b_alias = a_to_b.alias()
|
|
b_alias = b.alias()
|
|
|
|
j1 = a_to_b_alias.join(b_alias)
|
|
j2 = a.outerjoin(j1, a.c.id == a_to_b_alias.c.a_id)
|
|
|
|
# TODO: if we put straight a_to_b_alias here,
|
|
# it fails to alias the columns clause.
|
|
s = select(
|
|
[
|
|
a,
|
|
a_to_b_alias.c.a_id,
|
|
a_to_b_alias.c.b_id,
|
|
b_alias.c.id,
|
|
b_alias.c.a_id,
|
|
exists()
|
|
.select_from(c)
|
|
.where(c.c.b_id == b_alias.c.id)
|
|
.label(None),
|
|
],
|
|
use_labels=True,
|
|
).select_from(j2)
|
|
|
|
self._test(s, self._a_atobalias_balias_c_w_exists)
|
|
|
|
def test_a_atobalias_balias(self):
|
|
a_to_b_alias = a_to_b.alias()
|
|
b_alias = b.alias()
|
|
|
|
j1 = a_to_b_alias.join(b_alias)
|
|
j2 = a.outerjoin(j1, a.c.id == a_to_b_alias.c.a_id)
|
|
|
|
s = select([a, a_to_b_alias, b_alias], use_labels=True).select_from(j2)
|
|
|
|
self._test(s, self._a_atobalias_balias)
|
|
|
|
def test_b_ab1_union_b_ab2(self):
|
|
j1 = a.join(b1)
|
|
j2 = a.join(b2)
|
|
|
|
b_j1 = b.join(j1)
|
|
b_j2 = b.join(j2)
|
|
|
|
s = union(
|
|
select([b_j1], use_labels=True), select([b_j2], use_labels=True)
|
|
).select(use_labels=True)
|
|
|
|
self._test(s, self._b_ab1_union_c_ab2)
|
|
|
|
def test_b_a_id_double_overlap_annotated(self):
|
|
# test issue #3057
|
|
# this involves annotations so try to loop those in.
|
|
j1 = b.join(b_a, b.c.id == b_a.c.id)
|
|
annot = [
|
|
b.c.id._annotate({}),
|
|
b.c.a_id._annotate({}),
|
|
b_a.c.id._annotate({}),
|
|
]
|
|
|
|
s = select(annot).select_from(j1).apply_labels().alias()
|
|
|
|
s = select(list(s.c)).apply_labels()
|
|
|
|
self._test(s, self._b_a_id_double_overlap_annotated)
|
|
|
|
def test_f_b1a_where_in_b2a(self):
|
|
# test issue #3130
|
|
b1a = a.join(b1)
|
|
b2a = a.join(b2)
|
|
subq = select([b2.c.id]).select_from(b2a)
|
|
s = select([f]).select_from(f.join(b1a)).where(b1.c.id.in_(subq))
|
|
|
|
s = s.apply_labels()
|
|
self._test(s, self._f_b1a_where_in_b2a)
|
|
|
|
def test_anon_scalar_subqueries(self):
|
|
s1 = select([1]).as_scalar()
|
|
s2 = select([2]).as_scalar()
|
|
|
|
s = select([s1, s2]).apply_labels()
|
|
self._test(s, self._anon_scalar_subqueries)
|
|
|
|
|
|
class JoinRewriteTest(_JoinRewriteTestBase, fixtures.TestBase):
|
|
|
|
"""test rendering of each join with right-nested rewritten as
|
|
aliased SELECT statements.."""
|
|
|
|
@util.classproperty
|
|
def __dialect__(cls):
|
|
dialect = default.DefaultDialect()
|
|
dialect.supports_right_nested_joins = False
|
|
return dialect
|
|
|
|
_a__b_dc = (
|
|
"SELECT a.id AS a_id, anon_1.b_id AS b_id, "
|
|
"anon_1.b_a_id AS b_a_id, anon_1.c_id AS c_id, "
|
|
"anon_1.c_b_id AS c_b_id, anon_1.d_id AS d_id, "
|
|
"anon_1.d_c_id AS d_c_id "
|
|
"FROM a JOIN (SELECT b.id AS b_id, b.a_id AS b_a_id, "
|
|
"anon_2.c_id AS c_id, anon_2.c_b_id AS c_b_id, "
|
|
"anon_2.d_id AS d_id, anon_2.d_c_id AS d_c_id "
|
|
"FROM b JOIN (SELECT c.id AS c_id, c.b_id AS c_b_id, "
|
|
"d.id AS d_id, d.c_id AS d_c_id "
|
|
"FROM c JOIN d ON c.id = d.c_id) AS anon_2 "
|
|
"ON b.id = anon_2.c_b_id) AS anon_1 ON a.id = anon_1.b_a_id "
|
|
"WHERE anon_1.b_id = :id_1 AND anon_1.c_id = :id_2 AND "
|
|
"anon_1.d_id = :id_3 "
|
|
"ORDER BY a.id, anon_1.b_id, anon_1.c_id, anon_1.d_id"
|
|
)
|
|
|
|
_a_bc = (
|
|
"SELECT a.id AS a_id, anon_1.b_id AS b_id, "
|
|
"anon_1.b_a_id AS b_a_id, anon_1.c_id AS c_id, "
|
|
"anon_1.c_b_id AS c_b_id FROM a JOIN "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, "
|
|
"c.id AS c_id, c.b_id AS c_b_id "
|
|
"FROM b JOIN c ON b.id = c.b_id) AS anon_1 "
|
|
"ON a.id = anon_1.b_a_id "
|
|
"WHERE anon_1.b_id = :id_1 AND anon_1.c_id = :id_2 "
|
|
"ORDER BY a.id, anon_1.b_id, anon_1.c_id"
|
|
)
|
|
|
|
_a_bc_comma_a1_selbc = (
|
|
"SELECT a.id AS a_id, a_1.id AS a_1_id, anon_1.b_id AS b_id, "
|
|
"anon_1.b_a_id AS b_a_id, anon_1.c_id AS c_id, "
|
|
"anon_1.c_b_id AS c_b_id, anon_2.b_id AS anon_2_b_id, "
|
|
"anon_2.b_a_id AS anon_2_b_a_id, anon_2.c_id AS anon_2_c_id, "
|
|
"anon_2.c_b_id AS anon_2_c_b_id FROM a "
|
|
"JOIN (SELECT b.id AS b_id, b.a_id AS b_a_id, c.id AS c_id, "
|
|
"c.b_id AS c_b_id FROM b JOIN c ON b.id = c.b_id) AS anon_1 "
|
|
"ON a.id = anon_1.b_a_id, "
|
|
"a AS a_1 JOIN "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, "
|
|
"c.id AS c_id, c.b_id AS c_b_id "
|
|
"FROM b JOIN c ON b.id = c.b_id) AS anon_2 "
|
|
"ON a_1.id = anon_2.b_a_id ORDER BY anon_2.b_id"
|
|
)
|
|
|
|
_a_bkeyassoc = (
|
|
"SELECT a.id AS a_id, anon_1.b_key_id AS b_key_id "
|
|
"FROM a JOIN "
|
|
"(SELECT b_key.id AS b_key_id, a_to_b_key.aid AS a_to_b_key_aid, "
|
|
"a_to_b_key.bid AS a_to_b_key_bid FROM b_key "
|
|
"JOIN a_to_b_key ON b_key.id = a_to_b_key.bid) AS anon_1 "
|
|
"ON a.id = anon_1.a_to_b_key_aid"
|
|
)
|
|
|
|
_a_bkeyassoc_aliased = (
|
|
"SELECT a.id AS a_id, anon_1.b_key_1_id AS b_key_1_id "
|
|
"FROM a JOIN (SELECT b_key_1.id AS b_key_1_id, "
|
|
"a_to_b_key_1.aid AS a_to_b_key_1_aid, "
|
|
"a_to_b_key_1.bid AS a_to_b_key_1_bid FROM b_key AS b_key_1 "
|
|
"JOIN a_to_b_key AS a_to_b_key_1 ON b_key_1.id = a_to_b_key_1.bid) AS "
|
|
"anon_1 ON a.id = anon_1.a_to_b_key_1_aid"
|
|
)
|
|
|
|
_a_bkeyselect_bkey = (
|
|
"SELECT a.id AS a_id, anon_2.anon_1_aid AS anon_1_aid, "
|
|
"anon_2.anon_1_bid AS anon_1_bid, anon_2.b_key_id AS b_key_id "
|
|
"FROM a JOIN (SELECT anon_1.aid AS anon_1_aid, "
|
|
"anon_1.bid AS anon_1_bid, "
|
|
"b_key.id AS b_key_id "
|
|
"FROM (SELECT a_to_b_key.aid AS aid, a_to_b_key.bid AS bid "
|
|
"FROM a_to_b_key) AS anon_1 "
|
|
"JOIN b_key ON b_key.id = anon_1.bid) AS anon_2 "
|
|
"ON a.id = anon_2.anon_1_aid"
|
|
)
|
|
|
|
_a_atobalias_balias_c_w_exists = (
|
|
"SELECT a.id AS a_id, "
|
|
"anon_1.a_to_b_1_a_id AS a_to_b_1_a_id, "
|
|
"anon_1.a_to_b_1_b_id AS a_to_b_1_b_id, "
|
|
"anon_1.b_1_id AS b_1_id, anon_1.b_1_a_id AS b_1_a_id, "
|
|
"EXISTS (SELECT * FROM c WHERE c.b_id = anon_1.b_1_id) AS anon_2 "
|
|
"FROM a LEFT OUTER JOIN (SELECT a_to_b_1.a_id AS a_to_b_1_a_id, "
|
|
"a_to_b_1.b_id AS a_to_b_1_b_id, b_1.id AS b_1_id, "
|
|
"b_1.a_id AS b_1_a_id "
|
|
"FROM a_to_b AS a_to_b_1 "
|
|
"JOIN b AS b_1 ON b_1.id = a_to_b_1.b_id) AS anon_1 "
|
|
"ON a.id = anon_1.a_to_b_1_a_id"
|
|
)
|
|
|
|
_a_atobalias_balias = (
|
|
"SELECT a.id AS a_id, anon_1.a_to_b_1_a_id AS a_to_b_1_a_id, "
|
|
"anon_1.a_to_b_1_b_id AS a_to_b_1_b_id, anon_1.b_1_id AS b_1_id, "
|
|
"anon_1.b_1_a_id AS b_1_a_id FROM a LEFT OUTER JOIN "
|
|
"(SELECT a_to_b_1.a_id AS a_to_b_1_a_id, "
|
|
"a_to_b_1.b_id AS a_to_b_1_b_id, "
|
|
"b_1.id AS b_1_id, b_1.a_id AS b_1_a_id FROM a_to_b AS a_to_b_1 "
|
|
"JOIN b AS b_1 ON b_1.id = a_to_b_1.b_id) AS anon_1 "
|
|
"ON a.id = anon_1.a_to_b_1_a_id"
|
|
)
|
|
|
|
_b_ab1_union_c_ab2 = (
|
|
"SELECT b_id AS b_id, b_a_id AS b_a_id, a_id AS a_id, b1_id AS b1_id, "
|
|
"b1_a_id AS b1_a_id FROM "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, anon_1.a_id AS a_id, "
|
|
"anon_1.b1_id AS b1_id, anon_1.b1_a_id AS b1_a_id "
|
|
"FROM b JOIN (SELECT a.id AS a_id, b1.id AS b1_id, b1.a_id AS b1_a_id "
|
|
"FROM a JOIN b1 ON a.id = b1.a_id) AS anon_1 ON anon_1.a_id = b.a_id "
|
|
"UNION "
|
|
"SELECT b.id AS b_id, b.a_id AS b_a_id, anon_2.a_id AS a_id, "
|
|
"anon_2.b2_id AS b2_id, anon_2.b2_a_id AS b2_a_id "
|
|
"FROM b JOIN (SELECT a.id AS a_id, b2.id AS b2_id, b2.a_id AS b2_a_id "
|
|
"FROM a JOIN b2 ON a.id = b2.a_id) AS anon_2 ON anon_2.a_id = b.a_id)"
|
|
)
|
|
|
|
_b_a_id_double_overlap_annotated = (
|
|
"SELECT anon_1.b_id AS anon_1_b_id, anon_1.b_a_id AS anon_1_b_a_id, "
|
|
"anon_1.id_1 AS anon_1_id_1 "
|
|
"FROM (SELECT b.id AS b_id, b.a_id AS b_a_id, b_a.id AS id_1 "
|
|
"FROM b JOIN b_a ON b.id = b_a.id) AS anon_1"
|
|
)
|
|
|
|
_f_b1a_where_in_b2a = (
|
|
"SELECT f.id AS f_id, f.a_id AS f_a_id "
|
|
"FROM f JOIN (SELECT a.id AS a_id, b1.id AS b1_id, b1.a_id AS b1_a_id "
|
|
"FROM a JOIN b1 ON a.id = b1.a_id) AS anon_1 ON anon_1.a_id = f.a_id "
|
|
"WHERE anon_1.b1_id IN (SELECT b2.id "
|
|
"FROM a JOIN b2 ON a.id = b2.a_id)"
|
|
)
|
|
|
|
_anon_scalar_subqueries = (
|
|
"SELECT (SELECT 1) AS anon_1, (SELECT 2) AS anon_2"
|
|
)
|
|
|
|
|
|
class JoinPlainTest(_JoinRewriteTestBase, fixtures.TestBase):
|
|
|
|
"""test rendering of each join with normal nesting."""
|
|
|
|
@util.classproperty
|
|
def __dialect__(cls):
|
|
dialect = default.DefaultDialect()
|
|
return dialect
|
|
|
|
_a_bkeyselect_bkey = (
|
|
"SELECT a.id AS a_id, b_key.id AS b_key_id FROM a JOIN "
|
|
"((SELECT a_to_b_key.aid AS aid, a_to_b_key.bid AS bid "
|
|
"FROM a_to_b_key) AS anon_1 JOIN b_key ON b_key.id = anon_1.bid) "
|
|
"ON a.id = anon_1.aid"
|
|
)
|
|
_a__b_dc = (
|
|
"SELECT a.id AS a_id, b.id AS b_id, "
|
|
"b.a_id AS b_a_id, c.id AS c_id, "
|
|
"c.b_id AS c_b_id, d.id AS d_id, "
|
|
"d.c_id AS d_c_id "
|
|
"FROM a JOIN (b JOIN (c JOIN d ON c.id = d.c_id) "
|
|
"ON b.id = c.b_id) ON a.id = b.a_id "
|
|
"WHERE b.id = :id_1 AND c.id = :id_2 AND "
|
|
"d.id = :id_3 "
|
|
"ORDER BY a.id, b.id, c.id, d.id"
|
|
)
|
|
|
|
_a_bc = (
|
|
"SELECT a.id AS a_id, b.id AS b_id, "
|
|
"b.a_id AS b_a_id, c.id AS c_id, "
|
|
"c.b_id AS c_b_id FROM a JOIN "
|
|
"(b JOIN c ON b.id = c.b_id) "
|
|
"ON a.id = b.a_id "
|
|
"WHERE b.id = :id_1 AND c.id = :id_2 "
|
|
"ORDER BY a.id, b.id, c.id"
|
|
)
|
|
|
|
_a_bc_comma_a1_selbc = (
|
|
"SELECT a.id AS a_id, a_1.id AS a_1_id, b.id AS b_id, "
|
|
"b.a_id AS b_a_id, c.id AS c_id, "
|
|
"c.b_id AS c_b_id, anon_1.b_id AS anon_1_b_id, "
|
|
"anon_1.b_a_id AS anon_1_b_a_id, anon_1.c_id AS anon_1_c_id, "
|
|
"anon_1.c_b_id AS anon_1_c_b_id FROM a "
|
|
"JOIN (b JOIN c ON b.id = c.b_id) "
|
|
"ON a.id = b.a_id, "
|
|
"a AS a_1 JOIN "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, "
|
|
"c.id AS c_id, c.b_id AS c_b_id "
|
|
"FROM b JOIN c ON b.id = c.b_id) AS anon_1 "
|
|
"ON a_1.id = anon_1.b_a_id ORDER BY anon_1.b_id"
|
|
)
|
|
|
|
_a_bkeyassoc = (
|
|
"SELECT a.id AS a_id, b_key.id AS b_key_id "
|
|
"FROM a JOIN "
|
|
"(b_key JOIN a_to_b_key ON b_key.id = a_to_b_key.bid) "
|
|
"ON a.id = a_to_b_key.aid"
|
|
)
|
|
|
|
_a_bkeyassoc_aliased = (
|
|
"SELECT a.id AS a_id, b_key_1.id AS b_key_1_id FROM a "
|
|
"JOIN (b_key AS b_key_1 JOIN a_to_b_key AS a_to_b_key_1 "
|
|
"ON b_key_1.id = a_to_b_key_1.bid) ON a.id = a_to_b_key_1.aid"
|
|
)
|
|
|
|
_a_atobalias_balias_c_w_exists = (
|
|
"SELECT a.id AS a_id, a_to_b_1.a_id AS a_to_b_1_a_id, "
|
|
"a_to_b_1.b_id AS a_to_b_1_b_id, b_1.id AS b_1_id, "
|
|
"b_1.a_id AS b_1_a_id, "
|
|
"EXISTS (SELECT * FROM c WHERE c.b_id = b_1.id) AS anon_1 "
|
|
"FROM a LEFT OUTER JOIN "
|
|
"(a_to_b AS a_to_b_1 JOIN b AS b_1 ON b_1.id = a_to_b_1.b_id) "
|
|
"ON a.id = a_to_b_1.a_id"
|
|
)
|
|
|
|
_a_atobalias_balias = (
|
|
"SELECT a.id AS a_id, a_to_b_1.a_id AS a_to_b_1_a_id, "
|
|
"a_to_b_1.b_id AS a_to_b_1_b_id, b_1.id AS b_1_id, "
|
|
"b_1.a_id AS b_1_a_id "
|
|
"FROM a LEFT OUTER JOIN (a_to_b AS a_to_b_1 "
|
|
"JOIN b AS b_1 ON b_1.id = a_to_b_1.b_id) ON a.id = a_to_b_1.a_id"
|
|
)
|
|
|
|
_b_ab1_union_c_ab2 = (
|
|
"SELECT b_id AS b_id, b_a_id AS b_a_id, a_id AS a_id, b1_id AS b1_id, "
|
|
"b1_a_id AS b1_a_id FROM "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, a.id AS a_id, "
|
|
"b1.id AS b1_id, "
|
|
"b1.a_id AS b1_a_id FROM b "
|
|
"JOIN (a JOIN b1 ON a.id = b1.a_id) ON a.id = b.a_id "
|
|
"UNION "
|
|
"SELECT b.id AS b_id, b.a_id AS b_a_id, a.id AS a_id, b2.id AS b2_id, "
|
|
"b2.a_id AS b2_a_id FROM b "
|
|
"JOIN (a JOIN b2 ON a.id = b2.a_id) ON a.id = b.a_id)"
|
|
)
|
|
|
|
_b_a_id_double_overlap_annotated = (
|
|
"SELECT anon_1.b_id AS anon_1_b_id, anon_1.b_a_id AS anon_1_b_a_id, "
|
|
"anon_1.id_1 AS anon_1_id_1 FROM "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, b_a.id AS id_1 "
|
|
"FROM b JOIN b_a ON b.id = b_a.id) AS anon_1"
|
|
)
|
|
|
|
_f_b1a_where_in_b2a = (
|
|
"SELECT f.id AS f_id, f.a_id AS f_a_id "
|
|
"FROM f JOIN (a JOIN b1 ON a.id = b1.a_id) ON a.id = f.a_id "
|
|
"WHERE b1.id IN (SELECT b2.id "
|
|
"FROM a JOIN b2 ON a.id = b2.a_id)"
|
|
)
|
|
|
|
_anon_scalar_subqueries = (
|
|
"SELECT (SELECT 1) AS anon_1, (SELECT 2) AS anon_2"
|
|
)
|
|
|
|
|
|
class JoinNoUseLabelsTest(_JoinRewriteTestBase, fixtures.TestBase):
|
|
@util.classproperty
|
|
def __dialect__(cls):
|
|
dialect = default.DefaultDialect()
|
|
dialect.supports_right_nested_joins = False
|
|
return dialect
|
|
|
|
def _test(self, s, assert_):
|
|
s.use_labels = False
|
|
self.assert_compile(s, assert_)
|
|
|
|
_a_bkeyselect_bkey = (
|
|
"SELECT a.id, b_key.id FROM a JOIN ((SELECT a_to_b_key.aid AS aid, "
|
|
"a_to_b_key.bid AS bid FROM a_to_b_key) AS anon_1 "
|
|
"JOIN b_key ON b_key.id = anon_1.bid) ON a.id = anon_1.aid"
|
|
)
|
|
|
|
_a__b_dc = (
|
|
"SELECT a.id, b.id, "
|
|
"b.a_id, c.id, "
|
|
"c.b_id, d.id, "
|
|
"d.c_id "
|
|
"FROM a JOIN (b JOIN (c JOIN d ON c.id = d.c_id) "
|
|
"ON b.id = c.b_id) ON a.id = b.a_id "
|
|
"WHERE b.id = :id_1 AND c.id = :id_2 AND "
|
|
"d.id = :id_3 "
|
|
"ORDER BY a.id, b.id, c.id, d.id"
|
|
)
|
|
|
|
_a_bc = (
|
|
"SELECT a.id, b.id, "
|
|
"b.a_id, c.id, "
|
|
"c.b_id FROM a JOIN "
|
|
"(b JOIN c ON b.id = c.b_id) "
|
|
"ON a.id = b.a_id "
|
|
"WHERE b.id = :id_1 AND c.id = :id_2 "
|
|
"ORDER BY a.id, b.id, c.id"
|
|
)
|
|
|
|
_a_bc_comma_a1_selbc = (
|
|
"SELECT a.id, a_1.id, b.id, "
|
|
"b.a_id, c.id, "
|
|
"c.b_id, anon_1.b_id, "
|
|
"anon_1.b_a_id, anon_1.c_id, "
|
|
"anon_1.c_b_id FROM a "
|
|
"JOIN (b JOIN c ON b.id = c.b_id) "
|
|
"ON a.id = b.a_id, "
|
|
"a AS a_1 JOIN "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, "
|
|
"c.id AS c_id, c.b_id AS c_b_id "
|
|
"FROM b JOIN c ON b.id = c.b_id) AS anon_1 "
|
|
"ON a_1.id = anon_1.b_a_id ORDER BY anon_1.b_id"
|
|
)
|
|
|
|
_a_bkeyassoc = (
|
|
"SELECT a.id, b_key.id FROM a JOIN (b_key JOIN a_to_b_key "
|
|
"ON b_key.id = a_to_b_key.bid) ON a.id = a_to_b_key.aid"
|
|
)
|
|
|
|
_a_bkeyassoc_aliased = (
|
|
"SELECT a.id, b_key_1.id FROM a JOIN (b_key AS b_key_1 "
|
|
"JOIN a_to_b_key AS a_to_b_key_1 ON b_key_1.id = a_to_b_key_1.bid) "
|
|
"ON a.id = a_to_b_key_1.aid"
|
|
)
|
|
|
|
_a_atobalias_balias_c_w_exists = (
|
|
"SELECT a.id, a_to_b_1.a_id, a_to_b_1.b_id, b_1.id, b_1.a_id, "
|
|
"EXISTS (SELECT * FROM c WHERE c.b_id = b_1.id) AS anon_1 "
|
|
"FROM a LEFT OUTER JOIN "
|
|
"(a_to_b AS a_to_b_1 JOIN b AS b_1 ON b_1.id = a_to_b_1.b_id) "
|
|
"ON a.id = a_to_b_1.a_id"
|
|
)
|
|
|
|
_a_atobalias_balias = (
|
|
"SELECT a.id, a_to_b_1.a_id, a_to_b_1.b_id, b_1.id, b_1.a_id "
|
|
"FROM a LEFT OUTER JOIN (a_to_b AS a_to_b_1 "
|
|
"JOIN b AS b_1 ON b_1.id = a_to_b_1.b_id) ON a.id = a_to_b_1.a_id"
|
|
)
|
|
|
|
_b_ab1_union_c_ab2 = (
|
|
"SELECT b_id, b_a_id, a_id, b1_id, b1_a_id "
|
|
"FROM (SELECT b.id AS b_id, b.a_id AS b_a_id, a.id AS a_id, "
|
|
"b1.id AS b1_id, b1.a_id AS b1_a_id "
|
|
"FROM b JOIN (a JOIN b1 ON a.id = b1.a_id) ON a.id = b.a_id "
|
|
"UNION "
|
|
"SELECT b.id AS b_id, b.a_id AS b_a_id, a.id AS a_id, b2.id AS b2_id, "
|
|
"b2.a_id AS b2_a_id "
|
|
"FROM b JOIN (a JOIN b2 ON a.id = b2.a_id) ON a.id = b.a_id)"
|
|
)
|
|
|
|
_b_a_id_double_overlap_annotated = (
|
|
"SELECT anon_1.b_id, anon_1.b_a_id, anon_1.id_1 FROM "
|
|
"(SELECT b.id AS b_id, b.a_id AS b_a_id, b_a.id AS id_1 "
|
|
"FROM b JOIN b_a ON b.id = b_a.id) AS anon_1"
|
|
)
|
|
|
|
_f_b1a_where_in_b2a = (
|
|
"SELECT f.id, f.a_id "
|
|
"FROM f JOIN (a JOIN b1 ON a.id = b1.a_id) ON a.id = f.a_id "
|
|
"WHERE b1.id IN (SELECT b2.id "
|
|
"FROM a JOIN b2 ON a.id = b2.a_id)"
|
|
)
|
|
|
|
_anon_scalar_subqueries = (
|
|
"SELECT (SELECT 1) AS anon_1, (SELECT 2) AS anon_2"
|
|
)
|
|
|
|
|
|
class JoinExecTest(_JoinRewriteTestBase, fixtures.TestBase):
|
|
|
|
"""invoke the SQL on the current backend to ensure compatibility"""
|
|
|
|
__backend__ = True
|
|
|
|
_a_bc = (
|
|
_a_bc_comma_a1_selbc
|
|
) = (
|
|
_a__b_dc
|
|
) = (
|
|
_a_bkeyassoc
|
|
) = (
|
|
_a_bkeyassoc_aliased
|
|
) = (
|
|
_a_atobalias_balias_c_w_exists
|
|
) = (
|
|
_a_atobalias_balias
|
|
) = (
|
|
_b_ab1_union_c_ab2
|
|
) = (
|
|
_b_a_id_double_overlap_annotated
|
|
) = _f_b1a_where_in_b2a = _anon_scalar_subqueries = None
|
|
|
|
@classmethod
|
|
def setup_class(cls):
|
|
m.create_all(testing.db)
|
|
|
|
@classmethod
|
|
def teardown_class(cls):
|
|
m.drop_all(testing.db)
|
|
|
|
def _test(self, selectable, assert_):
|
|
result = testing.db.execute(selectable)
|
|
result.close()
|
|
for col in selectable.inner_columns:
|
|
assert col in result._metadata._keymap
|
|
|
|
@testing.skip_if("oracle", "oracle's cranky")
|
|
@testing.skip_if(
|
|
"mssql", "can't query EXISTS in the columns " "clause w/o subquery"
|
|
)
|
|
def test_a_atobalias_balias_c_w_exists(self):
|
|
super(JoinExecTest, self).test_a_atobalias_balias_c_w_exists()
|
|
|
|
@testing.only_on(
|
|
"sqlite",
|
|
"non-standard aliasing rules used at the moment, "
|
|
"possibly fix this or add another test that uses "
|
|
"cross-compatible aliasing",
|
|
)
|
|
def test_b_ab1_union_b_ab2(self):
|
|
super(JoinExecTest, self).test_b_ab1_union_b_ab2()
|
|
|
|
|
|
class DialectFlagTest(fixtures.TestBase, AssertsCompiledSQL):
|
|
def test_dialect_flag(self):
|
|
d1 = default.DefaultDialect(supports_right_nested_joins=True)
|
|
d2 = default.DefaultDialect(supports_right_nested_joins=False)
|
|
|
|
j1 = b.join(c)
|
|
j2 = a.join(j1)
|
|
|
|
s = select([a, b, c], use_labels=True).select_from(j2)
|
|
|
|
self.assert_compile(
|
|
s,
|
|
"SELECT a.id AS a_id, b.id AS b_id, b.a_id AS b_a_id, "
|
|
"c.id AS c_id, "
|
|
"c.b_id AS c_b_id FROM a JOIN (b JOIN c ON b.id = c.b_id) "
|
|
"ON a.id = b.a_id",
|
|
dialect=d1,
|
|
)
|
|
self.assert_compile(
|
|
s,
|
|
"SELECT a.id AS a_id, anon_1.b_id AS b_id, "
|
|
"anon_1.b_a_id AS b_a_id, "
|
|
"anon_1.c_id AS c_id, anon_1.c_b_id AS c_b_id "
|
|
"FROM a JOIN (SELECT b.id AS b_id, b.a_id AS b_a_id, "
|
|
"c.id AS c_id, "
|
|
"c.b_id AS c_b_id FROM b JOIN c ON b.id = c.b_id) AS anon_1 "
|
|
"ON a.id = anon_1.b_a_id",
|
|
dialect=d2,
|
|
)
|