[MDEV-15346] Server crashes on Windows in MYSQLparse upon creating a table partitioned by system_time with certain intervals Created: 2018-02-18  Updated: 2018-02-22  Resolved: 2018-02-22

Status: Closed
Project: MariaDB Server
Component/s: Partitioning, Versioned Tables
Affects Version/s: 10.3
Fix Version/s: 10.3.5

Type: Bug Priority: Blocker
Reporter: Elena Stepanova Assignee: Sergei Golubchik
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows


Attachments: PNG File Capture.PNG    
Issue Links:
Relates
relates to MDEV-14675 Questionable semantics of INTERVAL va... Closed

 Description   

Note: it only crashes on Windows for me, release and debug. Linux builds don't show any visible problems, neither debug, nor release, nor asan, nor valgrind.
INTERVAL 3 YEAR is important here. INTERVAL 2 YEAR does not crash. INTERVAL 36 MONTH also does not crash.

--source include/have_partition.inc
CREATE OR REPLACE TABLE t1 (pk INT) WITH SYSTEM VERSIONING PARTITION BY system_time INTERVAL 3 YEAR ( PARTITION p1 HISTORY, PARTITION pn CURRENT );
 
# Cleanup
DROP TABLE t1;

10.3 afc56a509cc7d

mysqld.exe!MYSQLparse()[sql_yacc.yy:5873]
mysqld.exe!parse_sql()[sql_parse.cc:10011]
mysqld.exe!mysql_unpack_partition()[sql_partition.cc:4194]
mysqld.exe!open_table_from_share()[table.cc:3364]
mysqld.exe!ha_create_table()[handler.cc:4911]
mysqld.exe!rea_create_table()[unireg.cc:526]
mysqld.exe!create_table_impl()[sql_table.cc:4995]
mysqld.exe!mysql_create_table_no_lock()[sql_table.cc:5108]
mysqld.exe!mysql_create_table()[sql_table.cc:5186]
mysqld.exe!mysql_execute_command()[sql_parse.cc:4257]
mysqld.exe!mysql_parse()[sql_parse.cc:7980]
mysqld.exe!dispatch_command()[sql_parse.cc:1827]
mysqld.exe!do_command()[sql_parse.cc:1369]
mysqld.exe!threadpool_process_request()[threadpool_common.cc:358]
mysqld.exe!tp_callback()[threadpool_common.cc:186]
mysqld.exe!tp_callback()[threadpool_win.cc:378]
mysqld.exe!work_callback()[threadpool_win.cc:452]
ntdll.dll!TpPostWork()
ntdll.dll!RtlRealSuccessor()
kernel32.dll!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()



 Comments   
Comment by Aleksey Midenkov [ 2018-02-19 ]

Trash value for Lex->create_last_non_select_table.

Comment by Aleksey Midenkov [ 2018-02-19 ]

thd->lex changed:

>	init_lex_with_single_table(thd=0x090dc4d0, table=0x0a71b0b4, lex=0x0a719a98)	C++
 	mysql_unpack_partition(thd=0x090dc4d0, part_buf=0x090ca330, part_info_len=145, table=0x0a71b0b4, is_create_table_ind=true, default_db_type=0x00ddee48, work_part_info_used=0x0a71aa7b)	C++
 	open_table_from_share(thd=0x090dc4d0, share=0x0a71ab88, alias=0x01d892b4, db_stat=0, prgflag=1, ha_open_flags=0, outparam=0x0a71b0b4, is_create_table=true, partitions_to_open=0x00000000)	C++
 	ha_create_table(thd=0x090dc4d0, path=0x0a71d1cc, db=0x090eaad0, table_name=0x090ea638, create_info=0x0a71eb10, frm=0x0a71d1bc)	C++
 	rea_create_table(thd=0x090dc4d0, frm=0x0a71d1bc, path=0x0a71d1cc, db=0x090eaad0, table_name=0x090ea638, create_info=0x0a71eb10, file=0x090ebb28, no_ha_create_table=false)	C++
 	create_table_impl(thd=0x090dc4d0, orig_db=0x090ea66c, orig_table_name=0x090ea674, db=0x090ea66c, table_name=0x090ea674, path=0x0a71d1cc, options={...}, create_info=0x0a71eb10, alter_info=0x0a71eaa0, create_table_mode=0, is_trans=0x0a71d933, key_info=0x0a71d3e8, key_count=0x0a71d3dc, frm=0x0a71d1bc)	C++
 	mysql_create_table_no_lock(thd=0x090dc4d0, db=0x090ea66c, table_name=0x090ea674, create_info=0x0a71eb10, alter_info=0x0a71eaa0, is_trans=0x0a71d933, create_table_mode=0, table_list=0x090ea660)	C++
 	mysql_create_table(thd=0x090dc4d0, create_table=0x090ea660, create_info=0x0a71eb10, alter_info=0x0a71eaa0)	C++
 	mysql_execute_command(thd=0x090dc4d0)	C++
 	mysql_parse(thd=0x090dc4d0, rawbuf=0x090ea4a8, length=146, parser_state=0x0a71f4d4, is_com_multi=false, is_next_command=false)	C++

int
init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex)
{
  TABLE_LIST *table_list;
  Table_ident *table_ident;
  SELECT_LEX *select_lex= &lex->select_lex;
  Name_resolution_context *context= &select_lex->context;
  /*
    We will call the parser to create a part_info struct based on the
    partition string stored in the frm file.
    We will use a local lex object for this purpose. However we also
    need to set the Name_resolution_object for this lex object. We
    do this by using add_table_to_list where we add the table that
    we're working with to the Name_resolution_context.
  */
  thd->lex= lex;

Comment by Aleksey Midenkov [ 2018-02-19 ]

+ rawbuf 0x08e59978 "CREATE OR REPLACE TABLE t1 (pk INT) WITH SYSTEM VERSIONING PARTITION BY system_time INTERVAL 3 YEAR ( PARTITION p1 HISTORY, PARTITION pn CURRENT )" char *

+ part_buf 0x08e39630 " PARTITION BY SYSTEM_TIME INTERVAL 18446744072252824320 SECOND \n(PARTITION `p1` HISTORY ENGINE = MyISAM,\n PARTITION `pn` CURRENT ENGINE = MyISAM)" char *

Unexpected args value -1456727296 __int64

  else if ((int) int_type <= INTERVAL_MICROSECOND)
  {
    value= args->val_int();
    if (args->null_value)
      return 1;
    if (value < 0)
    {
      interval->neg=1;
      value= -value;
    }
  }

>	get_interval_value(args=0x08e3c578, int_type=INTERVAL_SECOND, interval=0x0a56882c)	C++
 	MYSQLparse(thd=0x08e4b9a0)	C++
 	parse_sql(thd=0x08e4b9a0, parser_state=0x0a569398, creation_ctx=0x00000000, do_pfs_digest=false)	C++
 	mysql_unpack_partition(thd=0x08e4b9a0, part_buf=0x08e39630, part_info_len=145, table=0x0a56aa9c, is_create_table_ind=true, default_db_type=0x08cbaea0, work_part_info_used=0x0a56a463)	C++
 	open_table_from_share(thd=0x08e4b9a0, share=0x0a56a570, alias=0x01d892b4, db_stat=0, prgflag=1, ha_open_flags=0, outparam=0x0a56aa9c, is_create_table=true, partitions_to_open=0x00000000)	C++
 	ha_create_table(thd=0x08e4b9a0, path=0x0a56cbb4, db=0x08e59fa0, table_name=0x08e59b08, create_info=0x0a56e4f8, frm=0x0a56cba4)	C++
 	rea_create_table(thd=0x08e4b9a0, frm=0x0a56cba4, path=0x0a56cbb4, db=0x08e59fa0, table_name=0x08e59b08, create_info=0x0a56e4f8, file=0x08e5aff8, no_ha_create_table=false)	C++
 	create_table_impl(thd=0x08e4b9a0, orig_db=0x08e59b3c, orig_table_name=0x08e59b44, db=0x08e59b3c, table_name=0x08e59b44, path=0x0a56cbb4, options={...}, create_info=0x0a56e4f8, alter_info=0x0a56e488, create_table_mode=0, is_trans=0x0a56d31b, key_info=0x0a56cdd0, key_count=0x0a56cdc4, frm=0x0a56cba4)	C++
 	mysql_create_table_no_lock(thd=0x08e4b9a0, db=0x08e59b3c, table_name=0x08e59b44, create_info=0x0a56e4f8, alter_info=0x0a56e488, is_trans=0x0a56d31b, create_table_mode=0, table_list=0x08e59b30)	C++
 	mysql_create_table(thd=0x08e4b9a0, create_table=0x08e59b30, create_info=0x0a56e4f8, alter_info=0x0a56e488)	C++
 	mysql_execute_command(thd=0x08e4b9a0)	C++
 	mysql_parse(thd=0x08e4b9a0, rawbuf=0x08e59978, length=146, parser_state=0x0a56eebc, is_com_multi=false, is_next_command=false)	C++

Cause 1

Seconds overflow.
3 common years = 94608000 seconds.
3 leap years = 94867200 seconds.
But 18446744072252824320 in part_buf.

This was mitigated by MDEV-14675.

Cause 2

thd->lex->create_last_non_select_table is uninitialized under mysql_unpack_partition().

Fix 2

create_last_non_select_table must be initialized with table_list in init_lex_with_single_table().

Generated at Thu Feb 08 08:20:35 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.