summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2016-03-16 01:26:39 +0300
committerSergei Petrunia <psergey@askmonty.org>2016-03-16 01:26:39 +0300
commit833304313d65f426323b10016616c3a6d951804b (patch)
tree474c8216cc46d33ff16f0c6a0aa12535191570ad
parent21a0291c1de5553dbfc06447b8b81d3756adb843 (diff)
downloadmariadb-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.result30
-rw-r--r--sql/item_windowfunc.cc1
-rw-r--r--sql/item_windowfunc.h80
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,