mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
BUG#8804: wrong results for NULL IN (SELECT ...)
Evaluate "NULL IN (SELECT ...)" in a special way: Disable pushed-down
conditions and their "consequences":
= Do full table scans instead of unique_[index_subquery] lookups.
= Change appropriate "ref_or_null" accesses to full table scans in
subquery's joins.
Also cache value of NULL IN (SELECT ...) if the SELECT is not correlated
wrt any upper select.
mysql-test/r/subselect.result:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Updated test results
sql/item.h:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Added comments
sql/item_cmpfunc.cc:
BUG#8804: wrong results for NULL IN (SELECT ...):
Made Item_in_optimizer to:
- cache the value of "NULL IN (uncorrelated select)"
- Turn off pushed-down predicates when evaluating "NULL IN (SELECT ...)"
sql/item_cmpfunc.h:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Made Item_in_optimizer cache the value of "NULL IN (uncorrelated select)"
- Added comments
sql/item_subselect.cc:
BUG#8804: wrong results for NULL IN (SELECT ...):
- When needed, wrap the predicates we push into subquery into an
Item_func_trig_cond so we're able to turn them off when evaluating
NULL IN (SELECT ...).
- Added code to evaluate NULL IN (SELECT ...) in a special way:
= In [unique_]index_subquery, do full table scan to see if there
are any rows.
= For other subqueries, change ref[_or_null] to ALL if the
ref[_or_null] was created from pushed-down predicate.
sql/item_subselect.h:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Added Item_subselect::is_correlated
- Added comments
sql/records.cc:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Make rr_sequential() non-static
sql/sql_lex.cc:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Added st_select_lex::is_correlated and Item_subselect::is_correlated.
sql/sql_lex.h:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Added st_select_lex::is_correlated
sql/sql_select.cc:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Added KEY_FIELD::outer_ref to keep track of which ref accesses are
created from predicates that were pushed down into the subquery.
sql/sql_select.h:
BUG#8804: wrong results for NULL IN (SELECT ...):
- Added KEYUSE::outer_ref
mysql-test/r/subselect3.result:
New BitKeeper file ``mysql-test/r/subselect3.result''
mysql-test/t/subselect3.test:
New BitKeeper file ``mysql-test/t/subselect3.test''
This commit is contained in:
@@ -36,6 +36,8 @@ typedef struct keyuse_t {
|
||||
satisfied if val has NULL 'value'.
|
||||
*/
|
||||
bool null_rejecting;
|
||||
/* TRUE<=> This ref access is an outer subquery reference access */
|
||||
bool outer_ref;
|
||||
} KEYUSE;
|
||||
|
||||
class store_key;
|
||||
@@ -455,10 +457,11 @@ class store_key :public Sql_alloc
|
||||
Field *to_field; // Store data here
|
||||
char *null_ptr;
|
||||
char err;
|
||||
public:
|
||||
public:
|
||||
bool null_key; /* TRUE <=> the value of the key has a null part */
|
||||
enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
|
||||
store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length)
|
||||
:null_ptr(null),err(0)
|
||||
:null_ptr(null), err(0), null_key(0)
|
||||
{
|
||||
if (field_arg->type() == FIELD_TYPE_BLOB)
|
||||
{
|
||||
@@ -496,6 +499,7 @@ class store_key_field: public store_key
|
||||
enum store_key_result copy()
|
||||
{
|
||||
copy_field.do_copy(©_field);
|
||||
null_key= to_field->is_null();
|
||||
return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK;
|
||||
}
|
||||
const char *name() const { return field_name; }
|
||||
@@ -516,8 +520,8 @@ public:
|
||||
enum store_key_result copy()
|
||||
{
|
||||
int res= item->save_in_field(to_field, 1);
|
||||
null_key= to_field->is_null() || item->null_value;
|
||||
return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res);
|
||||
|
||||
}
|
||||
const char *name() const { return "func"; }
|
||||
};
|
||||
@@ -547,6 +551,7 @@ public:
|
||||
err= res;
|
||||
}
|
||||
}
|
||||
null_key= to_field->is_null() || item->null_value;
|
||||
return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err);
|
||||
}
|
||||
const char *name() const { return "const"; }
|
||||
|
||||
Reference in New Issue
Block a user