]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Allow flat for join with name (Fixes: #5262) 11531/head
authorEric Atkin <eatkin@certusllc.us>
Mon, 24 Jun 2024 23:53:11 +0000 (17:53 -0600)
committerEric Atkin <eatkin@certusllc.us>
Wed, 3 Jul 2024 20:00:29 +0000 (14:00 -0600)
lib/sqlalchemy/sql/selectable.py
test/sql/test_selectable.py

index a9ef7fd0301b71ca29345bcc779b66144dc20825..753d61bf853372c8abeb8229a1e1d30c7bcdeb59 100644 (file)
@@ -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)
index 0c0c23b870056747a9b6f977b897f8059ff504a0..c4f5c4d83a8c5c19d757e2ac2a39e4a0fa47094a 100644 (file)
@@ -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"))