diff options
author | unknown <timour@askmonty.org> | 2011-03-24 16:34:06 +0200 |
---|---|---|
committer | unknown <timour@askmonty.org> | 2011-03-24 16:34:06 +0200 |
commit | ec23949158b54e3c42bff4b4ec457f7cc2a1d182 (patch) | |
tree | 38272144d9b1cddb1065240e1c3b334a9e96fad7 /sql/item_func.h | |
parent | 8aaf9197d09ab3092bcacc23546d23fea93e4122 (diff) | |
download | mariadb-git-ec23949158b54e3c42bff4b4ec457f7cc2a1d182.tar.gz |
Fix LP BUG#715738
Analysis:
A query with implicit grouping is one with aggregate functions and
no GROUP BY clause. MariaDB inherits from MySQL an SQL extenstion
that allows mixing aggregate functions with non-aggregate fields.
If a query with such mixed select clause produces an empty result
set, the meaning of aggregate functions is well defined - either
NULL (MIN, MAX, etc.), or 0 (count(*)). However the non-aggregated
fields must also have some value, and the only reasonable value in
the case of empty result is NULL.
The cause of the many wrong results was that if a field is declared
as non-nullable (e.g. because it is a PK or NOT NULL), the semantic
analysis and the optimization phases treat this field as non-nullable,
and generate all related query plan elements based on this assumption.
Later during execution, these incorrectly configured/generated query
plan elements result in a wrong result because the selected fields
are not null due to the not-null assumption during optimization.
Solution:
Detect before the context analysys phase that a query uses implicit
grouping with mixed aggregates/non-aggregates, and set all fields
as nullable. The parser already walks the SELECT clause, and
already sets Item::with_sum_func for Items that reference aggreagate
functions. The patch adds a symmetric Item::with_field so that all
Items that reference an Item_field are marked during their
construction at parse time in the same way as with aggregate function
use.
Diffstat (limited to 'sql/item_func.h')
-rw-r--r-- | sql/item_func.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index 36f089de529..5c5ea33f247 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -64,6 +64,7 @@ public: allowed_arg_cols(1), arg_count(0) { with_sum_func= 0; + with_field= 0; } Item_func(Item *a): allowed_arg_cols(1), arg_count(1) @@ -71,6 +72,7 @@ public: args= tmp_arg; args[0]= a; with_sum_func= a->with_sum_func; + with_field= a->with_field; } Item_func(Item *a,Item *b): allowed_arg_cols(1), arg_count(2) @@ -78,6 +80,7 @@ public: args= tmp_arg; args[0]= a; args[1]= b; with_sum_func= a->with_sum_func || b->with_sum_func; + with_field= a->with_field || b->with_field; } Item_func(Item *a,Item *b,Item *c): allowed_arg_cols(1) @@ -88,6 +91,7 @@ public: arg_count= 3; args[0]= a; args[1]= b; args[2]= c; with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func; + with_field= a->with_field || b->with_field || c->with_field; } } Item_func(Item *a,Item *b,Item *c,Item *d): @@ -100,6 +104,8 @@ public: args[0]= a; args[1]= b; args[2]= c; args[3]= d; with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func || d->with_sum_func; + with_field= a->with_field || b->with_field || + c->with_field || d->with_field; } } Item_func(Item *a,Item *b,Item *c,Item *d,Item* e): @@ -111,6 +117,8 @@ public: args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e; with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func || d->with_sum_func || e->with_sum_func ; + with_field= a->with_field || b->with_field || + c->with_field || d->with_field || e->with_field; } } Item_func(List<Item> &list); |