From 99fe76453e61a5a5a74290269b097f9e5a8a26ad Mon Sep 17 00:00:00 2001 From: "bell@laptop.sanja.is.com.ua" <> Date: Fri, 10 Oct 2003 21:49:48 +0300 Subject: [PATCH 01/11] samall optimisation (any independent query will not save data for rexecution) saving/restoring join_tab array (to save it of chnging by create_sort_index() before reexecuting) (BUG#1523) --- mysql-test/r/subselect.result | 11 +++++++++++ mysql-test/t/subselect.test | 10 ++++++++++ sql/sql_select.cc | 30 +++++++++++++++++++++++++++--- sql/sql_select.h | 6 ++++-- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 6e35b6e78c1..d571ea035de 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1439,3 +1439,14 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort drop table if exists t2, t3; +CREATE TABLE t1 (number char(11) NOT NULL default '') TYPE=MyISAM CHARSET=latin1; +INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874'); +CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) TYPE=MyISAM CHARSET=latin1; +INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6'); +select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c; +phone code +69294728265 6 +18621828126 1862 +89356874041 NULL +95895001874 NULL +drop table t1, t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9ba91c7e0a6..7c3e825bdb2 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -965,3 +965,13 @@ insert into t2 values (2,2), (2,1), (3,3), (3,1); select * from t3 where a > all (select max(b) from t2 group by a); explain select * from t3 where a > all (select max(b) from t2 group by a); drop table if exists t2, t3; + +# +# filesort in subquery (restoring join_tab) +# +CREATE TABLE t1 (number char(11) NOT NULL default '') TYPE=MyISAM CHARSET=latin1; +INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874'); +CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) TYPE=MyISAM CHARSET=latin1; +INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6'); +select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c; +drop table t1, t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4bab97d4a46..517339e3823 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -980,8 +980,7 @@ JOIN::optimize() } } - if (select_lex != &thd->lex.select_lex && - select_lex->linkage != DERIVED_TABLE_TYPE) + if (select_lex->master_unit()->dependent) { if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) DBUG_RETURN(-1); @@ -994,10 +993,10 @@ JOIN::optimize() DBUG_RETURN(0); } + /* Restore values in temporary join */ - void JOIN::restore_tmp() { memcpy(tmp_join, this, (size_t) sizeof(JOIN)); @@ -1039,12 +1038,29 @@ JOIN::reinit() if (items0) set_items_ref_array(items0); + if (join_tab_save) + memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables); + if (tmp_join) restore_tmp(); DBUG_RETURN(0); } + +bool +JOIN::save_join_tab() +{ + if (!join_tab_save && select_lex->master_unit()->dependent) + { + if (!(join_tab_save= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB) * tables))) + return 1; + memcpy(join_tab_save, join_tab, sizeof(JOIN_TAB) * tables); + } + return 0; +} + + /* Exec select */ @@ -1246,6 +1262,10 @@ JOIN::exec() if (curr_join->group_list) { thd->proc_info= "Creating sort index"; + if (curr_join->join_tab == join_tab && save_join_tab()) + { + DBUG_VOID_RETURN; + } if (create_sort_index(thd, curr_join, curr_join->group_list, HA_POS_ERROR, HA_POS_ERROR) || make_group_fields(this, curr_join)) @@ -1427,6 +1447,10 @@ JOIN::exec() } } } + if (curr_join->join_tab == join_tab && save_join_tab()) + { + DBUG_VOID_RETURN; + } if (create_sort_index(thd, curr_join, curr_join->group_list ? curr_join->group_list : curr_join->order, diff --git a/sql/sql_select.h b/sql/sql_select.h index 6c17a646ee6..aa9dc4f01cf 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -131,6 +131,7 @@ class JOIN :public Sql_alloc { public: JOIN_TAB *join_tab,**best_ref,**map2table; + JOIN_TAB *join_tab_save; //saved join_tab for subquery reexecution TABLE **table,**all_tables,*sort_by_table; uint tables,const_tables; uint send_group_parts; @@ -202,7 +203,7 @@ class JOIN :public Sql_alloc void init(THD *thd_arg, List &fields, ulong select_options_arg, select_result *result_arg) { - join_tab= 0; + join_tab= join_tab_save= 0; table= 0; tables= 0; const_tables= 0; @@ -242,7 +243,7 @@ class JOIN :public Sql_alloc zero_result_cause= 0; optimized= 0; - fields_list = fields; + fields_list= fields; bzero((char*) &keyuse,sizeof(keyuse)); tmp_table_param.copy_field=0; tmp_table_param.end_write_records= HA_POS_ERROR; @@ -280,6 +281,7 @@ class JOIN :public Sql_alloc int rollup_send_data(uint idx); bool test_in_subselect(Item **where); void clear(); + bool save_join_tab(); }; From fa5520fbf8328c56e45f0f16d4ea4ad23cb03206 Mon Sep 17 00:00:00 2001 From: "bell@laptop.sanja.is.com.ua" <> Date: Sat, 11 Oct 2003 17:41:15 +0300 Subject: [PATCH 02/11] more resonable errors about name resolving in subqueries (BUG#1483) --- mysql-test/r/subselect.result | 11 ++++++++++- mysql-test/t/subselect.test | 17 +++++++++++++++-- sql/item.cc | 29 ++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 6e35b6e78c1..ff0a76b2c60 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1349,7 +1349,7 @@ create table t2 (s1 int); insert into t1 values (1); insert into t2 values (1); update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A); -ERROR 42S02: Unknown table 'x' in field list +ERROR 42S22: Unknown column 'x.s1' in 'field list' DROP TABLE t1, t2; create table t1 (a int) type=innodb; create table t2 (a int) type=innodb; @@ -1439,3 +1439,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort drop table if exists t2, t3; +create table t1 (s1 int); +create table t2 (s1 int); +select * from t1 where (select count(*) from t2 where t1.s2) = 1; +ERROR 42S22: Unknown column 't1.s2' in 'where clause' +select * from t1 where (select count(*) from t2 group by t1.s2) = 1; +ERROR 42S22: Unknown column 't1.s2' in 'group statement' +select count(*) from t2 group by t1.s2; +ERROR 42S02: Unknown table 't1' in group statement +drop table t1, t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9ba91c7e0a6..ad18e1279df 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -693,7 +693,7 @@ INSERT INTO t1 VALUES (1); UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i)); -- error 1111 UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); --- error 1109 +-- error 1054 UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t); drop table t1; @@ -887,7 +887,7 @@ create table t1 (s1 int); create table t2 (s1 int); insert into t1 values (1); insert into t2 values (1); --- error 1109 +-- error 1054 update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A); DROP TABLE t1, t2; @@ -965,3 +965,16 @@ insert into t2 values (2,2), (2,1), (3,3), (3,1); select * from t3 where a > all (select max(b) from t2 group by a); explain select * from t3 where a > all (select max(b) from t2 group by a); drop table if exists t2, t3; + +# +# unresolved field error +# +create table t1 (s1 int); +create table t2 (s1 int); +-- error 1054 +select * from t1 where (select count(*) from t2 where t1.s2) = 1; +-- error 1054 +select * from t1 where (select count(*) from t2 group by t1.s2) = 1; +-- error 1109 +select count(*) from t2 group by t1.s2; +drop table t1, t2; \ No newline at end of file diff --git a/sql/item.cc b/sql/item.cc index 4de4951cb51..0681fab9d1b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -794,6 +794,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!field) // If field is not checked { TABLE_LIST *where= 0; + bool upward_lookup= 0; Field *tmp= (Field *)not_found_field; if ((tmp= find_field_in_tables(thd, this, tables, &where, 0)) == not_found_field) @@ -821,6 +822,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) sl; sl= sl->outer_select()) { + upward_lookup= 1; table_list= (last= sl)->get_table_list(); if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) { @@ -846,8 +848,14 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 1; else if (tmp == not_found_field && refer == (Item **)not_found_item) { - // call to return error code - find_field_in_tables(thd, this, tables, &where, 1); + if (upward_lookup) + // We can't say exactly what absend table or field + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + full_name(), thd->where); + else + // Call to report error + find_field_in_tables(thd, this, tables, &where, 1); + return -1; } else if (refer != (Item **)not_found_item) @@ -1350,6 +1358,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) if (!ref) { TABLE_LIST *where= 0, *table_list; + bool upward_lookup= 0; SELECT_LEX *sl= thd->lex.current_select->outer_select(); /* Finding only in current select will be performed for selects that have @@ -1367,6 +1376,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) REPORT_ALL_ERRORS))) == (Item **)not_found_item) { + upward_lookup= 1; Field *tmp= (Field*) not_found_field; /* We can't find table field in table list of current select, @@ -1408,11 +1418,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) return -1; else if (ref == (Item **)not_found_item && tmp == not_found_field) { - // Call to report error - find_item_in_list(this, - *(thd->lex.current_select->get_item_list()), - &counter, - REPORT_ALL_ERRORS); + if (upward_lookup) + // We can't say exactly what absend (table or field) + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + full_name(), thd->where); + else + // Call to report error + find_item_in_list(this, + *(thd->lex.current_select->get_item_list()), + &counter, + REPORT_ALL_ERRORS); ref= 0; return 1; } From 3e10f8068252c25712807ebf664e3dcfee036882 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sat, 1 Nov 2003 19:02:43 +0200 Subject: [PATCH 03/11] fixed part of BUG#1708 (test suite will be with next part) --- sql/item_subselect.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 589a41052c5..252423db0a2 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -166,7 +166,7 @@ void Item_subselect::update_used_tables() if (!engine->uncacheable()) { // did all used tables become ststic? - if ((used_tables_cache & ~engine->upper_select_const_tables())) + if (!(used_tables_cache & ~engine->upper_select_const_tables())) const_item_cache= 1; } } From cac0c0ae6e2c20abec4099bd1ece7e95cc48ede4 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sat, 1 Nov 2003 21:05:17 +0200 Subject: [PATCH 04/11] key_map is class for now => can't be printed directly (found during BUG#1708 investigation) --- sql/sql_test.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 7e3513367fd..3547113cee8 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -164,10 +164,11 @@ TEST_join(JOIN *join) { JOIN_TAB *tab=join->join_tab+i; TABLE *form=tab->table; - fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %4d refs: %d key: %d len: %d\n", + fprintf(DBUG_FILE, + "%-16.16s type: %-7s q_keys: %4lld refs: %d key: %d len: %d\n", form->table_name, join_type_str[tab->type], - tab->keys, + tab->keys.to_ulonglong(), tab->ref.key_parts, tab->ref.key, tab->ref.key_length); From e32a1c923a1be736e6e99fed06de17c8cbd00ca1 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 2 Nov 2003 13:53:38 +0200 Subject: [PATCH 05/11] fixed locking problem with innodb & subqueries (BUG#1708) tests with innodb moved to separate file --- mysql-test/r/subselect.result | 37 ----------------------------- mysql-test/t/subselect.test | 44 ----------------------------------- sql/sql_select.cc | 5 ++-- 3 files changed, 3 insertions(+), 83 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index db0c3184120..26a802af478 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1219,31 +1219,6 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); a 1 -CREATE TABLE t1 -( -FOLDERID VARCHAR(32)BINARY NOT NULL -, FOLDERNAME VARCHAR(255)BINARY NOT NULL -, CREATOR VARCHAR(255)BINARY -, CREATED TIMESTAMP NOT NULL -, DESCRIPTION VARCHAR(255)BINARY -, FOLDERTYPE INTEGER NOT NULL -, MODIFIED TIMESTAMP -, MODIFIER VARCHAR(255)BINARY -, FOLDERSIZE INTEGER NOT NULL -, PARENTID VARCHAR(32)BINARY -, REPID VARCHAR(32)BINARY -, ORIGINATOR INTEGER -, PRIMARY KEY ( FOLDERID ) -) TYPE=InnoDB; -CREATE INDEX FFOLDERID_IDX ON t1 (FOLDERID); -CREATE INDEX CMFLDRPARNT_IDX ON t1 (PARENTID); -INSERT INTO t1 VALUES("0c9aab05b15048c59bc35c8461507deb", "System", "System", "2003-06-05 16:30:00", "The system content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "9c9aab05b15048c59bc35c8461507deb", "1"); -INSERT INTO t1 VALUES("2f6161e879db43c1a5b82c21ddc49089", "Default", "System", "2003-06-09 10:52:02", "The default content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "03eea05112b845949f3fd03278b5fe43", "1"); -INSERT INTO t1 VALUES("c373e9f5ad0791724315444553544200", "AddDocumentTest", "admin", "2003-06-09 10:51:25", "Movie Reviews", "0", "2003-06-09 10:51:25", "admin", "0", "2f6161e879db43c1a5b82c21ddc49089", "03eea05112b845949f3fd03278b5fe43", NULL); -SELECT 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1'); -'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1') -0 -drop table t1; create table t1 (a int not null, b int, primary key (a)); create table t2 (a int not null, primary key (a)); create table t3 (a int not null, b int, primary key (a)); @@ -1351,18 +1326,6 @@ insert into t2 values (1); update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A); ERROR 42S02: Unknown table 'x' in field list DROP TABLE t1, t2; -create table t1 (a int) type=innodb; -create table t2 (a int) type=innodb; -create table t3 (a int) type=innodb; -insert into t1 values (1),(2),(3),(4); -insert into t2 values (10),(20),(30),(40); -insert into t3 values (1),(2),(10),(50); -select a from t3 where t3.a in (select a from t1 where a <= 3 union select * from t2 where a <= 30); -a -1 -2 -10 -drop table t1,t2,t3; CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci, s2 CHAR(5) COLLATE latin1_swedish_ci); INSERT INTO t1 VALUES ('z','?'); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 576e96c5c18..b601838c378 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -784,36 +784,6 @@ drop table if exists t1; (SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0); -# -# key field overflow test -# ---disable_warnings -CREATE TABLE t1 -( -FOLDERID VARCHAR(32)BINARY NOT NULL -, FOLDERNAME VARCHAR(255)BINARY NOT NULL -, CREATOR VARCHAR(255)BINARY -, CREATED TIMESTAMP NOT NULL -, DESCRIPTION VARCHAR(255)BINARY -, FOLDERTYPE INTEGER NOT NULL -, MODIFIED TIMESTAMP -, MODIFIER VARCHAR(255)BINARY -, FOLDERSIZE INTEGER NOT NULL -, PARENTID VARCHAR(32)BINARY -, REPID VARCHAR(32)BINARY -, ORIGINATOR INTEGER - -, PRIMARY KEY ( FOLDERID ) -) TYPE=InnoDB; ---enable_warnings -CREATE INDEX FFOLDERID_IDX ON t1 (FOLDERID); -CREATE INDEX CMFLDRPARNT_IDX ON t1 (PARENTID); -INSERT INTO t1 VALUES("0c9aab05b15048c59bc35c8461507deb", "System", "System", "2003-06-05 16:30:00", "The system content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "9c9aab05b15048c59bc35c8461507deb", "1"); -INSERT INTO t1 VALUES("2f6161e879db43c1a5b82c21ddc49089", "Default", "System", "2003-06-09 10:52:02", "The default content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "03eea05112b845949f3fd03278b5fe43", "1"); -INSERT INTO t1 VALUES("c373e9f5ad0791724315444553544200", "AddDocumentTest", "admin", "2003-06-09 10:51:25", "Movie Reviews", "0", "2003-06-09 10:51:25", "admin", "0", "2f6161e879db43c1a5b82c21ddc49089", "03eea05112b845949f3fd03278b5fe43", NULL); -SELECT 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1'); -drop table t1; - # # IN subselect optimization test # @@ -891,20 +861,6 @@ insert into t2 values (1); update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A); DROP TABLE t1, t2; -# -# UNION unlocking test -# ---disable_warnings -create table t1 (a int) type=innodb; -create table t2 (a int) type=innodb; -create table t3 (a int) type=innodb; ---enable_warnings -insert into t1 values (1),(2),(3),(4); -insert into t2 values (10),(20),(30),(40); -insert into t3 values (1),(2),(10),(50); -select a from t3 where t3.a in (select a from t1 where a <= 3 union select * from t2 where a <= 30); -drop table t1,t2,t3; - # # collation test # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 65515ce7ad9..400919779a2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3684,7 +3684,7 @@ join_free(JOIN *join, bool full) free_io_cache(join->table[join->const_tables]); filesort_free_buffers(join->table[join->const_tables]); } - if (join->select_lex->dependent && !full) + if (!full && join->select_lex->dependent) { for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) { @@ -3736,7 +3736,8 @@ join_free(JOIN *join, bool full) We are not using tables anymore Unlock all tables. We may be in an INSERT .... SELECT statement. */ - if (join->lock && join->thd->lock && + if ((full || !join->select_lex->dependent) && + join->lock && join->thd->lock && !(join->select_options & SELECT_NO_UNLOCK)) { mysql_unlock_read_tables(join->thd, join->lock);// Don't free join->lock From cf535556c6ed290dbcce23f5e1b96dd8f82aebd7 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sun, 2 Nov 2003 14:00:25 +0200 Subject: [PATCH 06/11] Cleanups (comments and compiler warnings) dded init of variable to fix core dump on startup errors --- BitKeeper/etc/logging_ok | 1 + mysql-test/Makefile.am | 1 + mysql-test/mysql-test-run.sh | 6 ++++-- sql/derror.cc | 1 + sql/mysql_priv.h | 2 +- sql/mysqld.cc | 2 +- sql/sql_bitmap.h | 32 ++++++++++++++++++++++---------- sql/sql_class.cc | 2 ++ sql/sql_test.cc | 5 +++-- 9 files changed, 36 insertions(+), 16 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 9df789c0340..9fa17da17a1 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -75,6 +75,7 @@ monty@hundin.mysql.fi monty@mashka.(none) monty@mashka.mysql.fi monty@mishka.mysql.fi +monty@mysql.com monty@narttu. monty@narttu.mysql.fi monty@rescue. diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 2babb6fba66..d23a9919b48 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -73,6 +73,7 @@ SUFFIXES = .sh -e 's!@''PERL''@!@PERL@!' \ -e 's!@''VERSION''@!@VERSION@!' \ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ + -e 's!@''MYSQL_UNIX_ADDR''@!@MYSQL_UNIX_ADDR@!' \ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ -e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \ $< > $@-t diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index b7e39549411..94affe6b2f7 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -15,6 +15,7 @@ VERBOSE="" USE_MANAGER=0 MY_TZ=GMT-3 TZ=$MY_TZ; export TZ # for UNIX_TIMESTAMP tests to work +LOCAL_SOCKET=@MYSQL_UNIX_ADDR@ # For query_cache test ulimit -n 1024 @@ -226,7 +227,7 @@ while test $# -gt 0; do --slave-binary=*) SLAVE_MYSQLD=`$ECHO "$1" | $SED -e "s;--slave-binary=;;"` ;; --local) USE_RUNNING_SERVER="" ;; - --extern) USE_RUNNING_SERVER="1" ;; + --extern) USE_RUNNING_SERVER="1" ;; --tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;; --local-master) MASTER_MYPORT=3306; @@ -256,6 +257,7 @@ while test $# -gt 0; do --start-and-exit) START_AND_EXIT=1 ;; + --socket=*) LOCAL_SOCKET=`$ECHO "$1" | $SED -e "s;--socket=;;"` ;; --skip-rpl) NO_SLAVE=1 ;; --skip-test=*) SKIP_TEST=`$ECHO "$1" | $SED -e "s;--skip-test=;;"`;; --do-test=*) DO_TEST=`$ECHO "$1" | $SED -e "s;--do-test=;;"`;; @@ -501,7 +503,7 @@ then fi if [ -n "$USE_RUNNING_SERVER" ] then - MASTER_MYSOCK="/tmp/mysql.sock" + MASTER_MYSOCK=$LOCAL_SOCKET; DBUSER=${DBUSER:-test} else DBUSER=${DBUSER:-root} # We want to do FLUSH xxx commands diff --git a/sql/derror.cc b/sql/derror.cc index 7f4068c487e..f5fe92da238 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -136,6 +136,7 @@ err1: if (file != FERR) VOID(my_close(file,MYF(MY_WME))); unireg_abort(1); + return 1; } /* read_texts */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f7b12bd959c..53cbba36b93 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -15,6 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include @@ -24,7 +25,6 @@ #include #include /* Needed by field.h */ #include -#include #ifdef __EMX__ #undef write /* remove pthread.h macro definition for EMX */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fafc67e059d..75e2fc957e4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1884,7 +1884,7 @@ extern "C" int my_message_sql(uint error, const char *str, if ((thd= current_thd)) { /* - thd->lex.current_select equel to zero if lex structure is not inited + thd->lex.current_select == 0 if lex structure is not inited (not query command (COM_QUERY)) */ if (thd->lex.current_select && diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 53293e39591..e5e50c180bf 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -1,14 +1,26 @@ -#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Implementation of a bitmap type. + The idea with this is to be able to handle any constant number of bits but + also be able to use 32 or 64 bits bitmaps very efficiently +*/ + #include -#include template class Bitmap { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e5760dda8ae..ed8eaba9128 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -102,6 +102,8 @@ THD::THD():user_time(0), is_fatal_error(0), lock=locked_tables=0; used_tables=0; cuted_fields= sent_row_count= current_stmt_id= 0L; + // Must be reset to handle error with THD's created for init of mysqld + lex.current_select= 0; start_time=(time_t) 0; current_linfo = 0; slave_thread = 0; diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 7e3513367fd..47f0932b221 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -164,10 +164,11 @@ TEST_join(JOIN *join) { JOIN_TAB *tab=join->join_tab+i; TABLE *form=tab->table; - fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %4d refs: %d key: %d len: %d\n", + char key_map_buff[128]; + fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %s refs: %d key: %d len: %d\n", form->table_name, join_type_str[tab->type], - tab->keys, + tab->keys.print(key_map_buff), tab->ref.key_parts, tab->ref.key, tab->ref.key_length); From e0ff4138a588e4911d5ca53e49b326e03afe384f Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 2 Nov 2003 14:43:11 +0200 Subject: [PATCH 07/11] BUG#1708 & other subselects with innodb tests --- mysql-test/r/subselect_innodb.result | 65 ++++++++++++++++++++++++++ mysql-test/t/subselect_innodb.test | 70 ++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 mysql-test/r/subselect_innodb.result create mode 100644 mysql-test/t/subselect_innodb.test diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result new file mode 100644 index 00000000000..2f5b92fd05d --- /dev/null +++ b/mysql-test/r/subselect_innodb.result @@ -0,0 +1,65 @@ +drop table if exists t1,t2,t3; +CREATE TABLE t1 +( +FOLDERID VARCHAR(32)BINARY NOT NULL +, FOLDERNAME VARCHAR(255)BINARY NOT NULL +, CREATOR VARCHAR(255)BINARY +, CREATED TIMESTAMP NOT NULL +, DESCRIPTION VARCHAR(255)BINARY +, FOLDERTYPE INTEGER NOT NULL +, MODIFIED TIMESTAMP +, MODIFIER VARCHAR(255)BINARY +, FOLDERSIZE INTEGER NOT NULL +, PARENTID VARCHAR(32)BINARY +, REPID VARCHAR(32)BINARY +, ORIGINATOR INTEGER +, PRIMARY KEY ( FOLDERID ) +) TYPE=InnoDB; +CREATE INDEX FFOLDERID_IDX ON t1 (FOLDERID); +CREATE INDEX CMFLDRPARNT_IDX ON t1 (PARENTID); +INSERT INTO t1 VALUES("0c9aab05b15048c59bc35c8461507deb", "System", "System", "2003-06-05 16:30:00", "The system content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "9c9aab05b15048c59bc35c8461507deb", "1"); +INSERT INTO t1 VALUES("2f6161e879db43c1a5b82c21ddc49089", "Default", "System", "2003-06-09 10:52:02", "The default content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "03eea05112b845949f3fd03278b5fe43", "1"); +INSERT INTO t1 VALUES("c373e9f5ad0791724315444553544200", "AddDocumentTest", "admin", "2003-06-09 10:51:25", "Movie Reviews", "0", "2003-06-09 10:51:25", "admin", "0", "2f6161e879db43c1a5b82c21ddc49089", "03eea05112b845949f3fd03278b5fe43", NULL); +SELECT 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1'); +'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1') +0 +drop table t1; +create table t1 (a int) type=innodb; +create table t2 (a int) type=innodb; +create table t3 (a int) type=innodb; +insert into t1 values (1),(2),(3),(4); +insert into t2 values (10),(20),(30),(40); +insert into t3 values (1),(2),(10),(50); +select a from t3 where t3.a in (select a from t1 where a <= 3 union select * from t2 where a <= 30); +a +1 +2 +10 +drop table t1,t2,t3; +CREATE TABLE t1 ( +processor_id INTEGER NOT NULL, +PRIMARY KEY (processor_id) +) TYPE=InnoDB; +CREATE TABLE t3 ( +yod_id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, +login_processor INTEGER UNSIGNED , +PRIMARY KEY (yod_id) +) TYPE=InnoDB; +CREATE TABLE t2 ( +processor_id INTEGER NOT NULL, +yod_id BIGINT UNSIGNED NOT NULL, +PRIMARY KEY (processor_id, yod_id), +INDEX (processor_id), +INDEX (yod_id), +FOREIGN KEY (processor_id) REFERENCES t1(processor_id), +FOREIGN KEY (yod_id) REFERENCES t3(yod_id) +) TYPE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t3 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +SELECT distinct p1.processor_id, (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) FROM t1 p1; +processor_id (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) +1 1 +2 1 +3 1 +drop table t1,t2,t3; diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test new file mode 100644 index 00000000000..5e274ecbd5c --- /dev/null +++ b/mysql-test/t/subselect_innodb.test @@ -0,0 +1,70 @@ +-- source include/have_innodb.inc + +--disable_warnings +drop table if exists t1,t2,t3; +--enable_warnings + +# +# key field overflow test +# +CREATE TABLE t1 +( +FOLDERID VARCHAR(32)BINARY NOT NULL +, FOLDERNAME VARCHAR(255)BINARY NOT NULL +, CREATOR VARCHAR(255)BINARY +, CREATED TIMESTAMP NOT NULL +, DESCRIPTION VARCHAR(255)BINARY +, FOLDERTYPE INTEGER NOT NULL +, MODIFIED TIMESTAMP +, MODIFIER VARCHAR(255)BINARY +, FOLDERSIZE INTEGER NOT NULL +, PARENTID VARCHAR(32)BINARY +, REPID VARCHAR(32)BINARY +, ORIGINATOR INTEGER + +, PRIMARY KEY ( FOLDERID ) +) TYPE=InnoDB; +CREATE INDEX FFOLDERID_IDX ON t1 (FOLDERID); +CREATE INDEX CMFLDRPARNT_IDX ON t1 (PARENTID); +INSERT INTO t1 VALUES("0c9aab05b15048c59bc35c8461507deb", "System", "System", "2003-06-05 16:30:00", "The system content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "9c9aab05b15048c59bc35c8461507deb", "1"); +INSERT INTO t1 VALUES("2f6161e879db43c1a5b82c21ddc49089", "Default", "System", "2003-06-09 10:52:02", "The default content repository folder.", "3", "2003-06-05 16:30:00", "System", "0", NULL, "03eea05112b845949f3fd03278b5fe43", "1"); +INSERT INTO t1 VALUES("c373e9f5ad0791724315444553544200", "AddDocumentTest", "admin", "2003-06-09 10:51:25", "Movie Reviews", "0", "2003-06-09 10:51:25", "admin", "0", "2f6161e879db43c1a5b82c21ddc49089", "03eea05112b845949f3fd03278b5fe43", NULL); +SELECT 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1'); +drop table t1; + +# +# UNION unlocking test +# +create table t1 (a int) type=innodb; +create table t2 (a int) type=innodb; +create table t3 (a int) type=innodb; +insert into t1 values (1),(2),(3),(4); +insert into t2 values (10),(20),(30),(40); +insert into t3 values (1),(2),(10),(50); +select a from t3 where t3.a in (select a from t1 where a <= 3 union select * from t2 where a <= 30); +drop table t1,t2,t3; + + +CREATE TABLE t1 ( + processor_id INTEGER NOT NULL, + PRIMARY KEY (processor_id) +) TYPE=InnoDB; +CREATE TABLE t3 ( + yod_id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, + login_processor INTEGER UNSIGNED , + PRIMARY KEY (yod_id) +) TYPE=InnoDB; +CREATE TABLE t2 ( + processor_id INTEGER NOT NULL, + yod_id BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (processor_id, yod_id), + INDEX (processor_id), + INDEX (yod_id), + FOREIGN KEY (processor_id) REFERENCES t1(processor_id), + FOREIGN KEY (yod_id) REFERENCES t3(yod_id) +) TYPE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t3 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +SELECT distinct p1.processor_id, (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) FROM t1 p1; +drop table t1,t2,t3; \ No newline at end of file From 33f6f729797e58c0cfbfe80a432ff34c2b2333d9 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 2 Nov 2003 16:31:22 +0200 Subject: [PATCH 08/11] join_free now is method of JOIN and commented dependence should mean uncacheability --- sql/item_subselect.cc | 9 ++++--- sql/sql_lex.cc | 10 ++++---- sql/sql_select.cc | 56 +++++++++++++++++++++++++------------------ sql/sql_select.h | 1 + 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 252423db0a2..0483722b990 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -622,10 +622,10 @@ Item_in_subselect::single_value_transformer(JOIN *join, (char *)"", (char *)in_left_expr_name); - unit->dependent= 1; + unit->dependent= unit->uncacheable= 1; } - select_lex->dependent= 1; + select_lex->dependent= select_lex->uncacheable= 1; Item *item; item= (Item*) select_lex->item_list.head(); @@ -747,13 +747,12 @@ Item_in_subselect::row_value_transformer(JOIN *join, DBUG_RETURN(RES_ERROR); } thd->lex.current_select= current; - - unit->dependent= 1; + unit->dependent= unit->uncacheable= 1; } uint n= left_expr->cols(); - select_lex->dependent= 1; + select_lex->dependent= select_lex->uncacheable= 1; select_lex->setup_ref_array(thd, select_lex->order_list.elements + select_lex->group_list.elements); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c3ff69184e6..f842e44ff7d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1195,16 +1195,16 @@ void st_select_lex::mark_as_dependent(SELECT_LEX *last) found table as depended (of select where was found table) */ for (SELECT_LEX *s= this; - s &&s != last; + s && s != last; s= s->outer_select()) if ( !s->dependent ) { // Select is dependent of outer select - s->dependent= 1; - s->master_unit()->dependent= 1; + s->dependent= s->uncacheable= 1; + SELECT_LEX_UNIT *munit= s->master_unit(); + munit->dependent= munit->uncacheable= 1; //Tables will be reopened many times - for (TABLE_LIST *tbl= - s->get_table_list(); + for (TABLE_LIST *tbl= s->get_table_list(); tbl; tbl= tbl->next) tbl->shared= 1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 400919779a2..34b55367163 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -62,7 +62,6 @@ static store_key *get_store_key(THD *thd, static bool make_simple_join(JOIN *join,TABLE *tmp_table); static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item); static void make_join_readinfo(JOIN *join,uint options); -static void join_free(JOIN *join, bool full); static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables); static void update_depend_map(JOIN *join); static void update_depend_map(JOIN *join, ORDER *order); @@ -1232,7 +1231,7 @@ JOIN::exec() DBUG_PRINT("info",("Creating group table")); /* Free first data from old join */ - join_free(curr_join, 0); + curr_join->join_free(0); if (make_simple_join(curr_join, curr_tmp_table)) DBUG_VOID_RETURN; calc_group_buffer(curr_join, group_list); @@ -1327,7 +1326,7 @@ JOIN::exec() if (curr_tmp_table->distinct) curr_join->select_distinct=0; /* Each row is unique */ - join_free(curr_join, 0); /* Free quick selects */ + curr_join->join_free(0); /* Free quick selects */ if (select_distinct && ! group_list) { thd->proc_info="Removing duplicates"; @@ -1501,7 +1500,7 @@ JOIN::cleanup() } lock=0; // It's faster to unlock later - join_free(this, 1); + join_free(1); if (exec_tmp_table1) free_tmp_table(thd, exec_tmp_table1); if (exec_tmp_table2) @@ -3667,26 +3666,37 @@ bool error_if_full_join(JOIN *join) } -static void -join_free(JOIN *join, bool full) +/* + Free resources of given join + + SYNOPSIS + JOIN::join_free() + fill - true if we should free all resources, call with full==1 should be + last, before it this function can be called with full==0 + + NOTE: with subquery this function definitely will be called several times, + but even for simple query it can be called several times. +*/ +void +JOIN::join_free(bool full) { JOIN_TAB *tab,*end; DBUG_ENTER("join_free"); - if (join->table) + if (table) { /* Only a sorted table may be cached. This sorted table is always the first non const table in join->table */ - if (join->tables > join->const_tables) // Test for not-const tables + if (tables > const_tables) // Test for not-const tables { - free_io_cache(join->table[join->const_tables]); - filesort_free_buffers(join->table[join->const_tables]); + free_io_cache(table[const_tables]); + filesort_free_buffers(table[const_tables]); } - if (!full && join->select_lex->dependent) + if (!full && select_lex->uncacheable) { - for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) + for (tab= join_tab, end= tab+tables; tab != end; tab++) { if (tab->table) { @@ -3703,7 +3713,7 @@ join_free(JOIN *join, bool full) } else { - for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) + for (tab= join_tab, end= tab+tables; tab != end; tab++) { delete tab->select; delete tab->quick; @@ -3729,25 +3739,25 @@ join_free(JOIN *join, bool full) } end_read_record(&tab->read_record); } - join->table= 0; + table= 0; } } /* We are not using tables anymore Unlock all tables. We may be in an INSERT .... SELECT statement. */ - if ((full || !join->select_lex->dependent) && - join->lock && join->thd->lock && - !(join->select_options & SELECT_NO_UNLOCK)) + if ((full || !select_lex->uncacheable) && + lock && thd->lock && + !(select_options & SELECT_NO_UNLOCK)) { - mysql_unlock_read_tables(join->thd, join->lock);// Don't free join->lock - join->lock=0; + mysql_unlock_read_tables(thd, lock);// Don't free join->lock + lock=0; } if (full) { - join->group_fields.delete_elements(); - join->tmp_table_param.copy_funcs.delete_elements(); - join->tmp_table_param.cleanup(); + group_fields.delete_elements(); + tmp_table_param.copy_funcs.delete_elements(); + tmp_table_param.cleanup(); } DBUG_VOID_RETURN; } @@ -5459,7 +5469,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) The following will unlock all cursors if the command wasn't an update command */ - join_free(join, 0); // Unlock all cursors + join->join_free(0); // Unlock all cursors if (join->result->send_eof()) error= 1; // Don't send error } diff --git a/sql/sql_select.h b/sql/sql_select.h index 14450347244..569ca797b22 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -280,6 +280,7 @@ class JOIN :public Sql_alloc Item_sum ***func); int rollup_send_data(uint idx); bool test_in_subselect(Item **where); + void join_free(bool full); void clear(); bool save_join_tab(); }; From 74ddfaaddae303b6d6a3d8a3468eb48b900f7165 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 2 Nov 2003 16:56:39 +0200 Subject: [PATCH 09/11] after review fix --- mysql-test/t/subselect.test | 1 - sql/item.cc | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index a452bee79ea..9297573a6db 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -999,4 +999,3 @@ select * from t1 where (select count(*) from t2 group by t1.s2) = 1; -- error 1109 select count(*) from t2 group by t1.s2; drop table t1, t2; - diff --git a/sql/item.cc b/sql/item.cc index 9caea3cee4c..e1373cee41f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -872,13 +872,16 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) else if (tmp == not_found_field && refer == (Item **)not_found_item) { if (upward_lookup) + { // We can't say exactly what absend table or field my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), full_name(), thd->where); + } else + { // Call to report error find_field_in_tables(thd, this, tables, &where, 1); - + } return -1; } else if (refer != (Item **)not_found_item) @@ -1468,15 +1471,19 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) else if (ref == (Item **)not_found_item && tmp == not_found_field) { if (upward_lookup) + { // We can't say exactly what absend (table or field) my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), full_name(), thd->where); + } else + { // Call to report error find_item_in_list(this, *(thd->lex.current_select->get_item_list()), &counter, REPORT_ALL_ERRORS); + } ref= 0; return 1; } From 8e80431f8cbb96dd80255631bd0dca154385155a Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 2 Nov 2003 17:21:32 +0200 Subject: [PATCH 10/11] aftermerge fix --- mysql-test/t/subselect.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9297573a6db..bb8b4db2b62 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -693,7 +693,7 @@ INSERT INTO t1 VALUES (1); UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i)); -- error 1111 UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); --- error 1054 +-- error 1109 UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t); drop table t1; From 777316c3e1913ff669fea74c9a1380ba09a80ad1 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 2 Nov 2003 17:27:35 +0200 Subject: [PATCH 11/11] fixed BUG#1645 all calls of fix_fields() are inspected (copy of cset which I lost in accidatly tree delete) --- mysql-test/r/subselect.result | 7 +++++++ mysql-test/t/subselect.test | 10 ++++++++++ sql/item_subselect.cc | 12 +++++------- sql/item_subselect.h | 4 +--- sql/set_var.cc | 6 +++++- sql/sql_select.cc | 6 +----- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 26a802af478..9721785a97c 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1477,3 +1477,10 @@ phone code 89356874041 NULL 95895001874 NULL drop table t1, t2; +CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB)); +CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA)); +INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365'); +INSERT INTO t2 VALUES (100, 200, 'C'); +SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1); +COLC +DROP TABLE t1, t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index b601838c378..6ac2dbbff12 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -986,3 +986,13 @@ CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) TYPE=M INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6'); select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c; drop table t1, t2; + +# +# fix_fields() in add_ref_to_table_cond() +# +CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB)); +CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA)); +INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365'); +INSERT INTO t2 VALUES (100, 200, 'C'); +SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1); +DROP TABLE t1, t2; \ No newline at end of file diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 0483722b990..062a7c2ee2b 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -512,7 +512,6 @@ String *Item_in_subselect::val_str(String *str) Item_subselect::trans_res Item_in_subselect::single_value_transformer(JOIN *join, - Item *left_expr, compare_func_creator func) { DBUG_ENTER("Item_in_subselect::single_value_transformer"); @@ -587,7 +586,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, // left expression belong to outer select SELECT_LEX *current= thd->lex.current_select, *up; thd->lex.current_select= up= current->return_after_parsing(); - if (left_expr->fix_fields(thd, up->get_table_list(), 0)) + if (left_expr->fix_fields(thd, up->get_table_list(), &left_expr)) { thd->lex.current_select= current; DBUG_RETURN(RES_ERROR); @@ -716,8 +715,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, } Item_subselect::trans_res -Item_in_subselect::row_value_transformer(JOIN *join, - Item *left_expr) +Item_in_subselect::row_value_transformer(JOIN *join) { DBUG_ENTER("Item_in_subselect::row_value_transformer"); @@ -800,16 +798,16 @@ Item_subselect::trans_res Item_in_subselect::select_transformer(JOIN *join) { if (left_expr->cols() == 1) - return single_value_transformer(join, left_expr, + return single_value_transformer(join, &Item_bool_func2::eq_creator); - return row_value_transformer(join, left_expr); + return row_value_transformer(join); } Item_subselect::trans_res Item_allany_subselect::select_transformer(JOIN *join) { - return single_value_transformer(join, left_expr, func); + return single_value_transformer(join, func); } subselect_single_select_engine:: diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 7e735165c02..2a7f7b3f441 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -210,10 +210,8 @@ public: } trans_res select_transformer(JOIN *join); trans_res single_value_transformer(JOIN *join, - Item *left_expr, compare_func_creator func); - trans_res row_value_transformer(JOIN * join, - Item *left_expr); + trans_res row_value_transformer(JOIN * join); longlong val_int(); double val(); String *val_str(String*); diff --git a/sql/set_var.cc b/sql/set_var.cc index 57076bec603..66c8ef87d5a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2279,7 +2279,11 @@ int set_var::update(THD *thd) int set_var_user::check(THD *thd) { - return (user_var_item->fix_fields(thd,0, (Item**) 0) || + /* + Item_func_set_user_var can't substitute something else on its place => + 0 can be passed as last argument + */ + return (user_var_item->fix_fields(thd, 0, (Item**) 0) || user_var_item->check()) ? -1 : 0; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 34b55367163..f209bf886ff 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8525,11 +8525,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) if (thd->is_fatal_error) DBUG_RETURN(TRUE); - /* - Here we pass 0 as the first argument to fix_fields that don't need - to do any stack checking (This is already done in the initial fix_fields). - */ - cond->fix_fields((THD *) 0,(TABLE_LIST *) 0, (Item**)&cond); + cond->fix_fields(thd,(TABLE_LIST *) 0, (Item**)&cond); if (join_tab->select) { error=(int) cond->add(join_tab->select->cond);