]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed a bug where clause adaption as applied to a :class:`.Label`
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 10 Jun 2015 03:39:14 +0000 (23:39 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 10 Jun 2015 03:39:14 +0000 (23:39 -0400)
object would fail to accommodate the labeled SQL expression
in all cases, such that any SQL operation that made use of
:meth:`.Label.self_group` would use the original unadapted
expression.  One effect of this would be that an ORM :func:`.aliased`
construct would not fully accommodate attributes mapped by
:obj:`.column_property`, such that the un-aliased table could
leak out when the property were used in some kinds of SQL
comparisons.
fixes #3445

doc/build/changelog/changelog_10.rst
lib/sqlalchemy/sql/elements.py
test/sql/test_generative.py

index 8521a6cd23e1b71a4efd7f3a006e8ede1bb03d4f..3436a0ca6a57ac6947c1464642f39c1b8360d712 100644 (file)
 .. changelog::
     :version: 1.0.6
 
+    .. change::
+        :tags: bug, sql
+        :tickets: 3445
+
+        Fixed a bug where clause adaption as applied to a :class:`.Label`
+        object would fail to accommodate the labeled SQL expression
+        in all cases, such that any SQL operation that made use of
+        :meth:`.Label.self_group` would use the original unadapted
+        expression.  One effect of this would be that an ORM :func:`.aliased`
+        construct would not fully accommodate attributes mapped by
+        :obj:`.column_property`, such that the un-aliased table could
+        leak out when the property were used in some kinds of SQL
+        comparisons.
+
     .. change::
         :tags: bug, documentation
         :tickets: 2077
index a178ed99a133023b3c8103d64fc9e81298aab91e..27ecce2b0b39bd44297463180586057890367b94 100644 (file)
@@ -3103,7 +3103,8 @@ class Label(ColumnElement):
         return self.element,
 
     def _copy_internals(self, clone=_clone, anonymize_labels=False, **kw):
-        self.element = clone(self.element, **kw)
+        self._element = clone(self._element, **kw)
+        self.__dict__.pop('element', None)
         self.__dict__.pop('_allow_label_resolve', None)
         if anonymize_labels:
             self.name = self._resolve_label = _anonymous_label(
index 12bfdfa9d33ffe20b0967bd12194a5c80f757d3b..9cf1ef6124d2f51a6e89a554059a0fe1919d5a8c 100644 (file)
@@ -454,6 +454,27 @@ class ClauseTest(fixtures.TestBase, AssertsCompiledSQL):
             str(f1), str(f2)
         )
 
+    def test_labeled_expression_adapt(self):
+        lbl_x = (t3.c.col1 == 1).label('x')
+        t3_alias = t3.alias()
+
+        adapter = sql_util.ColumnAdapter(t3_alias)
+
+        lblx_adapted = adapter.traverse(lbl_x)
+        is_not_(lblx_adapted._element, lbl_x._element)
+
+        lblx_adapted = adapter.traverse(lbl_x)
+        self.assert_compile(
+            select([lblx_adapted.self_group()]),
+            "SELECT (table3_1.col1 = :col1_1) AS x FROM table3 AS table3_1"
+        )
+
+        self.assert_compile(
+            select([lblx_adapted.is_(True)]),
+            "SELECT (table3_1.col1 = :col1_1) IS 1 AS anon_1 "
+            "FROM table3 AS table3_1"
+        )
+
     def test_text(self):
         clause = text(
             "select * from table where foo=:bar",