From 4095a52a778cd227f94d14e8659dbdde71758911 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Jun 2005 01:57:40 +0400 Subject: Fix 11 "fetch from view returns wrong data" Wrong method for creating temporary field was choosen, which results in sending int field with int header but lonlong data. Test case is added to mysql_client_test.c because client library is required to test the bug. tests/mysql_client_test.c: Test case for bug#11111 "fetch from view returns wrong data" sql/sql_select.cc: Fix bug #11111 "fetch from view returns wrong data" sql/item.h: Fix bug #11111 "fetch from view returns wrong data" --- tests/mysql_client_test.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b6ca4996c70..fb18c83b30e 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13145,6 +13145,48 @@ static void test_bug9643() myquery(rc); } +/* + Bug#11111: fetch from view returns wrong data +*/ + +static void test_bug11111() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[2]; + char buf[2][20]; + long len[2]; + int i; + const char * query = "SELECT DISTINCT f1,ff2 FROM v1"; + + mysql_query(mysql, "drop table if exists t1, t2, v1"); + mysql_query(mysql, "create table t1 (f1 int, f2 int)"); + mysql_query(mysql, "create table t2 (ff1 int, ff2 int)"); + mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1"); + mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)"); + mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)"); + + stmt = mysql_stmt_init(mysql); + + mysql_stmt_prepare(stmt, query, strlen(query)); + mysql_stmt_execute(stmt); + + for (i=0; i < 2; i++) { + memset(&bind[i], '\0', sizeof(MYSQL_BIND)); + bind[i].buffer_type= MYSQL_TYPE_STRING; + bind[i].buffer= (gptr *)&buf[i]; + bind[i].buffer_length= 20; + bind[i].length= &len[i]; + } + + if (mysql_stmt_bind_result(stmt, bind)) + printf("Error: %s\n", mysql_stmt_error(stmt)); + + mysql_stmt_fetch(stmt); + DIE_UNLESS(!strcmp(buf[1],"1")); + mysql_stmt_close(stmt); + mysql_query(mysql, "drop table t1, t2, v1"); +} + /* Check that proper cleanups are done for prepared statement when fetching thorugh a cursor. @@ -13439,6 +13481,7 @@ static struct my_tests_st my_tests[]= { { "test_bug9478", test_bug9478 }, { "test_bug9643", test_bug9643 }, { "test_bug10729", test_bug10729 }, + { "test_bug11111", test_bug11111 }, { 0, 0 } }; -- cgit v1.2.1 From 4d8cbb0c27126b897ce26e53e2287c898004a33c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Jun 2005 01:57:25 +0300 Subject: fix of BUG#11111 fix sql/item.h: revrited as recursive sql/sql_select.cc: real_type is virtual tests/mysql_client_test.c: check results abd delete views --- tests/mysql_client_test.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index fb18c83b30e..7a683659df6 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13156,14 +13156,24 @@ static void test_bug11111() char buf[2][20]; long len[2]; int i; + int rc; const char * query = "SELECT DISTINCT f1,ff2 FROM v1"; + myheader("test_bug11111"); - mysql_query(mysql, "drop table if exists t1, t2, v1"); - mysql_query(mysql, "create table t1 (f1 int, f2 int)"); - mysql_query(mysql, "create table t2 (ff1 int, ff2 int)"); - mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1"); - mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)"); - mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)"); + rc= mysql_query(mysql, "drop table if exists t1, t2, v1"); + myquery(rc); + rc= mysql_query(mysql, "drop view if exists t1, t2, v1"); + myquery(rc); + rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)"); + myquery(rc); + rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)"); + myquery(rc); + rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1"); + myquery(rc); + rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)"); + myquery(rc); + rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)"); + myquery(rc); stmt = mysql_stmt_init(mysql); @@ -13176,15 +13186,19 @@ static void test_bug11111() bind[i].buffer= (gptr *)&buf[i]; bind[i].buffer_length= 20; bind[i].length= &len[i]; - } + } if (mysql_stmt_bind_result(stmt, bind)) printf("Error: %s\n", mysql_stmt_error(stmt)); mysql_stmt_fetch(stmt); - DIE_UNLESS(!strcmp(buf[1],"1")); + printf("return: %s", buf[1]); + DIE_UNLESS(!strcmp(buf[1],"1")); mysql_stmt_close(stmt); - mysql_query(mysql, "drop table t1, t2, v1"); + rc= mysql_query(mysql, "drop view v1"); + myquery(rc); + rc= mysql_query(mysql, "drop table t1, t2"); + myquery(rc); } /* -- cgit v1.2.1 From 63c21c07fc4745485804a2ab2e9599d13e732f43 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Jun 2005 23:26:25 +0400 Subject: Rename all prepared statements COM_ commands to prefix with COM_STMT_ libmysql/libmysql.c: Rename. libmysqld/lib_sql.cc: Rename. sql/item_cmpfunc.cc: Use proper method to check for stmt prepare, only_prepare is removed. sql/mysql_priv.h: Remove an obsolete define. Rename mysql_stmt_free to mysql_stmt_close. sql/sql_class.h: Remove THD::only_prepare. Rename. sql/sql_lex.cc: Rename COM_PREPARE -> COM_STMT_PREPARE sql/sql_parse.cc: Rename. sql/sql_prepare.cc: Rename. sql/sql_yacc.yy: Rename. tests/mysql_client_test.c: Rename. --- tests/mysql_client_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 7a683659df6..1cde3a1e978 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13040,7 +13040,7 @@ static void test_bug9478() int4store(buff, stmt->stmt_id); buff[4]= 0; /* Flag */ int4store(buff+5, 1); /* Return 1 row */ - rc= ((*mysql->methods->advanced_command)(mysql, COM_EXECUTE, buff, + rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_EXECUTE, buff, sizeof(buff), 0,0,1) || (*mysql->methods->read_query_result)(mysql)); DIE_UNLESS(rc); -- cgit v1.2.1 From 0f92333d6e6a1e2f6350cb781b8c580d957710e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jun 2005 17:02:31 +0400 Subject: Fix the test for Bug#11111: coding style, a compiler warning, don't use tabs. --- tests/mysql_client_test.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 1cde3a1e978..df268a798e4 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13151,13 +13151,14 @@ static void test_bug9643() static void test_bug11111() { - MYSQL_STMT *stmt; - MYSQL_BIND bind[2]; - char buf[2][20]; - long len[2]; + MYSQL_STMT *stmt; + MYSQL_BIND bind[2]; + char buf[2][20]; + ulong len[2]; int i; int rc; - const char * query = "SELECT DISTINCT f1,ff2 FROM v1"; + const char *query= "SELECT DISTINCT f1,ff2 FROM v1"; + myheader("test_bug11111"); rc= mysql_query(mysql, "drop table if exists t1, t2, v1"); @@ -13175,24 +13176,27 @@ static void test_bug11111() rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)"); myquery(rc); - stmt = mysql_stmt_init(mysql); + stmt= mysql_stmt_init(mysql); mysql_stmt_prepare(stmt, query, strlen(query)); mysql_stmt_execute(stmt); - for (i=0; i < 2; i++) { - memset(&bind[i], '\0', sizeof(MYSQL_BIND)); + bzero(bind, sizeof(bind)); + for (i=0; i < 2; i++) + { bind[i].buffer_type= MYSQL_TYPE_STRING; bind[i].buffer= (gptr *)&buf[i]; bind[i].buffer_length= 20; bind[i].length= &len[i]; } - if (mysql_stmt_bind_result(stmt, bind)) - printf("Error: %s\n", mysql_stmt_error(stmt)); + rc= mysql_stmt_bind_result(stmt, bind); + check_execute(stmt, rc); - mysql_stmt_fetch(stmt); - printf("return: %s", buf[1]); + rc= mysql_stmt_fetch(stmt); + check_execute(stmt, rc); + if (!opt_silent) + printf("return: %s", buf[1]); DIE_UNLESS(!strcmp(buf[1],"1")); mysql_stmt_close(stmt); rc= mysql_query(mysql, "drop view v1"); -- cgit v1.2.1 From c4bd17c0f09551b8bf80eed10c759059dd954987 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jun 2005 17:31:20 +0400 Subject: Rewrite the test for Bug#9992. --- tests/mysql_client_test.c | 76 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 21 deletions(-) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index df268a798e4..8bea0a20a0f 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13266,6 +13266,59 @@ static void test_bug10729() myquery(rc); } + +/* + Check that mysql_next_result works properly in case when one of + the statements used in a multi-statement query is erroneous +*/ + +static void test_bug9992() +{ + MYSQL *mysql1; + MYSQL_RES* res ; + int rc; + + myheader("test_bug9992"); + + if (!opt_silent) + printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n"); + + mysql1= mysql_init(NULL); + + if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password, + opt_db ? opt_db : "test", opt_port, opt_unix_socket, + CLIENT_MULTI_STATEMENTS)) + { + fprintf(stderr, "Failed to connect to the database\n"); + DIE_UNLESS(0); + } + + + /* Sic: SHOW DATABASE is incorrect syntax. */ + rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;"); + + if (rc) + { + fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1)); + DIE_UNLESS(0); + } + + if (!opt_silent) + printf("Testing mysql_store_result/mysql_next_result..\n"); + + res= mysql_store_result(mysql1); + DIE_UNLESS(res); + mysql_free_result(res); + rc= mysql_next_result(mysql1); + DIE_UNLESS(rc == 1); /* Got errors, as expected */ + + if (!opt_silent) + fprintf(stdout, "Got error, sa expected:\n [%d] %s\n", + mysql_errno(mysql1), mysql_error(mysql1)); + + mysql_close(mysql1); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -13500,6 +13553,7 @@ static struct my_tests_st my_tests[]= { { "test_bug9643", test_bug9643 }, { "test_bug10729", test_bug10729 }, { "test_bug11111", test_bug11111 }, + { "test_bug9992", test_bug9992 }, { 0, 0 } }; @@ -13604,23 +13658,6 @@ static void print_test_output() } } - -static void check_mupltiquery_bug9992() -{ - - MYSQL_RES* res ; - mysql_query(mysql,"SHOW TABLES;SHOW DATABASE;SELECT 1;"); - - fprintf(stdout, "\n\n!!! check_mupltiquery_bug9992 !!!\n"); - do - { - if (!(res= mysql_store_result(mysql))) - return; - mysql_free_result(res); - } while (!mysql_next_result(mysql)); - fprintf(stdout, "\n\n!!! SUCCESS !!!\n"); - return; -} /*************************************************************************** main routine ***************************************************************************/ @@ -13686,10 +13723,7 @@ int main(int argc, char **argv) } client_disconnect(); /* disconnect from server */ - - client_connect(CLIENT_MULTI_STATEMENTS); - check_mupltiquery_bug9992(); - client_disconnect(); + free_defaults(defaults_argv); print_test_output(); -- cgit v1.2.1 From c8c0140eec93f7acbf7daa14cf3ab0680879ec92 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Jun 2005 15:38:15 +0400 Subject: Fix a formatting bug and add a test for it. sql/share/errmsg.txt: Fix a formatting bug. sql/sql_prepare.cc: Fix a formatting bug. tests/mysql_client_test.c: Test the server side error message. --- tests/mysql_client_test.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 8bea0a20a0f..8debf7614a3 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -12995,6 +12995,19 @@ static void test_bug9478() rc= mysql_stmt_fetch(stmt); DIE_UNLESS(rc == MYSQL_NO_DATA); + { + char buff[8]; + /* Fill in the fethc packet */ + int4store(buff, stmt->stmt_id); + buff[4]= 1; /* prefetch rows */ + rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH, buff, + sizeof(buff), 0,0,1) || + (*mysql->methods->read_query_result)(mysql)); + DIE_UNLESS(rc); + if (!opt_silent && i == 0) + printf("Got error (as expected): %s\n", mysql_error(mysql)); + } + rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); @@ -13039,7 +13052,7 @@ static void test_bug9478() /* Fill in the execute packet */ int4store(buff, stmt->stmt_id); buff[4]= 0; /* Flag */ - int4store(buff+5, 1); /* Return 1 row */ + int4store(buff+5, 1); /* Reserved for array bind */ rc= ((*mysql->methods->advanced_command)(mysql, COM_STMT_EXECUTE, buff, sizeof(buff), 0,0,1) || (*mysql->methods->read_query_result)(mysql)); -- cgit v1.2.1 From 79c1be9e442f3ba8f735e14a0454533f5914a817 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jun 2005 20:52:15 +0400 Subject: A fix and a test case for Bug#10736 "mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY select within select". The bug was caused by the reset of thd->mem_root to thd->main_mem_root in Item_subselect::exec, which in turn triggered too early free_root() for data which was needed on subsequent fetches from a cursor. This reset also caused a memory leak in stored procedures, as subsequent executions of instructions containing a subselect were allocating memory in thd->main_mem_root, which is not freed until the end of the entire SP, instead of the per-call mem_root, which is freed in the end of execution of the instruction. sql/item_subselect.cc: Don't try to protect subqueries from the code that assumes that it can reset thd->mem_root and get away with it: it's responsibility of the caller to ensure that no assumption about the life span of the allocated memory made by the called code is broken. Besides, this didn't work well with cursors and stored procedures, where the runtime memory root is not the same as &thd->main_mem_root. sql/opt_range.cc: In get_mm_leaf restore the original mem_root of the thd which has been temporarily reset with the quick select mem_root earlier: if thd->mem_root points to the QUICK...::mem_root, the memory allocated in JOIN::exec during evaluation of a subquery gets freed too early. tests/mysql_client_test.c: A test case for Bug#10736 "mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY select within select" --- tests/mysql_client_test.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'tests/mysql_client_test.c') diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 8debf7614a3..585763c164d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13332,6 +13332,64 @@ static void test_bug9992() mysql_close(mysql1); } + +/* Bug#10736: cursors and subqueries, memroot management */ + +static void test_bug10736() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + char a[21]; + int rc; + const char *stmt_text; + int i= 0; + ulong type; + + myheader("test_bug10736"); + + mysql_query(mysql, "drop table if exists t1"); + mysql_query(mysql, "create table t1 (id integer not null primary key," + "name VARCHAR(20) NOT NULL)"); + rc= mysql_query(mysql, "insert into t1 (id, name) values " + "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + + type= (ulong) CURSOR_TYPE_READ_ONLY; + rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type); + check_execute(stmt, rc); + stmt_text= "select name from t1 where name=(select name from t1 where id=2)"; + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + + bzero(bind, sizeof(bind)); + bind[0].buffer_type= MYSQL_TYPE_STRING; + bind[0].buffer= (void*) a; + bind[0].buffer_length= sizeof(a); + mysql_stmt_bind_result(stmt, bind); + + for (i= 0; i < 3; i++) + { + int row_no= 0; + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + while ((rc= mysql_stmt_fetch(stmt)) == 0) + { + if (!opt_silent) + printf("%d: %s\n", row_no, a); + ++row_no; + } + DIE_UNLESS(rc == MYSQL_NO_DATA); + } + rc= mysql_stmt_close(stmt); + DIE_UNLESS(rc == 0); + + rc= mysql_query(mysql, "drop table t1"); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -13567,6 +13625,7 @@ static struct my_tests_st my_tests[]= { { "test_bug10729", test_bug10729 }, { "test_bug11111", test_bug11111 }, { "test_bug9992", test_bug9992 }, + { "test_bug10736", test_bug10736 }, { 0, 0 } }; -- cgit v1.2.1