mysql segfault in database-query
Nathan Bird <[email protected]>
| Newsgroups | gmane.lisp.clsql.general |
|---|---|
| Message-ID | <[email protected]> |
Mysql shouldn't segfault in database-query when running a command
with no resultset.
From docs at
http://dev.mysql.com/doc/refman/5.0/en/mysql-real-query.html and
http://dev.mysql.com/doc/refman/5.0/en/mysql-field-count.html after
performing the query
and attempting to get a result set, the RS ptr should be checked for
null and
if it is check mysql_errno to see if there actually was an error, or
just no result.
This patch makes database-query return NIL if there was no resultset.
git pull git://github.com/UnwashedMeme/clsql.git mysql-segfault
Based on your master branch, merges cleanly with dataset-refactoring.
This came up from client code calling the same query function and
expecting it to work everywhere returning a resultset when there is one
and not otherwise.
Added some tests :connect/4-6 that attempts to do the most basic send a
query to the database and get it back, ensuring that execute-command and
query work absent of anything else. postgresql, and odbc don't do well
on the queries with no result set right now either yet.
Let me know if there is any issues/problems.
Here's the diff ignoring whitespace changes so you can see the change
more directly:
diff --git a/db-mysql/mysql-sql.lisp b/db-mysql/mysql-sql.lisp
index 8f39471..debcb90 100644
--- a/db-mysql/mysql-sql.lisp
+++ b/db-mysql/mysql-sql.lisp
@@ -187,7 +187,7 @@
(if (zerop (mysql-real-query mysql-ptr query-native
(expression-length query-expression)))
(let ((res-ptr (mysql-use-result mysql-ptr)))
- (if res-ptr
+ (if (and res-ptr (not (uffi:null-pointer-p res-ptr)))
(unwind-protect
(let ((num-fields (mysql-num-fields res-ptr)))
(declare (fixnum num-fields))
@@ -214,11 +214,16 @@
(when field-names
(result-field-names res-ptr))))
(mysql-free-result res-ptr))
+ (unless (zerop (mysql-errno mysql-ptr))
+ ;;from
http://dev.mysql.com/doc/refman/5.0/en/mysql-field-count.html
+ ;; if mysql_use_result or mysql_store_result return a
null ptr,
+ ;; we use a mysql_errno check to see if it had a
problem or just
+ ;; was a query without a result. If no error, just
return nil.
(error 'sql-database-data-error
:database database
:expression query-expression
:error-id (mysql-errno mysql-ptr)
- :message (mysql-error-string mysql-ptr))))
+ :message (mysql-error-string mysql-ptr)))))
(error 'sql-database-data-error