Description:
This happens when the C API for prepared statements is used.
A sample C source using the standard mysql.helptopic table has been
included.
The query like
select * from mysql.help_topic
where help_topic_id = ?
or help_topic_id = ?
only returns 1 record.
How to repeat:
#include <stdlib.h>
#include <mysql.h>
typedef enum {
BUG_UNKNOWN = -1, /* Error occurred */
BUG_SOLVED = 0,
BUG_PRESENT = 1,
} BugStatus;
char * str_bug_stat( BugStatus bugstat )
{
if ( bugstat == BUG_PRESENT ) {
return "Bug still present";
} else if ( bugstat == BUG_SOLVED ) {
return "Bug solved";
}
return "Status UNKNOWN (or error occurred)";
}
BugStatus do_the_bug_test( MYSQL * mysql, char ** desc )
{
int rows;
MYSQL_STMT * stmt;
char * query;
MYSQL_BIND ParamBind[2];
my_bool ParamIsNull = 0;
long ParamIntData[2];
MYSQL_BIND ResultBind[1];
unsigned long ResultLength;
my_bool ResultIsNull;
char ResultStrData[ 128 ];
*desc =
"MySQL-#.... Baan-040620 wrong result with OR \n"
" err: where id = ? or id = ? \n"
;
if ( !(stmt = mysql_stmt_init(mysql) ) ) {
return BUG_UNKNOWN;
}
query = "select name from mysql.help_topic where help_topic_id = ? or help_topic_id = ?";
if (mysql_stmt_prepare(stmt, query, strlen(query))) {
printf( "Prepare ERR: %s\n", query );
mysql_stmt_close(stmt);
return BUG_UNKNOWN;
}
/* Bind the param buffers */
ParamBind[0].buffer_type= MYSQL_TYPE_LONG;
ParamBind[0].buffer = (char *) &ParamIntData[0];
ParamBind[0].is_null= &ParamIsNull;
ParamBind[1].buffer_type= MYSQL_TYPE_LONG;
ParamBind[1].buffer = (char *) &ParamIntData[1];
ParamBind[1].is_null= &ParamIsNull;
if (mysql_stmt_bind_param(stmt, ParamBind)) {
mysql_stmt_close(stmt);
return BUG_UNKNOWN;
}
/* Bind the result buffers */
ResultBind[0].buffer_type= MYSQL_TYPE_STRING;
ResultBind[0].buffer= ResultStrData;
ResultBind[0].is_null= &ResultIsNull;
ResultBind[0].length= &ResultLength;
if (mysql_stmt_bind_result(stmt, ResultBind)) {
mysql_stmt_close(stmt);
return BUG_UNKNOWN;
}
ParamIntData[0] = 1;
ParamIntData[1] = 6;
/* Execute */
if (mysql_stmt_execute(stmt)) {
mysql_stmt_close(stmt);
return BUG_UNKNOWN;
}
/* Fetch all rows */
while (!mysql_stmt_fetch(stmt))
{
rows++;
printf( "Fetched name = '%s'\n", ResultStrData );
}
/* Close the statement */
mysql_stmt_close(stmt);
if ( rows == 2 ) {
return BUG_SOLVED;
} else {
return BUG_PRESENT;
}
}
main()
{
MYSQL * mysql = mysql_init( NULL );
BugStatus bugstat;
char * desc;
/* Bind data */
if ( ! mysql_real_connect( mysql,
/* host */ NULL,
/* user */ User,
/* pwd */ Pwd,
/* dbase */ Dbase,
/* uint port */ 0,
/* char * socket */ NULL,
/* client_flag */ 0 ) )
{
fprintf(stderr, " mysql_real_connec() failed\n");
exit(0);
}
bugstat = do_the_bug_test( mysql, &desc );
fprintf(stdout, "%s\n%s\n\n", desc, str_bug_stat( bugstat ) );
return 0;
}