diff options
author | Patrick Crews <patrick.crews@sun.com> | 2009-02-20 08:40:28 -0500 |
---|---|---|
committer | Patrick Crews <patrick.crews@sun.com> | 2009-02-20 08:40:28 -0500 |
commit | fb20a7d6d0b21d69ff0941f3c0c57c1ae24fbbef (patch) | |
tree | 79b88d80fb3782c681f22352db4479bb313d0025 | |
parent | cf571967ad8625643e0a7251e20246207cee46a9 (diff) | |
parent | 4712e6b9b8e61e468ee94ec65105e61881f77421 (diff) | |
download | mariadb-git-fb20a7d6d0b21d69ff0941f3c0c57c1ae24fbbef.tar.gz |
automerge
-rw-r--r-- | mysql-test/include/wait_show_condition.inc | 78 | ||||
-rw-r--r-- | mysql-test/r/innodb_bug42419.result | 17 | ||||
-rw-r--r-- | mysql-test/r/mysqlbinlog.result | 10 | ||||
-rw-r--r-- | mysql-test/r/row.result | 14 | ||||
-rw-r--r-- | mysql-test/t/innodb_bug42419.test | 77 | ||||
-rw-r--r-- | mysql-test/t/mysqlbinlog.test | 20 | ||||
-rw-r--r-- | mysql-test/t/row.test | 18 | ||||
-rw-r--r-- | sql/item.cc | 77 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 13 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 36 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 64 |
13 files changed, 380 insertions, 48 deletions
diff --git a/mysql-test/include/wait_show_condition.inc b/mysql-test/include/wait_show_condition.inc new file mode 100644 index 00000000000..253101d1e07 --- /dev/null +++ b/mysql-test/include/wait_show_condition.inc @@ -0,0 +1,78 @@ +# include/wait_show_condition.inc +# +# SUMMARY +# +# Waits until the show statement ($show_statement) has at least within one of +# the rows of the result set for the field ($field) a value which fulfils +# a condition ($condition), or the operation times out. +# +# +# USAGE +# +# let $show_statement= SHOW PROCESSLIST; +# let $field= State; +# let $condition= = 'Updating'; +# --source include/wait_show_condition.inc +# +# OR +# +# let $wait_timeout= 60; # Override default of 30 seconds with 60. +# let $show_statement= SHOW PROCESSLIST; +# let $field= State; +# let $condition= = 'Updating'; +# --source include/wait_show_condition.inc +# +# Please do not use this use routine if you can replace the SHOW statement +# with a select. In such a case include/wait_condition.inc is recommended. +# +# Created: 2009-02-18 mleich +# + +let $max_run_time= 30; +if ($wait_timeout) +{ + let $max_run_time= $wait_timeout; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; + +# The smallest timespan till UNIX_TIMESTAMP() gets incremented is ~0 seconds. +# We add one second to avoid the case that somebody measures timespans on a +# real clock with fractions of seconds, detects that n seconds are sufficient, +# assigns n to this routine and suffers because he sometimes gets n - 1 +# seconds in reality. +inc $max_run_time; + +let $found= 0; +let $max_end_time= `SELECT UNIX_TIMESTAMP() + $max_run_time`; +while (`SELECT UNIX_TIMESTAMP() <= $max_end_time AND $found = 0`) +{ + # Sleep a bit to avoid too heavy load. + real_sleep 0.2; + let $rowno= 1; + let $process_result= 1; + while (`SELECT $process_result = 1 AND $found = 0`) + { + let $field_value= query_get_value($show_statement, $field, $rowno); + if (`SELECT '$field_value' $condition`) + { + let $found= 1; + } + if (`SELECT '$field_value' = 'No such row'`) + { + # We are behind the last row of the result set. + let $process_result= 0; + } + inc $rowno; + } +} +if (!$found) +{ + echo # Timeout in include/wait_show_condition.inc for $wait_condition; + echo # show_statement : $show_statement; + echo # field : $field; + echo # condition : $condition; + echo # max_run_time : $max_run_time; +} + diff --git a/mysql-test/r/innodb_bug42419.result b/mysql-test/r/innodb_bug42419.result new file mode 100644 index 00000000000..f304bb634cb --- /dev/null +++ b/mysql-test/r/innodb_bug42419.result @@ -0,0 +1,17 @@ +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t1_tmp ( b INT ); +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +Reap the server message for connection user2 UPDATE t1 ... +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; +DROP TABLE t1; diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index fe536950b4c..d263922e79d 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -369,4 +369,14 @@ drop table t1; 1 drop table t1; shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql +set @@global.server_id= 4294967295; +reset master; +select +(@a:=load_file("MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog")) +is not null; +(@a:=load_file("MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog")) +is not null +1 +*** Unsigned server_id 4294967295 is found: 1 *** +set @@global.server_id= 1; End of 5.0 tests diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result index 98c79d4bc00..9afb528b6dd 100644 --- a/mysql-test/r/row.result +++ b/mysql-test/r/row.result @@ -443,3 +443,17 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a; ROW(a, 1) IN (SELECT SUM(b), 3) 0 DROP TABLE t1; +create table t1 (a varchar(200), +b int unsigned not null primary key auto_increment) +default character set 'utf8'; +create table t2 (c varchar(200), +d int unsigned not null primary key auto_increment) +default character set 'latin1'; +insert into t1 (a) values('abc'); +insert into t2 (c) values('abc'); +select * from t1,t2 where (a,b) = (c,d); +a b c d +abc 1 abc 1 +select host,user from mysql.user where (host,user) = ('localhost','test'); +host user +drop table t1,t2; diff --git a/mysql-test/t/innodb_bug42419.test b/mysql-test/t/innodb_bug42419.test new file mode 100644 index 00000000000..389093a8465 --- /dev/null +++ b/mysql-test/t/innodb_bug42419.test @@ -0,0 +1,77 @@ +# +# Testcase for InnoDB +# Bug#42419 Server crash with "Pure virtual method called" on two concurrent connections +# + +--source include/have_innodb.inc + +let $innodb_lock_wait_timeout= query_get_value(SHOW VARIABLES LIKE 'innodb_lock_wait_timeout%', Value, 1); +if (`SELECT $innodb_lock_wait_timeout < 10`) +{ + --echo # innodb_lock_wait_timeout must be >= 10 seconds + --echo # so that this test can work all time fine on an overloaded testing box + SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'; + exit; +} + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +# First session +connection default; + + +--enable_warnings +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; + +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t1_tmp ( b INT ); + +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; + +# Second session +connect (user2,localhost,root,,,$MASTER_MYPORT,$MASTER_MYSOCK); + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); + +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +send +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; + +# The last update will wait for a lock held by the first session + +# First session +connection default; + +# Poll till the UPDATE of the second session waits for lock +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Updating'; +--source include/wait_show_condition.inc + +# If the testing box is overloadeded and innodb_lock_wait_timeout is too small +# we might get here ER_LOCK_WAIT_TIMEOUT. +--error ER_LOCK_DEADLOCK +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; + +# Second session +connection user2; +--echo Reap the server message for connection user2 UPDATE t1 ... +reap; + +# The server crashed when executing this UPDATE or the succeeding SQL command. +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; + +connection default; +disconnect user2; +DROP TABLE t1; + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index b52ab9c5496..5904115d023 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -272,4 +272,24 @@ echo shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql error 1; exec $MYSQL_BINLOG $MYSQL_TEST_DIR/std_data/corrupt-relay-bin.000624 > $MYSQLTEST_VARDIR/tmp/bug31793.sql; +# +# Bug #37313 BINLOG Contains Incorrect server id +# + +let $save_server_id= `select @@global.server_id`; +let $s_id_max=`select (1 << 32) - 1`; +eval set @@global.server_id= $s_id_max; + +reset master; +--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval select +(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog")) +is not null; +let $s_id_unsigned= `select @a like "%server id $s_id_max%" /* must return 1 */`; +echo *** Unsigned server_id $s_id_max is found: $s_id_unsigned ***; + +eval set @@global.server_id= $save_server_id; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog + --echo End of 5.0 tests diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index 1601f7afd0e..fcc4259168b 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -237,3 +237,21 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a; SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a; DROP TABLE t1; + +# +# Bug#37601 Cast Is Not Done On Row Comparison +# +create table t1 (a varchar(200), + b int unsigned not null primary key auto_increment) +default character set 'utf8'; + +create table t2 (c varchar(200), + d int unsigned not null primary key auto_increment) +default character set 'latin1'; + +insert into t1 (a) values('abc'); +insert into t2 (c) values('abc'); +select * from t1,t2 where (a,b) = (c,d); + +select host,user from mysql.user where (host,user) = ('localhost','test'); +drop table t1,t2; diff --git a/sql/item.cc b/sql/item.cc index bc1ae683e93..f32828629cf 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1608,42 +1608,11 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname, } -/* - Collect arguments' character sets together. - We allow to apply automatic character set conversion in some cases. - The conditions when conversion is possible are: - - arguments A and B have different charsets - - A wins according to coercibility rules - (i.e. a column is stronger than a string constant, - an explicit COLLATE clause is stronger than a column) - - character set of A is either superset for character set of B, - or B is a string constant which can be converted into the - character set of A without data loss. - - If all of the above is true, then it's possible to convert - B into the character set of A, and then compare according - to the collation of A. - - For functions with more than two arguments: - - collect(A,B,C) ::= collect(collect(A,B),C) - - Since this function calls THD::change_item_tree() on the passed Item ** - pointers, it is necessary to pass the original Item **'s, not copies. - Otherwise their values will not be properly restored (see BUG#20769). - If the items are not consecutive (eg. args[2] and args[5]), use the - item_sep argument, ie. - - agg_item_charsets(coll, fname, &args[2], 2, flags, 3) -*/ - -bool agg_item_charsets(DTCollation &coll, const char *fname, - Item **args, uint nargs, uint flags, int item_sep) +bool agg_item_set_converter(DTCollation &coll, const char *fname, + Item **args, uint nargs, uint flags, int item_sep) { Item **arg, *safe_args[2]; - if (agg_item_collations(coll, fname, args, nargs, flags, item_sep)) - return TRUE; /* For better error reporting: save the first and the second argument. @@ -1724,6 +1693,46 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, } +/* + Collect arguments' character sets together. + We allow to apply automatic character set conversion in some cases. + The conditions when conversion is possible are: + - arguments A and B have different charsets + - A wins according to coercibility rules + (i.e. a column is stronger than a string constant, + an explicit COLLATE clause is stronger than a column) + - character set of A is either superset for character set of B, + or B is a string constant which can be converted into the + character set of A without data loss. + + If all of the above is true, then it's possible to convert + B into the character set of A, and then compare according + to the collation of A. + + For functions with more than two arguments: + + collect(A,B,C) ::= collect(collect(A,B),C) + + Since this function calls THD::change_item_tree() on the passed Item ** + pointers, it is necessary to pass the original Item **'s, not copies. + Otherwise their values will not be properly restored (see BUG#20769). + If the items are not consecutive (eg. args[2] and args[5]), use the + item_sep argument, ie. + + agg_item_charsets(coll, fname, &args[2], 2, flags, 3) + +*/ + +bool agg_item_charsets(DTCollation &coll, const char *fname, + Item **args, uint nargs, uint flags, int item_sep) +{ + if (agg_item_collations(coll, fname, args, nargs, flags, item_sep)) + return TRUE; + + return agg_item_set_converter(coll, fname, args, nargs, flags, item_sep); +} + + void Item_ident_for_show::make_field(Send_field *tmp_field) { tmp_field->table_name= tmp_field->org_table_name= table_name; @@ -3010,7 +3019,7 @@ bool Item_param::convert_str_value(THD *thd) str_value.set_charset(value.cs_info.final_character_set_of_str_value); /* Here str_value is guaranteed to be in final_character_set_of_str_value */ - max_length= str_value.length(); + max_length= str_value.numchars() * str_value.charset()->mbmaxlen; decimals= 0; /* str_value_ptr is returned from val_str(). It must be not alloced diff --git a/sql/item.h b/sql/item.h index 1058cc5dbb8..852b0fcc1ba 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1169,6 +1169,8 @@ bool agg_item_collations(DTCollation &c, const char *name, Item **items, uint nitems, uint flags, int item_sep); bool agg_item_collations_for_comparison(DTCollation &c, const char *name, Item **items, uint nitems, uint flags); +bool agg_item_set_converter(DTCollation &coll, const char *fname, + Item **args, uint nargs, uint flags, int item_sep); bool agg_item_charsets(DTCollation &c, const char *name, Item **items, uint nitems, uint flags, int item_sep); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3b1d18b4252..01d3e9bed52 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -490,7 +490,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols()); return 1; } - comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i)); + if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i))) + return 1; } break; } @@ -835,6 +836,16 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, get_value_func= &get_time_value; return 0; } + else if (type == STRING_RESULT && + (*a)->result_type() == STRING_RESULT && + (*b)->result_type() == STRING_RESULT) + { + DTCollation coll; + coll.set((*a)->collation.collation); + if (agg_item_set_converter(coll, owner_arg->func_name(), + b, 1, MY_COLL_CMP_CONV, 1)) + return 1; + } return set_compare_func(owner_arg, type); } diff --git a/sql/log_event.cc b/sql/log_event.cc index ef419aaee40..90805877502 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -976,7 +976,7 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) fputc('#', file); print_timestamp(file); - fprintf(file, " server id %d end_log_pos %s ", server_id, + fprintf(file, " server id %lu end_log_pos %s ", server_id, llstr(log_pos,llbuff)); /* mysqlbinlog --hexdump */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a341cf5e0e9..a820e9966dc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2373,11 +2373,12 @@ typedef struct st_sargable_param */ static bool -make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, +make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, DYNAMIC_ARRAY *keyuse_array) { int error; TABLE *table; + TABLE_LIST *tables= tables_arg; uint i,table_count,const_count,key; table_map found_const_table_map, all_table_map, found_ref, refs; key_map const_ref, eq_part; @@ -2415,10 +2416,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, table_vector[i]=s->table=table=tables->table; table->pos_in_table_list= tables; error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); - if(error) + if (error) { - table->file->print_error(error, MYF(0)); - DBUG_RETURN(1); + table->file->print_error(error, MYF(0)); + goto error; } table->quick_keys.clear_all(); table->reginfo.join_tab=s; @@ -2503,7 +2504,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { join->tables=0; // Don't use join->table my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); - DBUG_RETURN(1); + goto error; } s->key_dependent= s->dependent; } @@ -2513,7 +2514,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, conds, join->cond_equal, ~outer_join, join->select_lex, &sargables)) - DBUG_RETURN(1); + goto error; /* Read tables with 0 or 1 rows (system tables) */ join->const_table_map= 0; @@ -2529,7 +2530,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp=join_read_const_table(s, p_pos))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= s->table->map; @@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp= join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2650,12 +2651,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, set_position(join,const_count++,s,start_keyuse); if (create_ref_for_key(join, s, start_keyuse, found_const_table_map)) - DBUG_RETURN(1); + goto error; if ((tmp=join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2732,7 +2733,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error); if (!select) - DBUG_RETURN(1); + goto error; records= get_quick_record_count(join->thd, select, s->table, &s->const_keys, join->row_limit); s->quick=select->quick; @@ -2778,7 +2779,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { optimize_keyuse(join, keyuse_array); if (choose_plan(join, all_table_map & ~join->const_table_map)) - DBUG_RETURN(TRUE); + goto error; } else { @@ -2788,6 +2789,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, } /* Generate an execution plan from the found optimal join order. */ DBUG_RETURN(join->thd->killed || get_best_combination(join)); + +error: + /* + Need to clean up join_tab from TABLEs in case of error. + They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab + may not be assigned yet by this function (which is building join_tab). + Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke. + */ + for (tables= tables_arg; tables; tables= tables->next_leaf) + tables->table->reginfo.join_tab= NULL; + DBUG_RETURN (1); } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 0fddffebf82..f848e93a5c6 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16410,6 +16410,69 @@ static void test_bug36326() #endif +/** + Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short + string value. +*/ + +static void test_bug41078(void) +{ + uint rc; + MYSQL_STMT *stmt= 0; + MYSQL_BIND param, result; + ulong cursor_type= CURSOR_TYPE_READ_ONLY; + ulong len; + char str[64]; + const char param_str[]= "abcdefghijklmn"; + my_bool is_null, error; + + DBUG_ENTER("test_bug41078"); + + rc= mysql_query(mysql, "SET NAMES UTF8"); + myquery(rc); + + stmt= mysql_simple_prepare(mysql, "SELECT ?"); + check_stmt(stmt); + verify_param_count(stmt, 1); + + rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type); + check_execute(stmt, rc); + + bzero(¶m, sizeof(param)); + param.buffer_type= MYSQL_TYPE_STRING; + param.buffer= (void *) param_str; + len= sizeof(param_str) - 1; + param.length= &len; + + rc= mysql_stmt_bind_param(stmt, ¶m); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + bzero(&result, sizeof(result)); + result.buffer_type= MYSQL_TYPE_STRING; + result.buffer= str; + result.buffer_length= sizeof(str); + result.is_null= &is_null; + result.length= &len; + result.error= &error; + + rc= mysql_stmt_bind_result(stmt, &result); + check_execute(stmt, rc); + + rc= mysql_stmt_store_result(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_fetch(stmt); + check_execute(stmt, rc); + + DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str)); + + mysql_stmt_close(stmt); + + DBUG_VOID_RETURN; +} /* Read and parse arguments and MySQL options from my.cnf @@ -16713,6 +16776,7 @@ static struct my_tests_st my_tests[]= { #ifdef HAVE_QUERY_CACHE { "test_bug36326", test_bug36326 }, #endif + { "test_bug41078", test_bug41078 }, { 0, 0 } }; |