Bug #110945 make_year_constant should set max_length=4
Submitted: 8 May 2023 6:36 Modified: 8 May 2023 9:31
Reporter: Fengchun Hua Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S6 (Debug Builds)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any

[8 May 2023 6:36] Fengchun Hua
Description:
I found there's a DBUG_ASSERT in Item::tmp_table_field_from_field_type(item.cc):
assert(max_length == 4);  // Field_year is only for length 4. 
I think no matter how, max_length for MYSQL_TYPE_YEAR item should alwarys be 4.

But suddenly, I found another function: Item *make_year_constant(item_cmpfunc.cc) which set item type to MYSQL_TYPE_YEAR, but didn't set its max_length, and the default max_length for Item_int is 21.

I think there's a chance that it will crash on the debug assert if an item created by `make_year_constant` and used for making a tmp field.  

How to repeat:
Didn't find a crash case.

Suggested fix:
I think this line should add in function make_year_constant:
year->max_length=4;
[8 May 2023 9:31] MySQL Verification Team
Hello Fengchun Hua,

Thank you for the report and feedback.

Thanks,
Umesh
[25 Aug 2024 7:28] MySQL Verification Team
On 8.0.39-debug I see this:

-- -------
drop table if exists t;
create table t(c0 int,c3 int);
insert into t values(1,1),(2,2),(3,3);

with t4f as
(
  select null c4
  union all 
  select(cast(1 as year)) c3
  from t where c3
)
select c0 from t4f ;
-- -------

mysqld-debug.exe: Version: '8.0.39-debug'  Source distribution.
Assertion failed: max_length == 4, file .\sql\item.cc, line 6477
abort() has been called
2024-08-25T07:27:30Z UTC - mysqld got exception 0x80000003 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.

mysqld-debug.exe!my_sigabrt_handler()[my_thr_init.cc:373]
ucrtbased.dll!raise()
ucrtbased.dll!abort()
ucrtbased.dll!_get_wide_winmain_command_line()
ucrtbased.dll!_get_wide_winmain_command_line()
ucrtbased.dll!_get_wide_winmain_command_line()
ucrtbased.dll!_wassert()
mysqld-debug.exe!Item::tmp_table_field_from_field_type()[item.cc:6477]
mysqld-debug.exe!Item_aggregate_type::make_field_by_type()[item.cc:10507]
mysqld-debug.exe!create_tmp_field()[sql_tmp_table.cc:499]
mysqld-debug.exe!create_tmp_table()[sql_tmp_table.cc:1143]
mysqld-debug.exe!Query_result_union::create_result_table()[sql_union.cc:222]
mysqld-debug.exe!create_tmp_table_for_set_op()[sql_union.cc:366]
mysqld-debug.exe!Query_expression::prepare_query_term()[sql_union.cc:650]
mysqld-debug.exe!Query_expression::prepare_query_term()[sql_union.cc:509]
mysqld-debug.exe!Query_expression::prepare()[sql_union.cc:861]
mysqld-debug.exe!Table_ref::resolve_derived()[sql_derived.cc:445]
mysqld-debug.exe!Query_block::resolve_placeholder_tables()[sql_resolver.cc:1299]
mysqld-debug.exe!Query_block::prepare()[sql_resolver.cc:247]
mysqld-debug.exe!Sql_cmd_select::prepare_inner()[sql_select.cc:651]
mysqld-debug.exe!Sql_cmd_dml::prepare()[sql_select.cc:567]
mysqld-debug.exe!Sql_cmd_dml::execute()[sql_select.cc:719]
mysqld-debug.exe!mysql_execute_command()[sql_parse.cc:4722]
mysqld-debug.exe!dispatch_sql_command()[sql_parse.cc:5371]
mysqld-debug.exe!dispatch_command()[sql_parse.cc:2059]
mysqld-debug.exe!do_command()[sql_parse.cc:1440]
mysqld-debug.exe!handle_connection()[connection_handler_per_thread.cc:303]
mysqld-debug.exe!pfs_spawn_thread()[pfs.cc:3052]
mysqld-debug.exe!win_thread_start()[my_thread.cc:74]