summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/compiler.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-03-05 21:52:03 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2021-03-06 11:15:38 -0500
commitf62e0c0c7fc4be842a0f4dc4f59019b3c6285fee (patch)
tree73c3523c6d4191cfedc1c20130847f9751b43ebd /lib/sqlalchemy/sql/compiler.py
parent1f3ef9817453faa021544841d10b5b7107b57916 (diff)
downloadsqlalchemy-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.py40
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")