]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
merge r6418 from 0.5, dedupe expressions on clause ident, not string value
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 20 Oct 2009 17:12:58 +0000 (17:12 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 20 Oct 2009 17:12:58 +0000 (17:12 +0000)
[ticket:1574]

CHANGES
lib/sqlalchemy/sql/compiler.py
test/sql/test_select.py

diff --git a/CHANGES b/CHANGES
index 850dcf8dbdf02f02a4eff72a6f8bcba725d04359..f83ea987a705222fbb705b36f0b194ab76b6fed8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -584,6 +584,13 @@ CHANGES
     - Fixed the "numeric" paramstyle, which apparently is the
       default paramstyle used by Informixdb.
       
+    - Repeat expressions in the columns clause of a select
+      are deduped based on the identity of each clause element,
+      not the actual string.  This allows positional 
+      elements to render correctly even if they all render
+      identically, such as "qmark" style bind parameters.
+      [ticket:1574]
+      
 - postgresql
     - Added support for reflecting the DOUBLE PRECISION type,
       via a new postgres.PGDoublePrecision object.  
index f07e6aca8cb8a558ca7049c1ec2acb76412b0db2..4c31308796e27512c7c473fb80712e0dffcd5d1f 100644 (file)
@@ -584,16 +584,16 @@ class SQLCompiler(engine.Compiled):
             column_clause_args = {}
 
         # the actual list of columns to print in the SELECT column list.
-        inner_columns = util.unique_list(
+        inner_columns = [
             c for c in [
                 self.process(
                     self.label_select_column(select, co, asfrom=asfrom), 
                     within_columns_clause=True,
                     **column_clause_args) 
-                for co in select.inner_columns
+                for co in util.unique_list(select.inner_columns)
             ]
             if c is not None
-        )
+        ]
         
         text = "SELECT "  # we're off to a good start !
         if select._prefixes:
index 757dc521367b66b0dbeaba3a06c687c93b9641f0..3dc09c9dfc1bb33e5c6c8ba265d5e41f79978a2d 100644 (file)
@@ -182,6 +182,49 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A
             , dialect=default.DefaultDialect(paramstyle='pyformat')
         )
         
+    def test_dupe_columns(self):
+        """test that deduping is performed against clause element identity, not rendered result."""
+        
+        self.assert_compile(
+            select([column('a'), column('a'), column('a')]),
+            "SELECT a, a, a"
+            , dialect=default.DefaultDialect()
+        )
+
+        c = column('a')
+        self.assert_compile(
+            select([c, c, c]),
+            "SELECT a"
+            , dialect=default.DefaultDialect()
+        )
+
+        a, b = column('a'), column('b')
+        self.assert_compile(
+            select([a, b, b, b, a, a]),
+            "SELECT a, b"
+            , dialect=default.DefaultDialect()
+        )
+        
+        self.assert_compile(
+            select([bindparam('a'), bindparam('b'), bindparam('c')]),
+            "SELECT :a, :b, :c"
+            , dialect=default.DefaultDialect(paramstyle='named')
+        )
+
+        self.assert_compile(
+            select([bindparam('a'), bindparam('b'), bindparam('c')]),
+            "SELECT ?, ?, ?"
+            , dialect=default.DefaultDialect(paramstyle='qmark'),
+        )
+
+        self.assert_compile(
+            select(["a", "a", "a"]),
+            "SELECT a, a, a"
+        )
+        
+        s = select([bindparam('a'), bindparam('b'), bindparam('c')])
+        s = s.compile(dialect=default.DefaultDialect(paramstyle='qmark'))
+        eq_(s.positiontup, ['a', 'b', 'c'])
         
     def test_nested_uselabels(self):
         """test nested anonymous label generation.  this