summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-10-20 17:12:58 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-10-20 17:12:58 +0000
commit404f43894a63cea858189240c4027a7451b87bf2 (patch)
tree9d8bfbcbcf78d4e53c01383784a4f0e0df1f3615
parent7b457b973102c8fe7c3105d5984f48a3265a5168 (diff)
downloadsqlalchemy-404f43894a63cea858189240c4027a7451b87bf2.tar.gz
merge r6418 from 0.5, dedupe expressions on clause ident, not string value
[ticket:1574]
-rw-r--r--CHANGES7
-rw-r--r--lib/sqlalchemy/sql/compiler.py6
-rw-r--r--test/sql/test_select.py43
3 files changed, 53 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index 850dcf8db..f83ea987a 100644
--- 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.
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index f07e6aca8..4c3130879 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -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:
diff --git a/test/sql/test_select.py b/test/sql/test_select.py
index 757dc5213..3dc09c9df 100644
--- a/test/sql/test_select.py
+++ b/test/sql/test_select.py
@@ -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