diff options
-rw-r--r-- | .bzrignore | 3 | ||||
-rw-r--r-- | mysql-test/r/row.result | 15 | ||||
-rw-r--r-- | mysql-test/t/row.test | 12 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 6 | ||||
-rw-r--r-- | sql/item_row.cc | 37 | ||||
-rw-r--r-- | sql/item_row.h | 1 |
7 files changed, 64 insertions, 12 deletions
diff --git a/.bzrignore b/.bzrignore index d3e2393aa8d..7aee59588ce 100644 --- a/.bzrignore +++ b/.bzrignore @@ -591,3 +591,6 @@ help.c vi.h include/readline/readline.h cmd-line-utils/libedit/common.h +stamp-h2 +stamp-h3 +stamp-h4 diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result index d86ae6c7961..40beeb4d3a5 100644 --- a/mysql-test/r/row.result +++ b/mysql-test/r/row.result @@ -144,3 +144,18 @@ Cardinality error (more/less than 1 columns) select count(*) from t1 having (1,1) order by i; Cardinality error (more/less than 1 columns) drop table t1; +create table t1 (a int, b int); +insert into t1 values (1, 4); +insert into t1 values (10, 40); +insert into t1 values (1, 4); +insert into t1 values (10, 43); +insert into t1 values (1, 4); +insert into t1 values (10, 41); +insert into t1 values (1, 4); +insert into t1 values (10, 43); +insert into t1 values (1, 4); +select a, MAX(b), (1, MAX(b)) = (1, 4) from t1 group by a; +a MAX(b) (1, MAX(b)) = (1, 4) +1 4 1 +10 43 0 +drop table t1; diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index 98fd640f12e..9d69e56f9ee 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -67,3 +67,15 @@ select count(*) from t1 order by ROW(1,1); select count(*) from t1 having (1,1) order by i; drop table t1; +create table t1 (a int, b int); +insert into t1 values (1, 4); +insert into t1 values (10, 40); +insert into t1 values (1, 4); +insert into t1 values (10, 43); +insert into t1 values (1, 4); +insert into t1 values (10, 41); +insert into t1 values (1, 4); +insert into t1 values (10, 43); +insert into t1 values (1, 4); +select a, MAX(b), (1, MAX(b)) = (1, 4) from t1 group by a; +drop table t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 7a9cce6d645..f28268d0f88 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1079,8 +1079,10 @@ in_string::in_string(uint elements,qsort_cmp cmp_func) in_string::~in_string() { if (base) + { for (uint i=0 ; i < count ; i++) ((String*) base)[i].free(); + } } void in_string::set(uint pos,Item *item) diff --git a/sql/item_func.cc b/sql/item_func.cc index dd452d99208..94cedfe1fa2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -157,8 +157,8 @@ void Item_func::set_outer_resolving() void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields) { - Item **arg,**arg_end; - for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) + Item **arg, **arg_end; + for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++) { if ((*arg)->with_sum_func && (*arg)->type() != SUM_FUNC_ITEM) (*arg)->split_sum_func(ref_pointer_array, fields); @@ -167,7 +167,7 @@ void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields) uint el= fields.elements; fields.push_front(*arg); ref_pointer_array[el]= *arg; - *arg=new Item_ref(ref_pointer_array + el, 0, (*arg)->name); + *arg= new Item_ref(ref_pointer_array + el, 0, (*arg)->name); } } } diff --git a/sql/item_row.cc b/sql/item_row.cc index 0c060b6d8db..dbab041aae5 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -48,26 +48,45 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) { null_value= 0; maybe_null= 0; - for (uint i= 0; i < arg_count; i++) + Item **arg, **arg_end; + for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) { - if (items[i]->fix_fields(thd, tabl, items+i)) + if ((*arg)->fix_fields(thd, tabl, arg)) return 1; - used_tables_cache |= items[i]->used_tables(); - if (const_item_cache&= items[i]->const_item() && !with_null) + used_tables_cache |= (*arg)->used_tables(); + if (const_item_cache&= (*arg)->const_item() && !with_null) { - if (items[i]->cols() > 1) - with_null|= items[i]->null_inside(); + if ((*arg)->cols() > 1) + with_null|= (*arg)->null_inside(); else { - items[i]->val_int(); - with_null|= items[i]->null_value; + (*arg)->val_int(); + with_null|= (*arg)->null_value; } } - maybe_null|= items[i]->maybe_null; + maybe_null|= (*arg)->maybe_null; + with_sum_func= with_sum_func || (*arg)->with_sum_func; } return 0; } +void Item_row::split_sum_func(Item **ref_pointer_array, List<Item> &fields) +{ + Item **arg, **arg_end; + for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) + { + if ((*arg)->with_sum_func && (*arg)->type() != SUM_FUNC_ITEM) + (*arg)->split_sum_func(ref_pointer_array, fields); + else if ((*arg)->used_tables() || (*arg)->type() == SUM_FUNC_ITEM) + { + uint el= fields.elements; + fields.push_front(*arg); + ref_pointer_array[el]= *arg; + *arg= new Item_ref(ref_pointer_array + el, 0, (*arg)->name); + } + } +} + void Item_row::update_used_tables() { used_tables_cache= 0; diff --git a/sql/item_row.h b/sql/item_row.h index ccaf68bed64..e28f18d24ff 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -63,6 +63,7 @@ public: return 0; }; bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); + void split_sum_func(Item **ref_pointer_array, List<Item> &fields); table_map used_tables() const { return used_tables_cache; }; bool const_item() const { return const_item_cache; }; enum Item_result result_type() const { return ROW_RESULT; } |