1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä
2019-06-13 18:36:09 +03:00
157 changed files with 3036 additions and 2605 deletions

View File

@ -5900,18 +5900,16 @@ add_key_field(JOIN *join,
(*key_fields)->level= and_level;
(*key_fields)->optimize= optimize;
/*
If the condition has form "tbl.keypart = othertbl.field" and
othertbl.field can be NULL, there will be no matches if othertbl.field
has NULL value.
We use null_rejecting in add_not_null_conds() to add
'othertbl.field IS NOT NULL' to tab->select_cond.
If the condition we are analyzing is NULL-rejecting and at least
one side of the equalities is NULLable, mark the KEY_FIELD object as
null-rejecting. This property is used by:
- add_not_null_conds() to add "column IS NOT NULL" conditions
- best_access_path() to produce better estimates for NULL-able unique keys.
*/
{
Item *real= (*value)->real_item();
if (((cond->functype() == Item_func::EQ_FUNC) ||
(cond->functype() == Item_func::MULT_EQUAL_FUNC)) &&
(real->type() == Item::FIELD_ITEM) &&
((Item_field*)real)->field->maybe_null())
if ((cond->functype() == Item_func::EQ_FUNC ||
cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
((*value)->maybe_null || field->real_maybe_null()))
(*key_fields)->null_rejecting= true;
else
(*key_fields)->null_rejecting= false;
@ -7235,6 +7233,7 @@ best_access_path(JOIN *join,
ulong key_flags;
uint key_parts;
key_part_map found_part= 0;
key_part_map notnull_part=0; // key parts which won't have NULL in lookup tuple.
table_map found_ref= 0;
uint key= keyuse->key;
filter= 0;
@ -7294,6 +7293,9 @@ best_access_path(JOIN *join,
if (!(keyuse->used_tables & ~join->const_table_map))
const_part|= keyuse->keypart_map;
if (!keyuse->val->maybe_null || keyuse->null_rejecting)
notnull_part|=keyuse->keypart_map;
double tmp2= prev_record_reads(join->positions, idx,
(found_ref | keyuse->used_tables));
if (tmp2 < best_prev_record_reads)
@ -7347,12 +7349,19 @@ best_access_path(JOIN *join,
loose_scan_opt.check_ref_access_part1(s, key, start_key, found_part);
/* Check if we found full key */
if (found_part == PREV_BITS(uint, key_parts) &&
!ref_or_null_part)
const key_part_map all_key_parts= PREV_BITS(uint, key_parts);
if (found_part == all_key_parts && !ref_or_null_part)
{ /* use eq key */
max_key_part= (uint) ~0;
if ((key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME ||
MY_TEST(key_flags & HA_EXT_NOSAME))
/*
If the index is a unique index (1), and
- all its columns are not null (2), or
- equalities we are using reject NULLs (3)
then the estimate is rows=1.
*/
if ((key_flags & (HA_NOSAME | HA_EXT_NOSAME)) && // (1)
(!(key_flags & HA_NULL_PART_KEY) || // (2)
all_key_parts == notnull_part)) // (3)
{
trace_access_idx.add("access_type", "eq_ref")
.add("index", keyinfo->name);
@ -10565,8 +10574,16 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
uint maybe_null= MY_TEST(keyinfo->key_part[i].null_bit);
j->ref.items[i]=keyuse->val; // Save for cond removal
j->ref.cond_guards[i]= keyuse->cond_guard;
if (keyuse->null_rejecting)
/*
Set ref.null_rejecting to true only if we are going to inject a
"keyuse->val IS NOT NULL" predicate.
*/
Item *real= (keyuse->val)->real_item();
if (keyuse->null_rejecting && (real->type() == Item::FIELD_ITEM) &&
((Item_field*)real)->field->maybe_null())
j->ref.null_rejecting|= (key_part_map)1 << i;
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
/*
We don't want to compute heavy expressions in EXPLAIN, an example would
@ -21163,7 +21180,6 @@ join_read_first(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record_func= join_read_next;
tab->read_record.table=table;
tab->read_record.record=table->record[0];
if (!table->file->inited)
error= table->file->ha_index_init(tab->index, tab->sorted);
if (likely(!error))
@ -21183,7 +21199,7 @@ static int
join_read_next(READ_RECORD *info)
{
int error;
if (unlikely((error= info->table->file->ha_index_next(info->record))))
if (unlikely((error= info->table->file->ha_index_next(info->record()))))
return report_error(info->table, error);
return 0;
@ -21203,7 +21219,6 @@ join_read_last(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record_func= join_read_prev;
tab->read_record.table=table;
tab->read_record.record=table->record[0];
if (!table->file->inited)
error= table->file->ha_index_init(tab->index, 1);
if (likely(!error))
@ -21220,7 +21235,7 @@ static int
join_read_prev(READ_RECORD *info)
{
int error;
if (unlikely((error= info->table->file->ha_index_prev(info->record))))
if (unlikely((error= info->table->file->ha_index_prev(info->record()))))
return report_error(info->table, error);
return 0;
}
@ -21250,7 +21265,7 @@ static int
join_ft_read_next(READ_RECORD *info)
{
int error;
if (unlikely((error= info->table->file->ha_ft_read(info->table->record[0]))))
if (unlikely((error= info->table->file->ha_ft_read(info->record()))))
return report_error(info->table, error);
return 0;
}
@ -26505,6 +26520,7 @@ int JOIN::save_explain_data_intern(Explain_query *output,
xpl_sel->exec_const_cond= exec_const_cond;
xpl_sel->outer_ref_cond= outer_ref_cond;
xpl_sel->pseudo_bits_cond= pseudo_bits_cond;
if (tmp_having)
xpl_sel->having= tmp_having;
else