]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Correctly apply self_group in type_coerce element.
authorFederico Caselli <cfederico87@gmail.com>
Fri, 22 May 2020 21:56:50 +0000 (23:56 +0200)
committerFederico Caselli <cfederico87@gmail.com>
Fri, 22 May 2020 21:56:50 +0000 (23:56 +0200)
The type coerce element did not correctly apply grouping rules when using
in an expression

Fixes: #5344
Change-Id: Id67b0e60ac54f8992f931aaed62731672f60c96c

doc/build/changelog/unreleased_13/5344.rst [new file with mode: 0644]
lib/sqlalchemy/sql/elements.py
test/sql/test_selectable.py

diff --git a/doc/build/changelog/unreleased_13/5344.rst b/doc/build/changelog/unreleased_13/5344.rst
new file mode 100644 (file)
index 0000000..d2e598c
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, sql
+    :tickets: 5344
+
+    Correctly apply self_group in type_coerce element.
+
+    The type coerce element did not correctly apply grouping rules when using
+    in an expression
\ No newline at end of file
index 43115f117ef013231b259b89d1f5896738cabd78..7310edd3f4bf64a480ca77490b214f2288528078 100644 (file)
@@ -2823,14 +2823,11 @@ class TypeCoerce(WrapsColumnExpression, ColumnElement):
         renders SQL that labels the expression, but otherwise does not
         modify its value on the SQL side::
 
-            SELECT date_string AS anon_1 FROM log
+            SELECT date_string AS date_string FROM log
 
-        When result rows are fetched, the ``StringDateTime`` type
+        When result rows are fetched, the ``StringDateTime`` type processor
         will be applied to result rows on behalf of the ``date_string`` column.
-        The rationale for the "anon_1" label is so that the type-coerced
-        column remains separate in the list of result columns vs. other
-        type-coerced or direct values of the target column.  In order to
-        provide a named label for the expression, use
+        In order to provide a named label for the expression, use
         :meth:`_expression.ColumnElement.label`::
 
             stmt = select([
@@ -2893,6 +2890,13 @@ class TypeCoerce(WrapsColumnExpression, ColumnElement):
     def wrapped_column_expression(self):
         return self.clause
 
+    def self_group(self, against=None):
+        grouped = self.clause.self_group(against=against)
+        if grouped is not self.clause:
+            return TypeCoerce(grouped, self.type)
+        else:
+            return self
+
 
 class Extract(ColumnElement):
     """Represent a SQL EXTRACT clause, ``extract(field FROM expr)``."""
index 8fb1f29510e4be9aeecc3156e1e8763fa3dfa9b9..e509c9f95ec8207c129397eec989f13a3ca12fc8 100644 (file)
@@ -439,6 +439,13 @@ class SelectableTest(
         assert isinstance(stmt2.selected_columns.foo.type, MyType)
         assert isinstance(subq2.c.foo.type, MyType)
 
+    def test_type_coerce_selfgroup(self):
+        no_group = column("a") / type_coerce(column("x"), Integer)
+        group = column("b") / type_coerce(column("y") * column("w"), Integer)
+
+        self.assert_compile(no_group, "a / x")
+        self.assert_compile(group, "b / (y * w)")
+
     def test_subquery_on_table(self):
         sel = select([table1, table2], use_labels=True).subquery()