diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-09-02 14:11:38 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-09-04 10:50:16 -0400 |
commit | 95870c9569053e935ffe92e34af4aeb4bfd978a3 (patch) | |
tree | 8e71bb961b90957fda63f6a0f77125643546c8c2 /lib/sqlalchemy/orm/context.py | |
parent | d640192877e4d1da75e8dea34d2374c404e80538 (diff) | |
download | sqlalchemy-95870c9569053e935ffe92e34af4aeb4bfd978a3.tar.gz |
turn off deduping for col expressions
Fixed ORM issue where column expressions passed to ``query()`` or
ORM-enabled ``select()`` would be deduplicated on the identity of the
object, such as a phrase like ``select(A.id, null(), null())`` would
produce only one "NULL" expression, which previously was not the case in
1.3. However, the change also allows for ORM expressions to render as given
as well, such as ``select(A.data, A.data)`` will produce a result row with
two columns.
Fixes: #6979
Change-Id: I4dd59d4c7b1baa711b686379eb959f87c44841c4
Diffstat (limited to 'lib/sqlalchemy/orm/context.py')
-rw-r--r-- | lib/sqlalchemy/orm/context.py | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py index 9318bb163..85c736e12 100644 --- a/lib/sqlalchemy/orm/context.py +++ b/lib/sqlalchemy/orm/context.py @@ -187,6 +187,12 @@ class ORMCompileState(CompileState): def __init__(self, *arg, **kw): raise NotImplementedError() + def _append_dedupe_col_collection(self, obj, col_collection): + dedupe = self.dedupe_columns + if obj not in dedupe: + dedupe.add(obj) + col_collection.append(obj) + @classmethod def _column_naming_convention(cls, label_style, legacy): @@ -443,6 +449,7 @@ class ORMFromStatementCompileState(ORMCompileState): self.primary_columns = [] self.secondary_columns = [] + self.dedupe_columns = set() self.create_eager_joins = [] self._fallback_from_clauses = [] @@ -645,6 +652,7 @@ class ORMSelectCompileState(ORMCompileState, SelectState): self.primary_columns = [] self.secondary_columns = [] + self.dedupe_columns = set() self.eager_joins = {} self.extra_criteria_entities = {} self.create_eager_joins = [] @@ -765,8 +773,6 @@ class ORMSelectCompileState(ORMCompileState, SelectState): # PART II - self.dedupe_cols = True - self._for_update_arg = query._for_update_arg for entity in self._entities: @@ -1036,9 +1042,8 @@ class ORMSelectCompileState(ORMCompileState, SelectState): # put FOR UPDATE on the inner query, where MySQL will honor it, # as well as if it has an OF so PostgreSQL can use it. inner = self._select_statement( - util.unique_list(self.primary_columns + order_by_col_expr) - if self.dedupe_cols - else (self.primary_columns + order_by_col_expr), + self.primary_columns + + [c for c in order_by_col_expr if c not in self.dedupe_columns], self.from_clauses, self._where_criteria, self._having_criteria, @@ -1116,9 +1121,7 @@ class ORMSelectCompileState(ORMCompileState, SelectState): self.primary_columns += to_add statement = self._select_statement( - util.unique_list(self.primary_columns + self.secondary_columns) - if self.dedupe_cols - else (self.primary_columns + self.secondary_columns), + self.primary_columns + self.secondary_columns, tuple(self.from_clauses) + tuple(self.eager_joins.values()), self._where_criteria, self._having_criteria, @@ -2822,6 +2825,7 @@ class _RawColumnEntity(_ColumnEntity): # result due to the __eq__() method, so use deannotated column = column._deannotate() + compile_state.dedupe_columns.add(column) compile_state.primary_columns.append(column) self._fetch_column = column @@ -2949,6 +2953,7 @@ class _ORMColumnEntity(_ColumnEntity): ): compile_state._fallback_from_clauses.append(ezero.selectable) + compile_state.dedupe_columns.add(column) compile_state.primary_columns.append(column) self._fetch_column = column |