Commit 0eeb472c authored by unknown's avatar unknown

reset() split in 2 function clear() & add()

aggregate function reinitialization (if no rows was found) made with help of clear()
(fixed BUG#860)


mysql-test/r/subselect.result:
  test for BUG#860
mysql-test/t/subselect.test:
  test for BUG#860
sql/item_sum.cc:
  reset() replaced with clear()
sql/item_sum.h:
  reset() replaced with clear()
  (reset now is just composition of clear() and add())
sql/item_uniq.h:
  reset() replaced with clear()
sql/sql_select.cc:
  removed NULL value assigment, now it will be done by clear() call
  function for clearing if there was not found any row in group
sql/sql_select.h:
  function for clearing if there was not found any row in group
parent 0acca0ab
...@@ -1352,3 +1352,12 @@ ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_ ...@@ -1352,3 +1352,12 @@ ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_
select * from t1 where s1 > any (select max(s2) from t1); select * from t1 where s1 > any (select max(s2) from t1);
ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>' ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
drop table t1; drop table t1;
create table t1(toid int,rd int);
create table t2(userid int,pmnew int,pmtotal int);
insert into t2 values(1,0,0),(2,0,0);
insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
userid pmtotal pmnew calc_total calc_new
1 0 0 9 3
2 0 0 4 2
drop table t1, t2;
...@@ -912,3 +912,13 @@ select * from t1 where s1 > (select max(s2) from t1); ...@@ -912,3 +912,13 @@ select * from t1 where s1 > (select max(s2) from t1);
-- error 1266 -- error 1266
select * from t1 where s1 > any (select max(s2) from t1); select * from t1 where s1 > any (select max(s2) from t1);
drop table t1; drop table t1;
#
# aggregate functions reinitialization
#
create table t1(toid int,rd int);
create table t2(userid int,pmnew int,pmtotal int);
insert into t2 values(1,0,0),(2,0,0);
insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
drop table t1, t2;
...@@ -223,10 +223,9 @@ Item *Item_sum_sum::copy_or_same(THD* thd) ...@@ -223,10 +223,9 @@ Item *Item_sum_sum::copy_or_same(THD* thd)
} }
bool Item_sum_sum::reset() void Item_sum_sum::clear()
{ {
null_value=1; sum=0.0; null_value=1; sum=0.0;
return Item_sum_sum::add();
} }
...@@ -251,10 +250,9 @@ Item *Item_sum_count::copy_or_same(THD* thd) ...@@ -251,10 +250,9 @@ Item *Item_sum_count::copy_or_same(THD* thd)
} }
bool Item_sum_count::reset() void Item_sum_count::clear()
{ {
count=0; count= 0;
return add();
} }
...@@ -286,10 +284,9 @@ Item *Item_sum_avg::copy_or_same(THD* thd) ...@@ -286,10 +284,9 @@ Item *Item_sum_avg::copy_or_same(THD* thd)
} }
bool Item_sum_avg::reset() void Item_sum_avg::clear()
{ {
sum=0.0; count=0; sum=0.0; count=0;
return Item_sum_avg::add();
} }
...@@ -342,11 +339,10 @@ Item *Item_sum_variance::copy_or_same(THD* thd) ...@@ -342,11 +339,10 @@ Item *Item_sum_variance::copy_or_same(THD* thd)
} }
bool Item_sum_variance::reset() void Item_sum_variance::clear()
{ {
sum=sum_sqr=0.0; sum=sum_sqr=0.0;
count=0; count=0;
return Item_sum_variance::add();
} }
bool Item_sum_variance::add() bool Item_sum_variance::add()
...@@ -592,10 +588,9 @@ longlong Item_sum_bit::val_int() ...@@ -592,10 +588,9 @@ longlong Item_sum_bit::val_int()
} }
bool Item_sum_bit::reset() void Item_sum_bit::clear()
{ {
bits=reset_bits; bits= reset_bits;
return add();
} }
Item *Item_sum_or::copy_or_same(THD* thd) Item *Item_sum_or::copy_or_same(THD* thd)
...@@ -1280,7 +1275,7 @@ Item *Item_sum_count_distinct::copy_or_same(THD* thd) ...@@ -1280,7 +1275,7 @@ Item *Item_sum_count_distinct::copy_or_same(THD* thd)
} }
bool Item_sum_count_distinct::reset() void Item_sum_count_distinct::clear()
{ {
if (use_tree) if (use_tree)
reset_tree(tree); reset_tree(tree);
...@@ -1290,7 +1285,6 @@ bool Item_sum_count_distinct::reset() ...@@ -1290,7 +1285,6 @@ bool Item_sum_count_distinct::reset()
table->file->delete_all_rows(); table->file->delete_all_rows();
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
} }
return add();
} }
bool Item_sum_count_distinct::add() bool Item_sum_count_distinct::add()
...@@ -1353,11 +1347,11 @@ longlong Item_sum_count_distinct::val_int() ...@@ -1353,11 +1347,11 @@ longlong Item_sum_count_distinct::val_int()
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
bool Item_udf_sum::clear() void Item_udf_sum::clear()
{ {
DBUG_ENTER("Item_udf_sum::reset"); DBUG_ENTER("Item_udf_sum::clear");
udf.clear(); udf.clear();
DBUG_RETURN(0); DBUG_VOID_RETURN;
} }
bool Item_udf_sum::add() bool Item_udf_sum::add()
...@@ -1685,7 +1679,7 @@ Item *Item_func_group_concat::copy_or_same(THD* thd) ...@@ -1685,7 +1679,7 @@ Item *Item_func_group_concat::copy_or_same(THD* thd)
} }
bool Item_func_group_concat::reset() void Item_func_group_concat::clear()
{ {
result.length(0); result.length(0);
result.copy(); result.copy();
...@@ -1699,7 +1693,6 @@ bool Item_func_group_concat::reset() ...@@ -1699,7 +1693,6 @@ bool Item_func_group_concat::reset()
} }
if (tree_mode) if (tree_mode)
reset_tree(tree); reset_tree(tree);
return add();
} }
......
...@@ -62,7 +62,8 @@ class Item_sum :public Item_result_field ...@@ -62,7 +62,8 @@ class Item_sum :public Item_result_field
enum Type type() const { return SUM_FUNC_ITEM; } enum Type type() const { return SUM_FUNC_ITEM; }
virtual enum Sumfunctype sum_func () const=0; virtual enum Sumfunctype sum_func () const=0;
virtual bool reset()=0; inline bool reset() { clear(); return add(); };
virtual void clear()= 0;
virtual bool add()=0; virtual bool add()=0;
virtual void reset_field()=0; virtual void reset_field()=0;
virtual void update_field(int offset)=0; virtual void update_field(int offset)=0;
...@@ -124,7 +125,7 @@ class Item_sum_sum :public Item_sum_num ...@@ -124,7 +125,7 @@ class Item_sum_sum :public Item_sum_num
Item_sum_sum(THD *thd, Item_sum_sum &item) Item_sum_sum(THD *thd, Item_sum_sum &item)
:Item_sum_num(thd, item), sum(item.sum) {} :Item_sum_num(thd, item), sum(item.sum) {}
enum Sumfunctype sum_func () const {return SUM_FUNC;} enum Sumfunctype sum_func () const {return SUM_FUNC;}
bool reset(); void clear();
bool add(); bool add();
double val(); double val();
void reset_field(); void reset_field();
...@@ -151,7 +152,7 @@ class Item_sum_count :public Item_sum_int ...@@ -151,7 +152,7 @@ class Item_sum_count :public Item_sum_int
table_map used_tables() const { return used_table_cache; } table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; } bool const_item() const { return !used_table_cache; }
enum Sumfunctype sum_func () const { return COUNT_FUNC; } enum Sumfunctype sum_func () const { return COUNT_FUNC; }
bool reset(); void clear();
void no_rows_in_result() { count=0; } void no_rows_in_result() { count=0; }
bool add(); bool add();
void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; } void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
...@@ -225,7 +226,7 @@ class Item_sum_count_distinct :public Item_sum_int ...@@ -225,7 +226,7 @@ class Item_sum_count_distinct :public Item_sum_int
table_map used_tables() const { return used_table_cache; } table_map used_tables() const { return used_table_cache; }
enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; } enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
bool reset(); void clear();
bool add(); bool add();
longlong val_int(); longlong val_int();
void reset_field() { return ;} // Never called void reset_field() { return ;} // Never called
...@@ -269,7 +270,7 @@ class Item_sum_avg :public Item_sum_num ...@@ -269,7 +270,7 @@ class Item_sum_avg :public Item_sum_num
Item_sum_avg(THD *thd, Item_sum_avg &item) Item_sum_avg(THD *thd, Item_sum_avg &item)
:Item_sum_num(thd, item), sum(item.sum), count(item.count) {} :Item_sum_num(thd, item), sum(item.sum), count(item.count) {}
enum Sumfunctype sum_func () const {return AVG_FUNC;} enum Sumfunctype sum_func () const {return AVG_FUNC;}
bool reset(); void clear();
bool add(); bool add();
double val(); double val();
void reset_field(); void reset_field();
...@@ -322,7 +323,7 @@ class Item_sum_variance : public Item_sum_num ...@@ -322,7 +323,7 @@ class Item_sum_variance : public Item_sum_num
Item_sum_num(thd, item), sum(item.sum), sum_sqr(item.sum_sqr), Item_sum_num(thd, item), sum(item.sum), sum_sqr(item.sum_sqr),
count(item.count) {} count(item.count) {}
enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
bool reset(); void clear();
bool add(); bool add();
double val(); double val();
void reset_field(); void reset_field();
...@@ -391,13 +392,12 @@ class Item_sum_hybrid :public Item_sum ...@@ -391,13 +392,12 @@ class Item_sum_hybrid :public Item_sum
table_map used_tables() const { return used_table_cache; } table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; } bool const_item() const { return !used_table_cache; }
bool reset() void clear()
{ {
sum=0.0; sum=0.0;
sum_int=0; sum_int=0;
value.length(0); value.length(0);
null_value=1; null_value=1;
return add();
} }
double val(); double val();
longlong val_int(); longlong val_int();
...@@ -451,7 +451,7 @@ class Item_sum_bit :public Item_sum_int ...@@ -451,7 +451,7 @@ class Item_sum_bit :public Item_sum_int
Item_sum_bit(THD *thd, Item_sum_bit &item): Item_sum_bit(THD *thd, Item_sum_bit &item):
Item_sum_int(thd, item), reset_bits(item.reset_bits), bits(item.bits) {} Item_sum_int(thd, item), reset_bits(item.reset_bits), bits(item.bits) {}
enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;} enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
bool reset(); void clear();
longlong val_int(); longlong val_int();
void reset_field(); void reset_field();
void fix_length_and_dec() void fix_length_and_dec()
...@@ -509,8 +509,7 @@ class Item_udf_sum : public Item_sum ...@@ -509,8 +509,7 @@ class Item_udf_sum : public Item_sum
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
virtual bool have_field_update(void) const { return 0; } virtual bool have_field_update(void) const { return 0; }
bool reset() { return 0; } /* TO BE FIXED */ void clear();
bool clear();
bool add(); bool add();
void reset_field() {}; void reset_field() {};
void update_field(int offset_arg) {}; void update_field(int offset_arg) {};
...@@ -592,7 +591,7 @@ class Item_sum_udf_float :public Item_sum_num ...@@ -592,7 +591,7 @@ class Item_sum_udf_float :public Item_sum_num
~Item_sum_udf_float() {} ~Item_sum_udf_float() {}
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
double val() { return 0.0; } double val() { return 0.0; }
bool reset() { return 0; } bool clear() {}
bool add() { return 0; } bool add() { return 0; }
void update_field(int offset) {} void update_field(int offset) {}
}; };
...@@ -609,7 +608,7 @@ class Item_sum_udf_int :public Item_sum_num ...@@ -609,7 +608,7 @@ class Item_sum_udf_int :public Item_sum_num
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
longlong val_int() { return 0; } longlong val_int() { return 0; }
double val() { return 0; } double val() { return 0; }
bool reset() { return 0; } void clear() {}
bool add() { return 0; } bool add() { return 0; }
void update_field(int offset) {} void update_field(int offset) {}
}; };
...@@ -629,7 +628,7 @@ class Item_sum_udf_str :public Item_sum_num ...@@ -629,7 +628,7 @@ class Item_sum_udf_str :public Item_sum_num
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec() { maybe_null=1; max_length=0; } void fix_length_and_dec() { maybe_null=1; max_length=0; }
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
bool reset() { return 0; } void clear() {}
bool add() { return 0; } bool add() { return 0; }
void update_field(int offset) {} void update_field(int offset) {}
}; };
...@@ -715,7 +714,7 @@ class Item_func_group_concat : public Item_sum ...@@ -715,7 +714,7 @@ class Item_func_group_concat : public Item_sum
const char *func_name() const { return "group_concat"; } const char *func_name() const { return "group_concat"; }
enum Type type() const { return SUM_FUNC_ITEM; } enum Type type() const { return SUM_FUNC_ITEM; }
virtual Item_result result_type () const { return STRING_RESULT; } virtual Item_result result_type () const { return STRING_RESULT; }
bool reset(); void clear();
bool add(); bool add();
void reset_field(); void reset_field();
bool fix_fields(THD *, TABLE_LIST *, Item **); bool fix_fields(THD *, TABLE_LIST *, Item **);
......
...@@ -41,7 +41,7 @@ class Item_sum_unique_users :public Item_sum_num ...@@ -41,7 +41,7 @@ class Item_sum_unique_users :public Item_sum_num
:Item_sum_num(thd, item) {} :Item_sum_num(thd, item) {}
double val() { return 0.0; } double val() { return 0.0; }
enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;} enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;}
bool reset() { return 0;} void clear() {}
bool add() { return 0; } bool add() { return 0; }
void reset_field() {} void reset_field() {}
void update_field(int offset) {} void update_field(int offset) {}
......
...@@ -1003,12 +1003,6 @@ JOIN::reinit() ...@@ -1003,12 +1003,6 @@ JOIN::reinit()
/* Reset of sum functions */ /* Reset of sum functions */
first_record= 0; first_record= 0;
if (sum_funcs)
{
Item_sum *func, **func_ptr= sum_funcs;
while ((func= *(func_ptr++)))
func->null_value= 1;
}
if (exec_tmp_table1) if (exec_tmp_table1)
{ {
...@@ -5979,8 +5973,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -5979,8 +5973,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->first_record) if (!join->first_record)
{ {
/* No matching rows for group function */ /* No matching rows for group function */
clear_tables(join); join->clear();
copy_fields(&join->tmp_table_param);
} }
if (join->having && join->having->val_int() == 0) if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having error= -1; // Didn't satisfy having
...@@ -6246,8 +6239,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -6246,8 +6239,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->first_record) if (!join->first_record)
{ {
/* No matching rows for group function */ /* No matching rows for group function */
clear_tables(join); join->clear();
copy_fields(&join->tmp_table_param);
} }
copy_sum_funcs(join->sum_funcs); copy_sum_funcs(join->sum_funcs);
if (!join->having || join->having->val_int()) if (!join->having || join->having->val_int())
...@@ -8542,6 +8534,26 @@ int JOIN::rollup_send_data(uint idx) ...@@ -8542,6 +8534,26 @@ int JOIN::rollup_send_data(uint idx)
return 0; return 0;
} }
/*
clear results if there are not rows found for group
(end_send_group/end_write_group)
SYNOPSYS
JOIN::clear()
*/
void JOIN::clear()
{
clear_tables(this);
copy_fields(&tmp_table_param);
if (sum_funcs)
{
Item_sum *func, **func_ptr= sum_funcs;
while ((func= *(func_ptr++)))
func->clear();
}
}
/**************************************************************************** /****************************************************************************
EXPLAIN handling EXPLAIN handling
......
...@@ -279,6 +279,7 @@ class JOIN :public Sql_alloc ...@@ -279,6 +279,7 @@ class JOIN :public Sql_alloc
Item_sum ***func); Item_sum ***func);
int rollup_send_data(uint idx); int rollup_send_data(uint idx);
bool test_in_subselect(Item **where); bool test_in_subselect(Item **where);
void clear();
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment