From: Mike Bayer Date: Fri, 7 Dec 2007 16:47:00 +0000 (+0000) Subject: fix to unique bind params, you *can* use the same unique bindparam multiple times X-Git-Tag: rel_0_4_2~96 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7bf90e2f4dc211423a409a747a2392922ed7a9c7;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git fix to unique bind params, you *can* use the same unique bindparam multiple times in a statement. the collision check is strictly detecting non-unique's that happen to have the same name. --- diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index aec75e76c3..6795c2fcd6 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -376,7 +376,7 @@ class DefaultCompiler(engine.Compiled): name = self._truncate_bindparam(bindparam) if name in self.binds: existing = self.binds[name] - if existing.unique or bindparam.unique: + if existing is not bindparam and (existing.unique or bindparam.unique): raise exceptions.CompileError("Bind parameter '%s' conflicts with unique bind parameter of the same name" % bindparam.key) self.binds[bindparam.key] = self.binds[name] = bindparam return self.bindparam_string(name) diff --git a/test/sql/query.py b/test/sql/query.py index 6233de7436..f675c9114c 100644 --- a/test/sql/query.py +++ b/test/sql/query.py @@ -170,18 +170,14 @@ class QueryTest(PersistTest): users.insert().execute(user_id = 8, user_name = 'fred') u = bindparam('userid') - s = users.select(or_(users.c.user_name==u, users.c.user_name==u)) + s = users.select(and_(users.c.user_name==u, users.c.user_name==u)) r = s.execute(userid='fred').fetchall() assert len(r) == 1 - def test_unique_conflict(self): u = bindparam('userid', unique=True) - s = users.select(or_(users.c.user_name==u, users.c.user_name==u)) - try: - str(s) - assert False - except exceptions.CompileError, e: - assert str(e) == "Bind parameter '{ANON %d userid}' conflicts with unique bind parameter of the same name" % id(u) + s = users.select(and_(users.c.user_name==u, users.c.user_name==u)) + r = s.execute({u:'fred'}).fetchall() + assert len(r) == 1 def test_bindparams_in_params(self): """test that a _BindParamClause itself can be a key in the params dict""" diff --git a/test/sql/select.py b/test/sql/select.py index d36703af43..66a87d6a04 100644 --- a/test/sql/select.py +++ b/test/sql/select.py @@ -968,7 +968,15 @@ EXISTS (select yay from foo where boo = lar)", assert s2.compile().params == {'myid':8, 'myotherid':7} assert s3.compile().params == {'myid':9, 'myotherid':7} - + # test using same 'unique' param object twice in one compile + s = select([table1.c.myid]).where(table1.c.myid==12).as_scalar() + s2 = select([table1, s], table1.c.myid==s) + self.assert_compile(s2, + "SELECT mytable.myid, mytable.name, mytable.description, (SELECT mytable.myid FROM mytable WHERE mytable.myid = :mytable_myid_2) AS anon_1 FROM mytable WHERE mytable.myid = (SELECT mytable.myid FROM mytable WHERE mytable.myid = :mytable_myid_2)") + positional = s2.compile(dialect=sqlite.dialect()) + pp = positional.get_params() + assert [pp[k] for k in positional.positiontup] == [12, 12] + # check that conflicts with "unique" params are caught s = select([table1], or_(table1.c.myid==7, table1.c.myid==bindparam('mytable_myid_1'))) try: