diff options
author | kostja@bodhi.local <> | 2006-11-29 02:44:12 +0300 |
---|---|---|
committer | kostja@bodhi.local <> | 2006-11-29 02:44:12 +0300 |
commit | 5fea0724bc46684390cfd9311dc8f854ece2bc9b (patch) | |
tree | f9f728e4fd94cdcf8bc3f5ea8270ee291aa94890 /sql/item_cmpfunc.cc | |
parent | ea47e05f3cc5929eb1f56cfdc094cedfce318499 (diff) | |
parent | 3406fcea39defef5d5cd92f99fa4e60d556f3dae (diff) | |
download | mariadb-git-5fea0724bc46684390cfd9311dc8f854ece2bc9b.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into bodhi.local:/opt/local/work/mysql-5.0-runtime
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 70a8622af85..29fa049b6c4 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -786,9 +786,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(); @@ -2196,7 +2228,7 @@ cmp_item* cmp_item_row::make_same() cmp_item_row::~cmp_item_row() { DBUG_ENTER("~cmp_item_row"); - DBUG_PRINT("enter",("this: 0x%lx", this)); + DBUG_PRINT("enter",("this: 0x%lx", (long) this)); if (comparators) { for (uint i= 0; i < n; i++) @@ -2970,7 +3002,7 @@ longlong Item_is_not_null_test::val_int() if (!used_tables_cache) { owner->was_null|= (!cached_value); - DBUG_PRINT("info", ("cached :%d", cached_value)); + DBUG_PRINT("info", ("cached :%ld", (long) cached_value)); DBUG_RETURN(cached_value); } if (args[0]->is_null()) |