1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Merge branch '11.2' into 11.4

This commit is contained in:
Oleksandr Byelkin
2024-10-30 09:24:04 +01:00
734 changed files with 10187 additions and 4442 deletions

View File

@@ -3309,7 +3309,7 @@ int JOIN::optimize_stage2()
having->update_used_tables();
if (having->const_item() && !having->is_expensive())
{
if (!having->val_int())
if (!having->val_bool())
{
having= Item_false;
zero_result_cause= "Impossible HAVING noticed after reading const tables";
@@ -3742,7 +3742,9 @@ bool JOIN::make_aggr_tables_info()
original DISTINCT. Thus, we set select_distinct || group_optimized_away
to Query::distinct.
*/
Query query= {&all_fields, select_distinct || group_optimized_away,
Query query= {&all_fields,
(int) all_fields.elements - (int) fields_list.elements,
select_distinct || group_optimized_away,
tables_list, conds,
group_list, order ? order : group_list, having,
&select_lex->master_unit()->lim};
@@ -4905,8 +4907,8 @@ int JOIN::exec_inner()
DBUG_ASSERT(error == 0);
if (cond_value != Item::COND_FALSE &&
having_value != Item::COND_FALSE &&
(!conds || conds->val_int()) &&
(!having || having->val_int()))
(!conds || conds->val_bool()) &&
(!having || having->val_bool()))
{
if (do_send_rows &&
(procedure ? (procedure->send_row(procedure_fields_list) ||
@@ -4938,11 +4940,11 @@ int JOIN::exec_inner()
*/
if (!zero_result_cause &&
exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
!exec_const_cond->val_int())
!exec_const_cond->val_bool())
zero_result_cause= "Impossible WHERE noticed after reading const tables";
/*
We've called exec_const_cond->val_int(). This may have caused an error.
We've called exec_const_cond->val_bool(). This may have caused an error.
*/
if (unlikely(thd->is_error()))
{
@@ -7255,8 +7257,14 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
{
if (!(form->keys_in_use_for_query.is_set(key)))
continue;
if (form->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
if (form->key_info[key].flags & (HA_FULLTEXT|HA_SPATIAL|HA_UNIQUE_HASH))
{
/*
HA_UNIQUE_HASH indexes are excluded since they cannot be used
for lookups. See Create_tmp_field::finalize() for details
*/
continue; // ToDo: ft-keys in non-ft queries. SerG
}
KEY *keyinfo= form->key_info+key;
uint key_parts= form->actual_n_key_parts(keyinfo);
@@ -8825,7 +8833,7 @@ best_access_path(JOIN *join,
loose_scan_opt.check_ref_access_part1(s, key, start_key, found_part);
/* Check if we found full key */
const key_part_map all_key_parts= PREV_BITS(uint, key_parts);
const key_part_map all_key_parts= PREV_BITS(key_part_map, key_parts);
if (found_part == all_key_parts && !ref_or_null_part)
{ /* use eq key */
max_key_part= (uint) ~0;
@@ -8975,7 +8983,8 @@ best_access_path(JOIN *join,
*/
if ((found_part & 1) &&
(!(table->key_info[key].index_flags & HA_ONLY_WHOLE_INDEX) ||
found_part == PREV_BITS(uint,keyinfo->user_defined_key_parts)))
found_part == PREV_BITS(key_part_map,
keyinfo->user_defined_key_parts)))
{
double extra_cost= 0;
@@ -10129,8 +10138,18 @@ choose_plan(JOIN *join, table_map join_tables, TABLE_LIST *emb_sjm_nest)
double limit_record_count;
POSITION *limit_plan= NULL;
/* First, build a join plan that can short-cut ORDER BY...LIMIT */
if (join->limit_shortcut_applicable && !join->emb_sjm_nest)
/*
First, build a join plan that can short-cut ORDER BY...LIMIT.
Do it if
(1) The SELECT in query makes it possible to do short-cutting for
some table TBL.
(2) We are optimizing the whole JOIN, not a semi-join nest
(3) The table TBL has not been marked as constant (in this case,
ORDER BY LIMIT will be optimized away)
*/
if (join->limit_shortcut_applicable && // (1)
!join->emb_sjm_nest && // (2)
!(join->sort_by_table->map & join->const_table_map)) //(3)
{
bool res;
Json_writer_object wrapper(join->thd);
@@ -11624,6 +11643,12 @@ double recompute_join_cost_with_limit(const JOIN *join, bool skip_sorting,
POSITION *pos= join->best_positions + join->const_tables;
/*
Generally, we assume that producing X% of output takes X% of the cost.
best_extension_by_limited_search() subtracts COST_EPS from
join->best_read, add it back.
(Note: before 11.0, we subtracted COST_EPS here. In 11.0+, there's no need
to do this)
*/
double partial_join_cost= join->best_read * fraction;
@@ -11644,10 +11669,12 @@ double recompute_join_cost_with_limit(const JOIN *join, bool skip_sorting,
{
/*
Subtract the remainder of the first table's cost we had in
join->best_read:
join->best_read.
(Before 11.0, we also subtracted pos->records_read/TIME_FOR_COMPARE.
In 11.0+, that time is already included in pos->read_time)
*/
partial_join_cost -= pos->read_time*fraction;
partial_join_cost -= pos->records_read*fraction * WHERE_COST_THD(join->thd);
DBUG_ASSERT(partial_join_cost >= 0.0);
/* Add the cost of the new access method we've got: */
partial_join_cost= COST_ADD(partial_join_cost, *first_table_cost);
@@ -11664,12 +11691,7 @@ double recompute_join_cost_with_limit(const JOIN *join, bool skip_sorting,
table. Do the same for costs of checking the WHERE.
*/
double extra_first_table_cost= pos->read_time * (1.0 - fraction);
double extra_first_table_where= pos->records_read * (1.0 - fraction) *
WHERE_COST_THD(join->thd);
partial_join_cost= COST_ADD(partial_join_cost,
COST_ADD(extra_first_table_cost,
extra_first_table_where));
partial_join_cost= COST_ADD(partial_join_cost, extra_first_table_cost);
}
return partial_join_cost;
}
@@ -14184,7 +14206,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
bool const_cond_result;
{
Json_writer_array a(thd, "computing_condition");
const_cond_result= const_cond->val_int() != 0;
const_cond_result= const_cond->val_bool() != 0;
}
if (!const_cond_result)
{
@@ -14293,11 +14315,41 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
used_tables|=current_map;
if ((tab->type == JT_REF || tab->type == JT_RANGE) && tab->quick &&
/*
Change from using ref access to using quick select on the same index
if the quick select uses more key parts.
There are two cases.
A. ref access is ref(const). quick select was also constructed using
equality restrictions that ref used, and so it will scan a subset of
rows that ref access scans.
Example: suppose the index is INDEX(kp1, kp2) and the WHERE has:
kp1='foo' and kp2 <= 10
here, ref access will use kp1='foo' and quick select will use
(foo) <= (kp1,kp2) <=(foo,10)
B. ref access is not constant. In this case, quick select was
constructed from some other restriction and in general will scan
totally different set of rows (it maybe larger or smaller).
Example: for INDEX(kp1, kp2) and the WHERE:
kp1 <='foo' and kp1=prev_table.col and kp2 <= 10
the ref access will use kp1=prev_table.col, while quick select will
use (-inf) < (kp1, kp2) <= ('foo',10).
Because of the above, we perform the rewrite ONLY when ref is
ref(const).
*/
if (tab->type == JT_REF && tab->quick &&
(((uint) tab->ref.key == tab->quick->index &&
tab->ref.key_length < tab->quick->max_used_key_length) ||
(!is_hash_join_key_no(tab->ref.key) &&
tab->table->intersect_keys.is_set(tab->ref.key))))
tab->table->intersect_keys.is_set(tab->ref.key))) &&
tab->ref.const_ref_part_map == // (ref-is-const)
make_prev_keypart_map(tab->ref.key_parts)) // (ref-is-const)
{
/* Range uses longer key; Use this instead of ref on key */
if (unlikely(thd->trace_started()))
@@ -17508,7 +17560,7 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> *tables,
join->no_rows_in_result_called= 1;
while ((item= it++))
item->no_rows_in_result();
if (having && having->val_int() == 0)
if (having && having->val_bool() == false)
send_row=0;
}
@@ -18734,7 +18786,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
{
List<Item> eq_list;
Item_func_eq *eq_item= 0;
if (((Item *) item_equal)->const_item() && !item_equal->val_int())
if (((Item *) item_equal)->const_item() && !item_equal->val_bool())
return (Item*) Item_false;
Item *item_const= item_equal->get_const();
Item_equal_fields_iterator it(*item_equal);
@@ -18803,7 +18855,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
Item_func_eq *func= new (thd->mem_root) Item_func_eq(thd, item_const, upper_const);
func->set_cmp_func(thd);
func->quick_fix_field();
if (func->val_int())
if (func->val_bool())
item= 0;
}
else
@@ -18853,6 +18905,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
return 0;
eq_item->eval_not_null_tables(0);
eq_item->quick_fix_field();
eq_item->base_flags|= item_base_t::IS_COND;
}
current_sjm= field_sjm;
}
@@ -20405,7 +20458,7 @@ void propagate_new_equalities(THD *thd, Item *cond,
List_iterator<Item_equal> ei(*cond_equalities);
while ((equal_item= ei++))
{
if (equal_item->const_item() && !equal_item->val_int())
if (equal_item->const_item() && !equal_item->val_bool())
{
*is_simplifiable_cond= true;
return;
@@ -20436,7 +20489,7 @@ void propagate_new_equalities(THD *thd, Item *cond,
{
equality->merge_with_check(thd, equal_item, true);
}
if (equality->const_item() && !equality->val_int())
if (equality->const_item() && !equality->val_bool())
*is_simplifiable_cond= true;
}
else
@@ -20601,7 +20654,7 @@ Item_cond::remove_eq_conds(THD *thd, Item::cond_result *cond_value,
Item_equal *eq_item;
while ((eq_item= it++))
{
if (eq_item->const_item() && eq_item->val_int())
if (eq_item->const_item() && eq_item->val_bool())
it.remove();
}
cond_arg_list->append((List<Item> *) cond_equalities);
@@ -20748,7 +20801,7 @@ Item_cond::remove_eq_conds(THD *thd, Item::cond_result *cond_value,
List_iterator_fast<Item_equal> ei(*cond_equalities);
while ((equality= ei++))
{
if (equality->const_item() && !equality->val_int())
if (equality->const_item() && !equality->val_bool())
{
*cond_value= Item::COND_FALSE;
return (COND*) 0;
@@ -21703,6 +21756,7 @@ TABLE *Create_tmp_table::start(THD *thd,
table->copy_blobs= 1;
table->in_use= thd;
table->no_rows_with_nulls= param->force_not_null_cols;
table->group_concat= param->group_concat;
table->expr_arena= thd;
table->s= share;
@@ -23482,7 +23536,7 @@ do_select(JOIN *join, Procedure *procedure)
sufficient to check only the condition pseudo_bits_cond.
*/
DBUG_ASSERT(join->outer_ref_cond == NULL);
if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int())
if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_bool())
{
// HAVING will be checked by end_select
error= (*end_select)(join, 0, 0);
@@ -23509,7 +23563,7 @@ do_select(JOIN *join, Procedure *procedure)
*/
clear_tables(join, &cleared_tables);
}
if (!join->having || join->having->val_int())
if (!join->having || join->having->val_bool())
{
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
join->fields);
@@ -23553,7 +23607,7 @@ do_select(JOIN *join, Procedure *procedure)
JOIN_TAB *join_tab= join->join_tab +
(join->tables_list ? join->const_tables : 0);
if (join->outer_ref_cond && !join->outer_ref_cond->val_int())
if (join->outer_ref_cond && !join->outer_ref_cond->val_bool())
error= NESTED_LOOP_NO_MORE_ROWS;
else
error= join->first_select(join,join_tab,0);
@@ -24024,7 +24078,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
/* Set first_unmatched for the last inner table of this group */
join_tab->last_inner->first_unmatched= join_tab;
if (join_tab->on_precond && !join_tab->on_precond->val_int())
if (join_tab->on_precond && !join_tab->on_precond->val_bool())
rc= NESTED_LOOP_NO_MORE_ROWS;
}
join->thd->get_stmt_da()->reset_current_row_for_warning(1);
@@ -24146,7 +24200,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
if (select_cond)
{
select_cond_result= MY_TEST(select_cond->val_int());
select_cond_result= MY_TEST(select_cond->val_bool());
/* check for errors evaluating the condition */
if (unlikely(join->thd->is_error()))
@@ -24206,7 +24260,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
*/
if (tab->select_cond)
{
const longlong res= tab->select_cond->val_int();
const longlong res= tab->select_cond->val_bool();
if (join->thd->is_error())
DBUG_RETURN(NESTED_LOOP_ERROR);
@@ -24345,7 +24399,7 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
mark_as_null_row(join_tab->table); // For group by without error
select_cond= join_tab->select_cond;
/* Check all attached conditions for inner table rows. */
if (select_cond && !select_cond->val_int())
if (select_cond && !select_cond->val_bool())
return NESTED_LOOP_OK;
}
join_tab--;
@@ -24367,7 +24421,7 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
first_unmatched->found= 1;
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
{
if (tab->select_cond && !tab->select_cond->val_int())
if (tab->select_cond && !tab->select_cond->val_bool())
{
join->return_tab= tab;
return NESTED_LOOP_OK;
@@ -24538,7 +24592,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos)
(*tab->on_expr_ref)->update_used_tables();
DBUG_ASSERT((*tab->on_expr_ref)->const_item());
#endif
if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_int() == 0)))
if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_bool() == 0)))
mark_as_null_row(table);
}
if (!table->null_row && ! tab->join->mixed_implicit_grouping)
@@ -25327,7 +25381,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
/* Copy non-aggregated fields when loose index scan is used. */
copy_fields(&join->tmp_table_param);
}
if (join->having && join->having->val_int() == 0)
if (join->having && join->having->val_bool() == 0)
DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
if (join->procedure)
{
@@ -25488,7 +25542,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
int error=0;
if (join->procedure)
{
if (join->having && join->having->val_int() == 0)
if (join->having && !join->having->val_bool())
error= -1; // Didn't satisfy having
else
{
@@ -25514,7 +25568,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
while ((item= it++))
item->no_rows_in_result();
}
if (join->having && join->having->val_int() == 0)
if (join->having && join->having->val_bool() == 0)// TODO: tests
error= -1; // Didn't satisfy having
else
{
@@ -25624,7 +25678,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd))
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if (likely(!join_tab->having || join_tab->having->val_int()))
if (likely(!join_tab->having || join_tab->having->val_bool()))
{
int error;
join->found_records++;
@@ -25874,7 +25928,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
copy_sum_funcs(join->sum_funcs,
join->sum_funcs_end[send_group_parts]);
if (!join_tab->having || join_tab->having->val_int())
if (!join_tab->having || join_tab->having->val_bool())
{
int error= table->file->ha_write_tmp_row(table->record[0]);
if (unlikely(error) &&
@@ -26501,7 +26555,7 @@ static int test_if_order_by_key(JOIN *join,
if (have_pk_suffix &&
reverse == 0 && // all were =const so far
key_parts == table->key_info[idx].ext_key_parts &&
table->const_key_parts[pk] == PREV_BITS(uint,
table->const_key_parts[pk] == PREV_BITS(key_part_map,
table->key_info[pk].
user_defined_key_parts))
{
@@ -27878,7 +27932,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
break;
goto err;
}
if (having && !having->val_int())
if (having && !having->val_bool())
{
if (unlikely((error= file->ha_delete_row(record))))
goto err;
@@ -28016,7 +28070,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
break;
goto err;
}
if (having && !having->val_int())
if (having && !having->val_bool())
{
if (unlikely((error= file->ha_delete_row(record))))
goto err;
@@ -30175,7 +30229,7 @@ int JOIN::rollup_send_data(uint idx)
int res= 0;
/* Get reference pointers to sum functions in place */
copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]);
if ((!having || having->val_int()))
if ((!having || having->val_bool()))
{
if (send_records < unit->lim.get_select_limit() && do_send_rows &&
(res= result->send_data_with_check(rollup.fields[i],
@@ -30218,7 +30272,7 @@ int JOIN::rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param_arg,
{
/* Get reference pointers to sum functions in place */
copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]);
if ((!having || having->val_int()))
if ((!having || having->val_bool()))
{
int write_error;
Item *item;