- orm
- Fixed bug introduced in 0.5.4 whereby Composite types
fail when default-holding columns are flushed.
+
+- sql
+ - Removed an obscure feature of execute() (including connection,
+ engine, Session) whereby a bindparam() construct can be sent as
+ a key to the params dictionary. This usage is undocumented
+ and is at the core of an issue whereby the bindparam() object
+ created implicitly by a text() construct may have the same
+ hash value as a string placed in the params dictionary and
+ may result in an inappropriate match when computing the final
+ bind parameters. Internal checks for this condition would
+ add significant latency to the critical task of parameter
+ rendering, so the behavior is removed. This is a backwards
+ incompatible change for any application that may have been
+ using this feature, however the feature has never been
+ documented.
0.5.4p2
=======
params = util.column_dict(params)
pd = {}
for bindparam, name in self.bind_names.iteritems():
- for paramname in (bindparam, bindparam.key, bindparam.shortname, name):
+ for paramname in (bindparam.key, bindparam.shortname, name):
if paramname in params:
pd[name] = params[paramname]
break
if bindparams is not None:
for b in bindparams:
self.bindparams[b.key] = b
-
+
@property
def type(self):
if self.typemap is not None and len(self.typemap) == 1:
r = s.execute(userid='fred').fetchall()
assert len(r) == 1
- u = bindparam('userid', unique=True)
- 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"""
-
- users.insert().execute(user_id = 7, user_name = 'jack')
- users.insert().execute(user_id = 8, user_name = 'fred')
-
- u = bindparam('userid')
- r = users.select(users.c.user_name==u).execute({u:'fred'}).fetchall()
- assert len(r) == 1
-
def test_bindparam_shortname(self):
"""test the 'shortname' field on BindParamClause."""
users.insert().execute(user_id = 7, user_name = 'jack')
s = select([table1], or_(table1.c.myid==7, table1.c.myid==8, table1.c.myid==bindparam('myid_1')))
self.assertRaisesMessage(exc.CompileError, "conflicts with unique bind parameter of the same name", str, s)
-
+ def test_binds_no_hash_collision(self):
+ """test that construct_params doesn't corrupt dict due to hash collisions"""
+
+ total_params = 100000
+
+ in_clause = [':in%d' % i for i in range(total_params)]
+ params = dict(('in%d' % i, i) for i in range(total_params))
+ sql = 'text clause %s' % ', '.join(in_clause)
+ t = text(sql)
+ assert len(t.bindparams) == total_params
+ c = t.compile()
+ pp = c.construct_params(params)
+ assert len(set(pp)) == total_params
+ assert len(set(pp.values())) == total_params
+
def test_bind_as_col(self):
t = table('foo', column('id'))