Bug #62136 | failed to fetch select result using embedded mysqld | ||
---|---|---|---|
Submitted: | 10 Aug 2011 5:59 | Modified: | 25 Apr 2012 19:12 |
Reporter: | Qi Zhou | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Embedded Library ( libmysqld ) | Severity: | S2 (Serious) |
Version: | 5.5.15, 5.1.62, 5.5.22 | OS: | Linux (Red Hat Enterprise Linux AS release 4 (Nahant Update 3)) |
Assigned to: | CPU Architecture: | Any | |
Tags: | libmysqld, regression |
[10 Aug 2011 5:59]
Qi Zhou
[10 Aug 2011 10:39]
MySQL Verification Team
Thank you for the bug report. Are you able to provide a complete test case (dump file + c code).? Thanks.
[11 Aug 2011 13:09]
Qi Zhou
#include <stdio.h> #include <mysql.h> #include <stdlib.h> #include <string.h> int main() { MYSQL* sql; MYSQL_STMT* stmt; MYSQL_BIND bind; unsigned* indice; int ret; int result; unsigned long length; char query1[] = "create database if not exists mydb"; char query2[] = "use mydb"; char query3[] = "create table if not exists mytable (id int not null, col int not null)"; char query4[] = "insert into mytable (id, col) values (1,100)"; char query5[] = "select col from mytable where id = ?"; char *server_options[] = { "","--defaults-file=my.cnf","--basedir=./"}; int num_elements = sizeof(server_options)/ sizeof(char *); if(mysql_server_init(num_elements, server_options, NULL)) { puts("failed to initialize server"); return 1; } sql = mysql_init(NULL); if(!mysql_real_connect(sql, NULL , NULL , NULL , NULL, 3306, NULL, 0)) printf("failed to connect\n"); if(mysql_query(sql, query1)) printf("failed to create database:%s\n", mysql_error(sql)); ret = mysql_query(sql, query2); if(ret) printf("failed to use database:%s\n", mysql_error(sql)); ret = mysql_query(sql, query3); if(ret) printf("failed to create table:%s\n", mysql_error(sql)); ret = mysql_query(sql, query4); if(ret) printf("failed to insert record:%s\n", mysql_error(sql)); stmt = mysql_stmt_init(sql); if(!stmt) printf("failed to init stmt:%s\n", mysql_error(sql)); ret = mysql_stmt_prepare(stmt, query5, strlen(query5)); if(ret) printf("failed to prepare:%s\n", mysql_stmt_error(stmt)); result = 1; memset(&bind, 0 , sizeof(bind)); bind.buffer_type = MYSQL_TYPE_LONG; bind.is_unsigned = (my_bool)0; bind.is_null = 0; bind.buffer = (char*)&result; bind.buffer_length = 4; bind.length = &length; ret = mysql_stmt_bind_param(stmt, &bind); if(ret) printf("failed to bind param:%s\n", mysql_stmt_error(stmt)); ret = mysql_stmt_execute(stmt); if(ret) printf("failed to execute stmt:%s\n", mysql_stmt_error(stmt)); memset(&bind, 0 , sizeof(bind)); bind.buffer_type = MYSQL_TYPE_LONG; bind.is_unsigned = (my_bool)0; bind.is_null = 0; bind.buffer = (char*)&result; bind.buffer_length = 4; bind.length = &length; ret = mysql_stmt_bind_result(stmt, &bind); if(ret) printf("failed to bind result:%s\n", mysql_stmt_error(stmt)); ret = mysql_stmt_store_result(stmt); if(ret) printf("failed to store result:%s\n", mysql_stmt_error(stmt)); ret = mysql_stmt_fetch(stmt); if(ret) printf("failed to fetch result:%s\n", mysql_stmt_error(stmt)); mysql_stmt_close(stmt); mysql_close(sql); mysql_server_end(); return 0; } this is my source code, and you need put my.cnf in the execute directory,my.cnf : [server] language=../../mysql/share/english datadir=./data [embedded] language=../../mysql/share/english language(../../mysql/share/english) points to mysql/share/english. and you need mkdir data as datadir this program failed on mysql_stmt_store_result and mysql_stmt_fetch, if modify the source as I suggested before, it would pass. looking forward to your answer.
[12 Aug 2011 2:13]
Qi Zhou
test file
Attachment: sql.cpp (text/plain), 2.57 KiB.
[15 Aug 2011 5:39]
Qi Zhou
here is my source code: #include <stdio.h> #include <mysql.h> #include <stdlib.h> #include <string.h> int main() { MYSQL* sql; MYSQL_STMT* stmt; MYSQL_BIND bind; unsigned* indice; int ret; int result; unsigned long length; char query1[] = "create database if not exists mydb"; char query2[] = "use mydb"; char query3[] = "create table if not exists mytable (id int not null, col int not null)"; char query4[] = "insert into mytable (id, col) values (1,100)"; char query5[] = "select col from mytable where id = ?"; char *server_options[] = { "","--defaults-file=my.cnf","--basedir=./"}; int num_elements = sizeof(server_options)/ sizeof(char *); if(mysql_server_init(num_elements, server_options, NULL)) { puts("failed to initialize server"); return 1; } sql = mysql_init(NULL); if(!mysql_real_connect(sql, NULL , NULL , NULL , NULL, 3306, NULL, 0)) printf("failed to connect\n"); if(mysql_query(sql, query1)) printf("failed to create database:%s\n", mysql_error(sql)); ret = mysql_query(sql, query2); if(ret) printf("failed to use database:%s\n", mysql_error(sql)); ret = mysql_query(sql, query3); if(ret) printf("failed to create table:%s\n", mysql_error(sql)); ret = mysql_query(sql, query4); if(ret) printf("failed to insert record:%s\n", mysql_error(sql)); stmt = mysql_stmt_init(sql); if(!stmt) printf("failed to init stmt:%s\n", mysql_error(sql)); ret = mysql_stmt_prepare(stmt, query5, strlen(query5)); if(ret) printf("failed to prepare:%s\n", mysql_stmt_error(stmt)); result = 1; memset(&bind, 0 , sizeof(bind)); bind.buffer_type = MYSQL_TYPE_LONG; bind.is_unsigned = (my_bool)0; bind.is_null = 0; bind.buffer = (char*)&result; bind.buffer_length = 4; bind.length = &length; ret = mysql_stmt_bind_param(stmt, &bind); if(ret) printf("failed to bind param:%s\n", mysql_stmt_error(stmt)); ret = mysql_stmt_execute(stmt); if(ret) printf("failed to execute stmt:%s\n", mysql_stmt_error(stmt)); memset(&bind, 0 , sizeof(bind)); bind.buffer_type = MYSQL_TYPE_LONG; bind.is_unsigned = (my_bool)0; bind.is_null = 0; bind.buffer = (char*)&result; bind.buffer_length = 4; bind.length = &length; ret = mysql_stmt_bind_result(stmt, &bind); if(ret) printf("failed to bind result:%s\n", mysql_stmt_error(stmt)); ret = mysql_stmt_store_result(stmt); if(ret) printf("failed to store result:%s\n", mysql_stmt_error(stmt)); ret = mysql_stmt_fetch(stmt); if(ret) printf("failed to fetch result:%s\n", mysql_stmt_error(stmt)); mysql_stmt_close(stmt); mysql_close(sql); mysql_server_end(); return 0; } you need create my.cnf in the execute's directory such as : [server] language=../../mysql/share/english datadir=./data [embedded] language=../../mysql/share/english language(../../mysql/share/english) points to mysql/share/english. and you need assign datadir for the data which means you need create the directory if it doesn`t exist. This program failed in mysql_stmt_store_result() and mysql_stmt_fetch(), if modify the source code as I suggested before, it would pass. Looking forward to your answer.
[24 Aug 2011 5:23]
Qi Zhou
i think i selected a wrong category of this bug. changing to libmysqld
[20 Feb 2012 18:34]
Sveta Smirnova
Thank you for the report. Verified as described. Problem is same fetch works for regular client, but not for one which connects to embedded server. In version 5.5 replace "int num_elements = (sizeof(server_options)/ sizeof(char *));" with "int num_elements = (sizeof(server_options)/ sizeof(char *)) - 1;"
[25 Apr 2012 19:12]
Paul DuBois
Noted in 5.1.63, 5.5.24, 5.6.6 changelogs. mysql_store_result() and mysql_use_result() are not for use with prepared statements and are not intended to be called following mysql_stmt_execute(), but failed to return an error when invoked that way in libmysqld.