From a1db45674b20c36212acf3bc647134372d048b62 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Oct 2005 21:57:32 +0500 Subject: [PATCH 01/54] Fix for bug #13573 (wrong data inserted for too big decimals) mysql-test/r/type_newdecimal.result: result fixed mysql-test/t/type_newdecimal.test: test case added sql/item_func.cc: conditions fixed sql/my_decimal.cc: overflow handling added sql/my_decimal.h: overflow handling added - so the result of operation gets maximum possible decimal value --- mysql-test/r/type_newdecimal.result | 28 ++++++++++++-- mysql-test/t/type_newdecimal.test | 15 ++++++++ sql/item_func.cc | 12 +++--- sql/my_decimal.cc | 2 +- sql/my_decimal.h | 60 +++++++++++++++++++++-------- 5 files changed, 91 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index be5e29ab662..a99e60e5780 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -846,15 +846,14 @@ select 0/0; NULL select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x; x -999999999999999999999999999999999999999999999999999999999999999999999999999999999 +99999999999999999999999999999999999999999999999999999999999999999 Warnings: Error 1292 Truncated incorrect DECIMAL value: '' select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x; x -NULL +100000000000000000000000000000000000000000000000000000000000000000 Warnings: Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' select 0.190287977636363637 + 0.040372670 * 0 - 0; 0.190287977636363637 + 0.040372670 * 0 - 0 0.190287977636363637 @@ -1019,3 +1018,26 @@ drop procedure wg2; select cast(@non_existing_user_var/2 as DECIMAL); cast(@non_existing_user_var/2 as DECIMAL) NULL +create table t1 (c1 decimal(64)); +insert into t1 values( +89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value adjusted for column 'c1' at row 1 +insert into t1 values( +99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * +99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); +Warnings: +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value adjusted for column 'c1' at row 1 +insert into t1 values(1e100); +Warnings: +Warning 1264 Out of range value adjusted for column 'c1' at row 1 +select * from t1; +c1 +9999999999999999999999999999999999999999999999999999999999999999 +9999999999999999999999999999999999999999999999999999999999999999 +9999999999999999999999999999999999999999999999999999999999999999 +drop table t1; diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 3f04aa931d2..bfebef6207a 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1044,3 +1044,18 @@ drop procedure wg2; # select cast(@non_existing_user_var/2 as DECIMAL); + + +# +# Bug #13573 (Wrong data inserted for too big values) +# + +create table t1 (c1 decimal(64)); +insert into t1 values( +89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); +insert into t1 values( +99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * +99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); +insert into t1 values(1e100); +select * from t1; +drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 491243e9de7..9e92049dea4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -972,8 +972,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || - my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, - val2) > 1))) + (my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, + val2) > 3)))) return decimal_value; return 0; } @@ -1045,8 +1045,8 @@ my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || - my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, - val2) > 1))) + (my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, + val2) > 3)))) return decimal_value; return 0; } @@ -1083,8 +1083,8 @@ my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || - my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, - val2) > 1))) + (my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, + val2) > 3)))) return decimal_value; return 0; } diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index f188d27ff78..1bd16940b47 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -185,7 +185,7 @@ int str2my_decimal(uint mask, const char *from, uint length, } } } - check_result(mask, err); + check_result_and_overflow(mask, err, decimal_value); return err; } diff --git a/sql/my_decimal.h b/sql/my_decimal.h index b65e6aedaa2..b02abacf0a3 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -126,6 +126,19 @@ inline int decimal_operation_results(int result) } #endif /*MYSQL_CLIENT*/ +inline +void max_my_decimal(my_decimal *to, int precision, int frac) +{ + DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&& + (frac <= DECIMAL_MAX_SCALE)); + max_decimal(precision, frac, (decimal_t*) to); +} + +inline void max_internal_decimal(my_decimal *to) +{ + max_my_decimal(to, DECIMAL_MAX_PRECISION, 0); +} + inline int check_result(uint mask, int result) { if (result & mask) @@ -133,6 +146,18 @@ inline int check_result(uint mask, int result) return result; } +inline int check_result_and_overflow(uint mask, int result, my_decimal *val) +{ + if (check_result(mask, result) & E_DEC_OVERFLOW) + { + bool sign= val->sign(); + val->fix_buffer_pointer(); + max_internal_decimal(val); + val->sign(sign); + } + return result; +} + inline uint my_decimal_length_to_precision(uint length, uint scale, bool unsigned_flag) { @@ -256,7 +281,8 @@ int my_decimal2double(uint mask, const my_decimal *d, double *result) inline int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end) { - return check_result(mask, string2decimal(str, (decimal_t*) d, end)); + return check_result_and_overflow(mask, string2decimal(str,(decimal_t*)d,end), + d); } @@ -274,7 +300,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d) inline int double2my_decimal(uint mask, double val, my_decimal *d) { - return check_result(mask, double2decimal(val, (decimal_t*) d)); + return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d); } @@ -303,7 +329,9 @@ inline int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { - return check_result(mask, decimal_add((decimal_t*) a, (decimal_t*) b, res)); + return check_result_and_overflow(mask, + decimal_add((decimal_t*)a,(decimal_t*)b,res), + res); } @@ -311,7 +339,9 @@ inline int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { - return check_result(mask, decimal_sub((decimal_t*) a, (decimal_t*) b, res)); + return check_result_and_overflow(mask, + decimal_sub((decimal_t*)a,(decimal_t*)b,res), + res); } @@ -319,7 +349,9 @@ inline int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { - return check_result(mask, decimal_mul((decimal_t*) a, (decimal_t*) b, res)); + return check_result_and_overflow(mask, + decimal_mul((decimal_t*)a,(decimal_t*)b,res), + res); } @@ -327,8 +359,10 @@ inline int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b, int div_scale_inc) { - return check_result(mask, decimal_div((decimal_t*) a, (decimal_t*) b, res, - div_scale_inc)); + return check_result_and_overflow(mask, + decimal_div((decimal_t*)a,(decimal_t*)b,res, + div_scale_inc), + res); } @@ -336,7 +370,9 @@ inline int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { - return check_result(mask, decimal_mod((decimal_t*) a, (decimal_t*) b, res)); + return check_result_and_overflow(mask, + decimal_mod((decimal_t*)a,(decimal_t*)b,res), + res); } @@ -347,13 +383,5 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b) return decimal_cmp((decimal_t*) a, (decimal_t*) b); } -inline -void max_my_decimal(my_decimal *to, int precision, int frac) -{ - DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&& - (frac <= DECIMAL_MAX_SCALE)); - max_decimal(precision, frac, (decimal_t*) to); -} - #endif /*my_decimal_h*/ From 516699af2372f216b612c18c4c5657d31a909b2e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Oct 2005 10:52:34 +0200 Subject: [PATCH 02/54] Fix for BUG#4544 "read_only also affects temporary tables": the READ_ONLY global variable now allows statements which are to update only temporary tables (note: if a statement, after parse stage, looks like it will update a non-temp table, it will be rejected, even if at execution it would have turned out that 0 rows would be updated; for example UPDATE my_non_tem_table SET a=1 WHERE 1 = 0; will be rejected). sql/sql_parse.cc: The READ_ONLY global variable now allows statements which are to update only temporary tables (note: if a statement, after parse stage, looks like it will update a non-temp table, it will be rejected, even if at execution it would have turned out that 0 rows would be updated; for example UPDATE my_non_tem_table SET a=1 WHERE 1 = 0; will be rejected). mysql-test/r/read_only.result: result for new test mysql-test/t/read_only.test: test for READ_ONLY (there was none!) and for the new behaviour of READ_ONLY --- mysql-test/r/read_only.result | 41 ++++++++++++++ mysql-test/t/read_only.test | 103 ++++++++++++++++++++++++++++++++++ sql/sql_parse.cc | 47 ++++++++++++---- 3 files changed, 181 insertions(+), 10 deletions(-) create mode 100644 mysql-test/r/read_only.result create mode 100644 mysql-test/t/read_only.test diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result new file mode 100644 index 00000000000..09a0861e0c4 --- /dev/null +++ b/mysql-test/r/read_only.result @@ -0,0 +1,41 @@ +DROP TABLE IF EXISTS t1,t2,t3; +grant CREATE, SELECT, DROP on *.* to test@localhost; +set global read_only=0; +create table t1 (a int); +insert into t1 values(1); +create table t2 select * from t1; +set global read_only=1; +create table t3 (a int); +drop table t3; +select @@global.read_only; +@@global.read_only +1 +create table t3 (a int); +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +insert into t1 values(1); +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a; +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +delete t1,t2 from t1,t2 where t1.a=t2.a; +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +create temporary table t3 (a int); +create temporary table t4 (a int) select * from t3; +insert into t3 values(1); +insert into t4 select * from t3; +update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a; +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a; +update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a; +delete t1 from t1,t3 where t1.a=t3.a; +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +delete t3 from t1,t3 where t1.a=t3.a; +delete t4 from t3,t4 where t4.a=t3.a; +create temporary table t1 (a int); +insert into t1 values(1); +update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a; +delete t1 from t1,t3 where t1.a=t3.a; +drop table t1; +insert into t1 values(1); +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +drop table t1,t2; +drop user test@localhost; diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test new file mode 100644 index 00000000000..0861951a6a1 --- /dev/null +++ b/mysql-test/t/read_only.test @@ -0,0 +1,103 @@ +# Test of the READ_ONLY global variable: +# check that it blocks updates unless they are only on temporary tables. + +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3; +--enable_warnings + +# READ_ONLY does nothing to SUPER users +# so we use a non-SUPER one: + +grant CREATE, SELECT, DROP on *.* to test@localhost; + +connect (con1,localhost,test,,test); + +connection default; + +set global read_only=0; + +connection con1; + +create table t1 (a int); + +insert into t1 values(1); + +create table t2 select * from t1; + +connection default; + +set global read_only=1; + +# We check that SUPER can: + +create table t3 (a int); +drop table t3; + +connection con1; + +select @@global.read_only; + +--error 1290 +create table t3 (a int); + +--error 1290 +insert into t1 values(1); + +# if a statement, after parse stage, looks like it will update a +# non-temp table, it will be rejected, even if at execution it would +# have turned out that 0 rows would be updated +--error 1290 +update t1 set a=1 where 1=0; + +# multi-update is special (see sql_parse.cc) so we test it +--error 1290 +update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a; + +# check multi-delete to be sure +--error 1290 +delete t1,t2 from t1,t2 where t1.a=t2.a; + +# With temp tables updates should be accepted: + +create temporary table t3 (a int); + +create temporary table t4 (a int) select * from t3; + +insert into t3 values(1); + +insert into t4 select * from t3; + +# a non-temp table updated: +--error 1290 +update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a; + +# no non-temp table updated (just swapped): +update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a; + +update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a; + +--error 1290 +delete t1 from t1,t3 where t1.a=t3.a; + +delete t3 from t1,t3 where t1.a=t3.a; + +delete t4 from t3,t4 where t4.a=t3.a; + +# and even homonymous ones + +create temporary table t1 (a int); + +insert into t1 values(1); + +update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a; + +delete t1 from t1,t3 where t1.a=t3.a; + +drop table t1; + +--error 1290 +insert into t1 values(1); + +connection default; +drop table t1,t2; +drop user test@localhost; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4d9fddec770..b6865fdebd0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -194,6 +194,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables) #endif +static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) +{ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + DBUG_ASSERT(table->db && table->table_name); + if (table->updating && + !find_temporary_table(thd, table->db, table->table_name)) + return 1; + } + return 0; +} + static HASH hash_user_connections; static int get_or_create_user_conn(THD *thd, const char *user, @@ -2363,7 +2375,7 @@ mysql_execute_command(THD *thd) mysql_reset_errors(thd, 0); #ifdef HAVE_REPLICATION - if (thd->slave_thread) + if (unlikely(thd->slave_thread)) { /* Check if statment should be skipped because of slave filtering @@ -2402,16 +2414,20 @@ mysql_execute_command(THD *thd) } #endif } + else #endif /* HAVE_REPLICATION */ /* - When option readonly is set deny operations which change tables. - Except for the replication thread and the 'super' users. + When option readonly is set deny operations which change non-temporary + tables. Except for the replication thread and the 'super' users. */ if (opt_readonly && - !(thd->slave_thread || - (thd->security_ctx->master_access & SUPER_ACL)) && - uc_update_queries[lex->sql_command]) + !(thd->security_ctx->master_access & SUPER_ACL) && + uc_update_queries[lex->sql_command] && + !((lex->sql_command == SQLCOM_CREATE_TABLE) && + (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) && + ((lex->sql_command != SQLCOM_UPDATE_MULTI) && + some_non_temp_table_to_be_updated(thd, all_tables))) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); DBUG_RETURN(-1); @@ -3210,13 +3226,24 @@ end_with_restore_list: #ifdef HAVE_REPLICATION /* Check slave filtering rules */ - if (thd->slave_thread && all_tables_not_ok(thd, all_tables)) + if (unlikely(thd->slave_thread)) { - /* we warn the slave SQL thread */ - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + if (all_tables_not_ok(thd, all_tables)) + { + /* we warn the slave SQL thread */ + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + break; + } + } + else +#endif /* HAVE_REPLICATION */ + if (opt_readonly && + !(thd->security_ctx->master_access & SUPER_ACL) && + some_non_temp_table_to_be_updated(thd, all_tables)) + { + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); break; } -#endif /* HAVE_REPLICATION */ res= mysql_multi_update(thd, all_tables, &select_lex->item_list, From 2b7f5a45e96413f88ba93ebd85971a3b82cbeb7c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 19:28:27 +0400 Subject: [PATCH 03/54] BUG#13126: When choosing join order for join with nested joins, don't produce join orders that cannot be handled by the executioner. mysql-test/r/bigint.result: Added mssing "drop table if exists" mysql-test/r/join_nested.result: Testcase for BUG#13126 mysql-test/t/bigint.test: Added mssing "drop table if exists" mysql-test/t/join_nested.test: Testcase for BUG#13126 sql/mysql_priv.h: BUG#13126: Added nested_join_map type. sql/sql_prepare.cc: BUG#13126: Don't set NESTED_JOIN::counter to 0 here as it is reset in other place now. sql/sql_select.cc: BUG#13126: When choosing join order for join with nested joins, don't produce join orders that the executioner cannot handle. The work is done by check_interleaving_with_nj() and restore_prev_nj_state() functions that are used from the join optimizer to avoid building invalid join orders. sql/sql_select.h: BUG#13126: Added JOIN_TAB::embedding_map and JOIN::cur_embedding_map. sql/table.h: BUG#13126: In NESTED_JOIN: added nj_map, added comment about where counter is used. --- mysql-test/r/bigint.result | 2 +- mysql-test/r/join_nested.result | 64 ++++++++ mysql-test/t/bigint.test | 2 +- mysql-test/t/join_nested.test | 68 +++++++++ sql/mysql_priv.h | 5 + sql/sql_prepare.cc | 2 - sql/sql_select.cc | 250 ++++++++++++++++++++++++++++++-- sql/sql_select.h | 11 +- sql/table.h | 10 +- 9 files changed, 397 insertions(+), 17 deletions(-) diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index ca9a2662f94..84779858b75 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1, t2; select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296; 0 256 00000000000000065536 2147483647 -2147483648 2147483648 4294967296 0 256 65536 2147483647 -2147483648 2147483648 4294967296 diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index 9d514be76e8..c4dd6cf9a86 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1403,3 +1403,67 @@ SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); ERROR 42S22: Unknown column 'v2.x' in 'field list' DROP VIEW v1, v2; DROP TABLE t1, t2, t3, t4, t5, t6; +create table t1 (id1 int(11) not null); +insert into t1 values (1),(2); +create table t2 (id2 int(11) not null); +insert into t2 values (1),(2),(3),(4); +create table t3 (id3 char(16) not null); +insert into t3 values ('100'); +create table t4 (id2 int(11) not null, id3 char(16)); +create table t5 (id1 int(11) not null, key (id1)); +insert into t5 values (1),(2),(1); +create view v1 as +select t4.id3 from t4 join t2 on t4.id2 = t2.id2; +select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3); +id1 +1 +2 +drop view v1; +drop table t1, t2, t3, t4, t5; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3); +create table t1(a int); +insert into t1 select A.a + 10*(B.a) from t0 A, t0 B; +create table t2 (a int, b int); +insert into t2 values (1,1), (2,2), (3,3); +create table t3(a int, b int, filler char(200), key(a)); +insert into t3 select a,a,'filler' from t1; +insert into t3 select a,a,'filler' from t1; +create table t4 like t3; +insert into t4 select * from t3; +insert into t4 select * from t3; +create table t5 like t4; +insert into t5 select * from t4; +insert into t5 select * from t4; +create table t6 like t5; +insert into t6 select * from t5; +insert into t6 select * from t5; +create table t7 like t6; +insert into t7 select * from t6; +insert into t7 select * from t6; +explain select * from t4 join +t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL X +1 SIMPLE t3 ref a a 5 test.t2.b X +1 SIMPLE t5 ref a a 5 test.t3.b X +1 SIMPLE t4 ref a a 5 test.t3.b X Using where +explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b +join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL X +1 SIMPLE t3 ref a a 5 test.t2.b X Using where +1 SIMPLE t4 ref a a 5 test.t3.b X +1 SIMPLE t6 ref a a 5 test.t4.b X +1 SIMPLE t5 ref a a 5 test.t2.b X +1 SIMPLE t7 ref a a 5 test.t5.b X +explain select * from t2 left join +(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b +join t5 on t5.a=t3.b) on t3.a=t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL X +1 SIMPLE t3 ref a a 5 test.t2.b X +1 SIMPLE t4 ref a a 5 test.t3.b X +1 SIMPLE t6 ref a a 5 test.t4.b X +1 SIMPLE t5 ref a a 5 test.t3.b X +drop table t0, t1, t2, t4, t5, t6; diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index d9c1abd9ba9..7871b3647e3 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -2,7 +2,7 @@ # Initialize --disable_warnings -drop table if exists t1; +drop table if exists t1, t2; --enable_warnings # diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index 0592ec3152f..9dbf153ec55 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -832,3 +832,71 @@ SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); DROP VIEW v1, v2; DROP TABLE t1, t2, t3, t4, t5, t6; + +# +# BUG#13126 -test case from bug report +# +create table t1 (id1 int(11) not null); +insert into t1 values (1),(2); + +create table t2 (id2 int(11) not null); +insert into t2 values (1),(2),(3),(4); + +create table t3 (id3 char(16) not null); +insert into t3 values ('100'); + +create table t4 (id2 int(11) not null, id3 char(16)); + +create table t5 (id1 int(11) not null, key (id1)); +insert into t5 values (1),(2),(1); + +create view v1 as + select t4.id3 from t4 join t2 on t4.id2 = t2.id2; + +select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3); + +drop view v1; +drop table t1, t2, t3, t4, t5; + +create table t0 (a int); +insert into t0 values (0),(1),(2),(3); +create table t1(a int); +insert into t1 select A.a + 10*(B.a) from t0 A, t0 B; + +create table t2 (a int, b int); +insert into t2 values (1,1), (2,2), (3,3); + +create table t3(a int, b int, filler char(200), key(a)); +insert into t3 select a,a,'filler' from t1; +insert into t3 select a,a,'filler' from t1; + +create table t4 like t3; +insert into t4 select * from t3; +insert into t4 select * from t3; + +create table t5 like t4; +insert into t5 select * from t4; +insert into t5 select * from t4; + +create table t6 like t5; +insert into t6 select * from t5; +insert into t6 select * from t5; + +create table t7 like t6; +insert into t7 select * from t6; +insert into t7 select * from t6; + +--replace_column 9 X +explain select * from t4 join + t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b; + +--replace_column 9 X +explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b + join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b; + +--replace_column 9 X +explain select * from t2 left join + (t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b + join t5 on t5.a=t3.b) on t3.a=t2.b; + +drop table t0, t1, t2, t4, t5, t6; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 19ebceab719..198a90dbd8a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -44,6 +44,11 @@ typedef ulonglong table_map; /* Used for table bits in join */ typedef Bitmap<64> key_map; /* Used for finding keys */ typedef ulong key_part_map; /* Used for finding key parts */ +/* + Used for nested join bits within a scope of a join (applicable to non-unary + nested joins that have not been simplified away) +*/ +typedef ulonglong nested_join_map; /* query_id */ typedef ulonglong query_id_t; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 5f3539ca1e9..bf74dd99a68 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2105,8 +2105,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) were closed in the end of previous prepare or execute call. */ tables->table= 0; - if (tables->nested_join) - tables->nested_join->counter= 0; if (tables->prep_on_expr) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 806a6d3ea32..a74e01b866b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -98,6 +98,12 @@ static COND* substitute_for_best_equal_field(COND *cond, void *table_join_idx); static COND *simplify_joins(JOIN *join, List *join_list, COND *conds, bool top); +static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next); +static void restore_prev_nj_state(JOIN_TAB *last); +static void reset_nj_counters(List *join_list); +static uint build_nj_bitmap_for_tables(JOIN *join, List *join_list, + uint first_unused); + static COND *optimize_cond(JOIN *join, COND *conds, List *join_list, Item::cond_result *cond_value); @@ -522,12 +528,14 @@ bool JOIN::test_in_subselect(Item **where) return 0; } + /* global select optimisation. return 0 - success 1 - error error code saved in field 'error' */ + int JOIN::optimize() { @@ -587,6 +595,7 @@ JOIN::optimize() /* Convert all outer joins to inner joins if possible */ conds= simplify_joins(this, join_list, conds, TRUE); + build_nj_bitmap_for_tables(this, join_list, 0); sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; @@ -699,7 +708,8 @@ JOIN::optimize() DBUG_PRINT("error",("Error: make_select() failed")); DBUG_RETURN(1); } - + + reset_nj_counters(join_list); make_outerjoin_info(this); /* @@ -1961,14 +1971,19 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, continue; } outer_join|= table->map; + s->embedding_map= 0; + for (;embedding; embedding= embedding->embedding) + s->embedding_map|= embedding->nested_join->nj_map; continue; } if (embedding) { /* s belongs to a nested join, maybe to several embedded joins */ + s->embedding_map= 0; do { NESTED_JOIN *nested_join= embedding->nested_join; + s->embedding_map|=nested_join->nj_map; s->dependent|= embedding->dep_tables; embedding= embedding->embedding; outer_join|= nested_join->used_tables; @@ -3542,6 +3557,8 @@ choose_plan(JOIN *join, table_map join_tables) bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN; DBUG_ENTER("choose_plan"); + join->cur_embedding_map= 0; + reset_nj_counters(join->join_list); /* if (SELECT_STRAIGHT_JOIN option is set) reorder tables so dependent tables come after tables they depend @@ -4022,7 +4039,9 @@ best_extension_by_limited_search(JOIN *join, for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) { table_map real_table_bit= s->table->map; - if ((remaining_tables & real_table_bit) && !(remaining_tables & s->dependent)) + if ((remaining_tables & real_table_bit) && + !(remaining_tables & s->dependent) && + (!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s))) { double current_record_count, current_read_time; @@ -4038,6 +4057,7 @@ best_extension_by_limited_search(JOIN *join, { DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx, "prune_by_cost");); + restore_prev_nj_state(s); continue; } @@ -4066,6 +4086,7 @@ best_extension_by_limited_search(JOIN *join, { DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx, "pruned_by_heuristic");); + restore_prev_nj_state(s); continue; } } @@ -4100,9 +4121,11 @@ best_extension_by_limited_search(JOIN *join, sizeof(POSITION) * (idx + 1)); join->best_read= current_read_time - 0.001; } - DBUG_EXECUTE("opt", - print_plan(join, current_read_time, current_record_count, idx, "full_plan");); + DBUG_EXECUTE("opt", print_plan(join, current_read_time, + current_record_count, idx, + "full_plan");); } + restore_prev_nj_state(s); } } DBUG_VOID_RETURN; @@ -4147,7 +4170,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++) { table_map real_table_bit=s->table->map; - if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent)) + if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) && + (!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s))) { double best,best_time,records; best=best_time=records=DBL_MAX; @@ -4485,10 +4509,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, join->unit->select_limit_cnt >= records) join->sort_by_table= (TABLE*) 1; // Must use temporary table - /* + /* Go to the next level only if there hasn't been a better key on this level! This will cut down the search for a lot simple cases! - */ + */ double current_record_count=record_count*records; double current_read_time=read_time+best; if (best_record_count > current_record_count || @@ -4509,6 +4533,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, return; swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); } + restore_prev_nj_state(s); if (join->select_options & SELECT_STRAIGHT_JOIN) break; // Don't test all combinations } @@ -5094,7 +5119,7 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab) This function can be called only after the execution plan has been chosen. */ - + static void make_outerjoin_info(JOIN *join) { @@ -7255,11 +7280,11 @@ propagate_cond_constants(THD *thd, I_List *save_list, ascent all attributes are calculated, all outer joins that can be converted are replaced and then all unnecessary braces are removed. As join list contains join tables in the reverse order sequential - elimination of outer joins does not requite extra recursive calls. + elimination of outer joins does not require extra recursive calls. EXAMPLES Here is an example of a join query with invalid cross references: - SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN ON t3.b=t1.b + SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b RETURN VALUE The new condition, if success @@ -7416,7 +7441,210 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) } DBUG_RETURN(conds); } - + + +/* + Assign each nested join structure a bit in nested_join_map + + SYNOPSIS + build_nj_bitmap_for_tables() + join Join being processed + join_list List of tables + first_unused Number of first unused bit in nested_join_map before the + call + + DESCRIPTION + Assign each nested join structure (except for unary nested joins, see + below) a bit in nested_join_map. + + NOTE + This function is called after simplify_joins(), when there are no + redundant nested joins, #non_unary_nested_joins <= #tables_in_join so we + will not run out of bits in nested_join_map. + + RETURN + First unused bit in nested_join_map after the call. +*/ + +static uint build_nj_bitmap_for_tables(JOIN *join, List *join_list, + uint first_unused) +{ + List_iterator li(*join_list); + TABLE_LIST *table; + DBUG_ENTER("build_nj_bitmap_for_tables"); + while ((table= li++)) + { + NESTED_JOIN *nested_join; + if ((nested_join= table->nested_join)) + { + /* + It is guaranteed by simplify_joins() function that a nested join + that has only one child represents a single table VIEW (and a child + is an underlying table). We don't assign a bit to the nested join + because + 1. it is redundant (a "sequence" of one table cannot be interleaved + with anything) + 2. we could run out bits in nested_join_map otherwise. + */ + if (nested_join->join_list.elements != 1) + { + nested_join->nj_map= 1 << first_unused++; + first_unused= build_nj_bitmap_for_tables(join, &nested_join->join_list, + first_unused); + } + } + } + DBUG_RETURN(first_unused); +} + + +/* + Set NESTED_JOIN::counter=0 in all nested joins in passed list + + SYNOPSIS + reset_nj_counters() + join_list List of nested joins to process. It may also contain base + tables which will be ignored. + + DESCRIPTION + Recursively set NESTED_JOIN::counter=0 for all nested joins contained in + the passed join_list. +*/ + +static void reset_nj_counters(List *join_list) +{ + List_iterator li(*join_list); + TABLE_LIST *table; + DBUG_ENTER("reset_nj_counters"); + while ((table= li++)) + { + NESTED_JOIN *nested_join; + if ((nested_join= table->nested_join)) + { + nested_join->counter= 0; + reset_nj_counters(&nested_join->join_list); + } + } + DBUG_VOID_RETURN; +} + + +/* + Check interleaving with an inner tables of an outer join for extension table + + SYNOPSIS + check_interleaving_with_nj() + join Join being processed + last_tab Last table in current partial join order (this function is + not called for empty partial join orders) + next_tab Table we're going to extend the current partial join with + + DESCRIPTION + Check if table next_tab can be added to current partial join order, and + if yes, record that it has been added. + + The function assumes that both current partial join order and its + extension with next_tab are valid wrt table dependencies. + + NOTE + The nested joins aspect of information about current partial join order is + stored in join->cur_embedding_map and + {each_join_table}->pos_in_table_list (->embedding)+ ->nested_join->counter + Joins optimizer calls check_interleaving_with_nj() and + restore_prev_nj_state() to update this info and avoid constructing invalid + join orders. There is no need for any initialization of + {each_join_table}->...->counter before the join optimizer run. + + IMPLEMENTATION + The nested [outer] joins executioner algorithm imposes these limitations + on join order: + 1. "Outer tables first" - any "outer" table must be before any + corresponding "inner" table. + 2. "No interleaving" - tables inside a nested join must form a continuous + sequence in join order (i.e. the sequence must not be interrupted by + tables that are outside of this nested join). + + #1 is checked elsewhere, this function checks #2 provided that #1 has been + already checked. + + WHY NEED NON-INTERLEAVING + Consider an example: + + select * from t0 join t1 left join (t2 join t3) on cond1 + + The join order "t1 t2 t0 t3" is invalid: + + table t0 is outside of the nested join, so WHERE condition for t0 is + attached directly to t0 (without triggers, and it may be used to access + t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss + combinations of (t1, t2, t3) that satisfy condition cond1, and produce a + null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have + been produced. + + If table t0 is not between t2 and t3, the problem doesn't exist: + * If t0 is located after (t2,t3), WHERE(t0) is applied after nested join + processing has finished. + * If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are + wrapped into condition triggers, which takes care of correct nested + join processing. + + RETURN + FALSE Join order extended, nested joins info about current join order + (see NOTE section) updated. + TRUE Requested join order extension not allowed. +*/ + +static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next) +{ + TABLE_LIST *next_emb= next->table->pos_in_table_list->embedding; + JOIN *join= last->join; + + if (join->cur_embedding_map & ~next->embedding_map) + return TRUE; + + for (;next_emb; next_emb= next_emb->embedding) + { + next_emb->nested_join->counter++; + if (next_emb->nested_join->counter == 1) + { + /* next_emb is a first table inside a nested join */ + join->cur_embedding_map |= next_emb->nested_join->nj_map; + } + if (next_emb->nested_join->join_list.elements != + next_emb->nested_join->counter) + break; + join->cur_embedding_map &= ~next_emb->nested_join->nj_map; + } + return FALSE; +} + + +/* + Nested joins perspective: Remove the last table from the join order + + SYNOPSIS + restore_prev_nj_state() + last join table to remove, it is assumed to be the last in current + partial join order. + + DESCRIPTION + Remove the last table from the partial join order and update the nested + joins counters and join->cur_embedding_map. It is ok to call this + function for the first table in join order (for which + check_interleaving_with_nj has not been called) +*/ + +static void restore_prev_nj_state(JOIN_TAB *last) +{ + TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding; + JOIN *join= last->join; + while (last_emb && !(--last_emb->nested_join->counter)) + { + join->cur_embedding_map &= last_emb->nested_join->nj_map; + last_emb= last_emb->embedding; + } +} + static COND * optimize_cond(JOIN *join, COND *conds, List *join_list, diff --git a/sql/sql_select.h b/sql/sql_select.h index d6161eb6372..15872731f0c 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -136,7 +136,9 @@ typedef struct st_join_table { TABLE_REF ref; JOIN_CACHE cache; JOIN *join; - + /* Bitmap of nested joins this table is part of */ + nested_join_map embedding_map; + void cleanup(); } JOIN_TAB; @@ -193,6 +195,13 @@ class JOIN :public Sql_alloc */ ha_rows fetch_limit; POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; + + /* + Bitmap of nested joins embedding the position at the end of the current + partial join (valid only during join optimizer run). + */ + nested_join_map cur_embedding_map; + double best_read; List *fields; List group_fields, group_fields_cache; diff --git a/sql/table.h b/sql/table.h index e76d005f494..00259ec0c18 100644 --- a/sql/table.h +++ b/sql/table.h @@ -757,7 +757,15 @@ typedef struct st_nested_join table_map used_tables; /* bitmap of tables in the nested join */ table_map not_null_tables; /* tables that rejects nulls */ struct st_join_table *first_nested;/* the first nested table in the plan */ - uint counter; /* to count tables in the nested join */ + /* + Used to count tables in the nested join in 2 isolated places: + 1. In make_outerjoin_info(). + 2. check_interleaving_with_nj/restore_prev_nj_state (these are called + by the join optimizer. + Before each use the counters are zeroed by reset_nj_counters. + */ + uint counter; + nested_join_map nj_map; /* Bit used to identify this nested join*/ } NESTED_JOIN; From 2cf69d07211e914a98f1b6f34ac4ae9dd2253ea2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Oct 2005 11:54:15 +0500 Subject: [PATCH 04/54] Additional fix for bug #13573 sql/item_func.cc: don't return NULL when we got E_DEC_OVERFLOW --- sql/item_func.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index 9e92049dea4..2b0f25a2b65 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1124,6 +1124,7 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) { my_decimal value1, *val1; my_decimal value2, *val2; + int err; val1= args[0]->val_decimal(&value1); if ((null_value= args[0]->null_value)) @@ -1131,17 +1132,15 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) val2= args[1]->val_decimal(&value2); if ((null_value= args[1]->null_value)) return 0; - switch (my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, - val1, val2, prec_increment)) { - case E_DEC_TRUNCATED: - case E_DEC_OK: - return decimal_value; - case E_DEC_DIV_ZERO: - signal_divide_by_null(); - default: - null_value= 1; // Safety + if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, + val1, val2, prec_increment)) > 3) + { + if (err == E_DEC_DIV_ZERO) + signal_divide_by_null(); + null_value= 1; return 0; } + return decimal_value; } From d44316cd44df5286da8f687455a85a1da5290872 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Oct 2005 12:15:46 +0500 Subject: [PATCH 05/54] Fix for bug #9551 (Show commands fail) sql/sql_select.cc: stop using temp_pool if we have TEST_KEEP_TMP_TABLES on --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 97d5bf4e1d5..ec5c7a7b51b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8025,7 +8025,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status); - if (use_temp_pool) + if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES)) temp_pool_slot = bitmap_set_next(&temp_pool); if (temp_pool_slot != MY_BIT_NONE) // we got a slot From 0125760fc86c6f0621e696c3384a2c0b3d7dd195 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 31 Oct 2005 13:31:06 -0500 Subject: [PATCH 06/54] fix some issues with IM and long pathnames (with spaces) server-tools/instance-manager/instance_options.cc: small cleanup -and- convert mysqld_path to the proper syntax after reading server-tools/instance-manager/parse_output.cc: stop using get_word since it stops at spaces. Now we just read the entire line and trim spaces. --- .../instance-manager/instance_options.cc | 10 ++++++---- server-tools/instance-manager/parse_output.cc | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 25609f489af..850530b35fc 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -47,14 +47,12 @@ static inline int create_mysqld_command(Buffer *buf, if (buf->get_size()) /* malloc succeeded */ { #ifdef __WIN__ - buf->append(position, "\"", 1); - position++; + buf->append(position++, "\"", 1); #endif buf->append(position, mysqld_path_str, mysqld_path_len); position+= mysqld_path_len; #ifdef __WIN__ - buf->append(position, "\"", 1); - position++; + buf->append(position++, "\"", 1); #endif /* here the '\0' character is copied from the option string */ buf->append(position, option, option_len); @@ -340,6 +338,10 @@ int Instance_options::complete_initialization(const char *default_path, if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path))) goto err; + // it's safe to cast this to char* since this is a buffer we are allocating + char* end= convert_dirname((char*)mysqld_path, mysqld_path, NullS); + end[-1] = 0; + mysqld_path_len= strlen(mysqld_path); if (mysqld_port) diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index b5af3cb83a7..96b0b0fbbc6 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -24,6 +24,20 @@ #include "portability.h" +void trim_space(const char **text, uint *word_len) +{ + const char* start = *text; + while (*start != 0 && *start == ' ') + start++; + *text = start; + + int len= strlen(start); + const char* end= start + len - 1; + while (end > start && (*end == ' ' || *end == '\r' || *end == '\n')) + end--; + *word_len= (end - start)+1; +} + /* Parse output of the given command @@ -85,14 +99,13 @@ int parse_output_and_get_value(const char *command, const char *word, Get the word, which might contain non-alphanumeric characters. (Usually these are '/', '-' and '.' in the path expressions and filenames) */ - get_word((const char **) &linep, &found_word_len, NONSPACE); if (!strncmp(word, linep, wordlen)) { /* If we have found the word, return the next one (this is usually an option value) or the whole line (if flag) */ - linep+= found_word_len; /* swallow the previous one */ + linep+= wordlen; /* swallow the previous one */ if (flag & GET_VALUE) { get_word((const char **) &linep, &found_word_len, NONSPACE); From 69f80875a6c6c00e434bddc117d9a239b138df44 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 31 Oct 2005 13:31:07 -0500 Subject: [PATCH 07/54] improved previous changeset per JimW's review server-tools/instance-manager/instance_options.cc: fixed to coding guidelines server-tools/instance-manager/parse_output.cc: removed tabs and added call to trim_space --- .../instance-manager/instance_options.cc | 2 +- server-tools/instance-manager/parse_output.cc | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 850530b35fc..54ad9da6ab2 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -340,7 +340,7 @@ int Instance_options::complete_initialization(const char *default_path, // it's safe to cast this to char* since this is a buffer we are allocating char* end= convert_dirname((char*)mysqld_path, mysqld_path, NullS); - end[-1] = 0; + end[-1]= 0; mysqld_path_len= strlen(mysqld_path); diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index 96b0b0fbbc6..60b15fde22d 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -26,16 +26,16 @@ void trim_space(const char **text, uint *word_len) { - const char* start = *text; - while (*start != 0 && *start == ' ') - start++; - *text = start; + const char* start = *text; + while (*start != 0 && *start == ' ') + start++; + *text= start; - int len= strlen(start); - const char* end= start + len - 1; - while (end > start && (*end == ' ' || *end == '\r' || *end == '\n')) - end--; - *word_len= (end - start)+1; + int len= strlen(start); + const char* end= start + len - 1; + while (end > start && (*end == ' ' || *end == '\r' || *end == '\n')) + end--; + *word_len= (end - start)+1; } /* @@ -108,7 +108,7 @@ int parse_output_and_get_value(const char *command, const char *word, linep+= wordlen; /* swallow the previous one */ if (flag & GET_VALUE) { - get_word((const char **) &linep, &found_word_len, NONSPACE); + trim_space((const char**) &linep, &found_word_len); if (input_buffer_len <= found_word_len) goto err; strmake(result, linep, found_word_len); From abf4f669a62baf64b8b1490e8682a0fdc5a024e6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Nov 2005 08:36:49 +0300 Subject: [PATCH 08/54] BUG#13126: Post-review fixes: better comments, some function renaming. sql/mysql_priv.h: BUG#13126: Post-review fixes: better comments --- sql/mysql_priv.h | 5 +- sql/sql_select.cc | 163 +++++++++++++++++++++++++++++----------------- 2 files changed, 108 insertions(+), 60 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 198a90dbd8a..e7dab6a6377 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -45,8 +45,9 @@ typedef ulonglong table_map; /* Used for table bits in join */ typedef Bitmap<64> key_map; /* Used for finding keys */ typedef ulong key_part_map; /* Used for finding key parts */ /* - Used for nested join bits within a scope of a join (applicable to non-unary - nested joins that have not been simplified away) + Used to identify NESTED_JOIN structures within a join (applicable only to + structures that have not been simplified away and embed more the one + element) */ typedef ulonglong nested_join_map; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a74e01b866b..219f707b0da 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -101,8 +101,8 @@ static COND *simplify_joins(JOIN *join, List *join_list, static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next); static void restore_prev_nj_state(JOIN_TAB *last); static void reset_nj_counters(List *join_list); -static uint build_nj_bitmap_for_tables(JOIN *join, List *join_list, - uint first_unused); +static uint build_bitmap_for_nested_joins(List *join_list, + uint first_unused); static COND *optimize_cond(JOIN *join, COND *conds, List *join_list, @@ -595,7 +595,7 @@ JOIN::optimize() /* Convert all outer joins to inner joins if possible */ conds= simplify_joins(this, join_list, conds, TRUE); - build_nj_bitmap_for_tables(this, join_list, 0); + build_bitmap_for_nested_joins(join_list, 0); sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; @@ -7447,31 +7447,31 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) Assign each nested join structure a bit in nested_join_map SYNOPSIS - build_nj_bitmap_for_tables() + build_bitmap_for_nested_joins() join Join being processed join_list List of tables first_unused Number of first unused bit in nested_join_map before the call DESCRIPTION - Assign each nested join structure (except for unary nested joins, see - below) a bit in nested_join_map. + Assign each nested join structure (except "confluent" ones - those that + embed only one element) a bit in nested_join_map. NOTE This function is called after simplify_joins(), when there are no - redundant nested joins, #non_unary_nested_joins <= #tables_in_join so we - will not run out of bits in nested_join_map. + redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so + we will not run out of bits in nested_join_map. RETURN First unused bit in nested_join_map after the call. */ -static uint build_nj_bitmap_for_tables(JOIN *join, List *join_list, - uint first_unused) +static uint build_bitmap_for_nested_joins(List *join_list, + uint first_unused) { List_iterator li(*join_list); TABLE_LIST *table; - DBUG_ENTER("build_nj_bitmap_for_tables"); + DBUG_ENTER("build_bitmap_for_nested_joins"); while ((table= li++)) { NESTED_JOIN *nested_join; @@ -7479,9 +7479,9 @@ static uint build_nj_bitmap_for_tables(JOIN *join, List *join_list, { /* It is guaranteed by simplify_joins() function that a nested join - that has only one child represents a single table VIEW (and a child - is an underlying table). We don't assign a bit to the nested join - because + that has only one child represents a single table VIEW (and the child + is an underlying table). We don't assign bits to such nested join + structures because 1. it is redundant (a "sequence" of one table cannot be interleaved with anything) 2. we could run out bits in nested_join_map otherwise. @@ -7489,8 +7489,8 @@ static uint build_nj_bitmap_for_tables(JOIN *join, List *join_list, if (nested_join->join_list.elements != 1) { nested_join->nj_map= 1 << first_unused++; - first_unused= build_nj_bitmap_for_tables(join, &nested_join->join_list, - first_unused); + first_unused= build_bitmap_for_nested_joins(&nested_join->join_list, + first_unused); } } } @@ -7546,73 +7546,120 @@ static void reset_nj_counters(List *join_list) The function assumes that both current partial join order and its extension with next_tab are valid wrt table dependencies. - NOTE - The nested joins aspect of information about current partial join order is - stored in join->cur_embedding_map and - {each_join_table}->pos_in_table_list (->embedding)+ ->nested_join->counter - Joins optimizer calls check_interleaving_with_nj() and - restore_prev_nj_state() to update this info and avoid constructing invalid - join orders. There is no need for any initialization of - {each_join_table}->...->counter before the join optimizer run. - IMPLEMENTATION - The nested [outer] joins executioner algorithm imposes these limitations - on join order: - 1. "Outer tables first" - any "outer" table must be before any - corresponding "inner" table. - 2. "No interleaving" - tables inside a nested join must form a continuous - sequence in join order (i.e. the sequence must not be interrupted by - tables that are outside of this nested join). + LIMITATIONS ON JOIN ORDER + The nested [outer] joins executioner algorithm imposes these limitations + on join order: + 1. "Outer tables first" - any "outer" table must be before any + corresponding "inner" table. + 2. "No interleaving" - tables inside a nested join must form a continuous + sequence in join order (i.e. the sequence must not be interrupted by + tables that are outside of this nested join). - #1 is checked elsewhere, this function checks #2 provided that #1 has been - already checked. + #1 is checked elsewhere, this function checks #2 provided that #1 has + been already checked. WHY NEED NON-INTERLEAVING - Consider an example: - - select * from t0 join t1 left join (t2 join t3) on cond1 - - The join order "t1 t2 t0 t3" is invalid: + Consider an example: + + select * from t0 join t1 left join (t2 join t3) on cond1 + + The join order "t1 t2 t0 t3" is invalid: - table t0 is outside of the nested join, so WHERE condition for t0 is - attached directly to t0 (without triggers, and it may be used to access - t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss - combinations of (t1, t2, t3) that satisfy condition cond1, and produce a - null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have - been produced. - - If table t0 is not between t2 and t3, the problem doesn't exist: - * If t0 is located after (t2,t3), WHERE(t0) is applied after nested join - processing has finished. - * If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are - wrapped into condition triggers, which takes care of correct nested - join processing. - + table t0 is outside of the nested join, so WHERE condition for t0 is + attached directly to t0 (without triggers, and it may be used to access + t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss + combinations of (t1, t2, t3) that satisfy condition cond1, and produce a + null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have + been produced. + + If table t0 is not between t2 and t3, the problem doesn't exist: + * If t0 is located after (t2,t3), WHERE(t0) is applied after nested join + processing has finished. + * If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are + wrapped into condition triggers, which takes care of correct nested + join processing. + + HOW IT IS IMPLEMENTED + The limitations on join order can be rephrased as follows: for valid + join order one must be able to: + 1. write down the used tables in the join order on one line. + 2. for each nested join, put one '(' and one ')' on the said line + 3. write "LEFT JOIN" and "ON (...)" where appropriate + 4. get a query equivalent to the query we're trying to execute. + + Calls to check_interleaving_with_nj() are equivalent to writing the + above described line from left to right. + A single check_interleaving_with_nj(A,B) call is equivalent to writing + table B and appropriate brackets on condition that table A and + appropriate brackets is the last what was written. Graphically the + transition is as follows: + + +---- current position + | + ... last_tab ))) | ( next_tab ) )..) | ... + X Y Z | + +- need to move to this + position. + + Notes about the position: + The caller guarantees that there is no more then one X-bracket by + checking "!(remaining_tables & s->dependent)" before calling this + function. X-bracket may have a pair in Y-bracket. + + When "writing" we store/update this auxilary info about the current + position: + 1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested + joins) we've opened but didn't close. + 2. {each NESTED_JOIN structure not simplified away}->counter - number + of this nested join's children that have already been added to to + the partial join order. + RETURN FALSE Join order extended, nested joins info about current join order (see NOTE section) updated. TRUE Requested join order extension not allowed. */ -static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next) +static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab) { - TABLE_LIST *next_emb= next->table->pos_in_table_list->embedding; - JOIN *join= last->join; + TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding; + JOIN *join= last_tab->join; - if (join->cur_embedding_map & ~next->embedding_map) + if (join->cur_embedding_map & ~next_tab->embedding_map) + { + /* + next_tab is outside of the "pair of brackets" we're currently in. + Cannot add it. + */ return TRUE; + } + /* + Do update counters for "pairs of brackets" that we've left (marked as + X,Y,Z in the above picture) + */ for (;next_emb; next_emb= next_emb->embedding) { next_emb->nested_join->counter++; if (next_emb->nested_join->counter == 1) { - /* next_emb is a first table inside a nested join */ + /* + next_emb is the first table inside a nested join we've "entered". In + the picture above, we're looking at the 'X' bracket. Don't exit yet as + X bracket might have Y pair bracket. + */ join->cur_embedding_map |= next_emb->nested_join->nj_map; } + if (next_emb->nested_join->join_list.elements != next_emb->nested_join->counter) break; + + /* + We're currently at Y or Z-bracket as depicted in the above picture. + Mark that we've left it and continue walking up the brackets hierarchy. + */ join->cur_embedding_map &= ~next_emb->nested_join->nj_map; } return FALSE; From 8439e6a4821471a1e627de3ed045df4364fceb2e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Nov 2005 13:18:46 +0400 Subject: [PATCH 09/54] Fix for bug #14183 (ctype_cp983.test fails with the embedded server) mysql-test/r/ctype_cp932.result: result fixed mysql-test/t/ctype_cp932.test: these lines don't work in embedded-server --- mysql-test/r/ctype_cp932.result | 16 ------------ mysql-test/r/ctype_cp932_binlog.result | 19 ++++++++++++++ mysql-test/t/ctype_cp932.test | 23 ----------------- mysql-test/t/ctype_cp932_binlog.test | 35 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 39 deletions(-) create mode 100644 mysql-test/r/ctype_cp932_binlog.result create mode 100644 mysql-test/t/ctype_cp932_binlog.test diff --git a/mysql-test/r/ctype_cp932.result b/mysql-test/r/ctype_cp932.result index 8763055647c..b384eaa144d 100644 --- a/mysql-test/r/ctype_cp932.result +++ b/mysql-test/r/ctype_cp932.result @@ -8576,22 +8576,6 @@ FC4B DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; -RESET MASTER; -CREATE TABLE t1(f1 blob); -PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; -SET @var1= x'8300'; -EXECUTE stmt1 USING @var1; -SHOW BINLOG EVENTS FROM 79; -Log_name Pos Event_type Server_id Orig_log_pos Info -master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 -master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(f1 blob) -master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 -master-bin.000001 # User var 1 # @`var1`=_binary 0x8300 COLLATE binary -master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@'var1') -SELECT HEX(f1) FROM t1; -HEX(f1) -8300 -DROP table t1; SET collation_connection='cp932_japanese_ci'; create table t1 select repeat('a',4000) a; delete from t1; diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result new file mode 100644 index 00000000000..89f0ae71f4f --- /dev/null +++ b/mysql-test/r/ctype_cp932_binlog.result @@ -0,0 +1,19 @@ +drop table if exists t1; +set names cp932; +set character_set_database = cp932; +RESET MASTER; +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +EXECUTE stmt1 USING @var1; +SHOW BINLOG EVENTS FROM 79; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 +master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(f1 blob) +master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 +master-bin.000001 # User var 1 # @`var1`=_binary 0x8300 COLLATE binary +master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@'var1') +SELECT HEX(f1) FROM t1; +HEX(f1) +8300 +DROP table t1; diff --git a/mysql-test/t/ctype_cp932.test b/mysql-test/t/ctype_cp932.test index d6c3c226140..3ea8be211df 100644 --- a/mysql-test/t/ctype_cp932.test +++ b/mysql-test/t/ctype_cp932.test @@ -401,29 +401,6 @@ DROP TABLE t2; DROP TABLE t3; #DROP TABLE t4; -# Test prepared statement with 0x8300 sequence in parameter while -# running with cp932 client character set. -RESET MASTER; -CREATE TABLE t1(f1 blob); -PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; -SET @var1= x'8300'; -# TODO: Note that this doesn't actually test the code which was added for -# bug#11338 because this syntax for prepared statements causes the PS to -# be replicated differently than if we executed the PS from C or Java. -# Using this syntax, variable names are inserted into the binlog instead -# of values. The real goal of this test is to check the code that was -# added to Item_param::query_val_str() in order to do hex encoding of -# PS parameters when the client character set is cp932; -# Bug#11338 has an example java program which can be used to verify this -# code (and I have used it to test the fix) until there is some way to -# exercise this code from mysql-test-run. -EXECUTE stmt1 USING @var1; ---replace_column 2 # 5 # -SHOW BINLOG EVENTS FROM 79; -SELECT HEX(f1) FROM t1; -DROP table t1; -# end test for bug#11338 - SET collation_connection='cp932_japanese_ci'; -- source include/ctype_filesort.inc -- source include/ctype_innodb_like.inc diff --git a/mysql-test/t/ctype_cp932_binlog.test b/mysql-test/t/ctype_cp932_binlog.test new file mode 100644 index 00000000000..e8ec0d46caf --- /dev/null +++ b/mysql-test/t/ctype_cp932_binlog.test @@ -0,0 +1,35 @@ +-- source include/not_embedded.inc +-- source include/have_cp932.inc + +--character_set cp932 +--disable_warnings +drop table if exists t1; +--enable_warnings + +set names cp932; +set character_set_database = cp932; + +# Test prepared statement with 0x8300 sequence in parameter while +# running with cp932 client character set. +RESET MASTER; +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +# TODO: Note that this doesn't actually test the code which was added for +# bug#11338 because this syntax for prepared statements causes the PS to +# be replicated differently than if we executed the PS from C or Java. +# Using this syntax, variable names are inserted into the binlog instead +# of values. The real goal of this test is to check the code that was +# added to Item_param::query_val_str() in order to do hex encoding of +# PS parameters when the client character set is cp932; +# Bug#11338 has an example java program which can be used to verify this +# code (and I have used it to test the fix) until there is some way to +# exercise this code from mysql-test-run. +EXECUTE stmt1 USING @var1; +--replace_column 2 # 5 # +SHOW BINLOG EVENTS FROM 79; +SELECT HEX(f1) FROM t1; +DROP table t1; +# end test for bug#11338 + +# End of 4.1 tests From 7dd86f7570fcf375af93aa669bda685351db79f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Nov 2005 17:27:10 +0300 Subject: [PATCH 10/54] Fix bug #14466 lost sort order in GROUP_CONCAT() in a view Item_func_group_concat::print() wasn't printing sort order thus creating wrong view. This results in reported error. sql/item_sum.cc: Fix bug #14466 lost sort order in GROUP_CONCAT() in a view Now Item_func_group_concat::print() prints sort order. mysql-test/r/view.result: Test case for bug #14466 lost sort order in GROUP_CONCAT() in a view mysql-test/t/view.test: Test case for bug #14466 lost sort order in GROUP_CONCAT() in a view --- mysql-test/r/view.result | 12 ++++++++++++ mysql-test/t/view.test | 12 +++++++++++- sql/item_sum.cc | 4 ++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 6f15e7af399..a74feb4de17 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2323,3 +2323,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where DROP VIEW v1,v2; DROP TABLE t1,t2,t3; +create table t1 (f1 int, f2 int); +insert into t1 values(1,1),(1,2),(1,3); +create view v1 as select f1 ,group_concat(f2 order by f2 asc) from t1 group by f1; +create view v2 as select f1 ,group_concat(f2 order by f2 desc) from t1 group by f1; +select * from v1; +f1 group_concat(f2 order by f2 asc) +1 1,2,3 +select * from v2; +f1 group_concat(f2 order by f2 desc) +1 3,2,1 +drop view v1,v2; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index aa3189bad69..0bd0e572193 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2189,4 +2189,14 @@ EXPLAIN SELECT * FROM v2 WHERE a=1; DROP VIEW v1,v2; DROP TABLE t1,t2,t3; - +# +# Bug #14466 lost sort order in GROUP_CONCAT() in a view +# +create table t1 (f1 int, f2 int); +insert into t1 values(1,1),(1,2),(1,3); +create view v1 as select f1 ,group_concat(f2 order by f2 asc) from t1 group by f1; +create view v2 as select f1 ,group_concat(f2 order by f2 desc) from t1 group by f1; +select * from v1; +select * from v2; +drop view v1,v2; +drop table t1; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b56d99cf245..b2eaf39d624 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3173,6 +3173,10 @@ void Item_func_group_concat::print(String *str) if (i) str->append(','); (*order[i]->item)->print(str); + if (order[i]->asc) + str->append(" ASC"); + else + str->append(" DESC"); } } str->append(" separator \'", 12); From 1a467f12d8d51b60e60647dcda6e5e53dc0dd2fa Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Nov 2005 16:30:55 +0200 Subject: [PATCH 11/54] Changed MTR_BUILD_THREAD port reserving policy. --- mysql-test/mysql-test-run.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 2133043a587..62c2b9014c3 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -223,10 +223,10 @@ MYSQL_MANAGER_USER=root # number is to be used, 0 - 16 or similar. # if [ -n "$MTR_BUILD_THREAD" ] ; then - MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 40 + 8120` + MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 5 + 10000` MYSQL_MANAGER_PORT=`expr $MASTER_MYPORT + 2` - SLAVE_MYPORT=`expr $MASTER_MYPORT + 16` - NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 24` + SLAVE_MYPORT=`expr $MASTER_MYPORT + 3` + NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 4` echo "Using MTR_BUILD_THREAD = $MTR_BUILD_THREAD" echo "Using MASTER_MYPORT = $MASTER_MYPORT" From 2dcc6cbea3d27ff7c60e27d59e4b11843596d2d4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Nov 2005 21:57:24 +0200 Subject: [PATCH 12/54] Add missing return Compile max with --yassl instead of --with-openssl sql/table.cc: Add missing return BUILD/SETUP.sh: Compile max with --yassl instead of --with-openssl --- BUILD/SETUP.sh | 4 ++-- sql/table.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 96ec5803b63..d598ab94fd0 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -52,9 +52,9 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch #debug_extra_warnings="-Wuninitialized" c_warnings="$global_warnings -Wunused" cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" -base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine" +base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-yassl" base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine" -max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-openssl --with-embedded-server --with-big-tables" +max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-yassl --with-embedded-server --with-big-tables" max_configs="$base_max_configs --with-embedded-server" max_no_ndb_configs="$base_max_no_ndb_configs --with-embedded-server" diff --git a/sql/table.cc b/sql/table.cc index a18ff4397d1..0ea153fa1f2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2538,11 +2538,11 @@ bool st_table_list::prepare_security(THD *thd) tbl->table->grant= grant; } thd->security_ctx= save_security_ctx; - DBUG_RETURN(FALSE); #else while ((tbl= tb++)) tbl->grant.privilege= ~NO_ACCESS; #endif + DBUG_RETURN(FALSE); } From 78ebed64361be7a7194f53ee7ac6e946a1022904 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Nov 2005 21:59:24 +0200 Subject: [PATCH 13/54] Added missing DBUG_ENTER (bug in last push) --- sql/table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/table.cc b/sql/table.cc index 0ea153fa1f2..cbc4342f123 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2511,9 +2511,9 @@ bool st_table_list::prepare_security(THD *thd) { List_iterator_fast tb(*view_tables); TABLE_LIST *tbl; + DBUG_ENTER("st_table_list::prepare_security"); #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *save_security_ctx= thd->security_ctx; - DBUG_ENTER("st_table_list::prepare_security"); DBUG_ASSERT(!prelocking_placeholder); if (prepare_view_securety_context(thd)) From 17fcbcf77290fff34a00ce1387760f5e5c71c134 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 07:05:19 +0300 Subject: [PATCH 14/54] BUG#14026: When doing the end-of-prepare fix up for TABLE_LISTs used in the PS, do the fixup for underlying tables of a merge VIEWs, too. mysql-test/r/view.result: Testcase for BUG#14026 mysql-test/t/view.test: Testcase for BUG#14026 --- mysql-test/r/view.result | 23 ++++++++++++++++++++++- mysql-test/t/view.test | 24 +++++++++++++++++++++++- sql/sql_lex.cc | 40 ++++++++++++++++++++++++++++++---------- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 6f15e7af399..a10972cca98 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1,4 +1,4 @@ -drop table if exists t1,t2,t9,`t1a``b`,v1,v2,v3,v4,v5,v6; +drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6; drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6; drop database if exists mysqltest; use test; @@ -2323,3 +2323,24 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where DROP VIEW v1,v2; DROP TABLE t1,t2,t3; +create table t1 (x int, y int); +create table t2 (x int, y int, z int); +create table t3 (x int, y int, z int); +create table t4 (x int, y int, z int); +create view v1 as +select t1.x +from ( +(t1 join t2 on ((t1.y = t2.y))) +join +(t3 left join t4 on (t3.y = t4.y) and (t3.z = t4.z)) +); +prepare stmt1 from "select count(*) from v1 where x = ?"; +set @parm1=1; +execute stmt1 using @parm1; +count(*) +0 +execute stmt1 using @parm1; +count(*) +0 +drop view v1; +drop table t1,t2,t3,t4; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index aa3189bad69..928e5788dd2 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1,5 +1,5 @@ --disable_warnings -drop table if exists t1,t2,t9,`t1a``b`,v1,v2,v3,v4,v5,v6; +drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6; drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6; drop database if exists mysqltest; --enable_warnings @@ -2189,4 +2189,26 @@ EXPLAIN SELECT * FROM v2 WHERE a=1; DROP VIEW v1,v2; DROP TABLE t1,t2,t3; +# +# BUG#14026 Crash on second PS execution when using views +# +create table t1 (x int, y int); +create table t2 (x int, y int, z int); +create table t3 (x int, y int, z int); +create table t4 (x int, y int, z int); +create view v1 as +select t1.x +from ( + (t1 join t2 on ((t1.y = t2.y))) + join + (t3 left join t4 on (t3.y = t4.y) and (t3.z = t4.z)) +); + +prepare stmt1 from "select count(*) from v1 where x = ?"; +set @parm1=1; + +execute stmt1 using @parm1; +execute stmt1 using @parm1; +drop view v1; +drop table t1,t2,t3,t4; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 11f056d6510..a302db15736 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2037,6 +2037,35 @@ void st_lex::cleanup_after_one_table_open() } +/* + Do end-of-prepare fixup for list of tables and their merge-VIEWed tables + + SYNOPSIS + fix_prepare_info_in_table_list() + thd Thread handle + tbl List of tables to process + + DESCRIPTION + Perform end-end-of prepare fixup for list of tables, if any of the tables + is a merge-algorithm VIEW, recursively fix up its underlying tables as + well. + +*/ + +static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl) +{ + for (; tbl; tbl= tbl->next_local) + { + if (tbl->on_expr) + { + tbl->prep_on_expr= tbl->on_expr; + tbl->on_expr= tbl->on_expr->copy_andor_structure(thd); + } + fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list); + } +} + + /* fix some structures at the end of preparation @@ -2056,16 +2085,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds) prep_where= *conds; *conds= where= prep_where->copy_andor_structure(thd); } - for (TABLE_LIST *tbl= (TABLE_LIST *)table_list.first; - tbl; - tbl= tbl->next_local) - { - if (tbl->on_expr) - { - tbl->prep_on_expr= tbl->on_expr; - tbl->on_expr= tbl->on_expr->copy_andor_structure(thd); - } - } + fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first); } } From a73b682af9d39bda9a1972d268a3703da4131a12 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 14:43:25 +0200 Subject: [PATCH 15/54] Fixed wrong merge Optimize new pushed code sql/item_func.cc: Fixed wrong merge sql/sql_update.cc: Optimize new pushed code (There is no reason to add extra test for not common error case if code can handle it anyway) --- sql/item_func.cc | 1 - sql/sql_update.cc | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index 44cee556dbd..9c1d1f63635 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1378,7 +1378,6 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value) void Item_func_abs::fix_length_and_dec() { Item_func_num1::fix_length_and_dec(); - maybe_null= 1; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index bd19d4d85f3..039aa0f71fa 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -121,7 +121,7 @@ int mysql_update(THD *thd, bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool used_key_is_modified, transactional_table; int res; - int error=0; + int error; uint used_index= MAX_KEY; bool need_sort= TRUE; #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -132,7 +132,7 @@ int mysql_update(THD *thd, ha_rows updated, found; key_map old_used_keys; TABLE *table; - SQL_SELECT *select= 0; + SQL_SELECT *select; READ_RECORD info; SELECT_LEX *select_lex= &thd->lex->select_lex; bool need_reopen; @@ -237,8 +237,7 @@ int mysql_update(THD *thd, } // Don't count on usage of 'only index' when calculating which key to use table->used_keys.clear_all(); - if (limit) - select= make_select(table, 0, 0, conds, 0, &error); + select= make_select(table, 0, 0, conds, 0, &error); if (error || !limit || (select && select->check_quick(thd, safe_update, limit))) { From 5ce36e8134f41aed1e6dbfe585eb8e3c0ef410e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 06:51:44 -0600 Subject: [PATCH 16/54] more refinement of IM patch to fix Windows pathnames with spaces server-tools/instance-manager/instance_options.cc: move declaration of end to start of function so gcc is happy server-tools/instance-manager/parse_output.cc: remove space before = use my_isspace to determine if *end is white space remove comments related to get_word which was removed replace tab character with appropriate # of spaces --- server-tools/instance-manager/instance_options.cc | 3 ++- server-tools/instance-manager/parse_output.cc | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 54ad9da6ab2..b060a1328ea 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -334,12 +334,13 @@ int Instance_options::complete_initialization(const char *default_path, uint instance_type) { const char *tmp; + char* end; if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path))) goto err; // it's safe to cast this to char* since this is a buffer we are allocating - char* end= convert_dirname((char*)mysqld_path, mysqld_path, NullS); + end= convert_dirname((char*)mysqld_path, mysqld_path, NullS); end[-1]= 0; mysqld_path_len= strlen(mysqld_path); diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index 60b15fde22d..d4a015495ea 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -26,14 +26,14 @@ void trim_space(const char **text, uint *word_len) { - const char* start = *text; + const char* start= *text; while (*start != 0 && *start == ' ') start++; *text= start; int len= strlen(start); const char* end= start + len - 1; - while (end > start && (*end == ' ' || *end == '\r' || *end == '\n')) + while (end > start && my_isspace(&my_charset_latin1, *end)) end--; *word_len= (end - start)+1; } @@ -96,19 +96,17 @@ int parse_output_and_get_value(const char *command, const char *word, linebuf[sizeof(linebuf) - 1]= '\0'; /* safety */ /* - Get the word, which might contain non-alphanumeric characters. (Usually - these are '/', '-' and '.' in the path expressions and filenames) + Compare the start of our line with the word(s) we are looking for. */ if (!strncmp(word, linep, wordlen)) { /* - If we have found the word, return the next one (this is usually - an option value) or the whole line (if flag) + If we have found our word(s), then move linep past the word(s) */ - linep+= wordlen; /* swallow the previous one */ + linep+= wordlen; if (flag & GET_VALUE) { - trim_space((const char**) &linep, &found_word_len); + trim_space((const char**) &linep, &found_word_len); if (input_buffer_len <= found_word_len) goto err; strmake(result, linep, found_word_len); From a9b66318889339132295ba313c50dd8023d44199 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 14:57:18 +0200 Subject: [PATCH 17/54] Build max builds with --yassl instead of openssl BUILD/SETUP.sh: Build with --yassl instead of openssl --- BUILD/SETUP.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index d598ab94fd0..3a330853855 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -52,8 +52,8 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch #debug_extra_warnings="-Wuninitialized" c_warnings="$global_warnings -Wunused" cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" -base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-yassl" -base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine" +base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-yassl" +base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-yassl" max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-yassl --with-embedded-server --with-big-tables" max_configs="$base_max_configs --with-embedded-server" max_no_ndb_configs="$base_max_no_ndb_configs --with-embedded-server" From 98d050fdf6de31c52e778c2625fdce5afc0b623a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 14:32:50 +0100 Subject: [PATCH 18/54] Portability fix, opnsrv6c mysys/base64.c: Use unsigned char for d --- mysys/base64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysys/base64.c b/mysys/base64.c index 0fcd6f096f5..fed7a7acc41 100644 --- a/mysys/base64.c +++ b/mysys/base64.c @@ -129,7 +129,7 @@ base64_decode(const char *src, size_t size, void *dst) { char b[3]; size_t i= 0; - void *d= dst; + unsigned char *d= (unsigned char*)dst; size_t j; while (i < size) @@ -181,14 +181,14 @@ base64_decode(const char *src, size_t size, void *dst) b[2]= (c >> 0) & 0xff; for (j=0; j<3-mark; j++) - *(char *)d++= b[j]; + *d++= b[j]; } if (i != size) { return -1; } - return d - dst; + return d - (unsigned char*)dst; } From d76d9dcdedba9322231b34ccfedee55743992b3a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 15:45:25 +0200 Subject: [PATCH 19/54] Use --with-openssl instead of --with-yassl for now BUILD/SETUP.sh: Use --with-openssl instead of --with-yassl for now (We need to fix that libmysqlclient_r links with a -PIC compiled yassl library before enabling yassl) --- BUILD/SETUP.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 3a330853855..4f2065657d5 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -44,17 +44,21 @@ set -e export AM_MAKEFLAGS AM_MAKEFLAGS="-j 4" +# SSL library to use. Should be changed to --with-yassl +SSL_LIBRARY=--with-openssl + # If you are not using codefusion add "-Wpointer-arith" to WARNINGS # The following warning flag will give too many warnings: # -Wshadow -Wunused -Winline (The later isn't usable in C++ as # __attribute()__ doesn't work with gnu C++) + global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings" #debug_extra_warnings="-Wuninitialized" c_warnings="$global_warnings -Wunused" cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" -base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-yassl" -base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-yassl" -max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-yassl --with-embedded-server --with-big-tables" +base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine $SSL_LIBRARY" +base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine $SSL_LIBRARY" +max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine $SSL_LIBRARY --with-embedded-server --with-big-tables" max_configs="$base_max_configs --with-embedded-server" max_no_ndb_configs="$base_max_no_ndb_configs --with-embedded-server" From 37f5c1a82c3dd38492131d78c10615f362a1f136 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 16:28:58 +0200 Subject: [PATCH 20/54] Portability fix (BDB test failed in Intel64) mysql-test/r/bdb.result: Portability fix mysql-test/t/bdb.test: Portability fix --- mysql-test/r/bdb.result | 2 +- mysql-test/t/bdb.test | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index 530ff6ef59b..5cdf9612300 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1870,7 +1870,7 @@ a b drop table t1; create table t1 (v varchar(65530), key(v)); Warnings: -Warning 1071 Specified key was too long; max key length is 1024 bytes +Warning 1071 Specified key was too long; max key length is MAX_KEY_LENGTH bytes drop table if exists t1; create table t1 (v varchar(65536)); Warnings: diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index 3167682f816..97d8f28cd3f 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -962,6 +962,7 @@ source include/varchar.inc; # Some errors/warnings on create # +--replace_result 1024 MAX_KEY_LENGTH 3072 MAX_KEY_LENGTH create table t1 (v varchar(65530), key(v)); drop table if exists t1; create table t1 (v varchar(65536)); From b6a711bf880928a8f74f89a1971cab19159492d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 18:46:13 +0400 Subject: [PATCH 21/54] Additional fix for #13573 strings/decimal.c: here we can run over the buffer - need to check on overflow --- strings/decimal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/strings/decimal.c b/strings/decimal.c index ea6ac2caf38..f536bdb1d6b 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1986,7 +1986,11 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to) carry+=hi; } for (; carry; buf0--) + { + if (buf0 < to->buf) + return E_DEC_OVERFLOW; ADD(*buf0, *buf0, 0, carry); + } } /* Now we have to check for -0.000 case */ From 316e95049d4957923e2a72394b16e988a1d68ad4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 15:53:04 +0100 Subject: [PATCH 22/54] BUG#14514 Creating table with packed key fails silently include/my_base.h: Move HA_CREATE_FROM_ENGINE to HA_OPTION_CREATE_FROM_ENGINE sql/ha_ndbcluster.cc: Use HA_OPTION_CREATE_FROM_ENGINE sql/handler.cc: Use HA_OPTION_CREATE_FROM_ENGINE --- include/my_base.h | 2 +- sql/ha_ndbcluster.cc | 2 +- sql/handler.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index c76cf8c604e..ba3edfad0c8 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -248,6 +248,7 @@ enum ha_base_keytype { #define HA_OPTION_CHECKSUM 32 #define HA_OPTION_DELAY_KEY_WRITE 64 #define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */ +#define HA_OPTION_CREATE_FROM_ENGINE 256 #define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */ #define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */ @@ -258,7 +259,6 @@ enum ha_base_keytype { #define HA_CREATE_TMP_TABLE 4 #define HA_CREATE_CHECKSUM 8 #define HA_CREATE_DELAY_KEY_WRITE 64 -#define HA_CREATE_FROM_ENGINE 128 /* Bits in flag to _status */ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 4248230abbe..71bd3acd2a6 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3861,7 +3861,7 @@ int ha_ndbcluster::create(const char *name, uint pack_length, length, i, pk_length= 0; const void *data, *pack_data; char name2[FN_HEADLEN]; - bool create_from_engine= (info->table_options & HA_CREATE_FROM_ENGINE); + bool create_from_engine= (info->table_options & HA_OPTION_CREATE_FROM_ENGINE); DBUG_ENTER("ha_ndbcluster::create"); DBUG_PRINT("enter", ("name: %s", name)); diff --git a/sql/handler.cc b/sql/handler.cc index 81e94af5dc7..0cc3deda523 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2016,7 +2016,7 @@ int ha_create_table_from_engine(THD* thd, DBUG_RETURN(3); update_create_info_from_table(&create_info, &table); - create_info.table_options|= HA_CREATE_FROM_ENGINE; + create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE; if (lower_case_table_names == 2 && !(table.file->table_flags() & HA_FILE_BASED)) From e9af959eef34eecefb7db59fe31afc250c6fabcb Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 09:30:01 -0600 Subject: [PATCH 23/54] make the IM compile on Windows server-tools/instance-manager/instance_options.cc: fix for coding guidelines server-tools/instance-manager/parse_output.cc: fix for coding guidelines server-tools/instance-manager/priv.cc: don't call pthread_attr_setstacksize on Windows server-tools/instance-manager/priv.h: include my_pthread so the thread functions will compile on Windows --- server-tools/instance-manager/instance_options.cc | 2 +- server-tools/instance-manager/parse_output.cc | 4 ++-- server-tools/instance-manager/priv.cc | 5 +++-- server-tools/instance-manager/priv.h | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index b060a1328ea..83f13b34aa2 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -334,7 +334,7 @@ int Instance_options::complete_initialization(const char *default_path, uint instance_type) { const char *tmp; - char* end; + char *end; if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path))) goto err; diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index d4a015495ea..ebc45c1f7d4 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -26,13 +26,13 @@ void trim_space(const char **text, uint *word_len) { - const char* start= *text; + const char *start= *text; while (*start != 0 && *start == ' ') start++; *text= start; int len= strlen(start); - const char* end= start + len - 1; + const char *end= start + len - 1; while (end > start && my_isspace(&my_charset_latin1, *end)) end--; *word_len= (end - start)+1; diff --git a/server-tools/instance-manager/priv.cc b/server-tools/instance-manager/priv.cc index cf073d9d7dc..a5040aa2e83 100644 --- a/server-tools/instance-manager/priv.cc +++ b/server-tools/instance-manager/priv.cc @@ -73,8 +73,9 @@ unsigned long open_files_limit; int set_stacksize_n_create_thread(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - int rc; + int rc= 0; +#ifndef __WIN__ /* Set stack size to be safe on the platforms with too small default thread stack. @@ -82,7 +83,7 @@ int set_stacksize_n_create_thread(pthread_t *thread, pthread_attr_t *attr, rc= pthread_attr_setstacksize(attr, (size_t) (PTHREAD_STACK_MIN + IM_THREAD_STACK_SIZE)); - +#endif if (!rc) rc= pthread_create(thread, attr, start_routine, arg); return rc; diff --git a/server-tools/instance-manager/priv.h b/server-tools/instance-manager/priv.h index db6fa2ec143..4739bca68eb 100644 --- a/server-tools/instance-manager/priv.h +++ b/server-tools/instance-manager/priv.h @@ -22,7 +22,7 @@ #else #include #endif - +#include "my_pthread.h" /* the pid of the manager process (of the signal thread on the LinuxThreads) */ extern pid_t manager_pid; From 11244083b9b693ead290d895d649cee3e570d682 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 17:34:40 +0100 Subject: [PATCH 24/54] BUG#14514 - Add tests mysql-test/r/ndb_basic.result: Add test result mysql-test/t/ndb_basic.test: Add test case --- mysql-test/r/ndb_basic.result | 4 ++++ mysql-test/t/ndb_basic.test | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index a374f845933..e288592c390 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -673,3 +673,7 @@ select * from atablewithareallylongandirritatingname; a 2 drop table atablewithareallylongandirritatingname; +CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; +select * from t1; +b +drop table t1; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 1c78a4b8744..1a351018b8d 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -615,3 +615,12 @@ create table atablewithareallylongandirritatingname (a int); insert into atablewithareallylongandirritatingname values (2); select * from atablewithareallylongandirritatingname; drop table atablewithareallylongandirritatingname; + + +# +# BUG#14514 +# + +CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; +select * from t1; +drop table t1; From 44a8096dd4b7475cb36c4a5bc0b7f283e11ba340 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 19:28:49 +0200 Subject: [PATCH 25/54] wait_for_update must unlock mutex. (Fixed failure in rpl0000008.test) --- sql/log.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/log.cc b/sql/log.cc index f9f71e2d55a..baa2edab101 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2074,7 +2074,10 @@ void MYSQL_LOG::wait_for_update(THD* thd, bool is_slave) DBUG_ENTER("wait_for_update"); if (reset_pending) + { + pthread_mutex_unlock(&LOCK_log); DBUG_VOID_RETURN; + } old_msg= thd->enter_cond(&update_cond, &LOCK_log, is_slave ? From 8d13a5f4bc2a3dfbf1a89466f1e1bc7277d9c85a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 20:44:09 +0300 Subject: [PATCH 26/54] Fix -ansi -pedantic compilation failure --- sql/spatial.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/spatial.h b/sql/spatial.h index 6189d5c1462..4253689c078 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -245,8 +245,8 @@ public: static Geometry *create_from_wkt(Geometry_buffer *buffer, Gis_read_stream *trs, String *wkt, bool init_stream=1); - static int Geometry::create_from_wkb(Geometry_buffer *buffer, - const char *wkb, uint32 len, String *res); + static int create_from_wkb(Geometry_buffer *buffer, + const char *wkb, uint32 len, String *res); int as_wkt(String *wkt, const char **end) { uint32 len= get_class_info()->m_name.length; From 8a80936517515360c432312a05db232a5e4c5dba Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 13:44:58 -0800 Subject: [PATCH 27/54] #view.test#: new file sql_table.cc, handler.h: Fixed bug #14540. Added error mnemonic code HA_ADMIN_NOT_BASE_TABLE to report that an operation cannot be applied for views. view.test, view.result: Added a test case for bug #14540. errmsg.txt: Fixed bug #14540. Added error ER_CHECK_NOT_BASE_TABLE. mysql-test/r/view.result: Added a test case for bug #14540. mysql-test/t/view.test: Added a test case for bug #14540. sql/handler.h: Fixed bug #14540. Added error mnemonic code HA_ADMIN_NOT_BASE_TABLE to report that an operation cannot be applied for views. sql/share/errmsg.txt: Added error ER_CHECK_NOT_BASE_TABLE. sql/sql_table.cc: Fixed bug #14540. Added error mnemonic code HA_ADMIN_NOT_BASE_TABLE to report that an operation cannot be applied for views. --- mysql-test/r/view.result | 19 +++++++++++++++++++ mysql-test/t/view.test | 15 +++++++++++++++ sql/handler.h | 1 + sql/share/errmsg.txt | 2 ++ sql/sql_table.cc | 33 +++++++++++++++++++++++---------- 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 6f15e7af399..cd35cf4382f 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2323,3 +2323,22 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where DROP VIEW v1,v2; DROP TABLE t1,t2,t3; +CREATE TABLE t1(id INT) ENGINE=MyISAM; +CREATE VIEW v1 AS SELECT id FROM t1; +OPTIMIZE TABLE v1; +Table Op Msg_type Msg_text +test.v1 optimize note You cannot apply optimize to a view +ANALYZE TABLE v1; +Table Op Msg_type Msg_text +test.v1 analyze note You cannot apply analyze to a view +REPAIR TABLE v1; +Table Op Msg_type Msg_text +test.v1 repair note You cannot apply repair to a view +DROP TABLE t1; +OPTIMIZE TABLE v1; +Table Op Msg_type Msg_text +test.v1 optimize note You cannot apply optimize to a view +Warnings: +Error 1146 Table 'test.t1' doesn't exist +Error 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +DROP VIEW v1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index aa3189bad69..2a941027d63 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2189,4 +2189,19 @@ EXPLAIN SELECT * FROM v2 WHERE a=1; DROP VIEW v1,v2; DROP TABLE t1,t2,t3; +# +# Bug #14540: OPTIMIZE, ANALYZE, REPAIR applied to not a view +# + +CREATE TABLE t1(id INT) ENGINE=MyISAM; +CREATE VIEW v1 AS SELECT id FROM t1; + +OPTIMIZE TABLE v1; +ANALYZE TABLE v1; +REPAIR TABLE v1; + +DROP TABLE t1; +OPTIMIZE TABLE v1; + +DROP VIEW v1; diff --git a/sql/handler.h b/sql/handler.h index af80f021e75..16eb8dc6f02 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -45,6 +45,7 @@ #define HA_ADMIN_REJECT -6 #define HA_ADMIN_TRY_ALTER -7 #define HA_ADMIN_WRONG_CHECKSUM -8 +#define HA_ADMIN_NOT_BASE_TABLE -9 /* Bits in table_flags() to show what database can do */ diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index f85bda90e81..0174a1ef98e 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5421,3 +5421,5 @@ ER_NO_REFERENCED_ROW_2 23000 eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" ER_SP_BAD_VAR_SHADOW 42000 eng "Variable '%-.64s' must be quoted with `...`, or renamed" +ER_CHECK_NOT_BASE_TABLE 4200 + eng "You cannot apply %s to a view" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b635c44c6dc..80b337e61d5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2189,7 +2189,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, /* if view are unsupported */ if (table->view && view_operator_func == NULL) { - result_code= HA_ADMIN_NOT_IMPLEMENTED; + result_code= HA_ADMIN_NOT_BASE_TABLE; goto send_result; } thd->open_options&= ~extra_open_options; @@ -2324,6 +2324,16 @@ send_result_message: } break; + case HA_ADMIN_NOT_BASE_TABLE: + { + char buf[ERRMSGSIZE+20]; + uint length=my_snprintf(buf, ERRMSGSIZE, + ER(ER_CHECK_NOT_BASE_TABLE), operator_name); + protocol->store("note", 4, system_charset_info); + protocol->store(buf, length, system_charset_info); + } + break; + case HA_ADMIN_OK: protocol->store("status", 6, system_charset_info); protocol->store("OK",2, system_charset_info); @@ -2424,16 +2434,19 @@ send_result_message: break; } } - if (fatal_error) - table->table->s->version=0; // Force close of table - else if (open_for_modify) + if (table->table) { - pthread_mutex_lock(&LOCK_open); - remove_table_from_cache(thd, table->table->s->db, - table->table->s->table_name, RTFC_NO_FLAG); - pthread_mutex_unlock(&LOCK_open); - /* May be something modified consequently we have to invalidate cache */ - query_cache_invalidate3(thd, table->table, 0); + if (fatal_error) + table->table->s->version=0; // Force close of table + else if (open_for_modify) + { + pthread_mutex_lock(&LOCK_open); + remove_table_from_cache(thd, table->table->s->db, + table->table->s->table_name, RTFC_NO_FLAG); + pthread_mutex_unlock(&LOCK_open); + /* Something may be modified, that's why we have to invalidate cache */ + query_cache_invalidate3(thd, table->table, 0); + } } close_thread_tables(thd); table->table=0; // For query cache From 6b2379afebdacf01d439ac311f14bebefb30bf0c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 01:50:36 +0300 Subject: [PATCH 28/54] func_gconcat.result: Fixed wrong test case table.cc: Fixed wrong DBUG_ENTER placement sql/table.cc: Fixed wrong DBUG_ENTER placement mysql-test/r/func_gconcat.result: Fixed wrong test case --- mysql-test/r/func_gconcat.result | 4 ++-- sql/table.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 6461c393d51..90884dcc596 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -93,7 +93,7 @@ explain extended select grp,group_concat(distinct c order by c desc) from t1 gro id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using filesort Warnings: -Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` separator ',') AS `group_concat(distinct c order by c desc)` from `test`.`t1` group by `test`.`t1`.`grp` +Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` DESC separator ',') AS `group_concat(distinct c order by c desc)` from `test`.`t1` group by `test`.`t1`.`grp` select grp,group_concat(c order by c separator ",") from t1 group by grp; grp group_concat(c order by c separator ",") 1 a @@ -113,7 +113,7 @@ explain extended select grp,group_concat(distinct c order by c separator ",") fr id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using filesort Warnings: -Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` separator ',') AS `group_concat(distinct c order by c separator ",")` from `test`.`t1` group by `test`.`t1`.`grp` +Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` ASC separator ',') AS `group_concat(distinct c order by c separator ",")` from `test`.`t1` group by `test`.`t1`.`grp` select grp,group_concat(distinct c order by c desc separator ",") from t1 group by grp; grp group_concat(distinct c order by c desc separator ",") 1 a diff --git a/sql/table.cc b/sql/table.cc index 809787a9203..dd6018b70f3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2511,9 +2511,9 @@ bool st_table_list::prepare_security(THD *thd) { List_iterator_fast tb(*view_tables); TABLE_LIST *tbl; + DBUG_ENTER("st_table_list::prepare_security"); #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *save_security_ctx= thd->security_ctx; - DBUG_ENTER("st_table_list::prepare_security"); DBUG_ASSERT(!prelocking_placeholder); if (prepare_view_securety_context(thd)) From 4934c9be9d6f61c3a91ae10002c5361d49f10dfe Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 17:56:12 -0800 Subject: [PATCH 29/54] Don't allow startup when default storage engine is specified to be a storage engine that is disabled. This was fixed once in 4.1, but regressed in 5.0 because of changes to storage engine initialization. (Bug #9815) sql/mysqld.cc: Move check of whether default storage engine is available to after storage engine initialization. --- sql/mysqld.cc | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 143ed74e012..190c1d951b4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3033,6 +3033,23 @@ server."); sql_print_error("Can't init databases"); unireg_abort(1); } + + /* + Check that the default storage engine is actually available. + */ + if (!ha_storage_engine_is_enabled((enum db_type) + global_system_variables.table_type)) + { + if (!opt_bootstrap) + { + sql_print_error("Default storage engine (%s) is not available", + ha_get_storage_engine((enum db_type) + global_system_variables.table_type)); + unireg_abort(1); + } + global_system_variables.table_type= DB_TYPE_MYISAM; + } + tc_log= (total_ha_2pc > 1 ? (opt_bin_log ? (TC_LOG *) &mysql_bin_log : (TC_LOG *) &tc_log_mmap) : @@ -6999,22 +7016,6 @@ static void get_options(int argc,char **argv) !opt_slow_log) sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set"); - /* - Check that the default storage engine is actually available. - */ - if (!ha_storage_engine_is_enabled((enum db_type) - global_system_variables.table_type)) - { - if (!opt_bootstrap) - { - sql_print_error("Default storage engine (%s) is not available", - ha_get_storage_engine((enum db_type) - global_system_variables.table_type)); - exit(1); - } - global_system_variables.table_type= DB_TYPE_MYISAM; - } - if (argc > 0) { fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv); From 3e2e44f044e51d51c5d6b00f94431d527e0a7cc1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Nov 2005 22:13:10 -0800 Subject: [PATCH 30/54] Post review fixes. sql/sql_table.cc: Post review fixes --- mysql-test/r/view.result | 2 +- mysql-test/t/view.test | 2 +- sql/share/errmsg.txt | 2 +- sql/sql_table.cc | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index cd35cf4382f..07627c9078b 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2323,7 +2323,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where DROP VIEW v1,v2; DROP TABLE t1,t2,t3; -CREATE TABLE t1(id INT) ENGINE=MyISAM; +CREATE TABLE t1(id INT); CREATE VIEW v1 AS SELECT id FROM t1; OPTIMIZE TABLE v1; Table Op Msg_type Msg_text diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 2a941027d63..db77982e3eb 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2193,7 +2193,7 @@ DROP TABLE t1,t2,t3; # Bug #14540: OPTIMIZE, ANALYZE, REPAIR applied to not a view # -CREATE TABLE t1(id INT) ENGINE=MyISAM; +CREATE TABLE t1(id INT); CREATE VIEW v1 AS SELECT id FROM t1; OPTIMIZE TABLE v1; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 0174a1ef98e..24e1d4b6b81 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5421,5 +5421,5 @@ ER_NO_REFERENCED_ROW_2 23000 eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" ER_SP_BAD_VAR_SHADOW 42000 eng "Variable '%-.64s' must be quoted with `...`, or renamed" -ER_CHECK_NOT_BASE_TABLE 4200 +ER_CHECK_NOT_BASE_TABLE 42000 eng "You cannot apply %s to a view" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 80b337e61d5..bc604537139 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2326,11 +2326,11 @@ send_result_message: case HA_ADMIN_NOT_BASE_TABLE: { - char buf[ERRMSGSIZE+20]; - uint length=my_snprintf(buf, ERRMSGSIZE, - ER(ER_CHECK_NOT_BASE_TABLE), operator_name); - protocol->store("note", 4, system_charset_info); - protocol->store(buf, length, system_charset_info); + char buf[ERRMSGSIZE+20]; + uint length= my_snprintf(buf, ERRMSGSIZE, + ER(ER_CHECK_NOT_BASE_TABLE), operator_name); + protocol->store("note", 4, system_charset_info); + protocol->store(buf, length, system_charset_info); } break; @@ -2442,7 +2442,7 @@ send_result_message: { pthread_mutex_lock(&LOCK_open); remove_table_from_cache(thd, table->table->s->db, - table->table->s->table_name, RTFC_NO_FLAG); + table->table->s->table_name, RTFC_NO_FLAG); pthread_mutex_unlock(&LOCK_open); /* Something may be modified, that's why we have to invalidate cache */ query_cache_invalidate3(thd, table->table, 0); From 1fb1802e71d7535b74d6880e69b8fa39250b0390 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 11:05:52 +0200 Subject: [PATCH 31/54] Changed mysql-test-run to correspond to the one in 5.0 tree. --- mysql-test/mysql-test-run.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 9a2c4345bae..296bbecc843 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -208,9 +208,9 @@ MYSQL_MANAGER_USER=root # number is to be used, 0 - 16 or similar. # if [ -n "$MTR_BUILD_THREAD" ] ; then - MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 40 + 8120` - SLAVE_MYPORT=`expr $MASTER_MYPORT + 16` + MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 5 + 10000` MYSQL_MANAGER_PORT=`expr $MASTER_MYPORT + 2` + SLAVE_MYPORT=`expr $MASTER_MYPORT + 3` echo "Using MTR_BUILD_THREAD = $MTR_BUILD_THREAD" echo "Using MASTER_MYPORT = $MASTER_MYPORT" From 9a714420677f0e5412f3f8df92425f28976d2c39 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 11:19:06 +0200 Subject: [PATCH 32/54] Added new build script for pentium64. --- BUILD/compile-pentium64-debug-max | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 BUILD/compile-pentium64-debug-max diff --git a/BUILD/compile-pentium64-debug-max b/BUILD/compile-pentium64-debug-max new file mode 100755 index 00000000000..f0745c88c90 --- /dev/null +++ b/BUILD/compile-pentium64-debug-max @@ -0,0 +1,13 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" $@ --with-debug=full + +extra_flags="$pentium64_cflags $debug_cflags $max_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$pentium_configs $debug_configs $max_configs" + +extra_configs="$extra_configs " + +. "$path/FINISH.sh" From f8aa1db39ca5a5dfb8027706b73c644e5679d310 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 10:37:49 +0100 Subject: [PATCH 33/54] Bug#13957 yassl: opensrv6c compile failure - Added some ifdefs and turn off auto template instantiation, use explicit template instantiation configure.in: Use -Tno_implict to indicate that we specifiy which template should be instantiated. Turn on HAVE_EXPLICIT_TEMPLATE_INSTATNTIATION extra/yassl/src/socket_wrapper.cpp: Include sys/filio.h if __SCO_VERSION__ is defined extra/yassl/src/timer.cpp: Dont' include files from within namespace yaSSL. --- configure.in | 4 ++++ extra/yassl/src/socket_wrapper.cpp | 2 +- extra/yassl/src/timer.cpp | 12 +++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 2179c82e2e5..5e1cc5f307d 100644 --- a/configure.in +++ b/configure.in @@ -334,6 +334,10 @@ case "$target_os" in # Use the built-in alloca() CFLAGS="$CFLAGS -Kalloca" CXXFLAGS="$CFLAGS -Kalloca" + # Use no_implicit for templates + CXXFLAGS="$CXXFLAGS -Tno_implicit" + AC_DEFINE([HAVE_EXPLICIT_TEMPLATE_INSTANTIATION], + [1], [Defined by configure. Use explicit template instantiation.]) fi ;; esac diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index 91cea1f9753..285e0dee2e5 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -39,7 +39,7 @@ #include #endif // _WIN32 -#ifdef __sun +#if defined(__sun) || defined(__SCO_VERSION__) #include #endif diff --git a/extra/yassl/src/timer.cpp b/extra/yassl/src/timer.cpp index 4fe0d3aa4f9..8b7d2d17a84 100644 --- a/extra/yassl/src/timer.cpp +++ b/extra/yassl/src/timer.cpp @@ -26,13 +26,17 @@ #include "runtime.hpp" #include "timer.hpp" +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else +#include +#endif + namespace yaSSL { #ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #include - timer_d timer() { static bool init(false); @@ -57,8 +61,6 @@ namespace yaSSL { #else // _WIN32 - #include - timer_d timer() { struct timeval tv; From a7956c817e8afa1c3b5c119cdf2bc033fe839324 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 12:38:46 +0300 Subject: [PATCH 34/54] Post-merge fixes --- mysql-test/r/view.result | 24 ++++++++++++------------ mysql-test/t/view.test | 31 ++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 52ccabf60cd..22edc4969e4 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2323,6 +2323,18 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where DROP VIEW v1,v2; DROP TABLE t1,t2,t3; +create table t1 (f1 int, f2 int); +insert into t1 values(1,1),(1,2),(1,3); +create view v1 as select f1 ,group_concat(f2 order by f2 asc) from t1 group by f1; +create view v2 as select f1 ,group_concat(f2 order by f2 desc) from t1 group by f1; +select * from v1; +f1 group_concat(f2 order by f2 asc) +1 1,2,3 +select * from v2; +f1 group_concat(f2 order by f2 desc) +1 3,2,1 +drop view v1,v2; +drop table t1; create table t1 (x int, y int); create table t2 (x int, y int, z int); create table t3 (x int, y int, z int); @@ -2344,15 +2356,3 @@ count(*) 0 drop view v1; drop table t1,t2,t3,t4; -create table t1 (f1 int, f2 int); -insert into t1 values(1,1),(1,2),(1,3); -create view v1 as select f1 ,group_concat(f2 order by f2 asc) from t1 group by f1; -create view v2 as select f1 ,group_concat(f2 order by f2 desc) from t1 group by f1; -select * from v1; -f1 group_concat(f2 order by f2 asc) -1 1,2,3 -select * from v2; -f1 group_concat(f2 order by f2 desc) -1 3,2,1 -drop view v1,v2; -drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 7918c78deb3..7ab2c4779b9 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2190,13 +2190,6 @@ DROP VIEW v1,v2; DROP TABLE t1,t2,t3; # -prepare stmt1 from "select count(*) from v1 where x = ?"; -set @parm1=1; - -execute stmt1 using @parm1; -execute stmt1 using @parm1; -drop view v1; -drop table t1,t2,t3,t4; # Bug #14466 lost sort order in GROUP_CONCAT() in a view # create table t1 (f1 int, f2 int); @@ -2207,3 +2200,27 @@ select * from v1; select * from v2; drop view v1,v2; drop table t1; + +# +# BUG#14026 Crash on second PS execution when using views +# +create table t1 (x int, y int); +create table t2 (x int, y int, z int); +create table t3 (x int, y int, z int); +create table t4 (x int, y int, z int); + +create view v1 as +select t1.x +from ( + (t1 join t2 on ((t1.y = t2.y))) + join + (t3 left join t4 on (t3.y = t4.y) and (t3.z = t4.z)) +); + +prepare stmt1 from "select count(*) from v1 where x = ?"; +set @parm1=1; + +execute stmt1 using @parm1; +execute stmt1 using @parm1; +drop view v1; +drop table t1,t2,t3,t4; From fb4c949f57b281a232ea581e26b8c48be6c1d873 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 11:47:54 +0200 Subject: [PATCH 35/54] Added test-force to Makefile. --- Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.am b/Makefile.am index 35c5a51caf4..54bafaaa40a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -96,3 +96,7 @@ tags: test: cd mysql-test ; \ ./mysql-test-run + +test-force: + cd mysql-test ; \ + ./mysql-test-run --force From bb841518b9755feadc97e2b1bc5b28bdd394075e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 13:53:49 +0300 Subject: [PATCH 36/54] Fix bug #14093 Query takes a lot of time when date format is not valid Invalid date like 2000-02-32 wasn't converted to int, which lead to not using index and comparison with field as astring, which results in slow query execution. convert_constatn_item() and get_mm_leaf() now forces MODE_INVALID_DATES to allow such conversion. sql/item.h: Fix bug #14093 Query takes a lot of time when date format is not valid To Item_int_with_ref added method real_item() which returns ref. sql/item_cmpfunc.cc: Fix bug #14093 Query takes a lot of time when date format is not valid convert_constant_item() now allows conversion of invalid dates like 2000-01-32 to int to make it possible to use index when comparing fields with such dates. sql/opt_range.cc: Fix bug #14093 Query takes a lot of time when date format is not valid get_mm_leaf() modified so it allows index usage for comparing fields with invalid dates like 2000-01-32. mysql-test/r/select.result: Test case for bug#14093 Query takes a lot of time when date format is not valid mysql-test/t/select.test: Test case for bug#14093 Query takes a lot of time when date format is not valid --- mysql-test/r/select.result | 40 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 18 +++++++++++++++++ sql/item.h | 1 + sql/item_cmpfunc.cc | 5 +++++ sql/opt_range.cc | 9 ++++++++- 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index cd7c70b603c..7ceedea344f 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3193,3 +3193,43 @@ a b c select * from t1 join t2 straight_join t3 on (t1.a=t3.c); a b c drop table t1, t2 ,t3; +create table t1(f1 int, f2 date); +insert into t1 values(1,'2005-01-01'),(2,'2005-09-01'),(3,'2005-09-30'), +(4,'2005-10-01'),(5,'2005-12-30'); +select * from t1 where f2 >= 0; +f1 f2 +1 2005-01-01 +2 2005-09-01 +3 2005-09-30 +4 2005-10-01 +5 2005-12-30 +select * from t1 where f2 >= '0000-00-00'; +f1 f2 +1 2005-01-01 +2 2005-09-01 +3 2005-09-30 +4 2005-10-01 +5 2005-12-30 +select * from t1 where f2 >= '2005-09-31'; +f1 f2 +4 2005-10-01 +5 2005-12-30 +select * from t1 where f2 >= '2005-09-3a'; +f1 f2 +4 2005-10-01 +5 2005-12-30 +Warnings: +Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1 +select * from t1 where f2 <= '2005-09-31'; +f1 f2 +1 2005-01-01 +2 2005-09-01 +3 2005-09-30 +select * from t1 where f2 <= '2005-09-3a'; +f1 f2 +1 2005-01-01 +2 2005-09-01 +3 2005-09-30 +Warnings: +Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1 +drop table t1; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index a3d83c531d2..128115ed12a 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2702,3 +2702,21 @@ select * from t1 join t2 left join t3 on (t1.a=t3.c); select * from t1 join t2 right join t3 on (t1.a=t3.c); select * from t1 join t2 straight_join t3 on (t1.a=t3.c); drop table t1, t2 ,t3; + +# +# Bug #14093 Query takes a lot of time when date format is not valid +# fix optimizes execution. so here we just check that returned set is +# correct. +create table t1(f1 int, f2 date); +insert into t1 values(1,'2005-01-01'),(2,'2005-09-01'),(3,'2005-09-30'), + (4,'2005-10-01'),(5,'2005-12-30'); +# should return all records +select * from t1 where f2 >= 0; +select * from t1 where f2 >= '0000-00-00'; +# should return 4,5 +select * from t1 where f2 >= '2005-09-31'; +select * from t1 where f2 >= '2005-09-3a'; +# should return 1,2,3 +select * from t1 where f2 <= '2005-09-31'; +select * from t1 where f2 <= '2005-09-3a'; +drop table t1; diff --git a/sql/item.h b/sql/item.h index 3e52cbe5fd7..5f31e402c77 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1749,6 +1749,7 @@ public: return ref->save_in_field(field, no_conversions); } Item *new_item(); + virtual Item *real_item() { return ref; } }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 761d15c8a3e..06cb83a7101 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -186,13 +186,18 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item) { if ((*item)->const_item()) { + /* For comparison purposes allow invalid dates like 2000-01-32 */ + ulong orig_sql_mode= field->table->in_use->variables.sql_mode; + field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES; if (!(*item)->save_in_field(field, 1) && !((*item)->null_value)) { Item *tmp=new Item_int_with_ref(field->val_int(), *item); + field->table->in_use->variables.sql_mode= orig_sql_mode; if (tmp) thd->change_item_tree(item, tmp); return 1; // Item was replaced } + field->table->in_use->variables.sql_mode= orig_sql_mode; } return 0; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ff2b14a27ee..4a9e2556df7 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3921,13 +3921,20 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, value->result_type() != STRING_RESULT && field->cmp_type() != value->result_type()) goto end; - + /* For comparison purposes allow invalid dates like 2000-01-32 */ + ulong orig_sql_mode= field->table->in_use->variables.sql_mode; + if (value->real_item()->type() == Item::STRING_ITEM && + (field->type() == FIELD_TYPE_DATE || + field->type() == FIELD_TYPE_DATETIME)) + field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES; if (value->save_in_field_no_warnings(field, 1) < 0) { + field->table->in_use->variables.sql_mode= orig_sql_mode; /* This happens when we try to insert a NULL field in a not null column */ tree= &null_element; // cmp with NULL is never TRUE goto end; } + field->table->in_use->variables.sql_mode= orig_sql_mode; str= (char*) alloc_root(alloc, key_part->store_length+1); if (!str) goto end; From 3fa0dd23e0b6df54f8c94085963264c17c3cd715 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 14:20:13 +0300 Subject: [PATCH 37/54] A fix and a test case for Bug#14210 "Simple query with > operator on large table gives server crash": make sure that when a MyISAM temporary table is created for a cursor, it's created in its memory root, not the memory root of the current query. mysql-test/r/sp.result: Test results fixed: a test case for Bug#14210 mysql-test/t/sp.test: A test case for Bug#14210 "Simple query with > operator on large table gives server crash" sql/handler.cc: - rewrite get_new_handler to accept a memory root and use it for sql/handler.h: - get_new_handler declaration changed sql/opt_range.cc: - get_new_handler declaration changed sql/sql_base.cc: - get_new_handler declaration changed sql/sql_select.cc: - the actual fix for Bug#14210. In create_myisam_from_heap we should create the new table handler in TABLE::mem_root, not in THD::mem_root: the latter is freed shortly after cursor is open. - adjust create_tmp_table to explicitly supply &table->mem_root to get_new_handler when creating a handler for a new temporary table sql/sql_table.cc: - get_new_handler declaration changed sql/table.cc: - get_new_handler declaration changed sql/unireg.cc: - get_new_handler declaration changed tests/mysql_client_test.c: A test case for Bug#14210 "Simple query with > operator on large table gives server crash": a C API test case is worth adding because of different memory allocation/freeing patterns in handling of C API and SP cursors --- mysql-test/r/sp.result | 42 ++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 52 +++++++++++++++++++++++++++++++++++++ sql/handler.cc | 36 ++++++++++++++------------ sql/handler.h | 2 +- sql/opt_range.cc | 2 +- sql/sql_base.cc | 2 +- sql/sql_select.cc | 9 ++++--- sql/sql_table.cc | 6 +++-- sql/table.cc | 3 ++- sql/unireg.cc | 4 +-- tests/mysql_client_test.c | 54 +++++++++++++++++++++++++++++++++++++++ 11 files changed, 184 insertions(+), 28 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1f3f7dba7da..d50e6dd3751 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3575,4 +3575,46 @@ DROP VIEW bug13095_v1 DROP PROCEDURE IF EXISTS bug13095; DROP VIEW IF EXISTS bug13095_v1; DROP TABLE IF EXISTS bug13095_t1; +drop procedure if exists bug14210| +set @@session.max_heap_table_size=16384| +select @@session.max_heap_table_size| +@@session.max_heap_table_size +16384 +create table t3 (a char(255)) engine=InnoDB| +create procedure bug14210_fill_table() +begin +declare table_size, max_table_size int default 0; +select @@session.max_heap_table_size into max_table_size; +delete from t3; +insert into t3 (a) values (repeat('a', 255)); +repeat +insert into t3 select a from t3; +select count(*)*255 from t3 into table_size; +until table_size > max_table_size*2 end repeat; +end| +call bug14210_fill_table()| +drop procedure bug14210_fill_table| +create table t4 like t3| +create procedure bug14210() +begin +declare a char(255); +declare done int default 0; +declare c cursor for select * from t3; +declare continue handler for sqlstate '02000' set done = 1; +open c; +repeat +fetch c into a; +if not done then +insert into t4 values (upper(a)); +end if; +until done end repeat; +close c; +end| +call bug14210()| +select count(*) from t4| +count(*) +256 +drop table t3, t4| +drop procedure bug14210| +set @@session.max_heap_table_size=default| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ab57139bb77..eaf69c0ab03 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4488,6 +4488,58 @@ DROP TABLE IF EXISTS bug13095_t1; delimiter |; +# +# BUG#14210: "Simple query with > operator on large table gives server +# crash" +# Check that cursors work in case when HEAP tables are converted to +# MyISAM +# +--disable_warnings +drop procedure if exists bug14210| +--enable_warnings +set @@session.max_heap_table_size=16384| +select @@session.max_heap_table_size| +# To trigger the memory corruption the original table must be InnoDB. +# No harm if it's not, so don't warn if the suite is run with --skip-innodb +--disable_warnings +create table t3 (a char(255)) engine=InnoDB| +--enable_warnings +create procedure bug14210_fill_table() +begin + declare table_size, max_table_size int default 0; + select @@session.max_heap_table_size into max_table_size; + delete from t3; + insert into t3 (a) values (repeat('a', 255)); + repeat + insert into t3 select a from t3; + select count(*)*255 from t3 into table_size; + until table_size > max_table_size*2 end repeat; +end| +call bug14210_fill_table()| +drop procedure bug14210_fill_table| +create table t4 like t3| + +create procedure bug14210() +begin + declare a char(255); + declare done int default 0; + declare c cursor for select * from t3; + declare continue handler for sqlstate '02000' set done = 1; + open c; + repeat + fetch c into a; + if not done then + insert into t4 values (upper(a)); + end if; + until done end repeat; + close c; +end| +call bug14210()| +select count(*) from t4| + +drop table t3, t4| +drop procedure bug14210| +set @@session.max_heap_table_size=default| # # BUG#NNNN: New bug synopsis diff --git a/sql/handler.cc b/sql/handler.cc index 81e94af5dc7..fe0af04cf48 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -293,61 +293,61 @@ enum db_type ha_checktype(THD *thd, enum db_type database_type, } /* ha_checktype */ -handler *get_new_handler(TABLE *table, enum db_type db_type) +handler *get_new_handler(TABLE *table, MEM_ROOT *alloc, enum db_type db_type) { switch (db_type) { #ifndef NO_HASH case DB_TYPE_HASH: - return new ha_hash(table); + return new (alloc) ha_hash(table); #endif case DB_TYPE_MRG_ISAM: - return new ha_myisammrg(table); + return new (alloc) ha_myisammrg(table); #ifdef HAVE_BERKELEY_DB case DB_TYPE_BERKELEY_DB: - return new ha_berkeley(table); + return new (alloc) ha_berkeley(table); #endif #ifdef HAVE_INNOBASE_DB case DB_TYPE_INNODB: - return new ha_innobase(table); + return new (alloc) ha_innobase(table); #endif #ifdef HAVE_EXAMPLE_DB case DB_TYPE_EXAMPLE_DB: - return new ha_example(table); + return new (alloc) ha_example(table); #endif #ifdef HAVE_ARCHIVE_DB case DB_TYPE_ARCHIVE_DB: - return new ha_archive(table); + return new (alloc) ha_archive(table); #endif #ifdef HAVE_BLACKHOLE_DB case DB_TYPE_BLACKHOLE_DB: - return new ha_blackhole(table); + return new (alloc) ha_blackhole(table); #endif #ifdef HAVE_FEDERATED_DB case DB_TYPE_FEDERATED_DB: - return new ha_federated(table); + return new (alloc) ha_federated(table); #endif #ifdef HAVE_CSV_DB case DB_TYPE_CSV_DB: - return new ha_tina(table); + return new (alloc) ha_tina(table); #endif #ifdef HAVE_NDBCLUSTER_DB case DB_TYPE_NDBCLUSTER: - return new ha_ndbcluster(table); + return new (alloc) ha_ndbcluster(table); #endif case DB_TYPE_HEAP: - return new ha_heap(table); + return new (alloc) ha_heap(table); default: // should never happen { enum db_type def=(enum db_type) current_thd->variables.table_type; /* Try first with 'default table type' */ if (db_type != def) - return get_new_handler(table, def); + return get_new_handler(table, alloc, def); } /* Fall back to MyISAM */ case DB_TYPE_MYISAM: - return new ha_myisam(table); + return new (alloc) ha_myisam(table); case DB_TYPE_MRG_MYISAM: - return new ha_myisammrg(table); + return new (alloc) ha_myisammrg(table); } } @@ -1300,7 +1300,7 @@ int ha_delete_table(THD *thd, enum db_type table_type, const char *path, /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */ if (table_type == DB_TYPE_UNKNOWN || - ! (file=get_new_handler(&dummy_table, table_type))) + ! (file=get_new_handler(&dummy_table, thd->mem_root, table_type))) DBUG_RETURN(ENOENT); if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED)) @@ -2469,6 +2469,7 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key, TYPELIB *ha_known_exts(void) { + MEM_ROOT *mem_root= current_thd->mem_root; if (!known_extensions.type_names || mysys_usage_id != known_extensions_id) { handlerton **types; @@ -2483,7 +2484,8 @@ TYPELIB *ha_known_exts(void) { if ((*types)->state == SHOW_OPTION_YES) { - handler *file= get_new_handler(0,(enum db_type) (*types)->db_type); + handler *file= get_new_handler(0, mem_root, + (enum db_type) (*types)->db_type); for (ext= file->bas_ext(); *ext; ext++) { while ((old_ext= it++)) diff --git a/sql/handler.h b/sql/handler.h index af80f021e75..e16c428954c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -874,7 +874,7 @@ extern ulong total_ha, total_ha_2pc; /* lookups */ enum db_type ha_resolve_by_name(const char *name, uint namelen); const char *ha_get_storage_engine(enum db_type db_type); -handler *get_new_handler(TABLE *table, enum db_type db_type); +handler *get_new_handler(TABLE *table, MEM_ROOT *alloc, enum db_type db_type); enum db_type ha_checktype(THD *thd, enum db_type database_type, bool no_substitute, bool report_error); bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ff2b14a27ee..1dc2996e351 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -931,7 +931,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) } THD *thd= current_thd; - if (!(file= get_new_handler(head, head->s->db_type))) + if (!(file= get_new_handler(head, thd->mem_root, head->s->db_type))) goto failure; DBUG_PRINT("info", ("Allocated new handler %p", file)); if (file->ha_open(head->s->path, head->db_stat, HA_OPEN_IGNORE_IF_LOCKED)) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5c929dcdf69..15fb477b0d1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2634,7 +2634,7 @@ bool rm_temporary_table(enum db_type base, char *path) if (my_delete(path,MYF(0))) error=1; /* purecov: inspected */ *fn_ext(path)='\0'; // remove extension - handler *file=get_new_handler((TABLE*) 0, base); + handler *file= get_new_handler((TABLE*) 0, current_thd->mem_root, base); if (file && file->delete_table(path)) { error=1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 285a5c5696b..f6e1f7e80e9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8279,7 +8279,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM)) { - table->file=get_new_handler(table,table->s->db_type= DB_TYPE_MYISAM); + table->file= get_new_handler(table, &table->mem_root, + table->s->db_type= DB_TYPE_MYISAM); if (group && (param->group_parts > table->file->max_key_parts() || param->group_length > table->file->max_key_length())) @@ -8287,7 +8288,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } else { - table->file=get_new_handler(table,table->s->db_type= DB_TYPE_HEAP); + table->file= get_new_handler(table, &table->mem_root, + table->s->db_type= DB_TYPE_HEAP); } if (!using_unique_constraint) @@ -8871,7 +8873,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, new_table= *table; new_table.s= &new_table.share_not_to_be_used; new_table.s->db_type= DB_TYPE_MYISAM; - if (!(new_table.file= get_new_handler(&new_table,DB_TYPE_MYISAM))) + if (!(new_table.file= get_new_handler(&new_table, &new_table.mem_root, + DB_TYPE_MYISAM))) DBUG_RETURN(1); // End of memory save_proc_info=thd->proc_info; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b635c44c6dc..ee5acea87c0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1508,7 +1508,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, if (create_info->row_type == ROW_TYPE_DYNAMIC) db_options|=HA_OPTION_PACK_RECORD; alias= table_case_name(create_info, table_name); - file=get_new_handler((TABLE*) 0, create_info->db_type); + file= get_new_handler((TABLE*) 0, thd->mem_root, create_info->db_type); #ifdef NOT_USED /* @@ -1806,10 +1806,12 @@ mysql_rename_table(enum db_type base, const char *new_db, const char *new_name) { + THD *thd= current_thd; char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN]; char *from_base= from, *to_base= to; char tmp_name[NAME_LEN+1]; - handler *file=(base == DB_TYPE_UNKNOWN ? 0 : get_new_handler((TABLE*) 0, base)); + handler *file= (base == DB_TYPE_UNKNOWN ? 0 : + get_new_handler((TABLE*) 0, thd->mem_root, base)); int error=0; DBUG_ENTER("mysql_rename_table"); diff --git a/sql/table.cc b/sql/table.cc index dd6018b70f3..1acf49bc03e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -338,7 +338,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, my_free(buff, MYF(0)); } /* Allocate handler */ - if (!(outparam->file= get_new_handler(outparam, share->db_type))) + if (!(outparam->file= get_new_handler(outparam, &outparam->mem_root, + share->db_type))) goto err; error=4; diff --git a/sql/unireg.cc b/sql/unireg.cc index 065f8583f71..0ab77462f61 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -90,7 +90,7 @@ bool mysql_create_frm(THD *thd, my_string file_name, if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0))) DBUG_RETURN(1); if (db_file == NULL) - db_file= get_new_handler((TABLE*) 0, create_info->db_type); + db_file= get_new_handler((TABLE*) 0, thd->mem_root, create_info->db_type); /* If fixed row records, we need one bit to check for deleted rows */ if (!(create_info->table_options & HA_OPTION_PACK_RECORD)) @@ -699,7 +699,7 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, /* We need a table to generate columns for default values */ bzero((char*) &table,sizeof(table)); table.s= &table.share_not_to_be_used; - handler= get_new_handler((TABLE*) 0, table_type); + handler= get_new_handler((TABLE*) 0, thd->mem_root, table_type); if (!handler || !(buff=(uchar*) my_malloc((uint) reclength,MYF(MY_WME | MY_ZEROFILL)))) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index f46b1cf1784..949c3d5bf1c 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -14319,6 +14319,7 @@ static void test_bug12243() mysql_autocommit(mysql, TRUE); /* restore default */ } + /* Bug#11718: query with function, join and order by returns wrong type */ @@ -14366,6 +14367,58 @@ static void test_bug12925() } +/* + Bug#14210 "Simple query with > operator on large table gives server + crash" +*/ + +static void test_bug14210() +{ + MYSQL_STMT *stmt; + int rc, i; + const char *stmt_text; + ulong type; + + myheader("test_bug14210"); + + mysql_query(mysql, "drop table if exists t1"); + /* + To trigger the problem the table must be InnoDB, although the problem + itself is not InnoDB related. In case the table is MyISAM this test + is harmless. + */ + mysql_query(mysql, "create table t1 (a varchar(255)) type=InnoDB"); + rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))"); + myquery(rc); + rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384"); + /* Create a big enough table (more than max_heap_table_size) */ + for (i= 0; i < 8; i++) + { + rc= mysql_query(mysql, "insert into t1 (a) select a from t1"); + myquery(rc); + } + /* create statement */ + stmt= mysql_stmt_init(mysql); + type= (ulong) CURSOR_TYPE_READ_ONLY; + mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); + + stmt_text= "select a from t1"; + + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + while ((rc= mysql_stmt_fetch(stmt)) == 0) + ; + DIE_UNLESS(rc == MYSQL_NO_DATA); + + rc= mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "drop table t1"); + myquery(rc); + rc= mysql_query(mysql, "set @@session.max_heap_table_size=default"); + myquery(rc); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -14621,6 +14674,7 @@ static struct my_tests_st my_tests[]= { { "test_bug11901", test_bug11901 }, { "test_bug11904", test_bug11904 }, { "test_bug12243", test_bug12243 }, + { "test_bug14210", test_bug14210 }, { 0, 0 } }; From f68daacfa8fc2ed1429a672b1dab245b8d0ad13b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 16:17:11 +0400 Subject: [PATCH 38/54] Merging mysql-test/r/ctype_cp932_binlog.result: test result fixed mysql-test/t/ctype_cp932_binlog.test: test fixed with 5.0 specific --- mysql-test/r/ctype_cp932_binlog.result | 12 +++++------- mysql-test/t/ctype_cp932_binlog.test | 3 +-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result index 89f0ae71f4f..d04fce7738c 100644 --- a/mysql-test/r/ctype_cp932_binlog.result +++ b/mysql-test/r/ctype_cp932_binlog.result @@ -6,13 +6,11 @@ CREATE TABLE t1(f1 blob); PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; SET @var1= x'8300'; EXECUTE stmt1 USING @var1; -SHOW BINLOG EVENTS FROM 79; -Log_name Pos Event_type Server_id Orig_log_pos Info -master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 -master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(f1 blob) -master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 -master-bin.000001 # User var 1 # @`var1`=_binary 0x8300 COLLATE binary -master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@'var1') +SHOW BINLOG EVENTS FROM 98; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob) +master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary +master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1') SELECT HEX(f1) FROM t1; HEX(f1) 8300 diff --git a/mysql-test/t/ctype_cp932_binlog.test b/mysql-test/t/ctype_cp932_binlog.test index e8ec0d46caf..270e27cf27f 100644 --- a/mysql-test/t/ctype_cp932_binlog.test +++ b/mysql-test/t/ctype_cp932_binlog.test @@ -26,8 +26,7 @@ SET @var1= x'8300'; # code (and I have used it to test the fix) until there is some way to # exercise this code from mysql-test-run. EXECUTE stmt1 USING @var1; ---replace_column 2 # 5 # -SHOW BINLOG EVENTS FROM 79; +SHOW BINLOG EVENTS FROM 98; SELECT HEX(f1) FROM t1; DROP table t1; # end test for bug#11338 From 5af7ca80d98459b9c163328eaf8709abdf8c9883 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 16:10:11 +0200 Subject: [PATCH 39/54] Changes in get_table_type() and mysql_frm_type(). The main problem was that in mysql_rm_table_part2_with_lock() previously we needed to open same file twice. Now once is enough. sql/mysql_priv.h: Merged functions get_table_type() and mysql_frm_type() into one, using the name from latter one. sql/sql_base.cc: Changed get_table_type() to mysql_frm_type() sql/sql_delete.cc: Changed get_table_type() to mysql_frm_type() sql/sql_rename.cc: Changed get_table_type() to mysql_frm_type() sql/sql_show.cc: Changed get_table_type() to mysql_frm_type() sql/sql_table.cc: Changed get_table_type() to mysql_frm_type() sql/sql_view.cc: Merged code from get_table_type() and mysql_frm_type() into the latter one. sql/sql_view.h: Function prototype changes. sql/table.cc: No longer needed. --- sql/mysql_priv.h | 1 - sql/sql_base.cc | 3 ++- sql/sql_delete.cc | 3 ++- sql/sql_rename.cc | 7 ++++--- sql/sql_show.cc | 3 ++- sql/sql_table.cc | 13 ++++++++++--- sql/sql_view.cc | 34 ++++++++++++++++++++++++---------- sql/sql_view.h | 2 +- sql/table.cc | 23 ----------------------- 9 files changed, 45 insertions(+), 44 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index e33ac05e293..abf44c98977 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1295,7 +1295,6 @@ int openfrm(THD *thd, const char *name,const char *alias,uint filestat, int readfrm(const char *name, const void** data, uint* length); int writefrm(const char* name, const void* data, uint len); int closefrm(TABLE *table); -db_type get_table_type(THD *thd, const char *name); int read_string(File file, gptr *to, uint length); void free_blobs(TABLE *table); int set_zone(int nr,int min_zone,int max_zone); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 973fbca12f5..b3072205514 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1193,10 +1193,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, */ { char path[FN_REFLEN]; + db_type not_used; strxnmov(path, FN_REFLEN, mysql_data_home, "/", table_list->db, "/", table_list->table_name, reg_ext, NullS); (void) unpack_filename(path, path); - if (mysql_frm_type(path) == FRMTYPE_VIEW) + if (mysql_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW) { TABLE tab;// will not be used (because it's VIEW) but have to be passed table= &tab; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 83f50ba3ac5..429db7cbf49 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -830,7 +830,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) if (!dont_send_ok) { db_type table_type; - if ((table_type=get_table_type(thd, path)) == DB_TYPE_UNKNOWN) + mysql_frm_type(thd, path, &table_type); + if (table_type == DB_TYPE_UNKNOWN) { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->table_name); diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 154e828b47e..80fcb973028 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -134,6 +134,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) { TABLE_LIST *ren_table,*new_table; frm_type_enum frm_type; + db_type table_type; + DBUG_ENTER("rename_tables"); for (ren_table= table_list; ren_table; ren_table= new_table->next_local) @@ -166,13 +168,12 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) reg_ext); unpack_filename(name, name); - frm_type= mysql_frm_type(name); + frm_type= mysql_frm_type(thd, name, &table_type); switch (frm_type) { case FRMTYPE_TABLE: { - db_type table_type; - if ((table_type= get_table_type(thd, name)) == DB_TYPE_UNKNOWN) + if (table_type == DB_TYPE_UNKNOWN) my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); else rc= mysql_rename_table(table_type, ren_table->db, old_alias, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 69b824f8cd9..1fa4e3f9b48 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2003,6 +2003,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) Security_context *sctx= thd->security_ctx; uint derived_tables= lex->derived_tables; int error= 1; + db_type not_used; Open_tables_state open_tables_state_backup; DBUG_ENTER("get_all_tables"); @@ -2114,7 +2115,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) else { my_snprintf(end, len, "/%s%s", file_name, reg_ext); - switch (mysql_frm_type(path)) { + switch (mysql_frm_type(thd, path, ¬_used)) { case FRMTYPE_ERROR: table->field[3]->store("ERROR", 5, system_charset_info); break; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1e96891113b..6861a29b4d2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -218,6 +218,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, String wrong_tables; int error; bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0; + DBUG_ENTER("mysql_rm_table_part2"); if (lock_table_names(thd, tables)) @@ -229,6 +230,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, for (table= tables; table; table= table->next_local) { char *db=table->db; + db_type table_type= DB_TYPE_UNKNOWN; + mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL); if (!close_temporary_table(thd, db, table->table_name)) { @@ -256,7 +259,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (drop_temporary || (access(path,F_OK) && ha_create_table_from_engine(thd,db,alias)) || - (!drop_view && mysql_frm_type(path) != FRMTYPE_TABLE)) + (!drop_view && + mysql_frm_type(thd, path, &table_type) != FRMTYPE_TABLE)) { // Table was not found on disk and table can't be created from engine if (if_exists) @@ -269,7 +273,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, else { char *end; - db_type table_type= get_table_type(thd, path); + if (table_type == DB_TYPE_UNKNOWN) + mysql_frm_type(thd, path, &table_type); *(end=fn_ext(path))=0; // Remove extension for delete error= ha_delete_table(thd, table_type, path, table->table_name, !dont_log_query); @@ -2611,6 +2616,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, char *src_table= table_ident->table.str; int err; bool res= TRUE; + db_type not_used; + TABLE_LIST src_tables_list; DBUG_ENTER("mysql_create_like_table"); src_db= table_ident->db.str ? table_ident->db.str : thd->db; @@ -2658,7 +2665,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, /* create like should be not allowed for Views, Triggers, ... */ - if (mysql_frm_type(src_path) != FRMTYPE_TABLE) + if (mysql_frm_type(thd, src_path, ¬_used) != FRMTYPE_TABLE) { my_error(ER_WRONG_OBJECT, MYF(0), src_db, src_table, "BASE TABLE"); goto err; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 858f0c2520e..42b1aa3c196 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1110,6 +1110,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) char path[FN_REFLEN]; TABLE_LIST *view; bool type= 0; + db_type not_used; for (view= views; view; view= view->next_local) { @@ -1117,7 +1118,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) view->table_name, reg_ext, NullS); (void) unpack_filename(path, path); VOID(pthread_mutex_lock(&LOCK_open)); - if (access(path, F_OK) || (type= (mysql_frm_type(path) != FRMTYPE_VIEW))) + if (access(path, F_OK) || + (type= (mysql_frm_type(thd, path, ¬_used) != FRMTYPE_VIEW))) { char name[FN_REFLEN]; my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name); @@ -1164,24 +1166,36 @@ err: FRMTYPE_VIEW view */ -frm_type_enum mysql_frm_type(char *path) +frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt) { File file; - char header[10]; //"TYPE=VIEW\n" it is 10 characters - int length; + uchar header[10]; //"TYPE=VIEW\n" it is 10 characters + int error; DBUG_ENTER("mysql_frm_type"); + *dbt= DB_TYPE_UNKNOWN; + if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) - { DBUG_RETURN(FRMTYPE_ERROR); - } - length= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME)); + error= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME | MY_NABP)); my_close(file, MYF(MY_WME)); - if (length == (int) MY_FILE_ERROR) + + if (error) DBUG_RETURN(FRMTYPE_ERROR); - if (length < (int) sizeof(header) || - !strncmp(header, "TYPE=VIEW\n", sizeof(header))) + if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header))) DBUG_RETURN(FRMTYPE_VIEW); + + /* + This is just a check for DB_TYPE. We'll return default unknown type + if the following test is true (arg #3). This should not have effect + on return value from this function (default FRMTYPE_TABLE) + */ + if (header[0] != (uchar) 254 || header[1] != 1 || + (header[2] != FRM_VER && header[2] != FRM_VER+1 && + (header[2] < FRM_VER+3 || header[2] > FRM_VER+4))) + DBUG_RETURN(FRMTYPE_TABLE); + + *dbt= ha_checktype(thd, (enum db_type) (uint) *(header + 3), 0, 0); DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table } diff --git a/sql/sql_view.h b/sql/sql_view.h index 4cc9eb454fb..4e3d50655e2 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -27,7 +27,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST * view); bool insert_view_fields(THD *thd, List *list, TABLE_LIST *view); -frm_type_enum mysql_frm_type(char *path); +frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt); int view_checksum(THD *thd, TABLE_LIST *view); diff --git a/sql/table.cc b/sql/table.cc index 722e4e4df25..777d8672ab3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1692,29 +1692,6 @@ bool check_column_name(const char *name) return last_char_is_space || (uint) (name - start) > NAME_LEN; } -/* -** Get type of table from .frm file -*/ - -db_type get_table_type(THD *thd, const char *name) -{ - File file; - uchar head[4]; - int error; - DBUG_ENTER("get_table_type"); - DBUG_PRINT("enter",("name: '%s'",name)); - - if ((file=my_open(name,O_RDONLY, MYF(0))) < 0) - DBUG_RETURN(DB_TYPE_UNKNOWN); - error=my_read(file,(byte*) head,4,MYF(MY_NABP)); - my_close(file,MYF(0)); - if (error || head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1 && - (head[2] < FRM_VER+3 || head[2] > FRM_VER+4))) - DBUG_RETURN(DB_TYPE_UNKNOWN); - DBUG_RETURN(ha_checktype(thd,(enum db_type) (uint) *(head+3),0,0)); -} - /* Create Item_field for each column in the table. From fa8dafe5bba7b4c72c1e0bbf10d7a9e10b4ebe8a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 17:43:03 +0300 Subject: [PATCH 40/54] opt_range.cc: Additional fix for bug#14093 sql/opt_range.cc: Additional fix for bug#14093 --- sql/opt_range.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 22e9f94d21a..63a49a46110 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3776,6 +3776,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, SEL_ARG *tree= 0; MEM_ROOT *alloc= param->mem_root; char *str; + ulong orig_sql_mode; DBUG_ENTER("get_mm_leaf"); /* @@ -3922,7 +3923,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, field->cmp_type() != value->result_type()) goto end; /* For comparison purposes allow invalid dates like 2000-01-32 */ - ulong orig_sql_mode= field->table->in_use->variables.sql_mode; + orig_sql_mode= field->table->in_use->variables.sql_mode; if (value->real_item()->type() == Item::STRING_ITEM && (field->type() == FIELD_TYPE_DATE || field->type() == FIELD_TYPE_DATETIME)) From 840834c1efb25ea821228edd05bdc73b63cbbcbc Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 17:39:40 +0200 Subject: [PATCH 41/54] Disabled a test temporarily. --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index eedf4b30e73..5d010235d97 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -16,3 +16,4 @@ rpl_until : Unstable test case, bug#12429 rpl_deadlock : Unstable test case, bug#12429 kill : Unstable test case, bug#9712 archive_gis : The test fails on 32bit Linux +ctype_cp932_binlog : The test is not ready yet. hf will complete shortly From 77afc1690053e16ff7fb83d866199a095f6e8208 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 21:01:27 +0400 Subject: [PATCH 42/54] test enabled --- mysql-test/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 5d010235d97..eedf4b30e73 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -16,4 +16,3 @@ rpl_until : Unstable test case, bug#12429 rpl_deadlock : Unstable test case, bug#12429 kill : Unstable test case, bug#9712 archive_gis : The test fails on 32bit Linux -ctype_cp932_binlog : The test is not ready yet. hf will complete shortly From 5ea3382fe45652c6ef9ca2ec636441c2a2752a55 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 20:29:21 +0200 Subject: [PATCH 43/54] Disabled ps_protocol for two statements. --- mysql-test/t/type_newdecimal.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 3e8d1f2e9e9..93a1a1afa45 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1056,11 +1056,13 @@ create table t (d decimal(0,10)); # create table t1 (c1 decimal(64)); +--disable_ps_protocol insert into t1 values( 89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); insert into t1 values( 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); +--enable_ps_protocol insert into t1 values(1e100); select * from t1; drop table t1; From d8f1fdc48d5f4ac07eda2dff3e387152636f80a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Nov 2005 22:42:25 +0200 Subject: [PATCH 44/54] Fixes during review of new code Destroy LOCK_uuid_generator sql/ha_berkeley.h: Fix portability problem (warnings from gcc on 32 bit linux) sql/ha_ndbcluster.cc: Fixed portability problem sql/mysqld.cc: Destroy LOCK_uuid_generator --- sql/ha_berkeley.h | 4 ++-- sql/ha_ndbcluster.cc | 3 ++- sql/mysqld.cc | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 99e13286554..16e4db59c10 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -94,8 +94,8 @@ class ha_berkeley: public handler uint max_supported_keys() const { return MAX_KEY-1; } uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; } ha_rows estimate_rows_upper_bound(); - uint max_supported_key_length() const { return 4294967295L; } - uint max_supported_key_part_length() const { return 4294967295L; } + uint max_supported_key_length() const { return UINT_MAX32; } + uint max_supported_key_part_length() const { return UINT_MAX32; } const key_map *keys_to_use_for_scanning() { return &key_map_full; } bool has_transactions() { return 1;} diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 71bd3acd2a6..80c34f1117f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3861,7 +3861,8 @@ int ha_ndbcluster::create(const char *name, uint pack_length, length, i, pk_length= 0; const void *data, *pack_data; char name2[FN_HEADLEN]; - bool create_from_engine= (info->table_options & HA_OPTION_CREATE_FROM_ENGINE); + bool create_from_engine= test(info->table_options & + HA_OPTION_CREATE_FROM_ENGINE); DBUG_ENTER("ha_ndbcluster::create"); DBUG_PRINT("enter", ("name: %s", name)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 143ed74e012..d31084a6839 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1194,6 +1194,7 @@ static void clean_up_mutexes() (void) rwlock_destroy(&LOCK_sys_init_slave); (void) pthread_mutex_destroy(&LOCK_global_system_variables); (void) pthread_mutex_destroy(&LOCK_global_read_lock); + (void) pthread_mutex_destroy(&LOCK_uuid_generator); (void) pthread_cond_destroy(&COND_thread_count); (void) pthread_cond_destroy(&COND_refresh); (void) pthread_cond_destroy(&COND_thread_cache); From 5dcd44e3ed309eb1a3778f661aaa8c87bbc1ffd6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Nov 2005 10:02:43 +0200 Subject: [PATCH 45/54] DROP created procedures (Caused sp-security to fail) --- mysql-test/r/mysqldump.result | 1 + mysql-test/t/mysqldump.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 60e7ebbd966..82a761252b5 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2236,6 +2236,7 @@ DROP FUNCTION bug9056_func1; DROP FUNCTION bug9056_func2; DROP PROCEDURE bug9056_proc1; DROP PROCEDURE bug9056_proc2; +DROP PROCEDURE `a'b`; drop table t1; drop table if exists t1; create table t1 (`d` timestamp, unique (`d`)); diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 4481bc62dfa..91a87e2c774 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -917,6 +917,7 @@ DROP FUNCTION bug9056_func1; DROP FUNCTION bug9056_func2; DROP PROCEDURE bug9056_proc1; DROP PROCEDURE bug9056_proc2; +DROP PROCEDURE `a'b`; drop table t1; # From d4a7867a9ee0a44c8c943c75b5eb15e450ac61a7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Nov 2005 15:12:22 +0200 Subject: [PATCH 46/54] Reorder struct elements to be more optimal for 64 bit computers (Main reason for reordering was to get rid of compiler warnings for order of element initialization) sql/log.cc: Remove compiler warning sql/sql_class.h: Reorder MYSQL_LOG struct elements to be more optimal for 64 bit computers (Main reason for reordering was to get rid of compiler warnings for order of element initialization) --- sql/log.cc | 7 +++--- sql/sql_class.h | 62 ++++++++++++++++++++++++------------------------- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index baa2edab101..7ea2dba2144 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -356,9 +356,10 @@ static int find_uniq_filename(char *name) MYSQL_LOG::MYSQL_LOG() :bytes_written(0), last_time(0), query_start(0), name(0), - file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0), - need_start_event(1), prepared_xids(0), description_event_for_exec(0), - description_event_for_queue(0), readers_count(0), reset_pending(FALSE) + prepared_xids(0), log_type(LOG_CLOSED), file_id(1), open_count(1), + readers_count(0), reset_pending(FALSE), write_error(FALSE), inited(FALSE), + need_start_event(TRUE), + description_event_for_exec(0), description_event_for_queue(0) { /* We don't want to initialize LOCK_Log here as such initialization depends on diff --git a/sql/sql_class.h b/sql/sql_class.h index 7ca168ec518..2d1880a6d9d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -190,10 +190,10 @@ class MYSQL_LOG: public TC_LOG private: /* LOCK_log and LOCK_index are inited by init_pthread_objects() */ pthread_mutex_t LOCK_log, LOCK_index, LOCK_readers; + pthread_mutex_t LOCK_prep_xids; + pthread_cond_t COND_prep_xids; pthread_cond_t update_cond; pthread_cond_t reset_cond; - bool reset_pending; - int readers_count; ulonglong bytes_written; time_t last_time,query_start; IO_CACHE log_file; @@ -201,21 +201,6 @@ class MYSQL_LOG: public TC_LOG char *name; char time_buff[20],db[NAME_LEN+1]; char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; - // current file sequence number for load data infile binary logging - uint file_id; - uint open_count; // For replication - volatile enum_log_type log_type; - enum cache_type io_cache_type; - bool write_error, inited; - bool need_start_event; - /* - no_auto_events means we don't want any of these automatic events : - Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't want - a Rotate_log event to be written to the relay log. When we start a relay log - etc. So in 4.x this is 1 for relay logs, 0 for binlogs. - In 5.0 it's 0 for relay logs too! - */ - bool no_auto_events; /* The max size before rotation (usable only if log_type == LOG_BIN: binary logs and relay logs). @@ -227,13 +212,38 @@ class MYSQL_LOG: public TC_LOG fix_max_relay_log_size). */ ulong max_size; - ulong prepared_xids; /* for tc log - number of xids to remember */ - pthread_mutex_t LOCK_prep_xids; - pthread_cond_t COND_prep_xids; + volatile enum_log_type log_type; + enum cache_type io_cache_type; + // current file sequence number for load data infile binary logging + uint file_id; + uint open_count; // For replication + int readers_count; + bool reset_pending; + bool write_error, inited; + bool need_start_event; + /* + no_auto_events means we don't want any of these automatic events : + Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't + want a Rotate_log event to be written to the relay log. When we start a + relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs. + In 5.0 it's 0 for relay logs too! + */ + bool no_auto_events; friend class Log_event; public: + /* + These describe the log's format. This is used only for relay logs. + _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's + necessary to have 2 distinct objects, because the I/O thread may be reading + events in a different format from what the SQL thread is reading (consider + the case of a master which has been upgraded from 5.0 to 5.1 without doing + RESET MASTER, or from 4.x to 5.0). + */ + Format_description_log_event *description_event_for_exec, + *description_event_for_queue; + MYSQL_LOG(); /* note that there's no destructor ~MYSQL_LOG() ! @@ -246,18 +256,6 @@ public: int log(THD *thd, my_xid xid); void unlog(ulong cookie, my_xid xid); int recover(IO_CACHE *log, Format_description_log_event *fdle); - - /* - These describe the log's format. This is used only for relay logs. - _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's - necessary to have 2 distinct objects, because the I/O thread may be reading - events in a different format from what the SQL thread is reading (consider - the case of a master which has been upgraded from 5.0 to 5.1 without doing - RESET MASTER, or from 4.x to 5.0). - */ - Format_description_log_event *description_event_for_exec, - *description_event_for_queue; - void reset_bytes_written() { bytes_written = 0; From 57923440f3711dd6287df9d8f54e94b9031c7ec0 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Nov 2005 16:17:43 +0300 Subject: [PATCH 47/54] fix --ansi --pedantic compilation failure --- sql/spatial.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/spatial.h b/sql/spatial.h index acd16172fcc..ec5e80e00fd 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -240,8 +240,8 @@ public: static Geometry *create_from_wkt(Geometry_buffer *buffer, Gis_read_stream *trs, String *wkt, bool init_stream=1); - static int Geometry::create_from_wkb(Geometry_buffer *buffer, - const char *wkb, uint32 len, String *res); + static int create_from_wkb(Geometry_buffer *buffer, + const char *wkb, uint32 len, String *res); int as_wkt(String *wkt, const char **end) { uint32 len= get_class_info()->m_name.length; From 0e878d7e541983757bc0b31e7caa8a16a5fd2896 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 5 Nov 2005 01:44:35 +0100 Subject: [PATCH 48/54] mysql.spec.sh: Always use bundled zlib support-files/mysql.spec.sh: Always use bundled zlib --- support-files/mysql.spec.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 5cd9d1646a4..7a1219736ae 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -249,6 +249,7 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ --enable-thread-safe-client \ + --with-zlib-dir=bundled \ --with-readline ; # Add this for more debugging support # --with-debug From 1b65c7041383073eee99deebe8569399f06e83ee Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 5 Nov 2005 15:08:15 +0300 Subject: [PATCH 49/54] Fix Bug#13894 Server crashes on update of CSV table mysql-test/r/csv.result: update result file mysql-test/t/csv.test: Add test for a bug sql/examples/ha_tina.cc: sort function should return reverted values for chains to be sorted in the right orded. don't do a strange memmove --- mysql-test/r/csv.result | 20 ++++++++++++++++++++ mysql-test/t/csv.test | 18 ++++++++++++++++++ sql/examples/ha_tina.cc | 19 +++++++++---------- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index ea0d34271b5..78a1f34636c 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -4929,3 +4929,23 @@ Warnings: Note 1051 Unknown table 't2' Note 1051 Unknown table 't3' Note 1051 Unknown table 't4' +DROP TABLE IF EXISTS bug13894; +CREATE TABLE bug13894 ( val integer ) ENGINE = CSV; +INSERT INTO bug13894 VALUES (5); +INSERT INTO bug13894 VALUES (10); +INSERT INTO bug13894 VALUES (11); +INSERT INTO bug13894 VALUES (10); +SELECT * FROM bug13894; +val +5 +10 +11 +10 +UPDATE bug13894 SET val=6 WHERE val=10; +SELECT * FROM bug13894; +val +5 +11 +6 +6 +DROP TABLE bug13894; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 2ac46d75f9a..61b4f9607a5 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1314,4 +1314,22 @@ select period from t1; drop table if exists t1,t2,t3,t4; +# +# Bug #13894 Server crashes on update of CSV table +# + +--disable_warnings +DROP TABLE IF EXISTS bug13894; +--enable_warnings + +CREATE TABLE bug13894 ( val integer ) ENGINE = CSV; +INSERT INTO bug13894 VALUES (5); +INSERT INTO bug13894 VALUES (10); +INSERT INTO bug13894 VALUES (11); +INSERT INTO bug13894 VALUES (10); +SELECT * FROM bug13894; +UPDATE bug13894 SET val=6 WHERE val=10; +SELECT * FROM bug13894; +DROP TABLE bug13894; + # End of 4.1 tests diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 8a9aa91c680..f4544670ed9 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -58,12 +58,16 @@ static int tina_init= 0; ** TINA tables *****************************************************************************/ -/* - Used for sorting chains. +/* + Used for sorting chains with qsort(). */ int sort_set (tina_set *a, tina_set *b) { - return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) ); + /* + We assume that intervals do not intersect. So, it is enought to compare + any two points. Here we take start of intervals for comparison. + */ + return ( a->begin > b->begin ? -1 : ( a->begin < b->begin ? 1 : 0 ) ); } static byte* tina_get_key(TINA_SHARE *share,uint *length, @@ -739,13 +743,8 @@ int ha_tina::rnd_end() qsort(chain, (size_t)(chain_ptr - chain), sizeof(tina_set), (qsort_cmp)sort_set); for (ptr= chain; ptr < chain_ptr; ptr++) { - /* We peek a head to see if this is the last chain */ - if (ptr+1 == chain_ptr) - memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end, - length - (size_t)ptr->end); - else - memmove((caddr_t)share->mapped_file + ptr->begin, (caddr_t)share->mapped_file + ptr->end, - (size_t)((ptr++)->begin - ptr->end)); + memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end, + length - (size_t)ptr->end); length= length - (size_t)(ptr->end - ptr->begin); } From b0829011b8053058f0419aee48da03970654cbc6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 6 Nov 2005 02:11:12 +0300 Subject: [PATCH 50/54] Fix Bug#14672 Bug in deletion mysql-test/r/csv.result: correct result file mysql-test/t/csv.test: Add test for a bug sql/examples/ha_tina.cc: Add O_APPEND flag to my_open. We should always add rows to the end of file --- mysql-test/r/csv.result | 27 +++++++++++++++++++++++++++ mysql-test/t/csv.test | 19 +++++++++++++++++++ sql/examples/ha_tina.cc | 3 ++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 78a1f34636c..2e3d11ad461 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -4949,3 +4949,30 @@ val 6 6 DROP TABLE bug13894; +DROP TABLE IF EXISTS bug14672; +CREATE TABLE bug14672 (c1 integer) engine = CSV; +INSERT INTO bug14672 VALUES (1), (2), (3); +SELECT * FROM bug14672; +c1 +1 +2 +3 +DELETE FROM bug14672 WHERE c1 = 2; +SELECT * FROM bug14672; +c1 +1 +3 +INSERT INTO bug14672 VALUES (4); +SELECT * FROM bug14672; +c1 +1 +3 +4 +INSERT INTO bug14672 VALUES (5); +SELECT * FROM bug14672; +c1 +1 +3 +4 +5 +DROP TABLE bug14672; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 61b4f9607a5..5b693335a43 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1332,4 +1332,23 @@ UPDATE bug13894 SET val=6 WHERE val=10; SELECT * FROM bug13894; DROP TABLE bug13894; +# +# Bug #14672 Bug in deletion +# + +--disable_warnings +DROP TABLE IF EXISTS bug14672; +--enable_warnings + +CREATE TABLE bug14672 (c1 integer) engine = CSV; +INSERT INTO bug14672 VALUES (1), (2), (3); +SELECT * FROM bug14672; +DELETE FROM bug14672 WHERE c1 = 2; +SELECT * FROM bug14672; +INSERT INTO bug14672 VALUES (4); +SELECT * FROM bug14672; +INSERT INTO bug14672 VALUES (5); +SELECT * FROM bug14672; +DROP TABLE bug14672; + # End of 4.1 tests diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index f4544670ed9..91e42bfea31 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -166,7 +166,8 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table) thr_lock_init(&share->lock); pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST); - if ((share->data_file= my_open(data_file_name, O_RDWR, MYF(0))) == -1) + if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND, + MYF(0))) == -1) goto error2; /* We only use share->data_file for writing, so we scan to the end to append */ From 502495271ddb0e289c0bd778dbad25e089574b2c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 5 Nov 2005 22:41:36 -0800 Subject: [PATCH 51/54] Post review fixes. --- mysql-test/r/view.result | 8 ++++---- sql/share/errmsg.txt | 2 -- sql/sql_table.cc | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 9b434ebe9f4..b92a50d079f 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2339,17 +2339,17 @@ CREATE TABLE t1(id INT); CREATE VIEW v1 AS SELECT id FROM t1; OPTIMIZE TABLE v1; Table Op Msg_type Msg_text -test.v1 optimize note You cannot apply optimize to a view +test.v1 optimize note Unknown table 'test.v1' ANALYZE TABLE v1; Table Op Msg_type Msg_text -test.v1 analyze note You cannot apply analyze to a view +test.v1 analyze note Unknown table 'test.v1' REPAIR TABLE v1; Table Op Msg_type Msg_text -test.v1 repair note You cannot apply repair to a view +test.v1 repair note Unknown table 'test.v1' DROP TABLE t1; OPTIMIZE TABLE v1; Table Op Msg_type Msg_text -test.v1 optimize note You cannot apply optimize to a view +test.v1 optimize note Unknown table 'test.v1' Warnings: Error 1146 Table 'test.t1' doesn't exist Error 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 24e1d4b6b81..f85bda90e81 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5421,5 +5421,3 @@ ER_NO_REFERENCED_ROW_2 23000 eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" ER_SP_BAD_VAR_SHADOW 42000 eng "Variable '%-.64s' must be quoted with `...`, or renamed" -ER_CHECK_NOT_BASE_TABLE 42000 - eng "You cannot apply %s to a view" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b339e6a81e9..fb190f5524f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2335,7 +2335,7 @@ send_result_message: { char buf[ERRMSGSIZE+20]; uint length= my_snprintf(buf, ERRMSGSIZE, - ER(ER_CHECK_NOT_BASE_TABLE), operator_name); + ER(ER_BAD_TABLE_ERROR), table_name); protocol->store("note", 4, system_charset_info); protocol->store(buf, length, system_charset_info); } From 50f48187f2f135b458aee47c561b3afe7df5aa07 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Nov 2005 16:18:46 +0100 Subject: [PATCH 52/54] Fix for BUG#14703 "Valgrind error when inserting 0 into a BIT column (like in type_bit.test)": test "length" first (otherwise when "length" is 0, the *from invalid access still triggers a Valgrind warning). I wrote to the Valgrind authors in case this is something fixable in Valgrind (normally the decision to issue a warning is based on the simulated CPU condition code, which should not be undefined here). BUILD/compile-pentium64-valgrind-max: putting this script in sync with compile-pentium-valgrind-max, otherwise we didn't have the federated engine compiled in. mysql-test/r/read_only.result: result update sql/field.cc: To avoid a Valgrind warning running the type_bit test: test "length" first (otherwise when "length" is 0, the *from invalid access still triggers a Valgrind warning). --- BUILD/compile-pentium64-valgrind-max | 4 ++-- mysql-test/r/read_only.result | 2 ++ sql/field.cc | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/BUILD/compile-pentium64-valgrind-max b/BUILD/compile-pentium64-valgrind-max index 2e4ff8e0082..ef932920130 100755 --- a/BUILD/compile-pentium64-valgrind-max +++ b/BUILD/compile-pentium64-valgrind-max @@ -3,13 +3,13 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$pentium64_cflags $debug_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max" +extra_flags="$pentium64_cflags $debug_cflags $max_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" # We want to test isam when building with valgrind -extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-isam --with-embedded-server --with-openssl --with-raid --with-ndbcluster" +extra_configs="$extra_configs $max_leave_isam_configs --with-isam" . "$path/FINISH.sh" diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result index 09a0861e0c4..55a14bcaec8 100644 --- a/mysql-test/r/read_only.result +++ b/mysql-test/r/read_only.result @@ -14,6 +14,8 @@ create table t3 (a int); ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement insert into t1 values(1); ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +update t1 set a=1 where 1=0; +ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a; ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement delete t1,t2 from t1,t2 where t1.a=t2.a; diff --git a/sql/field.cc b/sql/field.cc index 03d20b4bfe2..18ef77230f2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7931,7 +7931,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) { int delta; - for (; !*from && length; from++, length--); // skip left 0's + for (; length && !*from; from++, length--); // skip left 0's delta= field_length - length; if (delta < -1 || @@ -8151,7 +8151,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) int delta; uchar bits= create_length & 7; - for (; !*from && length; from++, length--); // skip left 0's + for (; length && !*from; from++, length--); // skip left 0's delta= field_length - length; if (delta < 0 || From 9725d32b5193f7d47eac67abd5aafd38d9a1b8fa Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Nov 2005 18:31:48 +0100 Subject: [PATCH 53/54] Bug#13707 - Server crash with INSERT DELAYED on MyISAM table Initialized 'ptr' for a newly instantiated varstring field. This is required by INSERT DELAYED. No test case. This is a migration issue. There are two shell scripts attached to the bug report. They can be used for testing. sql/field.cc: Bug#13707 - Server crash with INSERT DELAYED on MyISAM table Initialized 'ptr' for a newly instantiated varstring field. This is required by INSERT DELAYED. --- sql/field.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index 03d20b4bfe2..f7f7c22bfe9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6202,9 +6202,16 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table) This is done to ensure that ALTER TABLE will convert old VARCHAR fields to now VARCHAR fields. */ - return new Field_varstring(field_length, maybe_null(), - field_name, new_table, - charset()); + Field *new_field= new Field_varstring(field_length, maybe_null(), + field_name, new_table, + charset()); + /* + delayed_insert::get_local_table() needs a ptr copied from old table. + This is what other new_field() methods do too. The above method of + Field_varstring sets ptr to NULL. + */ + new_field->ptr= ptr; + return new_field; } /**************************************************************************** From af2e0dc41a5d2005210ff14143a1a25cca4ffb57 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Nov 2005 22:30:44 +0100 Subject: [PATCH 54/54] mysql-test/r/connect.result + mysql-test/t/connect.test Replace the full socket path name, not just a directory component. bug#14720 mysql-test/r/connect.result: In cases where "--tmpdir=" is given to the test run, the socket file is not created below "$MYSQL_TEST_DIR" but rather within this directory. So the "--replace_result" should not be done to a directory in the path but rather to the complete path name of the socket file. bug#14720 mysql-test/t/connect.test: In cases where "--tmpdir=" is given to the test run, the socket file is not created below "$MYSQL_TEST_DIR" but rather within this directory. So the "--replace_result" should not be done to a directory in the path but rather to the complete path name of the socket file. bug#14720 --- mysql-test/r/connect.result | 20 ++++++++++---------- mysql-test/t/connect.test | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index d5b1cf4dd63..4f49f77d46c 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -20,9 +20,9 @@ time_zone_transition_type user show tables; Tables_in_test -connect(localhost,root,z,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,root,z,test2,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'root'@'localhost' (using password: YES) -connect(localhost,root,z,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,root,z,test,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'root'@'localhost' (using password: YES) grant ALL on *.* to test@localhost identified by "gambling"; grant ALL on *.* to test@127.0.0.1 identified by "gambling"; @@ -47,13 +47,13 @@ time_zone_transition_type user show tables; Tables_in_test -connect(localhost,test,,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,,test2,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) -connect(localhost,test,,"",MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,,"",MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) -connect(localhost,test,zorro,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,zorro,test2,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) -connect(localhost,test,zorro,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) update mysql.user set password=old_password("gambling2") where user=_binary"test"; flush privileges; @@ -82,13 +82,13 @@ time_zone_transition_type user show tables; Tables_in_test -connect(localhost,test,,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,,test2,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) -connect(localhost,test,,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,,test,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) -connect(localhost,test,zorro,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,zorro,test2,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) -connect(localhost,test,zorro,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock); +connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) delete from mysql.user where user=_binary"test"; flush privileges; diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index a867baa9fc9..fef9d4552e6 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -17,10 +17,10 @@ show tables; connect (con2,localhost,root,,test); show tables; ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,root,z,test2); ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,root,z,); @@ -35,16 +35,16 @@ show tables; connect (con4,localhost,test,gambling,test); show tables; ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,,test2); ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,,""); ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,zorro,test2); ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,zorro,); @@ -63,16 +63,16 @@ show tables; connect (con6,localhost,test,gambling3,test); show tables; ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,,test2); ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,,); ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,zorro,test2); ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error 1045 connect (fail_con,localhost,test,zorro,);