diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-03-05 21:52:03 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-03-06 11:15:38 -0500 |
commit | f62e0c0c7fc4be842a0f4dc4f59019b3c6285fee (patch) | |
tree | 73c3523c6d4191cfedc1c20130847f9751b43ebd /lib/sqlalchemy/sql/compiler.py | |
parent | 1f3ef9817453faa021544841d10b5b7107b57916 (diff) | |
download | sqlalchemy-f62e0c0c7fc4be842a0f4dc4f59019b3c6285fee.tar.gz |
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 <col>" 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
Diffstat (limited to 'lib/sqlalchemy/sql/compiler.py')
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 40 |
1 files changed, 10 insertions, 30 deletions
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 @@ -406,35 +406,6 @@ class Compiled(object): """ - _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 _gen_time = 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") |