diff -u -r DBD-mysql-3.0008_1/dbdimp.c dbd-mysql-mine/dbdimp.c --- DBD-mysql-3.0008_1/dbdimp.c 2006-10-16 16:10:37.000000000 +0300 +++ dbd-mysql-mine/dbdimp.c 2006-11-03 14:17:24.000000000 +0200 @@ -1309,17 +1309,23 @@ * **************************************************************************/ -void do_error(SV* h, int rc, const char* what) -{ +void do_error(SV* h, int rc, const char* what, const char* sqlstate) { D_imp_xxh(h); STRLEN lna; SV *errstr; + SV *errstate; if (dbis->debug >= 2) PerlIO_printf(DBILOGFP, "\t\t--> do_error\n"); errstr= DBIc_ERRSTR(imp_xxh); sv_setiv(DBIc_ERR(imp_xxh), (IV)rc); /* set err early */ sv_setpv(errstr, what); + + if (sqlstate) { + errstate= DBIc_STATE(imp_xxh); + sv_setpvn(errstate, sqlstate, 5); + } + DBIh_EVENT2(h, ERROR_event, DBIc_ERR(imp_xxh), errstr); if (dbis->debug >= 2) PerlIO_printf(DBILOGFP, "%s error %d recorded: %s\n", @@ -1851,7 +1857,8 @@ if (!my_login(dbh, imp_dbh)) { do_error(dbh, mysql_errno(&imp_dbh->mysql), - mysql_error(&imp_dbh->mysql)); + mysql_error(&imp_dbh->mysql), + mysql_sqlstate(&imp_dbh->mysql)); return FALSE; } @@ -1901,7 +1908,8 @@ #endif { do_error(dbh, mysql_errno(&imp_dbh->mysql), - mysql_error(&imp_dbh->mysql)); + mysql_error(&imp_dbh->mysql), + mysql_sqlstate(&imp_dbh->mysql)); return FALSE; } } @@ -1933,13 +1941,14 @@ #endif { do_error(dbh, mysql_errno(&imp_dbh->mysql), - mysql_error(&imp_dbh->mysql)); + mysql_error(&imp_dbh->mysql), + mysql_sqlstate(&imp_dbh->mysql)); return FALSE; } } else do_error(dbh, JW_ERR_NOT_IMPLEMENTED, - "Rollback ineffective while AutoCommit is on"); + "Rollback ineffective while AutoCommit is on", NULL); return TRUE; } @@ -2062,7 +2071,7 @@ #else if (mysql_rollback(&imp_dbh->mysql)) #endif - do_error(dbh, TX_ERR_ROLLBACK,"ROLLBACK failed"); + do_error(dbh, TX_ERR_ROLLBACK,"ROLLBACK failed",NULL); } dbd_db_disconnect(dbh, imp_dbh); } @@ -2114,7 +2123,7 @@ if (mysql_autocommit(&imp_dbh->mysql, bool_value)) { do_error(dbh, TX_ERR_AUTOCOMMIT, - bool_value ? "Turning on AutoCommit failed" : "Turning off AutoCommit failed"); + bool_value ? "Turning on AutoCommit failed" : "Turning off AutoCommit failed",NULL); return FALSE; } #else @@ -2124,7 +2133,7 @@ /* Setting autocommit will do a commit of any pending statement */ if (mysql_real_query(&imp_dbh->mysql, "SET AUTOCOMMIT=1", 16)) { - do_error(dbh, TX_ERR_AUTOCOMMIT, "Turning on AutoCommit failed"); + do_error(dbh, TX_ERR_AUTOCOMMIT, "Turning on AutoCommit failed",NULL); return FALSE; } } @@ -2132,7 +2141,7 @@ { if (mysql_real_query(&imp_dbh->mysql, "SET AUTOCOMMIT=0", 16)) { - do_error(dbh, TX_ERR_AUTOCOMMIT, "Turning off AutoCommit failed"); + do_error(dbh, TX_ERR_AUTOCOMMIT, "Turning off AutoCommit failed",NULL); return FALSE; } } @@ -2148,7 +2157,7 @@ if (!SvTRUE(valuesv)) { do_error(dbh, JW_ERR_NOT_IMPLEMENTED, - "Transactions not supported by database"); + "Transactions not supported by database",NULL); croak("Transactions not supported by database"); } } @@ -2513,7 +2522,8 @@ else { do_error(sth, mysql_stmt_errno(imp_sth->stmt), - mysql_stmt_error(imp_sth->stmt)); + mysql_stmt_error(imp_sth->stmt), + mysql_sqlstate(&imp_dbh->mysql)); mysql_stmt_close(imp_sth->stmt); imp_sth->stmt= NULL; return FALSE; @@ -2722,7 +2732,7 @@ mysql_free_result(imp_sth->result); if (mysql_errno(svsock)) - do_error(sth, mysql_errno(svsock), mysql_error(svsock)); + do_error(sth, mysql_errno(svsock), mysql_error(svsock), mysql_sqlstate(svsock)); next_result_return_code= mysql_next_result(svsock); /* @@ -2733,7 +2743,7 @@ */ if (next_result_return_code > 0) { - do_error(sth,mysql_errno(svsock),mysql_error(svsock)); + do_error(sth,mysql_errno(svsock),mysql_error(svsock), mysql_sqlstate(svsock)); return 0; } else if (next_result_return_code < 0) @@ -2751,7 +2761,7 @@ *result= mysql_store_result(svsock); if (mysql_errno(svsock)) - do_error(sth, mysql_errno(svsock), mysql_error(svsock)); + do_error(sth, mysql_errno(svsock), mysql_error(svsock), mysql_sqlstate(svsock)); if (*result == NULL) { @@ -2912,12 +2922,12 @@ if (!slen) { - do_error(h, JW_ERR_QUERY, "Missing table name"); + do_error(h, JW_ERR_QUERY, "Missing table name",NULL); return -2; } if (!(table= malloc(slen+1))) { - do_error(h, JW_ERR_MEM, "Out of memory"); + do_error(h, JW_ERR_MEM, "Out of memory",NULL); return -2; } @@ -2936,7 +2946,7 @@ if (!(*result)) { - do_error(h, mysql_errno(svsock), mysql_error(svsock)); + do_error(h, mysql_errno(svsock), mysql_error(svsock), mysql_sqlstate(svsock)); return -2; } @@ -2948,7 +2958,7 @@ (mysql_real_query(svsock, sbuf, slen)))) { Safefree(salloc); - do_error(h, mysql_errno(svsock), mysql_error(svsock)); + do_error(h, mysql_errno(svsock), mysql_error(svsock), mysql_sqlstate(svsock)); return -2; } Safefree(salloc); @@ -2958,7 +2968,7 @@ mysql_use_result(svsock) : mysql_store_result(svsock); if (mysql_errno(svsock)) - do_error(h, mysql_errno(svsock), mysql_error(svsock)); + do_error(h, mysql_errno(svsock), mysql_error(svsock), mysql_sqlstate(svsock)); if (!*result) rows= mysql_affected_rows(svsock); @@ -3076,7 +3086,7 @@ " errno %d err message %s\n", mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); - do_error(sth, mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + do_error(sth, mysql_stmt_errno(stmt), mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt)); mysql_stmt_reset(stmt); if (dbis->debug >= 2) @@ -3149,7 +3159,7 @@ if (DBIc_ACTIVE(imp_sth) && !(mysql_st_clean_cursor(sth, imp_sth))) { do_error(sth, JW_ERR_SEQUENCE, - "Error happened while tried to clean up stmt"); + "Error happened while tried to clean up stmt",NULL); return 0; } @@ -3247,7 +3257,7 @@ { /* no metadata */ do_error(sth, JW_ERR_SEQUENCE, - "no metadata information while trying describe result set"); + "no metadata information while trying describe result set",NULL); return 0; } @@ -3257,7 +3267,7 @@ { /* Out of memory */ do_error(sth, JW_ERR_SEQUENCE, - "Out of memory in dbd_sescribe()"); + "Out of memory in dbd_sescribe()",NULL); return 0; } @@ -3316,7 +3326,8 @@ if (mysql_stmt_bind_result(imp_sth->stmt, imp_sth->buffer)) { do_error(sth, mysql_stmt_errno(imp_sth->stmt), - mysql_stmt_error(imp_sth->stmt)); + mysql_stmt_error(imp_sth->stmt), + mysql_stmt_sqlstate(imp_sth->stmt)); return 0; } } @@ -3363,13 +3374,13 @@ { if (!DBIc_ACTIVE(imp_sth) ) { - do_error(sth, JW_ERR_SEQUENCE, "no statement executing\n"); + do_error(sth, JW_ERR_SEQUENCE, "no statement executing\n", NULL); return Nullav; } if (imp_sth->fetch_done) { - do_error(sth, JW_ERR_SEQUENCE, "fetch() but fetch already done"); + do_error(sth, JW_ERR_SEQUENCE, "fetch() but fetch already done", NULL); return Nullav; } @@ -3377,7 +3388,7 @@ { if (!dbd_describe(sth, imp_sth)) { - do_error(sth, JW_ERR_SEQUENCE, "Error while describe result set."); + do_error(sth, JW_ERR_SEQUENCE, "Error while describe result set.", NULL); return Nullav; } } @@ -3393,7 +3404,7 @@ if (!imp_sth->result) { - do_error(sth, JW_ERR_SEQUENCE, "fetch() without execute()"); + do_error(sth, JW_ERR_SEQUENCE, "fetch() without execute()", NULL); return Nullav; } @@ -3410,7 +3421,9 @@ { if (rc == 1) do_error(sth, mysql_stmt_errno(imp_sth->stmt), - mysql_stmt_error(imp_sth->stmt)); + mysql_stmt_error(imp_sth->stmt), + mysql_stmt_sqlstate(imp_sth->stmt) + ); if (rc == MYSQL_NO_DATA) { @@ -3467,7 +3480,8 @@ /*TODO: Use offset instead of 0 to fetch only remain part of data*/ if (mysql_stmt_fetch_column(imp_sth->stmt, bind , i, 0)) do_error(sth, mysql_stmt_errno(imp_sth->stmt), - mysql_stmt_error(imp_sth->stmt)); + mysql_stmt_error(imp_sth->stmt), + mysql_stmt_sqlstate(imp_sth->stmt)); } /* This does look a lot like Georg's PHP driver doesn't it? --Brian */ @@ -3534,7 +3548,8 @@ { if (mysql_errno(&imp_dbh->mysql)) do_error(sth, mysql_errno(&imp_dbh->mysql), - mysql_error(&imp_dbh->mysql)); + mysql_error(&imp_dbh->mysql), + mysql_sqlstate(&imp_dbh->mysql)); dbd_st_finish(sth, imp_sth); return Nullav; @@ -3638,7 +3653,7 @@ if (!mysql_st_clean_cursor(sth, imp_sth)) { do_error(sth, JW_ERR_SEQUENCE, - "Error happened while tried to clean up stmt"); + "Error happened while tried to clean up stmt", NULL); return 0; } } @@ -3721,7 +3736,7 @@ "DESTROY: Error %s while close stmt\n", (char *) mysql_stmt_error(imp_sth->stmt)); do_error(sth, mysql_stmt_errno(imp_sth->stmt), - mysql_stmt_error(imp_sth->stmt)); + mysql_stmt_error(imp_sth->stmt),mysql_stmt_sqlstate(imp_sth->stmt)); } if (DBIc_NUM_PARAMS(imp_sth) > 0) { @@ -3869,7 +3884,7 @@ /* Are we asking for a legal value? */ if (what < 0 || what >= AV_ATTRIB_LAST) - do_error(sth, JW_ERR_NOT_IMPLEMENTED, "Not implemented"); + do_error(sth, JW_ERR_NOT_IMPLEMENTED, "Not implemented", NULL); /* Return cached value, if possible */ else if (cacheit && imp_sth->av_attr[what]) @@ -3878,7 +3893,7 @@ /* Does this sth really have a result? */ else if (!res) do_error(sth, JW_ERR_NOT_ACTIVE, - "statement contains no result"); + "statement contains no result", NULL); /* Do the real work. */ else { @@ -4197,7 +4212,7 @@ if (param_num <= 0 || param_num > DBIc_NUM_PARAMS(imp_sth)) { do_error(sth, JW_ERR_ILLEGAL_PARAM_NUM, - "Illegal parameter number"); + "Illegal parameter number", NULL); return FALSE; } @@ -4219,14 +4234,14 @@ sprintf(err_msg, "Binding non-numeric field %d, value %s as a numeric!", param_num, neatsvpv(value,0)); - do_error(sth, JW_ERR_ILLEGAL_PARAM_NUM, err_msg); + do_error(sth, JW_ERR_ILLEGAL_PARAM_NUM, err_msg, NULL); } } if (is_inout) { do_error(sth, JW_ERR_NOT_IMPLEMENTED, - "Output parameters not implemented"); + "Output parameters not implemented", NULL); return FALSE; } @@ -4383,7 +4398,7 @@ if (!my_login(h, imp_dbh)) { - do_error(h, mysql_errno(&imp_dbh->mysql), mysql_error(&imp_dbh->mysql)); + do_error(h, mysql_errno(&imp_dbh->mysql), mysql_error(&imp_dbh->mysql), mysql_sqlstate(&imp_dbh->mysql)); memcpy (&imp_dbh->mysql, &save_socket, sizeof(save_socket)); ++imp_dbh->stats.auto_reconnects_failed; return FALSE; diff -u -r DBD-mysql-3.0008_1/dbdimp.h dbd-mysql-mine/dbdimp.h --- DBD-mysql-3.0008_1/dbdimp.h 2006-10-10 22:58:48.000000000 +0300 +++ dbd-mysql-mine/dbdimp.h 2006-11-02 15:05:12.000000000 +0200 @@ -274,7 +274,7 @@ #endif #include -void do_error (SV* h, int rc, const char *what); +void do_error (SV* h, int rc, const char *what, const char *sqlstate); SV *dbd_db_fieldlist (MYSQL_RES* res); void dbd_preparse (imp_sth_t *imp_sth, SV *statement); Only in dbd-mysql-mine/: execute diff -u -r DBD-mysql-3.0008_1/mysql.xs dbd-mysql-mine/mysql.xs --- DBD-mysql-3.0008_1/mysql.xs 2006-10-10 22:58:48.000000000 +0300 +++ dbd-mysql-mine/mysql.xs 2006-11-03 14:06:26.000000000 +0200 @@ -54,7 +54,7 @@ MYSQL_RES* res = mysql_list_dbs(sock, NULL); if (!res) { - do_error(drh, mysql_errno(sock), mysql_error(sock)); + do_error(drh, mysql_errno(sock), mysql_error(sock), mysql_sqlstate(sock)); } else { @@ -98,7 +98,7 @@ sock = mysql_dr_connect(drh, &mysql, NULL, host, port, user, password, NULL, NULL); if (sock == NULL) { - do_error(drh, mysql_errno(&mysql), mysql_error(&mysql)); + do_error(drh, mysql_errno(&mysql), mysql_error(&mysql), mysql_sqlstate(&mysql)); XSRETURN_NO; } } @@ -119,7 +119,7 @@ char* buffer = malloc(strlen(dbname)+50); if (buffer == NULL) { - do_error(drh, JW_ERR_MEM, "Out of memory"); + do_error(drh, JW_ERR_MEM, "Out of memory",NULL); XSRETURN_NO; } else @@ -139,7 +139,7 @@ char* buffer = malloc(strlen(dbname)+50); if (buffer == NULL) { - do_error(drh, JW_ERR_MEM, "Out of memory"); + do_error(drh, JW_ERR_MEM, "Out of memory",NULL); XSRETURN_NO; } else @@ -158,7 +158,7 @@ if (retval) { do_error(SvOK(dbh) ? dbh : drh, mysql_errno(sock), - mysql_error(sock)); + mysql_error(sock), mysql_sqlstate(sock)); } if (SvOK(dbh)) @@ -207,7 +207,7 @@ !(res = mysql_list_dbs(&imp_dbh->mysql, NULL)))) { do_error(dbh, mysql_errno(&imp_dbh->mysql), - mysql_error(&imp_dbh->mysql)); + mysql_error(&imp_dbh->mysql), mysql_sqlstate(&imp_dbh->mysql)); } else { @@ -286,7 +286,7 @@ } else { - do_error(dbh, mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + do_error(dbh, mysql_stmt_errno(stmt), mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt)); retval=-2; } mysql_stmt_close(stmt); @@ -569,13 +569,13 @@ else { RETVAL = 0; - do_error(sth, JW_ERR_NOT_ACTIVE, "Statement not active"); + do_error(sth, JW_ERR_NOT_ACTIVE, "Statement not active",NULL); } } else { RETVAL = 0; - do_error(sth, JW_ERR_NOT_ACTIVE, "No result set"); + do_error(sth, JW_ERR_NOT_ACTIVE, "No result set",NULL); } } else @@ -586,7 +586,7 @@ RETVAL = 1; } else { RETVAL = 0; - do_error(sth, JW_ERR_NOT_ACTIVE, "Statement not active"); + do_error(sth, JW_ERR_NOT_ACTIVE, "Statement not active",NULL); } #if (MYSQL_VERSION_ID >=SERVER_PREPARE_VERSION) }