]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- for TextAsFrom, put the "inner" columns in the result map directly.
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 11 Feb 2014 00:17:00 +0000 (19:17 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 11 Feb 2014 00:17:00 +0000 (19:17 -0500)
Have also considered linking column.label() to the "column" itself being
in the result map but this reveals some naming collision problems (that
also seem to be very poorly tested...).   This should be as far as
we want to go right now with [ticket:2932].

lib/sqlalchemy/sql/compiler.py
test/sql/test_selectable.py
test/sql/test_text.py

index d4b080720d5056141c30610a6ae8569729640b8c..d597837bd5614751d7a8d42ac6c79597874fc9ff 100644 (file)
@@ -616,10 +616,9 @@ class SQLCompiler(Compiled):
                                     )
 
         if populate_result_map:
-            for c in taf.c:
-                self._add_to_result_map(
-                        c.key, c.key, (c,), c.type
-                )
+            for c in taf.column_args:
+                self.process(c, within_columns_clause=True,
+                                add_to_result_map=self._add_to_result_map)
 
         text = self.process(taf.element, **kw)
         if asfrom and parens:
index 3c29d9784e5ed432a39b76bf712cabaa5f747b7a..dbd73a83672f102a69f7144da3ee4e7e113da843 100644 (file)
@@ -1927,6 +1927,75 @@ class WithLabelsTest(fixtures.TestBase):
         )
         self._assert_result_keys(sel, ['t1_a', 't2_b'])
 
+class SelectProxyTest(fixtures.TestBase):
+    def _fixture(self):
+        m = MetaData()
+        t = Table('t', m, Column('x', Integer), Column('y', Integer))
+        return t
+
+    def _mapping(self, stmt):
+        compiled = stmt.compile()
+        return dict(
+                    (elem, key)
+                    for key, elements in compiled.result_map.items()
+                    for elem in elements[1]
+                )
+
+    def test_select_label_alt_name(self):
+        t = self._fixture()
+        l1, l2 = t.c.x.label('a'), t.c.y.label('b')
+        s = select([l1, l2])
+        mapping = self._mapping(s)
+        assert l1 in mapping
+
+        assert t.c.x not in mapping
+
+    def test_select_alias_label_alt_name(self):
+        t = self._fixture()
+        l1, l2 = t.c.x.label('a'), t.c.y.label('b')
+        s = select([l1, l2]).alias()
+        mapping = self._mapping(s)
+        assert l1 in mapping
+
+        assert t.c.x not in mapping
+
+    def test_select_alias_column(self):
+        t = self._fixture()
+        x, y = t.c.x, t.c.y
+        s = select([x, y]).alias()
+        mapping = self._mapping(s)
+
+        assert t.c.x in mapping
+
+    def test_select_alias_column_apply_labels(self):
+        t = self._fixture()
+        x, y = t.c.x, t.c.y
+        s = select([x, y]).apply_labels().alias()
+        mapping = self._mapping(s)
+        assert t.c.x in mapping
+
+    def test_select_table_alias_column(self):
+        t = self._fixture()
+        x, y = t.c.x, t.c.y
+
+        ta = t.alias()
+        s = select([ta.c.x, ta.c.y])
+        mapping = self._mapping(s)
+        assert x not in mapping
+
+    def test_select_label_alt_name_table_alias_column(self):
+        t = self._fixture()
+        x, y = t.c.x, t.c.y
+
+        ta = t.alias()
+        l1, l2 = ta.c.x.label('a'), ta.c.y.label('b')
+
+        s = select([l1, l2])
+        mapping = self._mapping(s)
+        assert x not in mapping
+        assert l1 in mapping
+        assert ta.c.x not in mapping
+
 class ForUpdateTest(fixtures.TestBase, AssertsCompiledSQL):
     __dialect__ = "default"
 
index 37346437ec3ecb3709e7cd331f25c26015d0e038..57dadfb160e278d0b6aac19cdf2d6c346c4036c5 100644 (file)
@@ -2,7 +2,7 @@
 
 from sqlalchemy.testing import fixtures, AssertsCompiledSQL, eq_, assert_raises_message
 from sqlalchemy import text, select, Integer, String, Float, \
-            bindparam, and_, func, literal_column, exc
+            bindparam, and_, func, literal_column, exc, MetaData, Table, Column
 from sqlalchemy.types import NullType
 from sqlalchemy.sql import table, column
 
@@ -291,8 +291,8 @@ class AsFromTest(fixtures.TestBase, AssertsCompiledSQL):
         eq_(
             compiled.result_map,
             {
-                'id': ('id', (t.c.id,), t.c.id.type),
-                'name': ('name', (t.c.name,), t.c.name.type)
+                'id': ('id', (t.c.id._proxies[0], 'id', 'id'), t.c.id.type),
+                'name': ('name', (t.c.name._proxies[0], 'name', 'name'), t.c.name.type)
             }
         )
 
@@ -303,8 +303,8 @@ class AsFromTest(fixtures.TestBase, AssertsCompiledSQL):
         eq_(
             compiled.result_map,
             {
-                'id': ('id', (t.c.id,), t.c.id.type),
-                'name': ('name', (t.c.name,), t.c.name.type)
+                'id': ('id', (t.c.id._proxies[0], 'id', 'id'), t.c.id.type),
+                'name': ('name', (t.c.name._proxies[0], 'name', 'name'), t.c.name.type)
             }
         )
 
@@ -322,6 +322,73 @@ class AsFromTest(fixtures.TestBase, AssertsCompiledSQL):
             }
         )
 
+    def _xy_table_fixture(self):
+        m = MetaData()
+        t = Table('t', m, Column('x', Integer), Column('y', Integer))
+        return t
+
+    def _mapping(self, stmt):
+        compiled = stmt.compile()
+        return dict(
+                    (elem, key)
+                    for key, elements in compiled.result_map.items()
+                    for elem in elements[1]
+                )
+
+    def test_select_label_alt_name(self):
+        t = self._xy_table_fixture()
+        l1, l2 = t.c.x.label('a'), t.c.y.label('b')
+        s = text("select x AS a, y AS b FROM t").columns(l1, l2)
+        mapping = self._mapping(s)
+        assert l1 in mapping
+
+        assert t.c.x not in mapping
+
+    def test_select_alias_label_alt_name(self):
+        t = self._xy_table_fixture()
+        l1, l2 = t.c.x.label('a'), t.c.y.label('b')
+        s = text("select x AS a, y AS b FROM t").columns(l1, l2).alias()
+        mapping = self._mapping(s)
+        assert l1 in mapping
+
+        assert t.c.x not in mapping
+
+    def test_select_column(self):
+        t = self._xy_table_fixture()
+        x, y = t.c.x, t.c.y
+        s = text("select x, y FROM t").columns(x, y)
+        mapping = self._mapping(s)
+        assert t.c.x in mapping
+
+    def test_select_alias_column(self):
+        t = self._xy_table_fixture()
+        x, y = t.c.x, t.c.y
+        s = text("select x, y FROM t").columns(x, y).alias()
+        mapping = self._mapping(s)
+        assert t.c.x in mapping
+
+    def test_select_table_alias_column(self):
+        t = self._xy_table_fixture()
+        x, y = t.c.x, t.c.y
+
+        ta = t.alias()
+        s = text("select ta.x, ta.y FROM t AS ta").columns(ta.c.x, ta.c.y)
+        mapping = self._mapping(s)
+        assert x not in mapping
+
+    def test_select_label_alt_name_table_alias_column(self):
+        t = self._xy_table_fixture()
+        x, y = t.c.x, t.c.y
+
+        ta = t.alias()
+        l1, l2 = ta.c.x.label('a'), ta.c.y.label('b')
+
+        s = text("SELECT ta.x AS a, ta.y AS b FROM t AS ta").columns(l1, l2)
+        mapping = self._mapping(s)
+        assert x not in mapping
+        assert l1 in mapping
+        assert ta.c.x not in mapping
+
     def test_cte(self):
         t = text("select id, name from user").columns(id=Integer, name=String).cte('t')