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