--- apr_dbd_mysql.c.prev	2006-02-24 13:32:46.000000000 +1100
+++ apr_dbd_mysql.c	2006-05-01 12:30:55.000000000 +1000
@@ -50,6 +50,10 @@
  *        - other string types are handled by fetch_result_str, which always adds terminating \0
  *      5. Removed mysql_stmt_close call-back registration - mysql_close removes all statements
  *        - I had this problem with stand-alone apr app (glibc double free exception)
+ *
+ *     Additional changes: Alex Dubov <oakad@yahoo.com> 2006-04-20
+ *
+ *	1. Make all function return mysql_errno/mysql_stmt_errno (much more informative)
  */
 
 #include "apu.h"
@@ -60,6 +64,7 @@
 #include <stdlib.h>
 
 #include <mysql/mysql.h>
+#include <mysql/errmsg.h>
 
 #include "apr_strings.h"
 
@@ -93,7 +98,7 @@
 };
 
 struct blob_t {
-    int len;
+    unsigned long length;
     char data[];
 };
 
@@ -124,7 +129,10 @@
                                       (void*)mysql_free_result,
                                       apr_pool_cleanup_null);
         }
+    } else {
+	ret = mysql_errno(sql->conn);
     }
+    
     if (sql->trans) {
         sql->trans->errnum = ret;
     }
@@ -142,7 +150,9 @@
                 mysql_stmt_data_seek(res->statement, (my_ulonglong)rownum);
             }
         }
-        ret = mysql_stmt_fetch(res->statement);
+        if((ret = mysql_stmt_fetch(res->statement))) {
+	    ret = mysql_stmt_errno(res->statement);
+	}
     }
     else {
         if (res->random) {
@@ -150,10 +160,9 @@
                 mysql_data_seek(res->res, (my_ulonglong) rownum);
             }
         }
-        r = mysql_fetch_row(res->res);
-        if (r == NULL) {
-            ret = 1;
-        }
+        if(!(r = mysql_fetch_row(res->res))) {
+    	    ret = -1;
+	}
     }
     if (ret == 0) {
         if (!*row) {
@@ -165,7 +174,6 @@
     else {
         mysql_free_result(res->res);
         apr_pool_cleanup_kill(pool, res->res, (void*)mysql_free_result);
-        ret = -1;
     }
     return ret;
 }
@@ -215,7 +223,7 @@
                || bind->buffer_type == MYSQL_TYPE_BLOB
                || bind->buffer_type == MYSQL_TYPE_BIT) {
                /* Use optional length field - bind->length points to the real data size */
-               ((struct blob_t*)(bind->buffer - sizeof(struct blob_t)))->len = *(bind->length);
+               ((struct blob_t*)(bind->buffer - sizeof(struct blob_t)))->length = *(bind->length);
                return bind->buffer - sizeof(struct blob_t);
             }
             else return bind->buffer;
@@ -237,7 +245,7 @@
     if (sql->trans && sql->trans->errnum) {
         return sql->trans->errnum;
     }
-    ret = mysql_query(sql->conn, query);
+    if((ret = mysql_query(sql->conn, query))) ret = mysql_errno(sql->conn);
     *nrows = mysql_affected_rows(sql->conn);
     if (sql->trans) {
         sql->trans->errnum = ret;
@@ -281,8 +289,8 @@
      *    %lld(u)       | MYSQL_TYPE_LONGLONG    | BIGINT                | long long int
      *    %f            | MYSQL_TYPE_FLOAT       | FLOAT                 | float
      *    %lf           | MYSQL_TYPE_DOUBLE      | DOUBLE                | double
-     *    %c            | MYSQL_TYPE_STRING      | CHAR/BINARY           | char*
-     *    %s            | MYSQL_TYPE_BLOB        | BLOB/TEXT             | struct blob_t*
+     *    %c            | MYSQL_TYPE_STRING      | CHAR/TEXT             | char*
+     *    %s            | MYSQL_TYPE_BLOB        | BLOB/BINARY           | struct blob_t*
      * These are not supported currently:
      *                  | MYSQL_TYPE_BIT
      *                  | MYSQL_TYPE_TIME        | TIME                  | MYSQL_TIME
@@ -367,7 +375,7 @@
                     // it will be nice to have realloc here
                     MYSQL_BIND* old_bind = (*statement)->bind;
                     if(!((*statement)->bind = apr_pcalloc(pool, (bind_size + bind_inc) * sizeof(MYSQL_BIND)))) 
-                        return 1;
+                        return CR_OUT_OF_MEMORY;
 
                     memcpy((*statement)->bind, old_bind, bind_size * sizeof(MYSQL_BIND));
                     bind_size += bind_inc;
@@ -381,7 +389,7 @@
 
     (*statement)->stmt = mysql_stmt_init(sql->conn);
 
-    if(!(*statement)->stmt) ret = 1;
+    if(!(*statement)->stmt) ret = CR_OUT_OF_MEMORY;
     else {
         /* apr_pool_cleanup_register(pool, *statement, (void*)mysql_stmt_close,
                                   apr_pool_cleanup_null); */
@@ -389,8 +397,10 @@
         if(!ret) {
             nargs = mysql_stmt_param_count((*statement)->stmt);
 
-            if(nargs != bind_pos) ret = 2; // SQL string probably has '?' characters we know nothing aboud
-        }
+            if(nargs != bind_pos) ret = CR_INVALID_PARAMETER_NO; // SQL string probably has '?' characters we know nothing aboud
+        } else {
+	    ret = mysql_stmt_errno((*statement)->stmt);
+	}
     }
 
     return ret;
@@ -429,7 +439,7 @@
             break;
         case MYSQL_TYPE_BLOB:
             bind->buffer = ((struct blob_t*)arg)->data;
-            bind->buffer_length = ((struct blob_t*)arg)->len;
+            bind->buffer_length = ((struct blob_t*)arg)->length;
             break;
         default:
             bind->buffer_type = MYSQL_TYPE_NULL;
@@ -475,9 +485,13 @@
     ret = mysql_stmt_bind_param(statement->stmt, statement->bind);
     if (ret != 0) {
         *nrows = 0;
+	ret = mysql_stmt_errno(statement->stmt);
     }
     else {
-        ret = mysql_stmt_execute(statement->stmt);
+        if((ret = mysql_stmt_execute(statement->stmt))) {
+	    ret = mysql_stmt_errno(statement->stmt);
+	}
+	
         *nrows = mysql_stmt_affected_rows(statement->stmt);
     }
     if (sql->trans) {
@@ -509,9 +523,12 @@
     ret = mysql_stmt_bind_param(statement->stmt, statement->bind);
     if (ret != 0) {
         *nrows = 0;
+	ret = mysql_stmt_errno(statement->stmt);
     }
     else {
-        ret = mysql_stmt_execute(statement->stmt);
+        if((ret = mysql_stmt_execute(statement->stmt))) {
+	    ret = mysql_stmt_errno(statement->stmt);
+	}
         *nrows = mysql_stmt_affected_rows(statement->stmt);
     }
     if (sql->trans) {
@@ -559,7 +576,7 @@
                 *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
                 if (!*res) {
                     while (!mysql_stmt_fetch(statement->stmt));
-                    return -1;
+                    return CR_OUT_OF_MEMORY;
                 }
             }
             (*res)->random = random;
@@ -599,9 +616,16 @@
             ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind);
             if (!ret) {
                 ret = mysql_stmt_store_result(statement->stmt);
-            }
-        }
+            } else {
+		ret = mysql_stmt_errno(statement->stmt);
+	    }
+        } else {
+	    ret = mysql_stmt_errno(statement->stmt);
+	}
+    } else {
+	ret = mysql_stmt_errno(statement->stmt);
     }
+    
     if (sql->trans) {
         sql->trans->errnum = ret;
     }
@@ -644,7 +668,7 @@
                 *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
                 if (!*res) {
                     while (!mysql_stmt_fetch(statement->stmt));
-                    return -1;
+                    return CR_OUT_OF_MEMORY;
                 }
             }
             (*res)->random = random;
@@ -684,9 +708,16 @@
             ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind);
             if (!ret) {
                 ret = mysql_stmt_store_result(statement->stmt);
-            }
-        }
+            } else {
+		ret = mysql_stmt_errno(statement->stmt);
+	    }
+        } else {
+	    ret = mysql_stmt_errno(statement->stmt);
+	}
+    } else {
+	ret = mysql_stmt_errno(statement->stmt);
     }
+    
     if (sql->trans) {
         sql->trans->errnum = ret;
     }
@@ -785,7 +816,7 @@
                                    fields[3].value, port,
                                    fields[5].value, 0);
 
-    if(sql->conn == NULL) return NULL; /* this is important */
+    if(!sql->conn) return 0; /* this is important */
 
     return sql;
 }
