Comment 3 for bug 691836

Revision history for this message
blep (blep) wrote :

I'm reproducing the issue with the reworked sample you provided with python 3.1.

The code causing the issue is:
http://bazaar.launchpad.net/~geertjmvdk/myconnpy/main/annotate/head%3A/python3/mysql/connector/cursor.py#L307

                elif isinstance(params, (list,tuple)):
                    for p in self._process_params(params):
                        stmt = stmt.replace(b'%s',p,1)

It replaces '%s' found in the statement as many times as it there is parameters, each replacement starting over from the beginning of the statement where previous parameters' value have already been substitued. This means that if one parameter value contains '%s', this occurrence of '%s' will be considered for substitution for the next parameter...

With your test case, you end up with the following statement:
"REPLACE INTO t1 VALUES (1,'ham2',%s)"

I figured why you do not reproduce the issue with python 2.6: the implementation of cursor.execute use a very different algorithm for substitution:
http://bazaar.launchpad.net/~geertjmvdk/myconnpy/main/annotate/head%3A/python2/mysql/connector/cursor.py#L307

stmt = operation % self._process_params(params)

which does not suffer from the bug I pointed out (but potentially introduce other issues as any format escape sequence such as "%r" or "%d" would also be substitued, though it is unlikely someone stumble on this).