Commits

jason kirtland committed 4a9f3a9

Fixed detection of internal '$' characters in :bind$params (Applied patch in [ticket:719], thanks!)

Comments (0)

Files changed (3)

 - sql
     - tweak DISTINCT precedence for clauses like
       `func.count(t.c.col.distinct())`
+    - Fixed detection of internal '$' characters in :bind$params [ticket:719]
 - orm
     - added a check for joining from A->B using join(), along two
       different m2m tables.  this raises an error in 0.3 but is 

lib/sqlalchemy/ansisql.py

         # this re will search for params like :param
         # it has a negative lookbehind for an extra ':' so that it doesnt match
         # postgres '::text' tokens
-        match = re.compile(r'(?<!:):([\w_]+)', re.UNICODE)
+        match = re.compile(r'(?<!:):([\w_\$]+)', re.UNICODE)
         if self.paramstyle=='pyformat':
             self.strings[self.statement] = match.sub(lambda m:'%(' + m.group(1) +')s', self.strings[self.statement])
         elif self.positional:

test/sql/query.py

 import tables
 from sqlalchemy import *
 from sqlalchemy.engine import ResultProxy, RowProxy
-from sqlalchemy import exceptions
+from sqlalchemy import exceptions, ansisql
 
 class QueryTest(PersistTest):
     
         s = self.users.select(self.users.c.user_name==u)
         r = s.execute(someshortname='fred').fetchall()
         assert len(r) == 1
+
+    def test_bindparam_detection(self):
+        dialect = ansisql.ANSIDialect(default_paramstyle='qmark')
+        prep = lambda q: str(dialect.compile(sql.text(q)))
+
+        def a_eq(got, wanted):
+            if got != wanted:
+                print "Wanted %s" % wanted
+                print "Received %s" % got
+            self.assert_(got == wanted)
+
+        a_eq(prep('select foo'), 'select foo')
+        a_eq(prep(":this :that"), "? ?")
+        a_eq(prep("(:this),(:that :other)"), "(?),(? ?)")
+        a_eq(prep("(:that_ :other)"), "(? ?)")
+        a_eq(prep("(:that_other)"), "(?)")
+        a_eq(prep("(:that$other)"), "(?)")
+        a_eq(prep(".:that$ :other."), ".? ?.")
         
     def testdelete(self):
         self.users.insert().execute(user_id = 7, user_name = 'jack')