Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#66 MySQLdb do not report errors from mysql_store_result

MySQLdb-0.9.2
closed
Andy Dustman
MySQLdb (285)
5
2012-09-19
2003-09-24
Gilbert Fine
No

Sometimes we need to serialize the queries to MySQL.
We use InnoDB tables. When we need to proctect some
rows from being updated, we can do this in a
transaction:
SELECT ... WHERE ... FOR UPDATE
(or we we can set the transaction isolation level to some
proper value.)

When someone else want to execute the same SQL, he
will be blocked until the first client finish his transaction.
And the second client is blocked in the function
'mysql_store_result'. If, the second client wait for a long
time (50 seconds in default configuration),
'mysql_store_result' will return and you can query the
actual error by calling mysql_errno().

The problem is, if you use MySQLdb, you can never tell
whether mysql_store_result returns an error or it
succeeds and returns nothing. This may be OK for most
programs, but is DISASTERS for others.

let's look at the source code.

in _mysql.c:

static PyObject
_mysql_ConnectionObject_store_result(
_mysql_ConnectionObject
self,
PyObject args)
{
PyObject
arglist=NULL, kwarglist=NULL,
result=NULL;
_mysql_ResultObject *r=NULL;

    .........

    r = MyAlloc(_mysql_ResultObject,

_mysql_ResultObject_Type);
if (!r) goto error;
result = (PyObject *) r;
if (_mysql_ResultObject_Initialize(r, arglist,
kwarglist))
goto error; <---- What will happen when we
get here?
'result' will be non-NULL at that time.
So no exception will be thrown.

    ......

error:
Py_XDECREF(arglist);
Py_XDECREF(kwarglist);
return result;
}

..........

static int
_mysql_ResultObject_Initialize(
_mysql_ResultObject self,
PyObject
args,
PyObject *kwargs)
{
....................

if (use)
            result =

mysql_use_result(&(conn->connection));
else
result =
mysql_store_result(&(conn->connection));
self->result = result;
Py_END_ALLOW_THREADS ;
if (!result) {
self->converter = PyTuple_New(0);
return 0; <------ here, error reported by
mysql_store_result
is silently ignored!!
We should check the condition:

mysql_errno(&(conn->connection)) == 0
to decide we should return a
empty result
set or throw an exception.
}

    ....................

}

Discussion

  • Andy Dustman
    Andy Dustman
    2003-11-22

    Logged In: YES
    user_id=71372

    Try current CVS, i.e. _mysql.c rev 1.44

     
  • Andy Dustman
    Andy Dustman
    2003-12-13

    Logged In: YES
    user_id=71372

    This has been fixed in the current CVS tree.