1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-12858 + MDEV+12859 + MDEV-12862 - a join patch fixing a few data type problems with CREATE..SELECT

MDEV-12858 Out-of-range error for CREATE..SELECT unsigned_int_column+1
MDEV-12859 Out-of-range error for CREATE..SELECT @a:=EXTRACT(MINUTE_MICROSECOND FROM..)
MDEV-12862 Data type of @a:=1e0 depends on the session character set

1. Moving a part of Item::create_tmp_field() into a new helper method
   Item::create_tmp_field_int() and reusing it in Item::create_tmp_field()
   and Item_func_signed::create_tmp_field().
   Fixing the code in Item::create_tmp_field_int() to call
   Type_handler::make_table_field() instead of doing "new Field_long[long]"
   directly. This change revealed a problem reported in MDEV-12862.

2. Changing the "long vs longlong" cut-off length for
     - Item_func::create_tmp_field()
     - Item_sum::create_tmp_field()
     - Item_func_get_user_var::create_tmp_field()
   from MY_INT32_NUM_DECIMAL_DIGITS to (MY_INT32_NUM_DECIMAL_DIGITS - 2).
   This fixes MDEV-12858.
   After this change, the "convert_int_length" parameter to
   Item::create_tmp_field() is not needed any more, because
   (MY_INT32_NUM_DECIMAL_DIGITS - 2) is always passed.
   So removing the "convert_int_length" parameter.

3. Fixing Item::create_tmp_field() to pass max_char_length() instead
   of max_length to the constructor of Field_double().
   This fixes MDEV-12862.

4. Additionally, fixing
   - Type_handler_{tiny|short|int24|long|longlong}::make_table_field()
   - Type_handler_{float|double}::make_table_field()
   to pass max_char_length() instead of max_length to Field contructors.
   This is needed by the change (1).

5. Adding new tests, and recording new correct results in the old tests in:
   - mysql-test/r/type_ranges.result
   - storage/tokudb/mysql-test/tokudb/r/type_ranges.result
This commit is contained in:
Alexander Barkov
2017-05-22 13:44:26 +04:00
parent feb15f4e45
commit c84bbeda7f
13 changed files with 136 additions and 39 deletions

View File

@ -15869,7 +15869,17 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field,
}
Field *Item::create_tmp_field(bool group, TABLE *table, uint convert_int_length)
Field *Item::create_tmp_field_int(TABLE *table, uint convert_int_length)
{
const Type_handler *h= &type_handler_long;
if (max_char_length() > convert_int_length)
h= &type_handler_longlong;
return h->make_and_init_table_field(&name, Record_addr(maybe_null),
*this, table);
}
Field *Item::create_tmp_field(bool group, TABLE *table)
{
Field *UNINIT_VAR(new_field);
MEM_ROOT *mem_root= table->in_use->mem_root;
@ -15878,23 +15888,11 @@ Field *Item::create_tmp_field(bool group, TABLE *table, uint convert_int_length)
case REAL_RESULT:
{
new_field= new (mem_root)
Field_double(max_length, maybe_null, &name, decimals, TRUE);
Field_double(max_char_length(), maybe_null, &name, decimals, TRUE);
break;
}
case INT_RESULT:
{
/*
Select an integer type with the minimal fit precision.
convert_int_length is sign inclusive, don't consider the sign.
*/
if (max_char_length() > convert_int_length)
new_field= new (mem_root)
Field_longlong(max_char_length(), maybe_null, &name, unsigned_flag);
else
new_field= new (mem_root)
Field_long(max_char_length(), maybe_null, &name, unsigned_flag);
break;
}
return create_tmp_field_int(table, MY_INT32_NUM_DECIMAL_DIGITS - 2);
case TIME_RESULT:
case DECIMAL_RESULT:
case STRING_RESULT: