From: Mike Bayer Date: Wed, 28 Apr 2021 18:11:20 +0000 (-0400) Subject: ensure SelectState.all_selected_columns not memoized as a generator X-Git-Tag: rel_1_4_12~12^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=029c68e636b8c635ffd35b7a38947be2e3b6e0cf;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git ensure SelectState.all_selected_columns not memoized as a generator This regression was found from #6261 before release of 1.4.12 Fixes: #6261 Fixes: #6394 Change-Id: I4c2c5da02dbcf5c2cea26c81d3521de892ef428e --- diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index f3c5008521..ff830dbf6c 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -5706,7 +5706,7 @@ class Select( @HasMemoized.memoized_attribute def _all_selected_columns(self): meth = SelectState.get_plugin_class(self).all_selected_columns - return meth(self) + return list(meth(self)) def _exported_columns_iterator(self): meth = SelectState.get_plugin_class(self).exported_columns_iterator @@ -5727,7 +5727,6 @@ class Select( """ cols = self._all_selected_columns - # when use_labels is on: # in all cases == if we see the same label name, use _label_anon_label # for subsequent occurrences of that label diff --git a/test/orm/test_core_compilation.py b/test/orm/test_core_compilation.py index c313843e90..7a7b8aa673 100644 --- a/test/orm/test_core_compilation.py +++ b/test/orm/test_core_compilation.py @@ -50,6 +50,29 @@ class SelectableTest(QueryTest, AssertsCompiledSQL): "WHERE users.name = :name_1", ) + def test_c_accessor_not_mutated_subq(self): + """test #6394, ensure all_selected_columns is generated each time""" + User = self.classes.User + + s1 = select(User.id) + + eq_(s1.subquery().c.keys(), ["id"]) + eq_(s1.subquery().c.keys(), ["id"]) + + def test_scalar_subquery_from_subq_same_source(self): + """test #6394, ensure all_selected_columns is generated each time""" + User = self.classes.User + + s1 = select(User.id) + + for i in range(2): + stmt = s1.subquery().select().scalar_subquery() + self.assert_compile( + stmt, + "(SELECT anon_1.id FROM " + "(SELECT users.id AS id FROM users) AS anon_1)", + ) + def test_froms_single_table(self): User, Address = self.classes("User", "Address") diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py index 2403db7c95..b54ef02fd9 100644 --- a/test/sql/test_selectable.py +++ b/test/sql/test_selectable.py @@ -590,6 +590,17 @@ class SelectableTest( "table1.col3, table1.colx FROM table1) AS anon_1", ) + def test_scalar_subquery_from_subq_same_source(self): + s1 = select(table1.c.col1) + + for i in range(2): + stmt = s1.subquery().select().scalar_subquery() + self.assert_compile( + stmt, + "(SELECT anon_1.col1 FROM " + "(SELECT table1.col1 AS col1 FROM table1) AS anon_1)", + ) + def test_type_coerce_preserve_subq(self): class MyType(TypeDecorator): impl = Integer