diff options
author | unknown <svoj@mysql.com> | 2005-02-25 22:19:04 +0400 |
---|---|---|
committer | unknown <svoj@mysql.com> | 2005-02-25 22:19:04 +0400 |
commit | d339dd13cdb7fea28bc3800328bb74fd68fb4683 (patch) | |
tree | dacd1c6c90c80b374fbffd31ffd2a7caed5943fa /sql | |
parent | c5d4d50ab703d9b3cb087ea5e721baed6fbdab8c (diff) | |
download | mariadb-git-d339dd13cdb7fea28bc3800328bb74fd68fb4683.tar.gz |
BUG#3190 fix (request for STDDEV_SAMP, VAR_SAMP).
This bug is also known as WL#1639.
mysql-test/r/func_group.result:
Test case for stddev_pop, var_pop, stddev_samp, var_samp was added.
mysql-test/t/func_group.test:
Test case for stddev_pop, var_pop, stddev_samp, var_samp was added.
sql/item_sum.cc:
New functions stddev_samp and var_samp were added.
sql/item_sum.h:
New functions stddev_samp and var_samp were added.
sql/lex.h:
New functions stddev_pop, var_pop, stddev_samp and var_samp were added.
sql/sql_yacc.yy:
New functions stddev_pop, var_pop, stddev_samp and var_samp were added.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_sum.cc | 25 | ||||
-rw-r--r-- | sql/item_sum.h | 9 | ||||
-rw-r--r-- | sql/lex.h | 4 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 10 |
4 files changed, 32 insertions, 16 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 9a4798b9dc9..f33494a4d53 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -853,7 +853,7 @@ Item *Item_sum_std::copy_or_same(THD* thd) Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item): Item_sum_num(thd, item), hybrid_type(item->hybrid_type), - cur_dec(item->cur_dec), count(item->count) + cur_dec(item->cur_dec), count(item->count), sample(item->sample) { if (hybrid_type == DECIMAL_RESULT) { @@ -1001,7 +1001,7 @@ double Item_sum_variance::val_real() if (hybrid_type == DECIMAL_RESULT) return val_real_from_decimal(); - if (!count) + if (count <= sample) { null_value=1; return 0.0; @@ -1009,30 +1009,31 @@ double Item_sum_variance::val_real() null_value=0; /* Avoid problems when the precision isn't good enough */ double tmp=ulonglong2double(count); - double tmp2=(sum_sqr - sum*sum/tmp)/tmp; + double tmp2= (sum_sqr - sum*sum/tmp)/(tmp - (double)sample); return tmp2 <= 0.0 ? 0.0 : tmp2; } my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf) { - my_decimal count_buf, sum_sqr_buf; + my_decimal count_buf, count1_buf, sum_sqr_buf; DBUG_ASSERT(fixed ==1 ); if (hybrid_type == REAL_RESULT) return val_decimal_from_real(dec_buf); - if (!count) + if (count <= sample) { null_value= 1; return 0; } null_value= 0; int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &count_buf); + int2my_decimal(E_DEC_FATAL_ERROR, count-sample, 0, &count1_buf); my_decimal_mul(E_DEC_FATAL_ERROR, &sum_sqr_buf, dec_sum+cur_dec, dec_sum+cur_dec); my_decimal_div(E_DEC_FATAL_ERROR, dec_buf, &sum_sqr_buf, &count_buf, 2); my_decimal_sub(E_DEC_FATAL_ERROR, &sum_sqr_buf, dec_sqr+cur_dec, dec_buf); - my_decimal_div(E_DEC_FATAL_ERROR, dec_buf, &sum_sqr_buf, &count_buf, 2); + my_decimal_div(E_DEC_FATAL_ERROR, dec_buf, &sum_sqr_buf, &count1_buf, 2); return dec_buf; } @@ -2004,6 +2005,7 @@ Item_variance_field::Item_variance_field(Item_sum_variance *item) max_length=item->max_length; field=item->result_field; maybe_null=1; + sample= item->sample; if ((hybrid_type= item->hybrid_type) == DECIMAL_RESULT) { f_scale0= item->f_scale0; @@ -2028,11 +2030,11 @@ double Item_variance_field::val_real() float8get(sum_sqr,(field->ptr+sizeof(double))); count=sint8korr(field->ptr+sizeof(double)*2); - if ((null_value= !count)) + if ((null_value= (count <= sample))) return 0.0; double tmp= (double) count; - double tmp2=(sum_sqr - sum*sum/tmp)/tmp; + double tmp2= (sum_sqr - sum*sum/tmp)/(tmp - (double)sample); return tmp2 <= 0.0 ? 0.0 : tmp2; } @@ -2052,11 +2054,12 @@ my_decimal *Item_variance_field::val_decimal(my_decimal *dec_buf) return val_decimal_from_real(dec_buf); longlong count= sint8korr(field->ptr+dec_bin_size0+dec_bin_size1); - if ((null_value= !count)) + if ((null_value= (count <= sample))) return 0; - my_decimal dec_count, dec_sum, dec_sqr, tmp; + my_decimal dec_count, dec1_count, dec_sum, dec_sqr, tmp; int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &dec_count); + int2my_decimal(E_DEC_FATAL_ERROR, count-sample, 0, &dec1_count); binary2my_decimal(E_DEC_FATAL_ERROR, field->ptr, &dec_sum, f_precision0, f_scale0); binary2my_decimal(E_DEC_FATAL_ERROR, field->ptr+dec_bin_size0, @@ -2064,7 +2067,7 @@ my_decimal *Item_variance_field::val_decimal(my_decimal *dec_buf) my_decimal_mul(E_DEC_FATAL_ERROR, &tmp, &dec_sum, &dec_sum); my_decimal_div(E_DEC_FATAL_ERROR, dec_buf, &tmp, &dec_count, 2); my_decimal_sub(E_DEC_FATAL_ERROR, &dec_sum, &dec_sqr, dec_buf); - my_decimal_div(E_DEC_FATAL_ERROR, dec_buf, &dec_sum, &dec_count, 2); + my_decimal_div(E_DEC_FATAL_ERROR, dec_buf, &dec_sum, &dec1_count, 2); return dec_buf; } diff --git a/sql/item_sum.h b/sql/item_sum.h index eca2ae188db..bc770553dec 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -379,6 +379,7 @@ public: uint f_precision0, f_scale0; uint f_precision1, f_scale1; uint dec_bin_size0, dec_bin_size1; + uint sample; Item_variance_field(Item_sum_variance *item); enum Type type() const {return FIELD_VARIANCE_ITEM; } double val_real(); @@ -422,9 +423,10 @@ public: uint f_precision0, f_scale0; uint f_precision1, f_scale1; uint dec_bin_size0, dec_bin_size1; + uint sample; - Item_sum_variance(Item *item_par) :Item_sum_num(item_par), hybrid_type(REAL_RESULT), - cur_dec(0),count(0) + Item_sum_variance(Item *item_par, uint sample_arg) :Item_sum_num(item_par), + hybrid_type(REAL_RESULT), cur_dec(0), count(0), sample(sample_arg) {} Item_sum_variance(THD *thd, Item_sum_variance *item); enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } @@ -463,7 +465,8 @@ public: class Item_sum_std :public Item_sum_variance { public: - Item_sum_std(Item *item_par) :Item_sum_variance(item_par) {} + Item_sum_std(Item *item_par, uint sample_arg) + :Item_sum_variance(item_par, sample_arg) {} Item_sum_std(THD *thd, Item_sum_std *item) :Item_sum_variance(thd, item) {} diff --git a/sql/lex.h b/sql/lex.h index 3894e8f6274..d0dc287775e 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -735,6 +735,8 @@ static SYMBOL sql_functions[] = { { "STARTPOINT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_startpoint)}, { "STD", SYM(STD_SYM)}, { "STDDEV", SYM(STD_SYM)}, + { "STDDEV_POP", SYM(STD_SYM)}, + { "STDDEV_SAMP", SYM(STDDEV_SAMP_SYM)}, { "STR_TO_DATE", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)}, { "STRCMP", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)}, { "SUBSTR", SYM(SUBSTRING)}, @@ -760,6 +762,8 @@ static SYMBOL sql_functions[] = { { "UPPER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, { "UUID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_uuid)}, { "VARIANCE", SYM(VARIANCE_SYM)}, + { "VAR_POP", SYM(VARIANCE_SYM)}, + { "VAR_SAMP", SYM(VAR_SAMP_SYM)}, { "VERSION", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)}, { "WEEKDAY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)}, { "WEEKOFYEAR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekofyear)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ba1b999b240..b7ef48cfc47 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -561,6 +561,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token START_SYM %token STATUS_SYM %token STD_SYM +%token STDDEV_SAMP_SYM %token STOP_SYM %token STORAGE_SYM %token STRAIGHT_JOIN @@ -624,6 +625,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token UTC_DATE_SYM %token UTC_TIMESTAMP_SYM %token UTC_TIME_SYM +%token VAR_SAMP_SYM %token VALUES %token VALUE_SYM %token VARBINARY @@ -4754,9 +4756,13 @@ sum_expr: | MAX_SYM '(' DISTINCT in_sum_expr ')' { $$=new Item_sum_max($4); } | STD_SYM '(' in_sum_expr ')' - { $$=new Item_sum_std($3); } + { $$=new Item_sum_std($3, 0); } | VARIANCE_SYM '(' in_sum_expr ')' - { $$=new Item_sum_variance($3); } + { $$=new Item_sum_variance($3, 0); } + | STDDEV_SAMP_SYM '(' in_sum_expr ')' + { $$=new Item_sum_std($3, 1); } + | VAR_SAMP_SYM '(' in_sum_expr ')' + { $$=new Item_sum_variance($3, 1); } | SUM_SYM '(' in_sum_expr ')' { $$=new Item_sum_sum($3); } | SUM_SYM '(' DISTINCT in_sum_expr ')' |