From: Eric Atkin Date: Mon, 24 Jun 2024 23:53:11 +0000 (-0600) Subject: Allow flat for join with name (Fixes: #5262) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f85535464be7b04d5f9745848d28f87dcd248b86;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Allow flat for join with name (Fixes: #5262) --- diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index a9ef7fd030..753d61bf85 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -1521,11 +1521,17 @@ class Join(roles.DMLTableRole, FromClause): ) -> TODO_Any: sqlutil = util.preloaded.sql_util if flat: - if name is not None: - raise exc.ArgumentError("Can't send name argument with flat") + if isinstance(self.left, (FromGrouping, Join)): + left_name = name # will recurse + else: + left_name = name and '{}_{}'.format(name, self.left.name) + if isinstance(self.right, (FromGrouping, Join)): + right_name = name # will recurse + else: + right_name = name and '{}_{}'.format(name, self.right.name) left_a, right_a = ( - self.left._anonymous_fromclause(flat=True), - self.right._anonymous_fromclause(flat=True), + self.left._anonymous_fromclause(name=left_name, flat=flat), + self.right._anonymous_fromclause(name=right_name, flat=flat), ) adapter = sqlutil.ClauseAdapter(left_a).chain( sqlutil.ClauseAdapter(right_a) diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py index 0c0c23b870..c4f5c4d83a 100644 --- a/test/sql/test_selectable.py +++ b/test/sql/test_selectable.py @@ -2045,6 +2045,14 @@ class JoinAnonymizingTest(fixtures.TestBase, AssertsCompiledSQL): "a AS a_1 JOIN b AS b_1 ON a_1.a = b_1.b", ) + def test_join_alias_name_flat(self): + a = table("a", column("a")) + b = table("b", column("b")) + self.assert_compile( + a.join(b, a.c.a == b.c.b)._anonymous_fromclause(name='foo', flat=True), + "a AS foo_a JOIN b AS foo_b ON foo_a.a = foo_b.b", + ) + def test_composed_join_alias_flat(self): a = table("a", column("a")) b = table("b", column("b")) @@ -2063,6 +2071,22 @@ class JoinAnonymizingTest(fixtures.TestBase, AssertsCompiledSQL): "ON b_1.b = c_1.c", ) + def test_composed_join_alias_name_flat(self): + a = table("a", column("a")) + b = table("b", column("b")) + c = table("c", column("c")) + d = table("d", column("d")) + + j1 = a.join(b, a.c.a == b.c.b) + j2 = c.join(d, c.c.c == d.c.d) + + self.assert_compile( + j1.join(j2, b.c.b == c.c.c)._anonymous_fromclause(name='foo', flat=True), + "a AS foo_a JOIN b AS foo_b ON foo_a.a = foo_b.b JOIN " + "(c AS foo_c JOIN d AS foo_d ON foo_c.c = foo_d.d) " + "ON foo_b.b = foo_c.c", + ) + def test_composed_join_alias(self): a = table("a", column("a")) b = table("b", column("b"))