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

MDEV-12426 Add Field::type_handler() + MDEV-12432

This is a joint patch for:

- MDEV-12426 Add Field::type_handler()
- MDEV-12432 Range optimizer for ENUM and SET does not return "Impossible WHERE" in some case

With the new type handler approach being added to Field, it was easier to fix
MDEV-12432 rather than to reproduce the old ENUM/SET behavior.

The patch does the following:

1. Adds Field::type_handler(), according to the task description.

2. Fixes the asymmetry between Fields and Items of ENUM and SET field types.
   Field_enum::cmp_type() returned INT_RESULT
   Item*::cmp_type() returned STRING_RESULT for ENUM and SET expressions

This asymmetry was originally done for easier coding in the optimizer sources.
However, in 10.1 we moved a lot of code to methods of the class Field:
- test_if_equality_guarantees_uniqueness()
- can_be_substituted_to_equal_item()
- get_equal_const_item()
- can_optimize_keypart_ref()
- can_optimize_hash_join()
- can_optimize_group_min_max()
- can_optimize_range()
- can_optimize_outer_join_table_elimination()

As of 10.2 only a few lines of the code in opt_range.cc, field.cc and field.h
still relayed on the fact that Field_enum::cmp_type() returns INT_RESULT:
- Some asserts in field.cc
- Field_year::get_copy_func()
- Item_func_like::get_mm_leaf()
- Item_bool_func::get_mm_leaf()
These lines have been fixed.

3. Item_bool_func::get_mm_leaf() did not work well for ENUM/SET,
see MDEV-12432. So the ENUM/SET code was rewritten, and the relevant
code in Field_enum::store() and Field_set::store() was fixed to
properly return errors to the caller.

4. The result of Field_decimal::result_type() was changed from REAL_RESULT
to DECIMAL_RESULT. Data type aggregation (e.g. in COALESCE()) is now more
precise for old DECIMAL, because Item::decimal_precision() now goes through
the DECIMAL_RESULT branch. Earlier it went through the REAL_RESULT branch.
This commit is contained in:
Alexander Barkov
2017-04-25 14:22:07 +04:00
parent 57bcc70fdc
commit 2fd635409d
12 changed files with 345 additions and 136 deletions

View File

@ -7926,7 +7926,9 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param,
if (!(res= value->val_str(&tmp)))
DBUG_RETURN(&null_element);
if (field->cmp_type() != STRING_RESULT)
if (field->cmp_type() != STRING_RESULT ||
field->type_handler() == &type_handler_enum ||
field->type_handler() == &type_handler_set)
DBUG_RETURN(0);
/*
@ -8022,19 +8024,31 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
goto end;
err= value->save_in_field_no_warnings(field, 1);
if (err == 2 && field->cmp_type() == STRING_RESULT)
{
if (type == EQ_FUNC || type == EQUAL_FUNC)
{
tree= new (alloc) SEL_ARG(field, 0, 0);
tree->type= SEL_ARG::IMPOSSIBLE;
}
else
tree= NULL; /* Cannot infer anything */
goto end;
}
if (err > 0)
{
if (field->type_handler() == &type_handler_enum ||
field->type_handler() == &type_handler_set)
{
if (type == EQ_FUNC || type == EQUAL_FUNC)
{
tree= new (alloc) SEL_ARG(field, 0, 0);
tree->type= SEL_ARG::IMPOSSIBLE;
}
goto end;
}
if (err == 2 && field->cmp_type() == STRING_RESULT)
{
if (type == EQ_FUNC || type == EQUAL_FUNC)
{
tree= new (alloc) SEL_ARG(field, 0, 0);
tree->type= SEL_ARG::IMPOSSIBLE;
}
else
tree= NULL; /* Cannot infer anything */
goto end;
}
if (field->cmp_type() != value->result_type())
{
if ((type == EQ_FUNC || type == EQUAL_FUNC) &&