Description:
The following debug information show a possible logical error. I marked key information prefix with ==> inlined.
The following logical error might cause a TRUNCATE warning, but it's useless. Because MySQL doesn't check such a warning returned value during UNION operation, so such a warning is not reported. However, if such a function is called by other plan which might check the returned value, it will cause some problem.
Thread 43 "mysqld" hit Breakpoint 6, well_formed_copy_nchars (to_cs=0x7c3ff00 <my_charset_utf8mb4_0900_ai_ci>, to=0x7fff38b8b7b2 "", to_length=88,
from_cs=0x7af6e80 <my_charset_latin1>, from=0x7fffe9aa2efd "9999999.", '9' <repeats 15 times>, from_length=23, nchars=22, well_formed_error_pos=0x7fffe9aa2eb0,
cannot_convert_error_pos=0x7fffe9aa2ea8, from_end_pos=0x7fffe9aa2ea0) at /home/simon/work/inlist/Parallel_Query/sql-common/sql_string.cc:829
829 (to_cs == from_cs) || my_charset_same(from_cs, to_cs)) {
(gdb) fin
Run till exit from #0 well_formed_copy_nchars (to_cs=0x7c3ff00 <my_charset_utf8mb4_0900_ai_ci>, to=0x7fff38b8b7b2 "", to_length=88, from_cs=0x7af6e80 <my_charset_latin1>,
from=0x7fffe9aa2efd "9999999.", '9' <repeats 15 times>, from_length=23, nchars=22, well_formed_error_pos=0x7fffe9aa2eb0, cannot_convert_error_pos=0x7fffe9aa2ea8,
from_end_pos=0x7fffe9aa2ea0) at /home/simon/work/inlist/Parallel_Query/sql-common/sql_string.cc:829
0x00000000035b944d in field_well_formed_copy_nchars (to_cs=0x7c3ff00 <my_charset_utf8mb4_0900_ai_ci>, to=0x7fff38b8b7b2 "9999999.", '9' <repeats 14 times>, to_length=88,
from_cs=0x7af6e80 <my_charset_latin1>, from=0x7fffe9aa2efd "9999999.", '9' <repeats 15 times>, from_length=23, nchars=22, well_formed_error_pos=0x7fffe9aa2eb0,
cannot_convert_error_pos=0x7fffe9aa2ea8, from_end_pos=0x7fffe9aa2ea0) at /home/simon/work/inlist/Parallel_Query/sql/field.cc:1480
1480 size_t res = well_formed_copy_nchars(
Value returned is $155 = 22
(gdb) fin
Run till exit from #0 0x00000000035b944d in field_well_formed_copy_nchars (to_cs=0x7c3ff00 <my_charset_utf8mb4_0900_ai_ci>, to=0x7fff38b8b7b2 "9999999.", '9' <repeats 14 times>,
to_length=88, from_cs=0x7af6e80 <my_charset_latin1>, from=0x7fffe9aa2efd "9999999.", '9' <repeats 15 times>, from_length=23, nchars=22, well_formed_error_pos=0x7fffe9aa2eb0,
cannot_convert_error_pos=0x7fffe9aa2ea8, from_end_pos=0x7fffe9aa2ea0) at /home/simon/work/inlist/Parallel_Query/sql/field.cc:1480
0x00000000035cb444 in Field_varstring::store (this=0x7fff38afe1c0, from=0x7fffe9aa2efd "9999999.", '9' <repeats 15 times>, length=23, cs=0x7af6e80 <my_charset_latin1>)
at /home/simon/work/inlist/Parallel_Query/sql/field.cc:6562
6562 copy_length = field_well_formed_copy_nchars(
Value returned is $156 = 22
(gdb) n
6567 if (length_bytes == 1)
(gdb)
6568 *ptr = (uchar)copy_length;
(gdb)
6572 return check_string_copy_error(well_formed_error_pos,
(gdb) s
Field_longstr::check_string_copy_error (this=0x7fff38afe1c0, well_formed_error_pos=0x0, cannot_convert_error_pos=0x0, from_end_pos=0x7fffe9aa2f13 "9", end=0x7fffe9aa2f14 "",
count_spaces=true, cs=0x7af6e80 <my_charset_latin1>) at /home/simon/work/inlist/Parallel_Query/sql/field.cc:6033
6033 THD *thd = table->in_use;
(gdb) n
6035 if (!(pos = well_formed_error_pos) && !(pos = cannot_convert_error_pos))
(gdb)
6036 return report_if_important_data(from_end_pos, end, count_spaces);
(gdb) s
Field_longstr::report_if_important_data (this=0x7fff38afe1c0, pstr=0x7fffe9aa2f13 "9", end=0x7fffe9aa2f14 "", count_spaces=true)
at /home/simon/work/inlist/Parallel_Query/sql/field.cc:6072
6072 if (pstr < end) // String is truncated
(gdb) n
6074 if (test_if_important_data(field_charset, pstr, end)) {
(gdb) p pstr<end ==》By here, optimizer will release a TRUNCATE warning.
$157 = true
(gdb) f 1
#1 0x00000000035c95a3 in Field_longstr::check_string_copy_error (this=0x7fff38afe1c0, well_formed_error_pos=0x0, cannot_convert_error_pos=0x0, from_end_pos=0x7fffe9aa2f13 "9",
end=0x7fffe9aa2f14 "", count_spaces=true, cs=0x7af6e80 <my_charset_latin1>) at /home/simon/work/inlist/Parallel_Query/sql/field.cc:6036
6036 return report_if_important_data(from_end_pos, end, count_spaces);
(gdb) f 2
#2 0x00000000035cb4b8 in Field_varstring::store (this=0x7fff38afe1c0, from=0x7fffe9aa2efd "9999999.", '9' <repeats 15 times>, length=23, cs=0x7af6e80 <my_charset_latin1>)
at /home/simon/work/inlist/Parallel_Query/sql/field.cc:6572
6572 return check_string_copy_error(well_formed_error_pos,
(gdb) l
6567 if (length_bytes == 1)
6568 *ptr = (uchar)copy_length;
6569 else
6570 int2store(ptr, static_cast<uint16>(copy_length));
6571
6572 return check_string_copy_error(well_formed_error_pos,
6573 cannot_convert_error_pos, from_end_pos,
6574 from + length, true, cs);
6575 }
6576
(gdb) p from_end_pos-from + 1
$158 = 23 ==>Here we can see whole decimal values can be converted into varchar.(Note:length of '9999999.999999999999999'string is 23).
(gdb) p from + length ==>But here the expression of 'from + length' is same as 'from + 23'. In other words, the value of from_end_pos must be less than the one of 'from + 23. Here it's an obvious mistake.
$159 = 0x7fffe9aa2f14 ""
(gdb) p from_end_pos
$160 = 0x7fffe9aa2f13 "9"
(gdb) p length
$161 = 23
How to repeat:
select 9999999.999999999999999 union select -3.40282e1 union select '1';