diff options
author | holyfoot/hf@deer.(none) <> | 2006-11-08 19:09:39 +0400 |
---|---|---|
committer | holyfoot/hf@deer.(none) <> | 2006-11-08 19:09:39 +0400 |
commit | 938ba3e11e5572437229427e9568660246b12de3 (patch) | |
tree | 533737794921f247b2bb1a19b363f96a1c6b22c6 /sql/item_cmpfunc.cc | |
parent | d947f1c84722b5ddfe9d0dcfe204b6bd30ba6d4e (diff) | |
parent | 4a00e76e7a5ce62d36d8690eafc5854620453c3c (diff) | |
download | mariadb-git-938ba3e11e5572437229427e9568660246b12de3.tar.gz |
Merge mysql.com:/home/hf/work/mysql-5.0.clean
into mysql.com:/home/hf/work/mysql-5.1.clean
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 9435b3767a0..f993ca8eddf 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -830,9 +830,41 @@ longlong Item_in_optimizer::val_int() { DBUG_ASSERT(fixed == 1); cache->store(args[0]); + if (cache->null_value) { - null_value= 1; + if (((Item_in_subselect*)args[1])->is_top_level_item()) + { + /* + We're evaluating "NULL IN (SELECT ...)". The result can be NULL or + FALSE, and we can return one instead of another. Just return NULL. + */ + null_value= 1; + } + else + { + if (!((Item_in_subselect*)args[1])->is_correlated && + result_for_null_param != UNKNOWN) + { + /* Use cached value from previous execution */ + null_value= result_for_null_param; + } + else + { + /* + We're evaluating "NULL IN (SELECT ...)". The result is: + FALSE if SELECT produces an empty set, or + NULL otherwise. + We disable the predicates we've pushed down into subselect, run the + subselect and see if it has produced any rows. + */ + ((Item_in_subselect*)args[1])->enable_pushed_conds= FALSE; + longlong tmp= args[1]->val_bool_result(); + result_for_null_param= null_value= + !((Item_in_subselect*)args[1])->engine->no_rows(); + ((Item_in_subselect*)args[1])->enable_pushed_conds= TRUE; + } + } return 0; } bool tmp= args[1]->val_bool_result(); |