Description:
A query which produces a warning, when fetched via mysql_stmt_fetch(), does not produce a warning count according to mysql_warning_count().
This worked correctly in 5.0.16, but currently it returns 0 instead of the correct count.
I tested this with a recent 5.0 build from BK, on FreeBSD and Linux.
How to repeat:
Here is a test case. When run against 5.0.16, it exits successfully with no messages. When run against 5.0.17-bk, it gives:
$ ./b1
!!! Error (91):
Expected value:1
Returned value:0
error: Assertion failed: (0), function main, file b1.cpp, line 91.
zsh: abort (core dumped) ./b1
// This cpp file should be compilable with:
// gcc -g -I ${MYSQL_DIR}/include ${THIS_FILE} ${MYSQL_DIR}/lib/libmysqlclient.a -lm -lz -lstdc++
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <string>
#include <list>
#include <iostream>
#include <sstream>
// Connection parameters
const char *MYSQL_CMD = "mysql"; // Used for table creation
const char *HOST_NAME = NULL;
const char *USER_NAME = NULL;
const char *USER_PWD = NULL;
const char *DB_NAME = "test";
const char *UNIX_SOCKET = NULL;
// use "#define M_EXPECT_EQUALS (void)" to disable data validation
typedef enum { STR, SESS, STMT } ;
#define M_EXPECT_EQUALS(X,Y,T,V) if ( X==Y ); else { \
cout << "!!! Error (" << __LINE__ << "): " << endl \
<< " Expected value:" << X << endl \
<< " Returned value:" << Y << endl; \
switch (T) { \
case STR : cout << " error: " << (const char *)V << endl; break;\
case SESS: cout << " mysql error: " << mysql_error((MYSQL*)V) << endl; break;\
case STMT: cout << " mysql error: " << mysql_stmt_error((MYSQL_STMT*)V) << endl; break;\
} \
assert( 0 ); \
} \
#include "mysql.h"
using namespace std;
// Global variables
const char *m_text;
int m_ret;
int m_count;
int m_err;
MYSQL_RES *m_result;
MYSQL_ROW m_row;
// Helper functions
inline void set_bind_attrs(MYSQL_BIND *mysql_bind, enum_field_types ext_type, void *buf, int bufsz, unsigned long *act_len, my_bool *is_null)
{
mysql_bind->buffer_type = ext_type;
mysql_bind->buffer = buf;
mysql_bind->length = act_len;
mysql_bind->is_null = is_null;
mysql_bind->buffer_length = bufsz;
}
int main(void)
{
MYSQL *sess_1;
sess_1 = mysql_init( NULL ); assert(sess_1);
sess_1 = mysql_real_connect(sess_1, HOST_NAME, USER_NAME, USER_PWD, DB_NAME, 0, UNIX_SOCKET, 0); assert(sess_1);
// Set sql_mode to ERROR_FOR_DIVISION_BY_ZERO so that we should get
// a warning on a division by zero
mysql_query(sess_1, "SET SESSION sql_mode=ERROR_FOR_DIVISION_BY_ZERO");
MYSQL_STMT *stmt_1;
stmt_1 = mysql_stmt_init(sess_1);
m_text = "SELECT 1 FROM DUAL WHERE 1 / 0";
m_ret = mysql_stmt_prepare(stmt_1,m_text,strlen(m_text)); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1);
m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL);
MYSQL_BIND *output_1 = (MYSQL_BIND *)calloc(1, sizeof(MYSQL_BIND));
int data_3;
unsigned long len_3;
my_bool null_3;
set_bind_attrs(&output_1[0],MYSQL_TYPE_LONG,&data_3,4,&len_3,&null_3);
m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL);
m_ret = mysql_stmt_execute(stmt_1); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1);
m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL);
mysql_stmt_bind_result(stmt_1,output_1);
m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL);
m_ret = mysql_stmt_fetch(stmt_1); M_EXPECT_EQUALS(100,m_ret,STMT,stmt_1);
// The previous fetch should give a "division by zero" warning.
m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(1,m_count,0,NULL);
m_ret = mysql_query(sess_1,"show warnings limit 0,1"); M_EXPECT_EQUALS(0,m_ret,SESS,sess_1);
m_result = mysql_store_result(sess_1); assert(m_result);
m_count = mysql_num_fields(m_result);M_EXPECT_EQUALS( 3,m_count,0,NULL );
m_row = mysql_fetch_row(m_result); M_EXPECT_EQUALS(1365,atoi(m_row[1]),STR,"Unexpected warning code"); // Message: "Division by 0"
mysql_free_result( m_result );
m_ret = mysql_stmt_free_result(stmt_1); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1);
m_ret = mysql_stmt_reset(stmt_1); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1);
m_ret = mysql_stmt_close(stmt_1); M_EXPECT_EQUALS(0,m_ret,0,NULL);
m_ret = mysql_rollback(sess_1); M_EXPECT_EQUALS(0,m_ret,SESS,sess_1);
mysql_close(sess_1);
return EXIT_SUCCESS;
}
Suggested fix:
n/a
Description: A query which produces a warning, when fetched via mysql_stmt_fetch(), does not produce a warning count according to mysql_warning_count(). This worked correctly in 5.0.16, but currently it returns 0 instead of the correct count. I tested this with a recent 5.0 build from BK, on FreeBSD and Linux. How to repeat: Here is a test case. When run against 5.0.16, it exits successfully with no messages. When run against 5.0.17-bk, it gives: $ ./b1 !!! Error (91): Expected value:1 Returned value:0 error: Assertion failed: (0), function main, file b1.cpp, line 91. zsh: abort (core dumped) ./b1 // This cpp file should be compilable with: // gcc -g -I ${MYSQL_DIR}/include ${THIS_FILE} ${MYSQL_DIR}/lib/libmysqlclient.a -lm -lz -lstdc++ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <assert.h> #include <string> #include <list> #include <iostream> #include <sstream> // Connection parameters const char *MYSQL_CMD = "mysql"; // Used for table creation const char *HOST_NAME = NULL; const char *USER_NAME = NULL; const char *USER_PWD = NULL; const char *DB_NAME = "test"; const char *UNIX_SOCKET = NULL; // use "#define M_EXPECT_EQUALS (void)" to disable data validation typedef enum { STR, SESS, STMT } ; #define M_EXPECT_EQUALS(X,Y,T,V) if ( X==Y ); else { \ cout << "!!! Error (" << __LINE__ << "): " << endl \ << " Expected value:" << X << endl \ << " Returned value:" << Y << endl; \ switch (T) { \ case STR : cout << " error: " << (const char *)V << endl; break;\ case SESS: cout << " mysql error: " << mysql_error((MYSQL*)V) << endl; break;\ case STMT: cout << " mysql error: " << mysql_stmt_error((MYSQL_STMT*)V) << endl; break;\ } \ assert( 0 ); \ } \ #include "mysql.h" using namespace std; // Global variables const char *m_text; int m_ret; int m_count; int m_err; MYSQL_RES *m_result; MYSQL_ROW m_row; // Helper functions inline void set_bind_attrs(MYSQL_BIND *mysql_bind, enum_field_types ext_type, void *buf, int bufsz, unsigned long *act_len, my_bool *is_null) { mysql_bind->buffer_type = ext_type; mysql_bind->buffer = buf; mysql_bind->length = act_len; mysql_bind->is_null = is_null; mysql_bind->buffer_length = bufsz; } int main(void) { MYSQL *sess_1; sess_1 = mysql_init( NULL ); assert(sess_1); sess_1 = mysql_real_connect(sess_1, HOST_NAME, USER_NAME, USER_PWD, DB_NAME, 0, UNIX_SOCKET, 0); assert(sess_1); // Set sql_mode to ERROR_FOR_DIVISION_BY_ZERO so that we should get // a warning on a division by zero mysql_query(sess_1, "SET SESSION sql_mode=ERROR_FOR_DIVISION_BY_ZERO"); MYSQL_STMT *stmt_1; stmt_1 = mysql_stmt_init(sess_1); m_text = "SELECT 1 FROM DUAL WHERE 1 / 0"; m_ret = mysql_stmt_prepare(stmt_1,m_text,strlen(m_text)); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1); m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL); MYSQL_BIND *output_1 = (MYSQL_BIND *)calloc(1, sizeof(MYSQL_BIND)); int data_3; unsigned long len_3; my_bool null_3; set_bind_attrs(&output_1[0],MYSQL_TYPE_LONG,&data_3,4,&len_3,&null_3); m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL); m_ret = mysql_stmt_execute(stmt_1); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1); m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL); mysql_stmt_bind_result(stmt_1,output_1); m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(0,m_count,0,NULL); m_ret = mysql_stmt_fetch(stmt_1); M_EXPECT_EQUALS(100,m_ret,STMT,stmt_1); // The previous fetch should give a "division by zero" warning. m_count = mysql_warning_count(sess_1); M_EXPECT_EQUALS(1,m_count,0,NULL); m_ret = mysql_query(sess_1,"show warnings limit 0,1"); M_EXPECT_EQUALS(0,m_ret,SESS,sess_1); m_result = mysql_store_result(sess_1); assert(m_result); m_count = mysql_num_fields(m_result);M_EXPECT_EQUALS( 3,m_count,0,NULL ); m_row = mysql_fetch_row(m_result); M_EXPECT_EQUALS(1365,atoi(m_row[1]),STR,"Unexpected warning code"); // Message: "Division by 0" mysql_free_result( m_result ); m_ret = mysql_stmt_free_result(stmt_1); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1); m_ret = mysql_stmt_reset(stmt_1); M_EXPECT_EQUALS(0,m_ret,STMT,stmt_1); m_ret = mysql_stmt_close(stmt_1); M_EXPECT_EQUALS(0,m_ret,0,NULL); m_ret = mysql_rollback(sess_1); M_EXPECT_EQUALS(0,m_ret,SESS,sess_1); mysql_close(sess_1); return EXIT_SUCCESS; } Suggested fix: n/a