mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge
This commit is contained in:
@@ -3764,28 +3764,28 @@ add_key_field(JOIN *join,
|
||||
|
||||
static void
|
||||
add_key_equal_fields(JOIN *join, KEY_FIELD **key_fields, uint and_level,
|
||||
Item_func *cond, Item_field *field_item,
|
||||
Item_func *cond, Item *field_item,
|
||||
bool eq_func, Item **val,
|
||||
uint num_values, table_map usable_tables,
|
||||
SARGABLE_PARAM **sargables)
|
||||
{
|
||||
Field *field= field_item->field;
|
||||
Field *field= ((Item_field *) (field_item->real_item()))->field;
|
||||
add_key_field(join, key_fields, and_level, cond, field,
|
||||
eq_func, val, num_values, usable_tables, sargables);
|
||||
Item_equal *item_equal= field_item->item_equal;
|
||||
Item_equal *item_equal= field_item->get_item_equal();
|
||||
if (item_equal)
|
||||
{
|
||||
/*
|
||||
Add to the set of possible key values every substitution of
|
||||
the field for an equal field included into item_equal
|
||||
*/
|
||||
Item_equal_iterator it(*item_equal);
|
||||
Item_field *item;
|
||||
while ((item= it++))
|
||||
Item_equal_fields_iterator it(*item_equal);
|
||||
while (it++)
|
||||
{
|
||||
if (!field->eq(item->field))
|
||||
Field *equal_field= it.get_curr_field();
|
||||
if (!field->eq(equal_field))
|
||||
{
|
||||
add_key_field(join, key_fields, and_level, cond, item->field,
|
||||
add_key_field(join, key_fields, and_level, cond, equal_field,
|
||||
eq_func, val, num_values, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
@@ -3982,8 +3982,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
case Item_func::OPTIMIZE_EQUAL:
|
||||
Item_equal *item_equal= (Item_equal *) cond;
|
||||
Item *const_item= item_equal->get_const();
|
||||
Item_equal_iterator it(*item_equal);
|
||||
Item_field *item;
|
||||
Item_equal_fields_iterator it(*item_equal);
|
||||
if (const_item)
|
||||
{
|
||||
/*
|
||||
@@ -3991,9 +3990,10 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
field1=const_item as a condition allowing an index access of the table
|
||||
with field1 by the keys value of field1.
|
||||
*/
|
||||
while ((item= it++))
|
||||
while (it++)
|
||||
{
|
||||
add_key_field(join, key_fields, *and_level, cond_func, item->field,
|
||||
Field *equal_field= it.get_curr_field();
|
||||
add_key_field(join, key_fields, *and_level, cond_func, equal_field,
|
||||
TRUE, &const_item, 1, usable_tables, sargables);
|
||||
}
|
||||
}
|
||||
@@ -4005,17 +4005,18 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
field1=field2 as a condition allowing an index access of the table
|
||||
with field1 by the keys value of field2.
|
||||
*/
|
||||
Item_equal_iterator fi(*item_equal);
|
||||
while ((item= fi++))
|
||||
Item_equal_fields_iterator fi(*item_equal);
|
||||
while (fi++)
|
||||
{
|
||||
Field *field= item->field;
|
||||
Field *field= fi.get_curr_field();
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
{
|
||||
if (!field->eq(item->field))
|
||||
Field *equal_field= it.get_curr_field();
|
||||
if (!field->eq(equal_field))
|
||||
{
|
||||
Item *tmp_item= item;
|
||||
add_key_field(join, key_fields, *and_level, cond_func, field,
|
||||
TRUE, &tmp_item, 1, usable_tables,
|
||||
TRUE, &item, 1, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
}
|
||||
@@ -9291,6 +9292,8 @@ finish:
|
||||
static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
Item *item, COND_EQUAL *cond_equal)
|
||||
{
|
||||
Item *orig_left_item= left_item;
|
||||
Item *orig_right_item= right_item;
|
||||
if (left_item->type() == Item::REF_ITEM &&
|
||||
((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
|
||||
{
|
||||
@@ -9357,7 +9360,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
{
|
||||
/* left item was found in the current or one of the upper levels */
|
||||
if (! right_item_equal)
|
||||
left_item_equal->add((Item_field *) right_item);
|
||||
left_item_equal->add(orig_right_item);
|
||||
else
|
||||
{
|
||||
/* Merge two multiple equalities forming a new one */
|
||||
@@ -9372,12 +9375,13 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
{
|
||||
/* left item was not found neither the current nor in upper levels */
|
||||
if (right_item_equal)
|
||||
right_item_equal->add((Item_field *) left_item);
|
||||
right_item_equal->add(orig_left_item);
|
||||
else
|
||||
{
|
||||
/* None of the fields was found in multiple equalities */
|
||||
Item_equal *item_equal= new Item_equal((Item_field *) left_item,
|
||||
(Item_field *) right_item);
|
||||
Item_equal *item_equal= new Item_equal(orig_left_item,
|
||||
orig_right_item,
|
||||
FALSE);
|
||||
cond_equal->current_level.push_back(item_equal);
|
||||
}
|
||||
}
|
||||
@@ -9388,18 +9392,21 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
/* The predicate of the form field=const/const=field is processed */
|
||||
Item *const_item= 0;
|
||||
Item_field *field_item= 0;
|
||||
Item *orig_field_item= 0;
|
||||
if (left_item->type() == Item::FIELD_ITEM &&
|
||||
!((Item_field*)left_item)->depended_from &&
|
||||
right_item->const_item())
|
||||
{
|
||||
field_item= (Item_field*) left_item;
|
||||
orig_field_item= left_item;
|
||||
field_item= (Item_field *) left_item;
|
||||
const_item= right_item;
|
||||
}
|
||||
else if (right_item->type() == Item::FIELD_ITEM &&
|
||||
!((Item_field*)right_item)->depended_from &&
|
||||
left_item->const_item())
|
||||
{
|
||||
field_item= (Item_field*) right_item;
|
||||
orig_field_item= right_item;
|
||||
field_item= (Item_field *) right_item;
|
||||
const_item= left_item;
|
||||
}
|
||||
|
||||
@@ -9414,7 +9421,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
if (!item)
|
||||
{
|
||||
Item_func_eq *eq_item;
|
||||
if ((eq_item= new Item_func_eq(left_item, right_item)))
|
||||
if ((eq_item= new Item_func_eq(orig_left_item, orig_right_item)))
|
||||
return FALSE;
|
||||
eq_item->set_cmp_func();
|
||||
eq_item->quick_fix_field();
|
||||
@@ -9439,11 +9446,11 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||
already contains a constant and its value is not equal to
|
||||
the value of const_item.
|
||||
*/
|
||||
item_equal->add(const_item, field_item);
|
||||
item_equal->add_const(const_item, orig_field_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
item_equal= new Item_equal(const_item, field_item);
|
||||
item_equal= new Item_equal(const_item, orig_field_item, TRUE);
|
||||
cond_equal->current_level.push_back(item_equal);
|
||||
}
|
||||
return TRUE;
|
||||
@@ -9688,7 +9695,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
item_equal->fix_fields(thd, NULL);
|
||||
item_equal->update_used_tables();
|
||||
set_if_bigger(thd->lex->current_select->max_equal_elems,
|
||||
item_equal->members());
|
||||
item_equal->n_field_items());
|
||||
}
|
||||
|
||||
((Item_cond_and*)cond)->cond_equal= cond_equal;
|
||||
@@ -9719,7 +9726,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
args->concat((List<Item> *)&cond_equal.current_level);
|
||||
}
|
||||
}
|
||||
else if (cond->type() == Item::FUNC_ITEM)
|
||||
else if (cond->type() == Item::FUNC_ITEM ||
|
||||
cond->real_item()->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
List<Item> eq_list;
|
||||
/*
|
||||
@@ -9741,10 +9749,10 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
{
|
||||
if ((item_equal= cond_equal.current_level.pop()))
|
||||
{
|
||||
item_equal->fix_length_and_dec();
|
||||
item_equal->fix_fields(thd, NULL);
|
||||
item_equal->update_used_tables();
|
||||
set_if_bigger(thd->lex->current_select->max_equal_elems,
|
||||
item_equal->members());
|
||||
item_equal->n_field_items());
|
||||
return item_equal;
|
||||
}
|
||||
|
||||
@@ -9765,7 +9773,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
item_equal->fix_length_and_dec();
|
||||
item_equal->update_used_tables();
|
||||
set_if_bigger(thd->lex->current_select->max_equal_elems,
|
||||
item_equal->members());
|
||||
item_equal->n_field_items());
|
||||
}
|
||||
and_cond->cond_equal= cond_equal;
|
||||
args->concat((List<Item> *)&cond_equal.current_level);
|
||||
@@ -9779,9 +9787,10 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
as soon the field is not of a string type or the field reference is
|
||||
an argument of a comparison predicate.
|
||||
*/
|
||||
uchar *is_subst_valid= (uchar *) 1;
|
||||
uchar is_subst_valid= (uchar) 1;
|
||||
uchar *is_subst_valid_ptr= &is_subst_valid;
|
||||
cond= cond->compile(&Item::subst_argument_checker,
|
||||
&is_subst_valid,
|
||||
&is_subst_valid_ptr,
|
||||
&Item::equal_fields_propagator,
|
||||
(uchar *) inherited);
|
||||
cond->update_used_tables();
|
||||
@@ -9935,18 +9944,24 @@ static COND *build_equal_items(THD *thd, COND *cond,
|
||||
0 otherwise
|
||||
*/
|
||||
|
||||
static int compare_fields_by_table_order(Item_field *field1,
|
||||
Item_field *field2,
|
||||
static int compare_fields_by_table_order(Item *field1,
|
||||
Item *field2,
|
||||
void *table_join_idx)
|
||||
{
|
||||
int cmp= 0;
|
||||
bool outer_ref= 0;
|
||||
if (field2->used_tables() & OUTER_REF_TABLE_BIT)
|
||||
Item_field *f1= (Item_field *) (field1->real_item());
|
||||
Item_field *f2= (Item_field *) (field2->real_item());
|
||||
if (f1->const_item())
|
||||
return 1;
|
||||
if (f2->const_item())
|
||||
return -1;
|
||||
if (f2->used_tables() & OUTER_REF_TABLE_BIT)
|
||||
{
|
||||
outer_ref= 1;
|
||||
cmp= -1;
|
||||
}
|
||||
if (field1->used_tables() & OUTER_REF_TABLE_BIT)
|
||||
if (f1->used_tables() & OUTER_REF_TABLE_BIT)
|
||||
{
|
||||
outer_ref= 1;
|
||||
cmp++;
|
||||
@@ -9954,10 +9969,10 @@ static int compare_fields_by_table_order(Item_field *field1,
|
||||
if (outer_ref)
|
||||
return cmp;
|
||||
JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
|
||||
cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
|
||||
cmp= idx[f2->field->table->tablenr]-idx[f1->field->table->tablenr];
|
||||
if (!cmp)
|
||||
{
|
||||
JOIN_TAB *tab= idx[field1->field->table->tablenr];
|
||||
JOIN_TAB *tab= idx[f1->field->table->tablenr];
|
||||
uint keyno= MAX_KEY;
|
||||
if (tab->ref.key_parts)
|
||||
keyno= tab->ref.key;
|
||||
@@ -9965,9 +9980,9 @@ static int compare_fields_by_table_order(Item_field *field1,
|
||||
keyno = tab->select->quick->index;
|
||||
if (keyno != MAX_KEY)
|
||||
{
|
||||
if (field2->field->part_of_key.is_set(keyno))
|
||||
if (f2->field->part_of_key.is_set(keyno))
|
||||
cmp= -1;
|
||||
if (field1->field->part_of_key.is_set(keyno))
|
||||
if (f1->field->part_of_key.is_set(keyno))
|
||||
cmp++;
|
||||
if (!cmp)
|
||||
{
|
||||
@@ -9975,12 +9990,12 @@ static int compare_fields_by_table_order(Item_field *field1,
|
||||
for (uint i= 0; i < key_info->key_parts; i++)
|
||||
{
|
||||
Field *fld= key_info->key_part[i].field;
|
||||
if (fld->eq(field2->field))
|
||||
if (fld->eq(f2->field))
|
||||
{
|
||||
cmp= -1;
|
||||
break;
|
||||
}
|
||||
if (fld->eq(field1->field))
|
||||
if (fld->eq(f1->field))
|
||||
{
|
||||
cmp= 1;
|
||||
break;
|
||||
@@ -9989,14 +10004,15 @@ static int compare_fields_by_table_order(Item_field *field1,
|
||||
}
|
||||
}
|
||||
else
|
||||
cmp= field2->field->field_index-field1->field->field_index;
|
||||
cmp= f2->field->field_index-f1->field->field_index;
|
||||
}
|
||||
return cmp < 0 ? -1 : (cmp ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
static TABLE_LIST* embedding_sjm(Item_field *item_field)
|
||||
static TABLE_LIST* embedding_sjm(Item *item)
|
||||
{
|
||||
Item_field *item_field= (Item_field *) (item->real_item());
|
||||
TABLE_LIST *nest= item_field->field->table->pos_in_table_list->embedding;
|
||||
if (nest && nest->sj_mat_info && nest->sj_mat_info->is_used)
|
||||
return nest;
|
||||
@@ -10069,7 +10085,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
|
||||
if (((Item *) item_equal)->const_item() && !item_equal->val_int())
|
||||
return new Item_int((longlong) 0,1);
|
||||
Item *item_const= item_equal->get_const();
|
||||
Item_equal_iterator it(*item_equal);
|
||||
Item_equal_fields_iterator it(*item_equal);
|
||||
Item *head;
|
||||
DBUG_ASSERT(!cond || cond->type() == Item::COND_ITEM);
|
||||
|
||||
@@ -10085,27 +10101,26 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
|
||||
else
|
||||
{
|
||||
TABLE_LIST *emb_nest;
|
||||
Item_field *item_field;
|
||||
head= item_field= item_equal->get_first(NULL);
|
||||
head= item_equal->get_first(NULL);
|
||||
it++;
|
||||
if ((emb_nest= embedding_sjm(item_field)))
|
||||
if ((emb_nest= embedding_sjm(head)))
|
||||
{
|
||||
current_sjm= emb_nest;
|
||||
current_sjm_head= head;
|
||||
}
|
||||
}
|
||||
|
||||
Item_field *item_field;
|
||||
Item *field_item;
|
||||
/*
|
||||
For each other item, generate "item=head" equality (except the tables that
|
||||
are within SJ-Materialization nests, for those "head" is defined
|
||||
differently)
|
||||
*/
|
||||
while ((item_field= it++))
|
||||
while ((field_item= it++))
|
||||
{
|
||||
Item_equal *upper= item_field->find_item_equal(upper_levels);
|
||||
Item_field *item= item_field;
|
||||
TABLE_LIST *field_sjm= embedding_sjm(item_field);
|
||||
Item_equal *upper= field_item->find_item_equal(upper_levels);
|
||||
Item *item= field_item;
|
||||
TABLE_LIST *field_sjm= embedding_sjm(field_item);
|
||||
if (!field_sjm)
|
||||
{
|
||||
current_sjm= NULL;
|
||||
@@ -10122,8 +10137,8 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
|
||||
item= 0;
|
||||
else
|
||||
{
|
||||
Item_equal_iterator li(*item_equal);
|
||||
while ((item= li++) != item_field)
|
||||
Item_equal_fields_iterator li(*item_equal);
|
||||
while ((item= li++) != field_item)
|
||||
{
|
||||
if (item->find_item_equal(upper_levels) == upper)
|
||||
break;
|
||||
@@ -10131,11 +10146,11 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
|
||||
}
|
||||
}
|
||||
|
||||
bool produce_equality= test(item == item_field);
|
||||
bool produce_equality= test(item == field_item);
|
||||
if (!item_const && field_sjm && field_sjm != current_sjm)
|
||||
{
|
||||
/* Entering an SJM nest */
|
||||
current_sjm_head= item_field;
|
||||
current_sjm_head= field_item;
|
||||
if (!field_sjm->sj_mat_info->is_sj_scan)
|
||||
produce_equality= FALSE;
|
||||
}
|
||||
@@ -10144,8 +10159,13 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
|
||||
{
|
||||
if (eq_item)
|
||||
eq_list.push_back(eq_item);
|
||||
|
||||
Item *head_item= current_sjm? current_sjm_head: head;
|
||||
Item *head_real_item= head_item->real_item();
|
||||
if (head_real_item->type() == Item::FIELD_ITEM)
|
||||
head_item= head_real_item;
|
||||
|
||||
eq_item= new Item_func_eq(item_field, current_sjm? current_sjm_head: head);
|
||||
eq_item= new Item_func_eq(field_item->real_item(), head_item);
|
||||
|
||||
if (!eq_item)
|
||||
return 0;
|
||||
@@ -10330,11 +10350,10 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
|
||||
if (!contained_const && item_equal->get_const())
|
||||
{
|
||||
/* Update keys for range analysis */
|
||||
Item_equal_iterator it(*item_equal);
|
||||
Item_field *item_field;
|
||||
while ((item_field= it++))
|
||||
Item_equal_fields_iterator it(*item_equal);
|
||||
while (it++)
|
||||
{
|
||||
Field *field= item_field->field;
|
||||
Field *field= it.get_curr_field();
|
||||
JOIN_TAB *stat= field->table->reginfo.join_tab;
|
||||
key_map possible_keys= field->key_start;
|
||||
possible_keys.intersect(field->table->keys_in_use_for_query);
|
||||
|
Reference in New Issue
Block a user