]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
fix to unique bind params, you *can* use the same unique bindparam multiple times
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 7 Dec 2007 16:47:00 +0000 (16:47 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 7 Dec 2007 16:47:00 +0000 (16:47 +0000)
in a statement.  the collision check is strictly detecting non-unique's that happen to have
the same name.

lib/sqlalchemy/sql/compiler.py
test/sql/query.py
test/sql/select.py

index aec75e76c3d4eddad945d4e2f885ebe2515aef44..6795c2fcd6efffaf81e10a0a8f67473d04d16dc3 100644 (file)
@@ -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)
index 6233de7436b11f1d4dff648ef67ff4fa8e4c1fa1..f675c9114c5d2f11607f0f3b1c5bf5467ad21a1d 100644 (file)
@@ -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"""
index d36703af437fa106ce53d820a29fa50520942eb4..66a87d6a04ea196025e06bb8ed44729d2661daee 100644 (file)
@@ -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: