summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ansisql.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-03-28 01:39:58 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-03-28 01:39:58 +0000
commitccbcbda43e74a1d09d50aa2f8212b3cb9adafd23 (patch)
tree5ecf17fa8dd62f9b9d1495e25273b770d3ad07fb /lib/sqlalchemy/ansisql.py
parentd7c0daf1ec7918a8d5635696a067f035bda61fd6 (diff)
downloadsqlalchemy-ccbcbda43e74a1d09d50aa2f8212b3cb9adafd23.tar.gz
added label truncation for bind param names which was lost in the previous related commit.
added more tests plus test for column targeting with text() clause.
Diffstat (limited to 'lib/sqlalchemy/ansisql.py')
-rw-r--r--lib/sqlalchemy/ansisql.py36
1 files changed, 27 insertions, 9 deletions
diff --git a/lib/sqlalchemy/ansisql.py b/lib/sqlalchemy/ansisql.py
index 37b6366a9..050e605eb 100644
--- a/lib/sqlalchemy/ansisql.py
+++ b/lib/sqlalchemy/ansisql.py
@@ -99,6 +99,10 @@ class ANSICompiler(sql.Compiled):
# a dictionary of bind parameter keys to _BindParamClause instances.
self.binds = {}
+
+ # a dictionary of _BindParamClause instances to "compiled" names that are
+ # actually present in the generated SQL
+ self.bind_names = {}
# a dictionary which stores the string representation for every ClauseElement
# processed by this compiler.
@@ -216,14 +220,16 @@ class ANSICompiler(sql.Compiled):
bindparams.update(params)
d = sql.ClauseParameters(self.dialect, self.positiontup)
for b in self.binds.values():
- d.set_parameter(b, b.value)
+ name = self.bind_names.get(b, b.key)
+ d.set_parameter(b, b.value, name)
for key, value in bindparams.iteritems():
try:
b = self.binds[key]
except KeyError:
continue
- d.set_parameter(b, value)
+ name = self.bind_names.get(b, b.key)
+ d.set_parameter(b, value, name)
return d
@@ -358,8 +364,11 @@ class ANSICompiler(sql.Compiled):
return binary.operator
def visit_bindparam(self, bindparam):
+ # apply truncation to the ultimate generated name
+
if bindparam.shortname != bindparam.key:
self.binds.setdefault(bindparam.shortname, bindparam)
+
if bindparam.unique:
count = 1
key = bindparam.key
@@ -367,20 +376,29 @@ class ANSICompiler(sql.Compiled):
# redefine the generated name of the bind param in the case
# that we have multiple conflicting bind parameters.
while self.binds.setdefault(key, bindparam) is not bindparam:
- # ensure the name doesn't expand the length of the string
- # in case we're at the edge of max identifier length
tag = "_%d" % count
- key = bindparam.key[0 : len(bindparam.key) - len(tag)] + tag
+ key = bindparam.key + tag
count += 1
bindparam.key = key
- self.strings[bindparam] = self.bindparam_string(key)
+ self.strings[bindparam] = self.bindparam_string(self._truncate_bindparam(bindparam))
else:
existing = self.binds.get(bindparam.key)
if existing is not None and existing.unique:
raise exceptions.CompileError("Bind parameter '%s' conflicts with unique bind parameter of the same name" % bindparam.key)
- self.strings[bindparam] = self.bindparam_string(bindparam.key)
+ self.strings[bindparam] = self.bindparam_string(self._truncate_bindparam(bindparam))
self.binds[bindparam.key] = bindparam
+
+ def _truncate_bindparam(self, bindparam):
+ if bindparam in self.bind_names:
+ return self.bind_names[bindparam]
+ bind_name = bindparam.key
+ if len(bind_name) >= self.dialect.max_identifier_length():
+ bind_name = bind_name[0:self.dialect.max_identifier_length() - 6] + "_" + hex(random.randint(0, 65535))[2:]
+ # add to bind_names for translation
+ self.bind_names[bindparam] = bind_name
+ return bind_name
+
def bindparam_string(self, name):
return self.bindtemplate % name
@@ -614,7 +632,7 @@ class ANSICompiler(sql.Compiled):
self.binds[p.key] = p
if p.shortname is not None:
self.binds[p.shortname] = p
- return self.bindparam_string(p.key)
+ return self.bindparam_string(self._truncate_bindparam(p))
else:
self.inline_params.add(col)
self.traverse(p)
@@ -648,7 +666,7 @@ class ANSICompiler(sql.Compiled):
if isinstance(p, sql._BindParamClause):
self.binds[p.key] = p
self.binds[p.shortname] = p
- return self.bindparam_string(p.key)
+ return self.bindparam_string(self._truncate_bindparam(p))
else:
self.traverse(p)
self.inline_params.add(col)