diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2016-03-16 01:26:39 +0300 |
---|---|---|
committer | Sergei Petrunia <psergey@askmonty.org> | 2016-03-16 01:26:39 +0300 |
commit | 833304313d65f426323b10016616c3a6d951804b (patch) | |
tree | 474c8216cc46d33ff16f0c6a0aa12535191570ad | |
parent | 21a0291c1de5553dbfc06447b8b81d3756adb843 (diff) | |
download | mariadb-git-833304313d65f426323b10016616c3a6d951804b.tar.gz |
Continuation of "Implemented a counter within Item_sum_sum" a few commits before
Query result had 0 where it should have had NULLs:
- Make Item_window_func::val* functions honor NULL-handling conventions:
1. set null_value to indicate whether we've returned a NULL value
2. val_str and val_decimal should return NULL pointer when they're
returning SQL NULL value.
Fix assertion failure when sending results to network.
- The assert was due to window func returing SQL NULL despite having
maybe_null=false
- Fixed by settting Item_window_func::maybe_null correctly in fix_fields
-rw-r--r-- | mysql-test/r/win_sum.result | 30 | ||||
-rw-r--r-- | sql/item_windowfunc.cc | 1 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 80 |
3 files changed, 83 insertions, 28 deletions
diff --git a/mysql-test/r/win_sum.result b/mysql-test/r/win_sum.result index 1db6c6eefab..9449300f91d 100644 --- a/mysql-test/r/win_sum.result +++ b/mysql-test/r/win_sum.result @@ -24,19 +24,19 @@ select pk, a, b, sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDIN sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) from t1; pk a b sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) -101 0 10 20 3.2 -102 0 10 20 3.2 -103 1 10 20 7.199999999999999 -104 1 10 20 7.199999999999999 -105 2 20 40 13.2 -106 2 20 60 21.35 -107 2 20 50 20.35 -108 2 10 30 13.250000000000002 -109 4 20 40 19.3 -110 4 20 40 19.3 -111 5 NULL 1 23.4 -112 5 1 1 36.75 -113 5 NULL 1 40.1 -114 5 NULL 0 43.5 -115 5 NULL 0 30.15 +101 0 10 0 3.2 +102 0 10 0 3.2 +103 1 10 0 7.199999999999999 +104 1 10 0 7.199999999999999 +105 2 20 0 13.2 +106 2 20 0 21.35 +107 2 20 0 20.35 +108 2 10 0 13.250000000000002 +109 4 20 0 19.3 +110 4 20 0 19.3 +111 5 NULL 0 23.4 +112 5 1 0 36.75 +113 5 NULL 0 40.1 +114 5 NULL NULL 43.5 +115 5 NULL NULL 30.15 drop table t1; diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 82e84ab5c36..027b0bdf0a1 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -59,6 +59,7 @@ Item_window_func::fix_fields(THD *thd, Item **ref) fix_length_and_dec(); max_length= window_func->max_length; + maybe_null= window_func->maybe_null; fixed= 1; force_return_blank= true; diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 5cb1e8aae32..e316c6d712a 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -481,37 +481,91 @@ public: double val_real() { + double res; if (force_return_blank) - return 0.0; - return read_value_from_result_field? result_field->val_real() : - window_func->val_real(); + { + res= 0.0; + null_value= false; + } + else if (read_value_from_result_field) + { + res= result_field->val_real(); + null_value= false; + } + else + { + res= window_func->val_real(); + null_value= window_func->null_value; + } } longlong val_int() { + longlong res; if (force_return_blank) - return 0; - return read_value_from_result_field? result_field->val_int() : - window_func->val_int(); + { + res= 0; + null_value= false; + } + else if (read_value_from_result_field) + { + res= result_field->val_int(); + null_value= result_field->is_null(); + } + else + { + res= window_func->val_int(); + null_value= window_func->null_value; + } + return res; } String* val_str(String* str) { + String *res; if (force_return_blank) - return str; - return read_value_from_result_field? result_field->val_str(str) : - window_func->val_str(str); + { + null_value= false; + str->length(0); + res= str; + } + else if (read_value_from_result_field) + { + if ((null_value= result_field->is_null())) + res= NULL; + else + res= result_field->val_str(str); + } + else + { + res= window_func->val_str(str); + null_value= window_func->null_value; + } + return res; } my_decimal* val_decimal(my_decimal* dec) - { + { + my_decimal *res; if (force_return_blank) { my_decimal_set_zero(dec); - return dec; + null_value= false; + res= dec; + } + else if (read_value_from_result_field) + { + if ((null_value= result_field->is_null())) + res= NULL; + else + res= result_field->val_decimal(dec); + } + else + { + res= result_field->val_decimal(dec); + null_value= window_func->null_value; } - return read_value_from_result_field? result_field->val_decimal(dec) : - window_func->val_decimal(dec); + return res; } void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array, |