summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
authorunknown <sanja@askmonty.org>2011-09-02 10:11:13 +0300
committerunknown <sanja@askmonty.org>2011-09-02 10:11:13 +0300
commit37a8497d494ea256ff4b13a89e62150e06a17dae (patch)
tree608813a49f5688186b2ae0dac4472c00829b11a3 /sql/sql_class.cc
parent31c8c95bb204e74431412d07970a8133a352984f (diff)
downloadmariadb-git-37a8497d494ea256ff4b13a89e62150e06a17dae.tar.gz
LP BUG#823169 fix.
For ANY subqueries NULLs should be ignored (if there is other values) when finding max min. For ALL subqueries NULLs should be saved if they found. Optimisation for ALL suqbueries if NULL is possible in the SELECT list with max/min aggregate function switched off. Some test changed where NULL is not used but optimization with max/min aggregate function important so NOT NULL added. mysql-test/r/explain.result: Forced old optimization. mysql-test/r/subselect.result: Forced old optimization. New test suite. mysql-test/t/explain.test: Forced old optimization. mysql-test/t/subselect.test: Forced old optimization. New test suite. sql/item_subselect.cc: Store converted subquery type. Switch off aggregate function optimisation for ALL and nulls. sql/sql_class.cc: Fixed NULL comparison. sql/sql_class.h: Store converted subquery type.
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc60
1 files changed, 36 insertions, 24 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index cf800384b17..0b6a3ebf85e 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2580,26 +2580,32 @@ bool select_max_min_finder_subselect::cmp_real()
{
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
double val1= cache->val_real(), val2= maxmin->val_real();
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 > val2);
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 < val2);
+ return(val1 > val2);
+ return (val1 < val2);
}
bool select_max_min_finder_subselect::cmp_int()
{
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
longlong val1= cache->val_int(), val2= maxmin->val_int();
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 > val2);
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 < val2);
+ return(val1 > val2);
+ return (val1 < val2);
}
bool select_max_min_finder_subselect::cmp_decimal()
@@ -2607,13 +2613,16 @@ bool select_max_min_finder_subselect::cmp_decimal()
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
my_decimal cval, *cvalue= cache->val_decimal(&cval);
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- my_decimal_cmp(cvalue, mvalue) > 0) ;
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- my_decimal_cmp(cvalue,mvalue) < 0);
+ return (my_decimal_cmp(cvalue, mvalue) > 0) ;
+ return (my_decimal_cmp(cvalue,mvalue) < 0);
}
bool select_max_min_finder_subselect::cmp_str()
@@ -2626,13 +2635,16 @@ bool select_max_min_finder_subselect::cmp_str()
*/
val1= cache->val_str(&buf1);
val2= maxmin->val_str(&buf1);
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- sortcmp(val1, val2, cache->collation.collation) > 0) ;
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- sortcmp(val1, val2, cache->collation.collation) < 0);
+ return (sortcmp(val1, val2, cache->collation.collation) > 0) ;
+ return (sortcmp(val1, val2, cache->collation.collation) < 0);
}
int select_exists_subselect::send_data(List<Item> &items)