From c9af2ebf5e5d288aea3a3a26bdf950e08ac4f927 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 19 Sep 2022 09:40:40 -0400 Subject: break out text() from TextualSelect for col matching Fixed issue where mixing "*" with additional explicitly-named column expressions within the columns clause of a :func:`_sql.select` construct would cause result-column targeting to sometimes consider the label name or other non-repeated names to be an ambiguous target. Fixes: #8536 Change-Id: I3c845eaf571033e54c9208762344f67f4351ac3a --- lib/sqlalchemy/engine/cursor.py | 16 +++++++++++++--- lib/sqlalchemy/engine/default.py | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'lib/sqlalchemy/engine') diff --git a/lib/sqlalchemy/engine/cursor.py b/lib/sqlalchemy/engine/cursor.py index 0204fbbbb..8840b5916 100644 --- a/lib/sqlalchemy/engine/cursor.py +++ b/lib/sqlalchemy/engine/cursor.py @@ -237,6 +237,7 @@ class CursorResultMetaData(ResultMetaData): result_columns, cols_are_ordered, textual_ordered, + ad_hoc_textual, loose_column_name_matching, ) = context.result_column_struct num_ctx_cols = len(result_columns) @@ -245,6 +246,8 @@ class CursorResultMetaData(ResultMetaData): cols_are_ordered ) = ( num_ctx_cols + ) = ( + ad_hoc_textual ) = loose_column_name_matching = textual_ordered = False # merge cursor.description with the column info @@ -256,6 +259,7 @@ class CursorResultMetaData(ResultMetaData): num_ctx_cols, cols_are_ordered, textual_ordered, + ad_hoc_textual, loose_column_name_matching, ) @@ -282,8 +286,11 @@ class CursorResultMetaData(ResultMetaData): } if len(by_key) != num_ctx_cols: - # if by-primary-string dictionary smaller (or bigger?!) than - # number of columns, assume we have dupes, rewrite + # if by-primary-string dictionary smaller than + # number of columns, assume we have dupes; (this check + # is also in place if string dictionary is bigger, as + # can occur when '*' was used as one of the compiled columns, + # which may or may not be suggestive of dupes), rewrite # dupe records with "None" for index which results in # ambiguous column exception when accessed. # @@ -368,6 +375,7 @@ class CursorResultMetaData(ResultMetaData): num_ctx_cols, cols_are_ordered, textual_ordered, + ad_hoc_textual, loose_column_name_matching, ): """Merge a cursor.description with compiled result column information. @@ -461,7 +469,9 @@ class CursorResultMetaData(ResultMetaData): # name-based or text-positional cases, where we need # to read cursor.description names - if textual_ordered: + if textual_ordered or ( + ad_hoc_textual and len(cursor_description) == num_ctx_cols + ): self._safe_for_cache = True # textual positional case raw_iterator = self._merge_textual_cols_by_position( diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 9ad0ebbfc..3a53f8157 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -939,7 +939,7 @@ class DefaultExecutionContext(ExecutionContext): executemany = False compiled: Optional[Compiled] = None result_column_struct: Optional[ - Tuple[List[ResultColumnsEntry], bool, bool, bool] + Tuple[List[ResultColumnsEntry], bool, bool, bool, bool] ] = None returned_default_rows: Optional[Sequence[Row[Any]]] = None @@ -1057,6 +1057,7 @@ class DefaultExecutionContext(ExecutionContext): compiled._result_columns, compiled._ordered_columns, compiled._textual_ordered_columns, + compiled._ad_hoc_textual, compiled._loose_column_name_matching, ) -- cgit v1.2.1