summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorholyfoot/hf@deer.(none) <>2006-11-08 19:09:39 +0400
committerholyfoot/hf@deer.(none) <>2006-11-08 19:09:39 +0400
commit938ba3e11e5572437229427e9568660246b12de3 (patch)
tree533737794921f247b2bb1a19b363f96a1c6b22c6 /sql/item_cmpfunc.cc
parentd947f1c84722b5ddfe9d0dcfe204b6bd30ba6d4e (diff)
parent4a00e76e7a5ce62d36d8690eafc5854620453c3c (diff)
downloadmariadb-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.cc34
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();