1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge 10.6 into 10.10

The MDEV-29693 conflict resolution is from Monty, as well as is
a bug fix where ANALYZE TABLE wrongly built histograms for
single-column PRIMARY KEY.
Also includes a fix for safe_malloc error reporting.

Other things:
- Copied main.log_slow from 10.4 to avoid mtr issue

Disabled test:
- spider/bugfix.mdev_27239 because we started to get
  +Error	1429 Unable to connect to foreign data source: localhost
  -Error	1158 Got an error reading communication packets
- main.delayed
  - Bug#54332 Deadlock with two connections doing LOCK TABLE+INSERT DELAYED
    This part is disabled for now as it fails randomly with different
    warnings/errors (no corruption).
This commit is contained in:
Marko Mäkelä
2023-10-13 15:14:37 +03:00
committed by Monty
436 changed files with 13299 additions and 28179 deletions

View File

@@ -725,7 +725,8 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param,
result_keys.set_bit(key_no);
#ifdef EXTRA_DEBUG
if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
if (param->alloced_sel_args <
param->thd->variables.optimizer_max_sel_args)
{
key1= result->keys[key_no];
(key1)->test_use_count(key1);
@@ -2055,7 +2056,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
SEL_ARG *tmp;
/* Bail out if we have already generated too many SEL_ARGs */
if (++param->alloced_sel_args > MAX_SEL_ARGS)
if (++param->alloced_sel_args > param->thd->variables.optimizer_max_sel_args)
return 0;
if (type != KEY_RANGE)
@@ -2682,7 +2683,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
ha_rows limit, bool force_quick_range,
bool ordered_output,
bool remove_false_parts_of_where,
bool only_single_index_range_scan)
bool only_single_index_range_scan,
bool suppress_unusable_key_notes)
{
uint idx;
double scan_time;
@@ -2757,6 +2759,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
DBUG_RETURN(0); // Fatal error flag is set
/* set up parameter that is passed to all functions */
bzero((void*) &param, sizeof(param));
param.thd= thd;
param.baseflag= head->file->ha_table_flags();
param.prev_tables=prev_tables | const_tables;
@@ -2773,6 +2776,9 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
param.max_key_parts= 0;
param.remove_false_where_parts= remove_false_parts_of_where;
param.force_default_mrr= ordered_output;
param.note_unusable_keys= (!suppress_unusable_key_notes &&
thd->give_notes_for_unusable_keys());
param.possible_keys.clear_all();
thd->no_errors=1; // Don't warn about NULL
@@ -2895,7 +2901,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if (notnull_cond_tree)
tree= tree_and(&param, tree, notnull_cond_tree);
if (thd->trace_started() &&
param.alloced_sel_args >= SEL_ARG::MAX_SEL_ARGS)
param.alloced_sel_args >= thd->variables.optimizer_max_sel_args)
{
Json_writer_object wrapper(thd);
Json_writer_object obj(thd, "sel_arg_alloc_limit_hit");
@@ -3950,6 +3956,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
prune_param.part_info= part_info;
init_sql_alloc(key_memory_quick_range_select_root, &alloc,
thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC));
bzero((void*) range_par, sizeof(*range_par));
range_par->mem_root= &alloc;
range_par->old_root= thd->mem_root;
@@ -3975,6 +3982,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
range_par->remove_jump_scans= FALSE;
range_par->real_keynr[0]= 0;
range_par->alloced_sel_args= 0;
range_par->note_unusable_keys= 0;
thd->no_errors=1; // Don't warn about NULL
thd->mem_root=&alloc;
@@ -8729,14 +8737,21 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param,
if (key_part->image_type != Field::itRAW)
DBUG_RETURN(0);
uint keynr= param->real_keynr[key_part->key];
if (param->using_real_indexes &&
!field->optimize_range(param->real_keynr[key_part->key],
key_part->part))
!field->optimize_range(keynr, key_part->part))
DBUG_RETURN(0);
if (field->result_type() == STRING_RESULT &&
field->charset() != compare_collation())
{
if (param->note_unusable_keys)
field->raise_note_cannot_use_key_part(param->thd, keynr, key_part->part,
func_name_cstring(), value,
Data_type_compatibility::
INCOMPATIBLE_COLLATION);
DBUG_RETURN(0);
}
StringBuffer<MAX_FIELD_WIDTH> tmp(value->collation.collation);
String *res;
@@ -8747,7 +8762,14 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param,
if (field->cmp_type() != STRING_RESULT ||
field->type_handler() == &type_handler_enum ||
field->type_handler() == &type_handler_set)
{
if (param->note_unusable_keys)
field->raise_note_cannot_use_key_part(param->thd, keynr, key_part->part,
func_name_cstring(), value,
Data_type_compatibility::
INCOMPATIBLE_DATA_TYPE);
DBUG_RETURN(0);
}
/*
TODO:
@@ -8827,19 +8849,44 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
}
bool Field::can_optimize_scalar_range(const RANGE_OPT_PARAM *param,
const KEY_PART *key_part,
const Item_bool_func *cond,
scalar_comparison_op op,
const Item *value) const
Data_type_compatibility
Field::can_optimize_scalar_range(const RANGE_OPT_PARAM *param,
const KEY_PART *key_part,
const Item_bool_func *cond,
scalar_comparison_op op,
Item *value) const
{
bool is_eq_func= op == SCALAR_CMP_EQ || op == SCALAR_CMP_EQUAL;
if ((param->using_real_indexes &&
!optimize_range(param->real_keynr[key_part->key],
key_part->part) && !is_eq_func) ||
!can_optimize_range(cond, value, is_eq_func))
return false;
return true;
uint keynr= param->real_keynr[key_part->key];
if (param->using_real_indexes &&
!optimize_range(keynr, key_part->part) && !is_eq_func)
return Data_type_compatibility::INCOMPATIBLE_DATA_TYPE;
Data_type_compatibility compat= can_optimize_range(cond, value, is_eq_func);
if (compat == Data_type_compatibility::OK)
return compat;
/*
Raise a note that the index part could not be used.
TODO: Perhaps we also need to raise a similar note when
a partition could not be used (when using_real_indexes==false).
*/
if (param->using_real_indexes && param->note_unusable_keys)
{
DBUG_ASSERT(keynr < table->s->keys);
/*
Here "cond" can be any sargable predicate, e.g.:
1. field=value (and other scalar comparison predicates: <, <=, <=>, =>, >)
2. field [NOT] BETWEEN value1 AND value2
3. field [NOT] IN (value1, value2...)
Don't print the entire "cond" as in case of BETWEEN and IN
it would list all values.
Let's only print the current field/value pair.
*/
raise_note_cannot_use_key_part(param->thd, keynr, key_part->part,
scalar_comparison_op_to_lex_cstring(op),
value, compat);
}
return compat;
}
@@ -8879,7 +8926,8 @@ SEL_ARG *Field_num::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
scalar_comparison_op op, Item *value)
{
DBUG_ENTER("Field_num::get_mm_leaf");
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
Data_type_compatibility::OK)
DBUG_RETURN(0);
int err= value->save_in_field_no_warnings(this, 1);
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
@@ -8895,7 +8943,8 @@ SEL_ARG *Field_temporal::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
scalar_comparison_op op, Item *value)
{
DBUG_ENTER("Field_temporal::get_mm_leaf");
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
Data_type_compatibility::OK)
DBUG_RETURN(0);
int err= value->save_in_field_no_warnings(this, 1);
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
@@ -8913,7 +8962,8 @@ SEL_ARG *Field_date_common::get_mm_leaf(RANGE_OPT_PARAM *prm,
Item *value)
{
DBUG_ENTER("Field_date_common::get_mm_leaf");
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
Data_type_compatibility::OK)
DBUG_RETURN(0);
int err= value->save_in_field_no_warnings(this, 1);
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
@@ -8955,7 +9005,8 @@ SEL_ARG *Field_str::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
scalar_comparison_op op, Item *value)
{
DBUG_ENTER("Field_str::get_mm_leaf");
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
Data_type_compatibility::OK)
DBUG_RETURN(0);
int err= value->save_in_field_no_warnings(this, 1);
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
@@ -8976,7 +9027,8 @@ SEL_ARG *Field::get_mm_leaf_int(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
bool unsigned_field)
{
DBUG_ENTER("Field::get_mm_leaf_int");
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
Data_type_compatibility::OK)
DBUG_RETURN(0);
int err= value->save_in_field_no_warnings(this, 1);
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
@@ -9244,7 +9296,8 @@ int and_range_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2,
}
result_keys.set_bit(key_no);
#ifdef EXTRA_DEBUG
if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
if (param->alloced_sel_args <
param->thd->variables.optimizer_max_sel_args)
key->test_use_count(key);
#endif
}
@@ -9897,7 +9950,8 @@ and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
key1->weight+= (tmp? tmp->weight: 0) - old_weight;
if (use_count)
next->increment_use_count(use_count);
if (param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
if (param->alloced_sel_args >
param->thd->variables.optimizer_max_sel_args)
break;
}
else
@@ -14466,13 +14520,16 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
Field *field= min_max_arg_item->field;
if (!args[2]) // this is a binary function
{
if (!field->can_optimize_group_min_max(bool_func, args[1]))
if (field->can_optimize_group_min_max(bool_func, args[1]) !=
Data_type_compatibility::OK)
DBUG_RETURN(FALSE);
}
else // this is BETWEEN
{
if (!field->can_optimize_group_min_max(bool_func, args[1]) ||
!field->can_optimize_group_min_max(bool_func, args[2]))
if (field->can_optimize_group_min_max(bool_func, args[1]) !=
Data_type_compatibility::OK ||
field->can_optimize_group_min_max(bool_func, args[2]) !=
Data_type_compatibility::OK)
DBUG_RETURN(FALSE);
}
}