From 57868f587ee9f1e35661e8dfadc0b73740300da6 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 12 Mar 2012 13:35:27 -0700 Subject: [PATCH] - [bug] Fixed bug whereby a primaryjoin condition with a "literal" in it would raise an error on compile with certain kinds of deeply nested expressions which also needed to render the same bound parameter name more than once. [ticket:2425] --- CHANGES | 8 ++++++++ lib/sqlalchemy/sql/compiler.py | 3 ++- test/sql/test_selectable.py | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 3936964c4c..6c94f3161c 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,14 @@ CHANGES after the event was associated with the Session class. [ticket:2424] + - [bug] Fixed bug whereby a primaryjoin + condition with a "literal" in it would + raise an error on compile with certain + kinds of deeply nested expressions + which also needed to render the same + bound parameter name more than once. + [ticket:2425] + - [feature] Added "no_autoflush" context manager to Session, used with with: will temporarily disable autoflush. diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index e8f86634d2..6f010ed54c 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -655,7 +655,8 @@ class SQLCompiler(engine.Compiled): if name in self.binds: existing = self.binds[name] if existing is not bindparam: - if existing.unique or bindparam.unique: + if (existing.unique or bindparam.unique) and \ + not existing.proxy_set.intersection(bindparam.proxy_set): raise exc.CompileError( "Bind parameter '%s' conflicts with " "unique bind parameter of the same name" % diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py index 8f599f1d6d..9048192152 100644 --- a/test/sql/test_selectable.py +++ b/test/sql/test_selectable.py @@ -1134,3 +1134,13 @@ class AnnotationsTest(fixtures.TestBase): assert b4.left is bin.left # since column is immutable assert b4.right is not bin.right is not b2.right is not b3.right + def test_bind_unique_test(self): + t1 = table('t', column('a'), column('b')) + + b = bindparam("bind", value="x", unique=True) + + # the annotation of "b" should render the + # same. The "unique" test in compiler should + # also pass, [ticket:2425] + eq_(str(or_(b, b._annotate({"foo":"bar"}))), + ":bind_1 OR :bind_1") -- 2.47.2