From 932ee96eec364c23797257aff5b063446e5db4b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Apr 2006 18:26:26 +0200 Subject: [PATCH 01/12] configure.in: Recloning, set back to 5.0.21 configure.in: Recloning, set back to 5.0.21 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 74ac7ed4574..174c9a16d8e 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.22) +AM_INIT_AUTOMAKE(mysql, 5.0.21) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=22 +NDB_VERSION_BUILD=21 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 4ab4631b068587756e247652d000e87bdb460d1a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 May 2006 11:21:21 +0300 Subject: [PATCH 02/12] Bug#19136: Crashing log-bin and uninitialized user variables in a derived table The reason of the bug is in that `get_var_with_binlog' performs missed assingment of the variables as side-effect. Doing that it eventually calls `free_underlaid_joins' to pass as an argument `thd->lex->select_lex' of the lex which belongs to the user query, not to one which is emulated i.e SET @var1:=NULL. `get_var_with_binlog' is refined to supply a temporary lex to sql_set_variables's stack. mysql-test/r/rpl_user_variables.result: results changed mysql-test/t/rpl_user_variables.test: a problematic query to be binlogged is added sql/item_func.cc: BUG#19136: Crashing log-bin and uninitialized user variables The reason of the bug is in that how `get_var_with_binlog' performs missed assingment of the variables: `free_underlaid_joins' gets as an argument `thd->lex->select_lex' which belongs to the user query, not to one which is emulated i.e SET @var1:=NULL. `get_var_with_binlog' is refined to supply a temporary lex to sql_set_variables's stack. --- mysql-test/r/rpl_user_variables.result | 1 + mysql-test/t/rpl_user_variables.test | 6 ++++++ sql/item_func.cc | 10 ++++++++++ 3 files changed, 17 insertions(+) diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result index 85768270ba3..8af2c3e0b22 100644 --- a/mysql-test/r/rpl_user_variables.result +++ b/mysql-test/r/rpl_user_variables.result @@ -105,5 +105,6 @@ slave-bin.000001 1370 User var 2 1370 @`a`=5 slave-bin.000001 1412 Query 1 1412 use `test`; insert into t1 values (@a),(@a) slave-bin.000001 1478 User var 2 1478 @`a`=NULL slave-bin.000001 1503 Query 1 1503 use `test`; insert into t1 values (@a),(@a),(@a*5) +insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; stop slave; diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test index 5cf502e05bd..6597413c22e 100644 --- a/mysql-test/t/rpl_user_variables.test +++ b/mysql-test/t/rpl_user_variables.test @@ -47,9 +47,15 @@ connection slave; sync_with_master; select * from t1; show binlog events from 141; + +# +# BUG19136: Crashing log-bin and uninitialized user variables in a derived table +# just to check nothing bad happens anymore connection master; +insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; save_master_pos; + connection slave; sync_with_master; stop slave; diff --git a/sql/item_func.cc b/sql/item_func.cc index 174a8c55d01..15e272cdef8 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2733,14 +2733,24 @@ int get_var_with_binlog(THD *thd, LEX_STRING &name, sql_set_variables(), we could instead manually call check() and update(); this would save memory and time; but calling sql_set_variables() makes one unique place to maintain (sql_set_variables()). + + Manipulation with lex is necessary since free_underlaid_joins + is going to release memory belonging to the main query. */ List tmp_var_list; + LEX *sav_lex= thd->lex, lex_tmp; + thd->lex= &lex_tmp; + lex_start(thd, NULL, 0); tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, new Item_null()))); /* Create the variable */ if (sql_set_variables(thd, &tmp_var_list)) + { + thd->lex= sav_lex; goto err; + } + thd->lex= sav_lex; if (!(var_entry= get_variable(&thd->user_vars, name, 0))) goto err; } From c13144722aaf7892a64d6fdeffc130dcda041ab3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 6 May 2006 13:15:00 +0400 Subject: [PATCH 03/12] BUG#16798: Inapplicable ref_or_null query plan and bad query result on random occasions The bug was as follows: When merge_key_fields() encounters "t.key=X OR t.key=Y" it will try to join them into ref_or_null access via "t.key=X OR NULL". In order to make this inference it checks if Y<=>NULL, ignoring the fact that value of Y may be not yet known. The fix is that the check if Y<=>NULL is made only if value of Y is known (i.e. it is a constant). TODO: When merging to 5.0, replace used_tables() with const_item() everywhere in merge_key_fields(). mysql-test/r/innodb_mysql.result: Testcase for BUG16798 mysql-test/t/innodb_mysql.test: Testcase for BUG16798 sql/sql_select.cc: BUG#16798: Inapplicable ref_or_null query plan and bad query result on random occasions In merge_key_fields() don't call val->is_null() if the value of val is not known. --- mysql-test/r/innodb_mysql.result | 57 +++++++++++++++++++++++++++++++- mysql-test/t/innodb_mysql.test | 56 ++++++++++++++++++++++++++++++- sql/sql_select.cc | 3 +- 3 files changed, 113 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 878c5cb5451..2a4e3555e3b 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1 +1,56 @@ -drop table if exists t1; +drop table if exists t1,t2; +create table t1 ( +c_id int(11) not null default '0', +org_id int(11) default null, +unique key contacts$c_id (c_id), +key contacts$org_id (org_id) +) engine=innodb; +insert into t1 values +(2,null),(120,null),(141,null),(218,7), (128,1), +(151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), +(246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); +create table t2 ( +slai_id int(11) not null default '0', +owner_tbl int(11) default null, +owner_id int(11) default null, +sla_id int(11) default null, +inc_web int(11) default null, +inc_email int(11) default null, +inc_chat int(11) default null, +inc_csr int(11) default null, +inc_total int(11) default null, +time_billed int(11) default null, +activedate timestamp null default null, +expiredate timestamp null default null, +state int(11) default null, +sla_set int(11) default null, +unique key t2$slai_id (slai_id), +key t2$owner_id (owner_id), +key t2$sla_id (sla_id) +) engine=innodb; +insert into t2(slai_id, owner_tbl, owner_id, sla_id) values +(1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), +(8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); +flush tables; +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +select * from t1 where org_id is null; +c_id org_id +2 NULL +120 NULL +141 NULL +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +drop table t1, t2; diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index b942b9fbc0d..f31e4d64789 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1,5 +1,59 @@ -- source include/have_innodb.inc --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; --enable_warnings + +# BUG#16798: Uninitialized row buffer reads in ref-or-null optimizer +# (repeatable only w/innodb). +create table t1 ( + c_id int(11) not null default '0', + org_id int(11) default null, + unique key contacts$c_id (c_id), + key contacts$org_id (org_id) +) engine=innodb; +insert into t1 values + (2,null),(120,null),(141,null),(218,7), (128,1), + (151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), + (246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); + +create table t2 ( + slai_id int(11) not null default '0', + owner_tbl int(11) default null, + owner_id int(11) default null, + sla_id int(11) default null, + inc_web int(11) default null, + inc_email int(11) default null, + inc_chat int(11) default null, + inc_csr int(11) default null, + inc_total int(11) default null, + time_billed int(11) default null, + activedate timestamp null default null, + expiredate timestamp null default null, + state int(11) default null, + sla_set int(11) default null, + unique key t2$slai_id (slai_id), + key t2$owner_id (owner_id), + key t2$sla_id (sla_id) +) engine=innodb; +insert into t2(slai_id, owner_tbl, owner_id, sla_id) values + (1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), + (8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); + +flush tables; +select si.slai_id +from t1 c join t2 si on + ((si.owner_tbl = 3 and si.owner_id = c.org_id) or + ( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where + c.c_id = 218 and expiredate is null; + +select * from t1 where org_id is null; +select si.slai_id +from t1 c join t2 si on + ((si.owner_tbl = 3 and si.owner_id = c.org_id) or + ( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where + c.c_id = 218 and expiredate is null; + +drop table t1, t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 46dba61cfc5..4995a164226 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2090,7 +2090,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, new_fields->null_rejecting); } else if (old->eq_func && new_fields->eq_func && - (old->val->is_null() || new_fields->val->is_null())) + ((!old->val->used_tables() && old->val->is_null()) || + new_fields->val->is_null())) { /* field = expression OR field IS NULL */ old->level= and_level; From 375749b8afd8b7f47a0b717d0546ad1b2a8f05eb Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 6 May 2006 23:48:13 -0700 Subject: [PATCH 04/12] Fixed bug #14927. A query with a group by and having clauses could return a wrong result set if the having condition contained a constant conjunct evaluated to FALSE. It happened because the pushdown condition for table with grouping columns lost its constant conjuncts. Pushdown conditions are always built by the function make_cond_for_table that ignores constant conjuncts. This is apparently not correct when constant false conjuncts are present. mysql-test/r/having.result: Added a test case for bug #14927. mysql-test/t/having.test: Added a test case for bug #14927. sql/sql_lex.cc: Fixed bug #14927. Initialized fields for having conditions in st_select_lex::init_query(). sql/sql_lex.h: Fixed bug #14927. Added a field to restore having condititions for execution in SP and PS. sql/sql_prepare.cc: Fixed bug #14927. Added code to restore havinf conditions for execution in SP and PS. sql/sql_select.cc: Fixed bug #14927. Performed evaluation of constant expressions in having clauses. If the having condition contains a constant conjunct that is always false an empty result set is returned after the optimization phase. In this case the corresponding EXPLAIN command now returns "Impossible HAVING" in the last column. --- mysql-test/r/having.result | 17 +++++++++++++++++ mysql-test/t/having.test | 16 ++++++++++++++++ sql/sql_lex.cc | 2 ++ sql/sql_lex.h | 1 + sql/sql_prepare.cc | 10 ++++++++-- sql/sql_select.cc | 28 +++++++++++++++++++--------- 6 files changed, 63 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 9730f9f81bf..ccd1f0e61e7 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -141,3 +141,20 @@ SUM(a) 6 4 DROP TABLE t1; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (1), (3), (2), (1); +SELECT a FROM t1 GROUP BY a HAVING a > 1; +a +2 +3 +SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +a +SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; +x a +EXPLAIN SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +DROP table t1; diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 3dd9ace6a1b..8b39e3bd454 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -135,4 +135,20 @@ SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a); DROP TABLE t1; +# +# Bug #14927: HAVING clause containing constant false conjunct +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (1), (3), (2), (1); + +SELECT a FROM t1 GROUP BY a HAVING a > 1; +SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; + +EXPLAIN SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; + +DROP table t1; + # End of 4.1 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 16641ad6dd5..7348816ea27 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1074,6 +1074,7 @@ void st_select_lex::init_query() item_list.empty(); join= 0; where= 0; + having= 0; olap= UNSPECIFIED_OLAP_TYPE; having_fix_field= 0; resolve_mode= NOMATTER_MODE; @@ -1081,6 +1082,7 @@ void st_select_lex::init_query() ref_pointer_array= 0; select_n_having_items= 0; prep_where= 0; + prep_having= 0; subquery_in_having= explicit_limit= 0; parsing_place= NO_MATTER; is_item_list_lookup= 0; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index bd79a194122..35f02db6cf9 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -422,6 +422,7 @@ public: char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ Item *where, *having; /* WHERE & HAVING clauses */ Item *prep_where; /* saved WHERE clause for prepared statement processing */ + Item *prep_having;/* saved HAVING clause for prepared statement processing */ enum olap_type olap; SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */ List item_list; /* list of fields & expressions */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 741d84eab44..2d9e80df63c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1667,10 +1667,11 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, for (; sl; sl= sl->next_select_in_list()) { /* - Save WHERE clause pointers, because they may be changed + Save WHERE, HAVING clause pointers, because they may be changed during query optimisation. */ sl->prep_where= sl->where; + sl->prep_having= sl->having; /* Switch off a temporary flag that prevents evaluation of subqueries in statement prepare. @@ -1696,13 +1697,18 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) /* remove option which was put by mysql_explain_union() */ sl->options&= ~SELECT_DESCRIBE; /* - Copy WHERE clause pointers to avoid damaging they by optimisation + Copy WHERE, HAVING clause pointers to avoid damaging they by optimisation */ if (sl->prep_where) { sl->where= sl->prep_where->copy_andor_structure(thd); sl->where->cleanup(); } + if (sl->prep_having) + { + sl->having= sl->prep_having->copy_andor_structure(thd); + sl->having->cleanup(); + } DBUG_ASSERT(sl->join == 0); ORDER *order; /* Fix GROUP list */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4995a164226..57fb9738612 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -501,12 +501,24 @@ JOIN::optimize() DBUG_RETURN(1); } - if (cond_value == Item::COND_FALSE || - (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) - { /* Impossible cond */ - zero_result_cause= "Impossible WHERE"; - error= 0; - DBUG_RETURN(0); + { + Item::cond_result having_value; + having= optimize_cond(thd, having, &having_value); + if (thd->net.report_error) + { + error= 1; + DBUG_PRINT("error",("Error from optimize_cond")); + DBUG_RETURN(1); + } + + if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE || + (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) + { /* Impossible cond */ + zero_result_cause= having_value == Item::COND_FALSE ? + "Impossible HAVING" : "Impossible WHERE"; + error= 0; + DBUG_RETURN(0); + } } /* Optimize count(*), min() and max() */ @@ -4612,10 +4624,8 @@ optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) DBUG_EXECUTE("info", print_where(conds, "after remove");); } else - { *cond_value= Item::COND_TRUE; - select->prep_where= 0; - } + DBUG_RETURN(conds); } From 5b09d7a5e11470613d35808a89892262e1c8951c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 7 May 2006 19:01:49 +0400 Subject: [PATCH 05/12] BUG#16798: Merge into 5.0: s/used_tables()/!const_item()/, added comment about its effects. --- sql/sql_select.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 02110023cac..465f41fa8de 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2377,7 +2377,19 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, { if (old->field == new_fields->field) { - if (new_fields->val->used_tables()) + /* + NOTE: below const_item() call really works as "!used_tables()", i.e. + it can return FALSE where it is feasible to make it return TRUE. + + The cause is as follows: Some of the tables are already known to be + const tables (the detection code is in make_join_statistics(), + above the update_ref_and_keys() call), but we didn't propagate + information about this: TABLE::const_table is not set to TRUE, and + Item::update_used_tables() hasn't been called for each item. + The result of this is that we're missing some 'ref' accesses. + TODO: OptimizerTeam: Fix this + */ + if (!new_fields->val->const_item()) { /* If the value matches, we can use the key reference. @@ -2407,7 +2419,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, new_fields->null_rejecting); } else if (old->eq_func && new_fields->eq_func && - ((!old->val->used_tables() && old->val->is_null()) || + ((old->val->const_item() && old->val->is_null()) || new_fields->val->is_null())) { /* field = expression OR field IS NULL */ From a910a0bf6938beaf39d3b1ef8af61195894ab908 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 7 May 2006 19:54:57 +0300 Subject: [PATCH 06/12] Bug#19136: Crashing log-bin and uninitialized user variables in a derived table recalculating results mysql-test/r/rpl_user_variables.result: fixing results --- mysql-test/r/rpl_user_variables.result | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result index 4198bbcc154..45618688a33 100644 --- a/mysql-test/r/rpl_user_variables.result +++ b/mysql-test/r/rpl_user_variables.result @@ -106,5 +106,6 @@ slave-bin.000001 # User var 2 # @`a`=5 slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a) slave-bin.000001 # User var 2 # @`a`=NULL slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a),(@a*5) +insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; stop slave; From 5aa69d34a73556cccfd6b2762bc0683198637742 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 7 May 2006 16:14:43 -0700 Subject: [PATCH 07/12] Post-merge fixes. --- mysql-test/r/rpl_user_variables.result | 59 +++++++++++++------------- sql/sql_lex.cc | 2 +- sql/sql_prepare.cc | 27 ++++++------ 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result index 8af2c3e0b22..45618688a33 100644 --- a/mysql-test/r/rpl_user_variables.result +++ b/mysql-test/r/rpl_user_variables.result @@ -76,35 +76,36 @@ abcn1n2 NULL NULL NULL -show binlog events from 141; -Log_name Pos Event_type Server_id Orig_log_pos Info -slave-bin.000001 141 User var 2 141 @`i1`=12345678901234 -slave-bin.000001 184 User var 2 184 @`i2`=-12345678901234 -slave-bin.000001 227 User var 2 227 @`i3`=0 -slave-bin.000001 270 User var 2 270 @`i4`=-1 -slave-bin.000001 313 Query 1 313 use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4) -slave-bin.000001 396 User var 2 396 @`r1`=12.5 -slave-bin.000001 439 User var 2 439 @`r2`=-12.5 -slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2) -slave-bin.000001 551 User var 2 551 @`s1`=_latin1 0x5468697320697320612074657374 COLLATE latin1_swedish_ci -slave-bin.000001 600 User var 2 600 @`s2`=_latin1 "" COLLATE latin1_swedish_ci -slave-bin.000001 635 User var 2 635 @`s3`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci -slave-bin.000001 677 User var 2 677 @`s4`=_latin1 0x6162635C646566 COLLATE latin1_swedish_ci -slave-bin.000001 719 User var 2 719 @`s5`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci -slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5) -slave-bin.000001 851 User var 2 851 @`n1`=NULL -slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1) -slave-bin.000001 939 User var 2 939 @`n2`=NULL -slave-bin.000001 965 Query 1 965 use `test`; insert into t1 values (@n2) -slave-bin.000001 1027 Query 1 1027 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1) -slave-bin.000001 1115 User var 2 1115 @`a`=2 -slave-bin.000001 1157 Query 1 1157 use `test`; insert into t1 values (@a+(@b:=@a+1)) -slave-bin.000001 1229 User var 2 1229 @`q`=_latin1 0x616263 COLLATE latin1_swedish_ci -slave-bin.000001 1266 Query 1 1266 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')) -slave-bin.000001 1370 User var 2 1370 @`a`=5 -slave-bin.000001 1412 Query 1 1412 use `test`; insert into t1 values (@a),(@a) -slave-bin.000001 1478 User var 2 1478 @`a`=NULL -slave-bin.000001 1503 Query 1 1503 use `test`; insert into t1 values (@a),(@a),(@a*5) +show binlog events from 98; +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Query 1 # use `test`; create table t1(n char(30)) +slave-bin.000001 # User var 2 # @`i1`=12345678901234 +slave-bin.000001 # User var 2 # @`i2`=-12345678901234 +slave-bin.000001 # User var 2 # @`i3`=0 +slave-bin.000001 # User var 2 # @`i4`=-1 +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4) +slave-bin.000001 # User var 2 # @`r1`=12.5 +slave-bin.000001 # User var 2 # @`r2`=-12.5 +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@r1), (@r2) +slave-bin.000001 # User var 2 # @`s1`=_latin1 0x5468697320697320612074657374 COLLATE latin1_swedish_ci +slave-bin.000001 # User var 2 # @`s2`=_latin1 "" COLLATE latin1_swedish_ci +slave-bin.000001 # User var 2 # @`s3`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci +slave-bin.000001 # User var 2 # @`s4`=_latin1 0x6162635C646566 COLLATE latin1_swedish_ci +slave-bin.000001 # User var 2 # @`s5`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5) +slave-bin.000001 # User var 2 # @`n1`=NULL +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@n1) +slave-bin.000001 # User var 2 # @`n2`=NULL +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@n2) +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1) +slave-bin.000001 # User var 2 # @`a`=2 +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a+(@b:=@a+1)) +slave-bin.000001 # User var 2 # @`q`=_latin1 0x616263 COLLATE latin1_swedish_ci +slave-bin.000001 # Query 1 # use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')) +slave-bin.000001 # User var 2 # @`a`=5 +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a) +slave-bin.000001 # User var 2 # @`a`=NULL +slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a),(@a*5) insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; stop slave; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 927be007ba2..c4c72910265 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1145,7 +1145,7 @@ void st_select_lex::init_query() cond_count= with_wild= 0; conds_processed_with_permanent_arena= 0; ref_pointer_array= 0; - select_n_having_items= 0;} + select_n_having_items= 0; subquery_in_having= explicit_limit= 0; is_item_list_lookup= 0; first_execution= 1; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d615b6528e2..103a0b9e54e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1965,6 +1965,7 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len) memcpy(query_str, var_value->ptr(), var_value->length()); query_str[len]= '\0'; // Safety (mostly for debug) *query_len= len; + } else { query_str= lex->prepared_stmt_code.str; @@ -2084,19 +2085,20 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) sl->exclude_from_table_unique_test= FALSE; /* - Copy WHERE, HAVING clause pointers to avoid damaging them by optimisation + Copy WHERE, HAVING clause pointers to avoid damaging them + by optimisation */ - if (sl->prep_where) - { - sl->where= sl->prep_where->copy_andor_structure(thd); - sl->where->cleanup(); - } - if (sl->prep_having) - { - sl->having= sl->prep_having->copy_andor_structure(thd); - sl->having->cleanup(); - } - DBUG_ASSERT(sl->join == 0); + if (sl->prep_where) + { + sl->where= sl->prep_where->copy_andor_structure(thd); + sl->where->cleanup(); + } + if (sl->prep_having) + { + sl->having= sl->prep_having->copy_andor_structure(thd); + sl->having->cleanup(); + } + DBUG_ASSERT(sl->join == 0); ORDER *order; /* Fix GROUP list */ for (order= (ORDER *)sl->group_list.first; order; order= order->next) @@ -2104,6 +2106,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) /* Fix ORDER list */ for (order= (ORDER *)sl->order_list.first; order; order= order->next) order->item= &order->item_ptr; + } { SELECT_LEX_UNIT *unit= sl->master_unit(); unit->unclean(); From 42f20d7538f282ccf283eeadd0454c5bea9e8d7d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 May 2006 00:11:54 +0200 Subject: [PATCH 08/12] --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index b3f929de19c..ac1c122c2ea 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.21) +AM_INIT_AUTOMAKE(mysql, 5.0.22) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=21 +NDB_VERSION_BUILD=22 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 3c0ca0ce2dccf450191eecc8d5aa88f8b16e15b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 May 2006 11:33:36 -0600 Subject: [PATCH 09/12] Bug #6061 mysql-log-rotate script - error logging doesn't use new file - Fix mysqld_safe so that it always passes correct --log-error argument to mysqld - A few other minor clean-ups to mysqld_safe scripts/mysqld_safe.sh: Bug #6061 mysql-log-rotate script - error logging doesn't use new file - Change mysqld_safe to pass --log-error to mysqld in all cases. The old behavior was to usually "swallow" the --log-error=file.name argument, which caused mysqld to write to stderr and not be able to flush the error log file. Ironically, passing --log-error (with no file name) seemed to work fine, because mysqld_safe didn't recognize it and passed it on to mysqld as an unknown option. - Ensure that the error log file matches what mysqld uses; in particular, add ".err" if given a --log-error argument with no extension, and add "$DATADIR" to the front of a relative path - Various other mysqld_safe clean-ups while there - quote arguments properly, remove some redundant code --- scripts/mysqld_safe.sh | 68 ++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 83bc8ce8954..744a4791307 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -31,7 +31,6 @@ Usage: $0 [OPTIONS] --defaults-file=FILE Use the specified defaults file --defaults-extra-file=FILE Also use defaults from the specified file --ledir=DIRECTORY Look for mysqld in the specified directory - --log-error=FILE Log errors to the specified log file --open-files-limit=LIMIT Limit the number of open files --core-file-size=LIMIT Limit core files to the specified size --timezone=TZ Set the system timezone @@ -46,6 +45,11 @@ EOF exit 1 } +shell_quote_string() { + # This sed command makes sure that any special chars are quoted, + # so the arg gets passed exactly to the server. + echo "$1" | sed -e 's,\([^a-zA-Z0-9/_.=-]\),\\\1,g' +} parse_arguments() { # We only need to pass arguments through to the server if we don't @@ -69,14 +73,14 @@ parse_arguments() { --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;; --user=*) user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 ;; - # these two might have been set in a [mysqld_safe] section of my.cnf + # these might have been set in a [mysqld_safe] section of my.cnf # they are added to mysqld command line to override settings from my.cnf + --log-error=*) err_log=`echo "$arg" | sed -e "s;--log-error=;;"` ;; --socket=*) mysql_unix_port=`echo "$arg" | sed -e "s;--socket=;;"` ;; --port=*) mysql_tcp_port=`echo "$arg" | sed -e "s;--port=;;"` ;; # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])! --ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;; - --log-error=*) err_log=`echo "$arg" | sed -e "s;--log-error=;;"` ;; --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--open-files-limit=;;"` ;; --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--core-file-size=;;"` ;; --timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;; @@ -97,9 +101,7 @@ parse_arguments() { *) if test -n "$pick_args" then - # This sed command makes sure that any special chars are quoted, - # so the arg gets passed exactly to the server. - args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'` + append_arg_to_args "$arg" fi ;; esac @@ -194,6 +196,10 @@ else print_defaults="my_print_defaults" fi +append_arg_to_args () { + args="$args "`shell_quote_string "$1"` +} + args= SET_USER=2 parse_arguments `$print_defaults $defaults --loose-verbose mysqld server` @@ -239,15 +245,39 @@ else * ) pid_file="$DATADIR/$pid_file" ;; esac fi -test -z "$err_log" && err_log=$DATADIR/`@HOSTNAME@`.err +append_arg_to_args "--pid-file=$pid_file" + +if [ -n "$err_log" ] +then + # mysqld adds ".err" if there is no extension on the --log-err + # argument; must match that here, or mysqld_safe will write to a + # different log file than mysqld + + # mysqld does not add ".err" to "--log-error=foo."; it considers a + # trailing "." as an extension + if expr "$err_log" : '.*\.[^/]*$' > /dev/null + then + : + else + err_log="$err_log".err + fi + + case "$err_log" in + /* ) ;; + * ) err_log="$DATADIR/$err_log" ;; + esac +else + err_log=$DATADIR/`@HOSTNAME@`.err +fi +append_arg_to_args "--log-error=$err_log" if test -n "$mysql_unix_port" then - args="--socket=$mysql_unix_port $args" + append_arg_to_args "--socket=$mysql_unix_port" fi if test -n "$mysql_tcp_port" then - args="--port=$mysql_tcp_port $args" + append_arg_to_args "--port=$mysql_tcp_port" fi if test $niceness -eq 0 @@ -314,7 +344,7 @@ then if test -n "$open_files" then ulimit -n $open_files - args="--open-files-limit=$open_files $args" + append_arg_to_args "--open-files-limit=$open_files" fi if test -n "$core_file_size" then @@ -372,12 +402,18 @@ echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log while true do rm -f $safe_mysql_unix_port $pid_file # Some extra safety - if test -z "$args" - then - $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1 - else - eval "$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ $args >> $err_log 2>&1" - fi + + cmd="$NOHUP_NICENESS" + + for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \ + "--datadir=$DATADIR" "$USER_OPTION" + do + cmd="$cmd "`shell_quote_string "$i"` + done + cmd="$cmd $args >> "`shell_quote_string "$err_log"`" 2>&1" + #echo "Running mysqld: [$cmd]" + eval "$cmd" + if test ! -f $pid_file # This is removed if normal shutdown then echo "STOPPING server from pid file $pid_file" From c4c0e1edd5cdf47300b57cb0171dff4665985373 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 May 2006 00:58:13 +0200 Subject: [PATCH 10/12] rpl_log.test: Correct fix for test bug #19158 mysql-test/extra/rpl_tests/rpl_log.test: Correct fix for test bug #19158 --- mysql-test/extra/rpl_tests/rpl_log.test | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test index 116bdd1028e..7cb10ed1acb 100644 --- a/mysql-test/extra/rpl_tests/rpl_log.test +++ b/mysql-test/extra/rpl_tests/rpl_log.test @@ -81,7 +81,12 @@ start slave; # This is timing out in pushbuild and should be changed to use # wait_slave_status.inc # -sleep 2; +--disable_query_log +--disable_result_log +let $result_pattern= '%127.0.0.1%root%master-bin.000002%slave-relay-bin.000007%Yes%Yes%0%0%None%'; +--source include/wait_slave_status.inc +--enable_query_log +--enable_result_log sync_with_master; flush logs; stop slave; From f82ae1c556d66abe2dfa5613fdaca8adb13f1bf5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 May 2006 00:59:34 +0200 Subject: [PATCH 11/12] rpl_log.test: Remove comments not needed mysql-test/extra/rpl_tests/rpl_log.test: Remove comments not needed --- mysql-test/extra/rpl_tests/rpl_log.test | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test index 7cb10ed1acb..c9d9a4214d2 100644 --- a/mysql-test/extra/rpl_tests/rpl_log.test +++ b/mysql-test/extra/rpl_tests/rpl_log.test @@ -77,10 +77,6 @@ connection slave; # to go into the relay log (the master always sends a fake one when replication # starts). start slave; -# -# This is timing out in pushbuild and should be changed to use -# wait_slave_status.inc -# --disable_query_log --disable_result_log let $result_pattern= '%127.0.0.1%root%master-bin.000002%slave-relay-bin.000007%Yes%Yes%0%0%None%'; From a04f6024b058070389a16a34ba5ecff1d609914e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 May 2006 11:06:35 -0500 Subject: [PATCH 12/12] bringing handlerton-win.cc back after incorrectly deleteing it. It is not needed for 5.1 or later but is used by 5.0 sql/handlerton-win.cc: Rename: BitKeeper/deleted/.del-handlerton-win.cc~322a7e59507976df -> sql/handlerton-win.cc --- sql/handlerton-win.cc | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 sql/handlerton-win.cc diff --git a/sql/handlerton-win.cc b/sql/handlerton-win.cc new file mode 100644 index 00000000000..9ce4eab2444 --- /dev/null +++ b/sql/handlerton-win.cc @@ -0,0 +1,72 @@ +#include "mysql_priv.h" + +extern handlerton heap_hton; +extern handlerton myisam_hton; +extern handlerton myisammrg_hton; +extern handlerton binlog_hton; +#ifdef WITH_INNOBASE_STORAGE_ENGINE +extern handlerton innobase_hton; +#endif +#ifdef WITH_BERKELEY_STORAGE_ENGINE +extern handlerton berkeley_hton; +#endif +#ifdef WITH_EXAMPLE_STORAGE_ENGINE +extern handlerton example_hton; +#endif +#ifdef WITH_ARCHIVE_STORAGE_ENGINE +extern handlerton archive_hton; +#endif +#ifdef WITH_CSV_STORAGE_ENGINE +extern handlerton tina_hton; +#endif +#ifdef WITH_BLACKHOLE_STORAGE_ENGINE +extern handlerton blackhole_hton; +#endif +#ifdef WITH_FEDERATED_STORAGE_ENGINE +extern handlerton federated_hton; +#endif +#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE +extern handlerton ndbcluster_hton; +#endif +#ifdef WITH_PARTITION_STORAGE_ENGINE +extern handlerton partition_hton; +#endif + +/* + This array is used for processing compiled in engines. +*/ +handlerton *sys_table_types[]= +{ + &heap_hton, + &myisam_hton, +#ifdef WITH_INNOBASE_STORAGE_ENGINE + &innobase_hton, +#endif +#ifdef WITH_BERKELEY_STORAGE_ENGINE + &berkeley_hton, +#endif +#ifdef WITH_EXAMPLE_STORAGE_ENGINE + &example_hton, +#endif +#ifdef WITH_ARCHIVE_STORAGE_ENGINE + &archive_hton, +#endif +#ifdef WITH_CSV_STORAGE_ENGINE + &tina_hton, +#endif +#ifdef WITH_BLACKHOLE_STORAGE_ENGINE + &blackhole_hton, +#endif +#ifdef WITH_FEDERATED_STORAGE_ENGINE + &federated_hton, +#endif +#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE + &ndbcluster_hton, +#endif +#ifdef WITH_PARTITION_STORAGE_ENGINE + &partition_hton, +#endif + &myisammrg_hton, + &binlog_hton, + NULL +};