diff options
-rw-r--r-- | mysql-test/r/subselect.result | 7 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 13 | ||||
-rw-r--r-- | sql/item.cc | 13 | ||||
-rw-r--r-- | sql/item.h | 1 | ||||
-rw-r--r-- | sql/item_subselect.cc | 2 | ||||
-rw-r--r-- | sql/sql_derived.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 | ||||
-rw-r--r-- | sql/sql_union.cc | 3 |
10 files changed, 41 insertions, 14 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index bba86ff8891..f0cf2fa6be2 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1225,3 +1225,10 @@ a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 an 2 2 1 2 drop table t1,t2,t3; +create table t1 (s1 int); +create table t2 (s1 int); +insert into t1 values (1); +insert into t2 values (1); +select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1); +s1 +drop table t1,t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 66d8dd2bc32..f4b0cd5ca23 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -807,6 +807,7 @@ INSERT INTO t1 VALUES("2f6161e879db43c1a5b82c21ddc49089", "Default", "System", " 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; + # # alloc_group_fields() working # @@ -817,4 +818,14 @@ insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10); insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1); insert into t3 values (3,3), (2,2), (1,1); select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3; -drop table t1,t2,t3;s +drop table t1,t2,t3; + +# +# aggregate functions in HAVING test +# +create table t1 (s1 int); +create table t2 (s1 int); +insert into t1 values (1); +insert into t2 values (1); +select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1); +drop table t1,t2; diff --git a/sql/item.cc b/sql/item.cc index 072dec4e6a6..74c64dffe98 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -49,15 +49,19 @@ Item::Item(): THD *thd= current_thd; next= thd->free_list; // Put in free list thd->free_list= this; - loop_id= 0; /* Item constructor can be called during execution other tnen SQL_COM command => we should check thd->lex.current_select on zero (thd->lex can be uninitialised) */ - if (thd->lex.current_select && - thd->lex.current_select->parsing_place == SELECT_LEX_NODE::SELECT_LIST) - thd->lex.current_select->select_items++; + if (thd->lex.current_select) + { + SELECT_LEX_NODE::enum_parsing_place place= + thd->lex.current_select->parsing_place; + if (place == SELECT_LEX_NODE::SELECT_LIST || + place == SELECT_LEX_NODE::IN_HAVING) + thd->lex.current_select->select_n_having_items++; + } } /* @@ -66,7 +70,6 @@ Item::Item(): tables */ Item::Item(THD *thd, Item &item): - loop_id(0), str_value(item.str_value), name(item.name), max_length(item.max_length), diff --git a/sql/item.h b/sql/item.h index 450cb396787..9df6532a637 100644 --- a/sql/item.h +++ b/sql/item.h @@ -83,7 +83,6 @@ public: }; class Item { - uint loop_id; /* Used to find selfrefering loops */ Item(const Item &); /* Prevent use of these */ void operator=(Item &); public: diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index cd78edfee7b..15ad64e44be 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -508,7 +508,7 @@ void Item_in_subselect::single_value_transformer(THD *thd, { sl->item_list.push_back(item); setup_ref_array(thd, &sl->ref_pointer_array, - 1 + sl->select_items + + 1 + sl->select_n_having_items + sl->order_list.elements + sl->group_list.elements); // To prevent crash on Item_ref_null_helper destruction in case of error sl->ref_pointer_array[0]= 0; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index c61e8f42343..9ed26bc4062 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -126,7 +126,8 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, item_list= select_cursor->item_list; select_cursor->with_wild= 0; if (setup_ref_array(thd, &select_cursor->ref_pointer_array, - (item_list.elements + select_cursor->select_items + + (item_list.elements + + select_cursor->select_n_having_items + select_cursor->order_list.elements + select_cursor->group_list.elements)) || setup_fields(thd, select_cursor->ref_pointer_array, first_table, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 16ebd758639..cc163dc3757 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -959,7 +959,7 @@ void st_select_lex_node::init_select() order_list.next= (byte**) &order_list.first; select_limit= HA_POS_ERROR; offset_limit= 0; - select_items= 0; + select_n_having_items= 0; with_sum_func= 0; parsing_place= SELECT_LEX_NODE::NO_MATTER; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index faf7e16e54a..3b9f5906c21 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -205,8 +205,12 @@ public: ha_rows select_limit, offset_limit; /* LIMIT clause parameters */ // Arrays of pointers to top elements of all_fields list Item **ref_pointer_array; - - uint select_items; /* number of items in select_list */ + /* + number of items in select_list and HAVING clause used to get number + bigger then can be number of entries that will be added to all item + list during split_sum_func + */ + uint select_n_having_items; uint cond_count; /* number of arguments of and/or/xor in where/having */ enum_parsing_place parsing_place; /* where we are parsing expression */ bool with_sum_func; /* sum function indicator */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0aa7e67a12b..7803e87572d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -294,7 +294,8 @@ JOIN::prepare(Item ***rref_pointer_array, fields_list, &all_fields, wild_num))) || setup_ref_array(thd, rref_pointer_array, (fields_list.elements + - select_lex->select_items + + select_lex-> + select_n_having_items + og_num)) || setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1, &all_fields, 1) || diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 724cc658b15..5f3fbadc99a 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -159,7 +159,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, item_list= select_cursor->item_list; select_cursor->with_wild= 0; if (setup_ref_array(thd, &select_cursor->ref_pointer_array, - (item_list.elements + select_cursor->select_items + + (item_list.elements + + select_cursor->select_n_having_items + select_cursor->order_list.elements + select_cursor->group_list.elements)) || setup_fields(thd, select_cursor->ref_pointer_array, first_table, |