From 333eadf1b21698779f6a574786986c3b846f2958 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Mon, 3 May 2004 19:15:26 +0300 Subject: [PATCH 1/4] Fix for a bug involving UNION's and SET SQL_SELECT_LIMIT --- mysql-test/r/union.result | 11 +++++++++++ mysql-test/t/union.test | 4 ++++ sql/sql_union.cc | 15 ++++++++++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index fbd4624a57c..8a5e5e5b6e3 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -924,3 +924,14 @@ a 1 2 2 +set sql_select_limit=1; +select 1 union select 2; +1 +1 +(select 1) union (select 2); +1 +1 +(select 1) union (select 2) union (select 3) limit 2; +1 +1 +2 diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 9866b867427..6b76ceea65a 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -498,4 +498,8 @@ select * from t1 UNION ALL select * from t1; select * from t1 UNION select * from t1 UNION ALL select * from t1; drop table t1; select 1 as a union all select 1 union all select 2 union select 1 union all select 2; +set sql_select_limit=1; +select 1 union select 2; +(select 1) union (select 2); +(select 1) union (select 2) union (select 3) limit 2; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 468bdab9119..df20f04a67e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -377,12 +377,21 @@ int st_select_lex_unit::exec() if (!thd->is_fatal_error) // Check if EOM { ulong options_tmp= thd->options; + /* + We have to take into the account a case when: + SET SQL_SELECT_LIMIT was set. + In mysql_new_select() function this value was copied to + the fake_select_lex node of the top-level unit. + Here below, we just take this value if global LIMIT was not applied + to the entire UNION. + */ + ha_rows select_limit= ((global_parameters->select_limit != HA_POS_ERROR) ? + global_parameters->select_limit : fake_select_lex->select_limit); thd->lex->current_select= fake_select_lex; offset_limit_cnt= global_parameters->offset_limit; - select_limit_cnt= global_parameters->select_limit + - global_parameters->offset_limit; + select_limit_cnt= select_limit + global_parameters->offset_limit; - if (select_limit_cnt < global_parameters->select_limit) + if (select_limit_cnt < select_limit) select_limit_cnt= HA_POS_ERROR; // no limit if (select_limit_cnt == HA_POS_ERROR) options_tmp&= ~OPTION_FOUND_ROWS; From 909d69ff0ad7f0f088350d895d6b5dd8dbdd509c Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 4 May 2004 14:11:23 +0300 Subject: [PATCH 2/4] union.result, union.test: a small fix for the test case --- mysql-test/r/union.result | 1 + mysql-test/t/union.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 8a5e5e5b6e3..842c8e4c25e 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -935,3 +935,4 @@ select 1 union select 2; 1 1 2 +set sql_select_limit=1; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 6b76ceea65a..f3d61f37b1f 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -502,4 +502,5 @@ set sql_select_limit=1; select 1 union select 2; (select 1) union (select 2); (select 1) union (select 2) union (select 3) limit 2; +set sql_select_limit=1; From b58127689ed39d995eb8eda389066defae3dc7e0 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 4 May 2004 16:48:34 +0300 Subject: [PATCH 3/4] union.result: fixing typo union.test: fixing type --- mysql-test/r/union.result | 2 +- mysql-test/t/union.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 842c8e4c25e..54bba1fd958 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -935,4 +935,4 @@ select 1 union select 2; 1 1 2 -set sql_select_limit=1; +set sql_select_limit=default; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index f3d61f37b1f..effb0139111 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -502,5 +502,5 @@ set sql_select_limit=1; select 1 union select 2; (select 1) union (select 2); (select 1) union (select 2) union (select 3) limit 2; -set sql_select_limit=1; +set sql_select_limit=default; From 68cb444c62f0df0c244f9088a1422108829d34d5 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 4 May 2004 23:04:05 +0300 Subject: [PATCH 4/4] Fix for a multi table updates when one of the tables is not updated but used in a nested query. --- mysql-test/r/multi_update.result | 1 + mysql-test/t/multi_update.test | 4 ++++ sql/sql_update.cc | 11 ++++++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index f0975b6fa10..2b312a86289 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -324,6 +324,7 @@ a b 7 7 8 8 9 9 +update t1,t2 set t1.b=t2.b, t1.a=t2.a where t1.a=t2.a and not exists (select * from t2 where t2.a > 10); drop table t1,t2; CREATE TABLE t3 ( KEY1 varchar(50) NOT NULL default '', PARAM_CORR_DISTANCE_RUSH double default NULL, PARAM_CORR_DISTANCE_GEM double default NULL, PARAM_AVG_TARE double default NULL, PARAM_AVG_NB_DAYS double default NULL, PARAM_DEFAULT_PROP_GEM_SRVC varchar(50) default NULL, PARAM_DEFAULT_PROP_GEM_NO_ETIK varchar(50) default NULL, PARAM_SCENARIO_COSTS varchar(50) default NULL, PARAM_DEFAULT_WAGON_COST double default NULL, tmp int(11) default NULL, PRIMARY KEY (KEY1)) ENGINE=MyISAM; INSERT INTO t3 VALUES ('A',1,1,22,3.2,'R','R','BASE2',0.24,NULL); diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 8b6941c4a94..36854551a7f 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -260,6 +260,10 @@ update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t2.a=t1 select * from t1; select * from t2; +# test for non-updating table which is also used in sub-select + +update t1,t2 set t1.b=t2.b, t1.a=t2.a where t1.a=t2.a and not exists (select * from t2 where t2.a > 10); + drop table t1,t2; CREATE TABLE t3 ( KEY1 varchar(50) NOT NULL default '', PARAM_CORR_DISTANCE_RUSH double default NULL, PARAM_CORR_DISTANCE_GEM double default NULL, PARAM_AVG_TARE double default NULL, PARAM_AVG_NB_DAYS double default NULL, PARAM_DEFAULT_PROP_GEM_SRVC varchar(50) default NULL, PARAM_DEFAULT_PROP_GEM_NO_ETIK varchar(50) default NULL, PARAM_SCENARIO_COSTS varchar(50) default NULL, PARAM_DEFAULT_WAGON_COST double default NULL, tmp int(11) default NULL, PRIMARY KEY (KEY1)) ENGINE=MyISAM; INSERT INTO t3 VALUES ('A',1,1,22,3.2,'R','R','BASE2',0.24,NULL); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 55ea15f1af4..d985d2c2e78 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -578,7 +578,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, int multi_update::prepare(List ¬_used_values, SELECT_LEX_UNIT *lex_unit) { - TABLE_LIST *table_ref; + TABLE_LIST *table_ref, *tables; SQL_LIST update; table_map tables_to_update= 0; Item_field *item; @@ -604,8 +604,9 @@ int multi_update::prepare(List ¬_used_values, We have to check values after setup_tables to get used_keys right in reference tables */ + tables= thd->lex->select_lex.get_table_list(); - if (setup_fields(thd, 0, all_tables, *values, 1, 0, 0)) + if (setup_fields(thd, 0, tables, *values, 1, 0, 0)) DBUG_RETURN(1); /* @@ -615,7 +616,7 @@ int multi_update::prepare(List ¬_used_values, */ update.empty(); - for (table_ref= all_tables; table_ref; table_ref=table_ref->next) + for (table_ref= tables; table_ref; table_ref=table_ref->next) { TABLE *table=table_ref->table; if (tables_to_update & table->map) @@ -684,10 +685,10 @@ int multi_update::prepare(List ¬_used_values, which will cause an error when reading a row. (This issue is mostly relevent for MyISAM tables) */ - for (table_ref= all_tables; table_ref; table_ref=table_ref->next) + for (table_ref= tables; table_ref; table_ref=table_ref->next) { TABLE *table=table_ref->table; - if (!(tables_to_update & table->map) && + if (!(tables_to_update & table->map) || !table->no_keyread && find_real_table_in_list(update_tables, table_ref->db, table_ref->real_name)) table->no_cache= 1; // Disable row cache