From f62e0c0c7fc4be842a0f4dc4f59019b3c6285fee Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 5 Mar 2021 21:52:03 -0500 Subject: improve targeting and labeling for unary() in columns clause Fixed regression where usage of the standalone :func:`_sql.distinct()` used in the form of being directly SELECTed would fail to be locatable in the result set by column identity, which is how the ORM locates columns. While standalone :func:`_sql.distinct()` is not oriented towards being directly SELECTed (use :meth:`_sql.select.distinct` for a regular ``SELECT DISTINCT..``) , it was usable to a limited extent in this way previously (but wouldn't work in subqueries, for example). The column targeting for unary expressions such as "DISTINCT " has been improved so that this case works again, and an additional improvement has been made so that usage of this form in a subquery at least generates valid SQL which was not the case previously. The change additionally enhances the ability to target elements in ``row._mapping`` based on SQL expression objects in ORM-enabled SELECT statements, including whether the statement was invoked by ``connection.execute()`` or ``session.execute()``. Fixes: #6008 Change-Id: I5cfa39435f5418861d70a7db8f52ab4ced6a792e --- lib/sqlalchemy/sql/compiler.py | 40 ++++++++++------------------------------ 1 file changed, 10 insertions(+), 30 deletions(-) (limited to 'lib/sqlalchemy/sql') diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index c6fa6072e..f635c1ee4 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -404,35 +404,6 @@ class Compiled(object): .. versionadded:: 1.4 - """ - - _rewrites_selected_columns = False - """if True, indicates the compile_state object rewrites an incoming - ReturnsRows (like a Select) so that the columns we compile against in the - result set are not what were expressed on the outside. this is a hint to - the execution context to not link the statement.selected_columns to the - columns mapped in the result object. - - That is, when this flag is False:: - - stmt = some_statement() - - result = conn.execute(stmt) - row = result.first() - - # selected_columns are in a 1-1 relationship with the - # columns in the result, and are targetable in mapping - for col in stmt.selected_columns: - assert col in row._mapping - - When True:: - - # selected columns are not what are in the rows. the context - # rewrote the statement for some other set of selected_columns. - for col in stmt.selected_columns: - assert col not in row._mapping - - """ cache_key = None @@ -1858,7 +1829,15 @@ class SQLCompiler(Compiled): ) return getattr(self, attrname, None) - def visit_unary(self, unary, **kw): + def visit_unary( + self, unary, add_to_result_map=None, result_map_targets=(), **kw + ): + + if add_to_result_map is not None: + result_map_targets += (unary,) + kw["add_to_result_map"] = add_to_result_map + kw["result_map_targets"] = result_map_targets + if unary.operator: if unary.modifier: raise exc.CompileError( @@ -2870,6 +2849,7 @@ class SQLCompiler(Compiled): and ( not isinstance(column, elements.UnaryExpression) or column.wraps_column_expression + or asfrom ) and ( not hasattr(column, "name") -- cgit v1.2.1