Bug #4233 Wrong result with bindings like WHERE col = ? or col = ?
Submitted: 21 Jun 2004 15:38 Modified: 27 Jun 2004 1:43
Reporter: Anthon Ouwendijk Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:4.1.2 OS:HP/UX (HP-UX 11, x86 linux)
Assigned to: Oleksandr Byelkin CPU Architecture:Any

[21 Jun 2004 15:38] Anthon Ouwendijk
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;
}
[25 Jun 2004 22:16] Oleksandr Byelkin
ChangeSet 
  1.2004 04/06/25 23:15:23 bell@sanja.is.com.ua +3 -0 
  correct eq() method for Item_param (BUG#4233)
[27 Jun 2004 1:43] Sergei Golubchik
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

fixed in 4.1.3