farcepest / MySQLdb1

MySQL database connector for Python (legacy version)
https://sourceforge.net/projects/mysql-python/
666 stars 318 forks source link

MySQLdb doesn't properly check errors after call to mysql_store_result #101

Open blackwithwhite666 opened 9 years ago

blackwithwhite666 commented 9 years ago

Hi!

Seem that driver doesn't properly check for error after call to mysql_store_result. Currently, it calls mysql_field_count when mysql_store_result returns NULL but throws an error only if mysql_field_count result is greather then zero, which contradicts with one doc - https://dev.mysql.com/doc/refman/5.5/en/mysql-store-result.html but not with another - https://dev.mysql.com/doc/refman/5.5/en/mysql-field-count.html. That is why i replace check with call to mysql_errno.

I can check it with this code (not very effective method, but it works):

import signal
import traceback
import MySQLdb

signal.signal(signal.SIGUSR1, signal.SIG_IGN)

conn = MySQLdb.connect(user="root")
while True:
    cursor = conn.cursor()
    signal.signal(signal.SIGUSR1, lambda *args: None)
    cursor.execute("SELECT SQL_NO_CACHE row_id FROM big_table")
    assert len(list(cursor)) == cursor.rowcount
    signal.signal(signal.SIGUSR1, signal.SIG_IGN)

Start script and send SIGUSR1 to it:

while true; do kill -USR1 <PID>; sleep 0.001; done

After some time if will fail with:

$ python test_signal.py
Traceback (most recent call last):
  File "test_signal.py", line 12, in <module>
    assert len(list(cursor)) == cursor.rowcount
AssertionError

After fix it fails only with:

python test_signal.py
Traceback (most recent call last):
  File "test_signal.py", line 11, in <module>
     cursor.execute("SELECT SQL_NO_CACHE row_id FROM big_table")
  File "/home/dldmitry/Work/github.com/blackwithwhite666/MySQLdb1/MySQLdb/cursors.py", line 205, in execute
    self.errorhandler(self, exc, value)
  File "/home/dldmitry/Work/github.com/blackwithwhite666/MySQLdb1/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')

Which is expected behavior for libmysqlclient.