Bug #111450 Assertion `to->field_ptr() != from->field_ptr()' failed.
Submitted: 15 Jun 2023 20:58 Modified: 14 Nov 2023 21:26
Reporter: Yu Liang Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DML Severity:S6 (Debug Builds)
Version:8.0.33 OS:Ubuntu (20.04 LTS)
Assigned to: CPU Architecture:x86 (Intel(R) Core(TM) i7-10700 CPU)

[15 Jun 2023 20:58] Yu Liang
Description:
The latest version of the MySQL Server (version 8.0.33 debug build) (git commit hash: ea7087d8850) crashes with Assertion Failure when executing the following query:

Config from "/etc/mysql/conf.d/mysql.cnf":

```
[mysqld]
sql_mode = "NO_ENGINE_SUBSTITUTION"
```

```sql
drop database if exists test123;
create database test123;
use test123;
CREATE TABLE v0 ( v1 CHAR ( 0 ) NOT NULL , v2 INT ) ;
INSERT INTO v0 ( v2 ) VALUES ( 0 ) , ( v1 ) ;
```

In the debug build, the server crashes with the following stack trace: 

```
mysql> INSERT INTO v0 ( v2 ) VALUES ( 0 ) , ( v1 ) ;
mysqld: /home/mysql/mysql-server/sql/item.cc:6509: type_conversion_status field_conv_with_cache(Field *, Field *, Field **, uint32_t *): Assertion `to->field_ptr() != from->field_ptr()' failed.
2023-06-15T20:54:49Z UTC - mysqld got signal 6 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
BuildID[sha1]=1d55d4671b7469352fc317efb0121b604c26443d
Thread pointer: 0xffff08001040
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = ffff786f5538 thread_stack 0x100000
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x60) [0x4e6bc30]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(print_fatal_signal(int)+0x340) [0x1a89320]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(handle_fatal_signal+0x16c) [0x1a896dc]
linux-vdso.so.1(__kernel_rt_sigreturn+0) [0xffffbb97d7a0]
/lib/aarch64-linux-gnu/libc.so.6(gsignal+0xe0) [0xffffbaff1d78]
/lib/aarch64-linux-gnu/libc.so.6(abort+0x114) [0xffffbafdeaac]
/lib/aarch64-linux-gnu/libc.so.6(+0x2d490) [0xffffbafeb490]
/lib/aarch64-linux-gnu/libc.so.6(+0x2d4f4) [0xffffbafeb4f4]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Item_field::save_in_field_inner(Field*, bool)+0x3dc) [0x1eabc24]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Item::save_in_field(Field*, bool)+0xe4) [0x1e8bb34]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(fill_record(THD*, TABLE*, mem_root_deque<Item*> const&, mem_root_deque<Item*> const&, MY_BITMAP*, MY_BITMAP*, bool)+0x900) [0x1448e60]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(fill_record_n_invoke_before_triggers(THD*, COPY_INFO*, mem_root_deque<Item*> const&, mem_root_deque<Item*> const&, TABLE*, enum_trigger_event_type, int, bool, bool*)+0x224) [0x1449bd4]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Sql_cmd_insert_values::execute_inner(THD*)+0x9f0) [0x25b0060]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Sql_cmd_dml::execute(THD*)+0x7a0) [0x1737e1c]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(mysql_execute_command(THD*, bool)+0x3884) [0x162cd40]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(dispatch_sql_command(THD*, Parser_state*)+0x1124) [0x16252c0]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(dispatch_command(THD*, COM_DATA const*, enum_server_command)+0x5434) [0x161e224]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(do_command(THD*)+0xb8c) [0x16228f4]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld() [0x1a59a64]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld() [0x655c1a0]
/lib/aarch64-linux-gnu/libpthread.so.0(+0x7624) [0xffffbb923624]
/lib/aarch64-linux-gnu/libc.so.6(+0xd149c) [0xffffbb08f49c]

Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (ffff080243c0): INSERT INTO v0 ( v2 ) VALUES ( 0 ) , ( v1 )
Connection ID (thread ID): 14
Status: NOT_KILLED
```

How to repeat:
Steps to repeat the Assertion Failure:
1. Download the MySQL Server source code from the official github repo: `https://github.com/mysql/mysql-server`
2. Checkout to the latest mysql released version: 8.0.33 (hash: `ea7087d8850`)
3. Compile MySQL using the command: 

```
mkdir -p bld
cd bld
cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST=../boost -DWITH_UNIT_TESTS=OFF -DWITH_DEBUG=1
make
```

4. Run the MySQL Server with command: 

```
./bin/mysqld --basedir=$(pwd) --datadir=$(pwd)/data_all/ori_data --port=7000  --socket=/tmp/mysql_0.sock --mysqlx=OFF --performance_schema=OFF
```

5. Setup the MySQL Server config in the path: "/etc/mysql/conf.d/mysql.cnf"

```
[mysqld]
sql_mode = "NO_ENGINE_SUBSTITUTION"
```

6. Run the MySQL Client with the PoC:

```
./bin/mysql --port=7000 --user=root --socket=/tmp/mysql_0.sock < poc_0.sql
```

where `poc_0.sql` is:

```sql
drop database if exists test123;
create database test123;
use test123;
CREATE TABLE v0 ( v1 CHAR ( 0 ) NOT NULL , v2 INT ) ;
INSERT INTO v0 ( v2 ) VALUES ( 0 ) , ( v1 ) ;
```

Suggested fix:
The server should continue running instead of crashing by Assertion Failure.
[16 Jun 2023 7:03] MySQL Verification Team
Hello Yu Liang,

Thank you for the report and test case.
Observed that 8.0.33 debug build is affected.

regards,
Umesh
[16 Jun 2023 7:04] MySQL Verification Team
-- release build - not affected
./mtr bug111450 --nocheck-testcases  --mysqld="--sql-mode="
Logging: ./mtr  bug111450 --nocheck-testcases --mysqld=--sql-mode=
MySQL Version 8.0.33
Checking supported features
Using 'all' suites
Collecting tests
Checking leftover processes
Removing old var directory
 - WARNING: Using the 'mysql-test/var' symlink
Creating var directory '/export/home/tmp/ushastry/mysql-8.0.33/mysql-test/var'
Installing system database
Using parallel: 1

==============================================================================
                  TEST NAME                       RESULT  TIME (ms) COMMENT
------------------------------------------------------------------------------
drop database if exists test123;
Warnings:
Note    1008    Can't drop database 'test123'; database doesn't exist
create database test123;
use test123;
CREATE TABLE v0 ( v1 CHAR ( 0 ) NOT NULL , v2 INT ) ;
INSERT INTO v0 ( v2 ) VALUES ( 0 ) , ( v1 ) ;
Warnings:
Warning 1364    Field 'v1' doesn't have a default value
Warning 1366    Incorrect integer value: '' for column 'v2' at row 2
[ 50%] main.bug111450                            [ pass ]      7
[100%] shutdown_report                           [ pass ]

-- debug build - affected
 ./mtr bug111450 --nocheck-testcases --debug-server --mysqld="--sql-mode="
Logging: ./mtr  bug111450 --nocheck-testcases --debug-server --mysqld=--sql-mode=
MySQL Version 8.0.33
Checking supported features
 - Binaries are debug compiled
Using 'all' suites
Collecting tests
Checking leftover processes
Removing old var directory
 - WARNING: Using the 'mysql-test/var' symlink
Creating var directory '/export/home/tmp/ushastry/mysql-8.0.33/mysql-test/var'
Installing system database
Using parallel: 1

==============================================================================
                  TEST NAME                       RESULT  TIME (ms) COMMENT
------------------------------------------------------------------------------
drop database if exists test123;
Warnings:
Note    1008    Can't drop database 'test123'; database doesn't exist
create database test123;
use test123;
CREATE TABLE v0 ( v1 CHAR ( 0 ) NOT NULL , v2 INT ) ;
INSERT INTO v0 ( v2 ) VALUES ( 0 ) , ( v1 ) ;
[ 50%] main.bug111450                            [ fail ]
        Test ended at 2023-06-16 09:03:44

CURRENT_TEST: main.bug111450
mysqltest: At line 5: Query 'INSERT INTO v0 ( v2 ) VALUES ( 0 ) , ( v1 ) ' failed.
ERROR 2013 (HY000): Lost connection to MySQL server during query

-bt
#0  0x00007f7e32c6aaa1 in pthread_kill () from /lib64/libpthread.so.0
#1  0x0000000003f9296e in my_write_core(int) ()
#2  0x00000000032365f5 in handle_fatal_signal ()
#3  <signal handler called>
#4  0x00007f7e30ea4387 in raise () from /lib64/libc.so.6
#5  0x00007f7e30ea5a78 in abort () from /lib64/libc.so.6
#6  0x00007f7e30e9d1a6 in __assert_fail_base () from /lib64/libc.so.6
#7  0x00007f7e30e9d252 in __assert_fail () from /lib64/libc.so.6
#8  0x000000000337c12d in field_conv_with_cache(Field*, Field*, Field**, unsigned int*) ()
#9  0x000000000337c282 in Item_field::save_in_field_inner(Field*, bool) ()
#10 0x00000000033925b7 in Item::save_in_field(Field*, bool) ()
#11 0x00000000030108ba in fill_record(THD*, TABLE*, mem_root_deque<Item*> const&, mem_root_deque<Item*> const&, MY_BITMAP*, MY_BITMAP*, bool) ()
#12 0x0000000003010d23 in fill_record_n_invoke_before_triggers(THD*, COPY_INFO*, mem_root_deque<Item*> const&, mem_root_deque<Item*> const&, TABLE*, enum_trigger_event_type, int, bool, bool*) ()
#13 0x000000000358e9e9 in Sql_cmd_insert_values::execute_inner(THD*) ()
#14 0x0000000003123873 in Sql_cmd_dml::execute(THD*) ()
#15 0x00000000030c24af in mysql_execute_command(THD*, bool) ()
#16 0x00000000030c5dc9 in dispatch_sql_command(THD*, Parser_state*) ()
#17 0x00000000030c752b in dispatch_command(THD*, COM_DATA const*, enum_server_command) ()
#18 0x00000000030c926e in do_command(THD*) ()
#19 0x0000000003227bb7 in handle_connection ()
#20 0x0000000004743af9 in pfs_spawn_thread ()
#21 0x00007f7e32c65ea5 in start_thread () from /lib64/libpthread.so.0
#22 0x00007f7e30f6cb2d in clone () from /lib64/libc.so.6
[14 Nov 2023 21:26] Christine Cole
Posted by developer:
 
Fixed as of the upcoming MySQL 8.3.0 release, and here's the proposed changelog entry from the documentation team:

An assertion could fail in debug builds when inserting data with a
zero-length column, such as CHAR(0) or BINARY(0), into a table. Now, a
less strict assertion more accurately fails only if it detects that a
non-zero number of bytes copied from a source is identical to the target.

Thank you for the bug report.
[17 Jan 2024 18:28] Jean-François Gagné
This is flagged as fixed in 8.3.0, but also as affecting 8.0.33.

Will this be fixed in a future 8.0 release.
[26 Feb 2024 23:09] Jon Stephens
The fix for this issue appears in MySQL 8.0.37 and 8.4.0; the changelog entries have been updated accordingly.
[13 Mar 2024 7:04] ximin liang
hi mysql team:
  seems some fix have added in mysql 8.3.0(git log grep Bug#35507763) and from early comment 8.4.0 will add final fix.
  here i provide another test case for consideration. can be repeated before fix for Bug#35507763 added.(eg 8.0.26)
  CREATE TABLE `t2` (
  `c1` bit(2) DEFAULT NULL,
  `c2` bit(2) DEFAULT NULL
) ENGINE=MyISAM;
  insert into t2 (c1,c2) values (b'01',b'10');
  update t2 set c2 = c1;
  this is because for myisam storage engine, treat_bit_as_char is not enabled, ptr for field c1,c2 has same address. do not affect innodb.
  backtrace:
#0  0x00007f04a446f387 in raise () from /lib64/libc.so.6
#1  0x00007f04a4470a78 in abort () from /lib64/libc.so.6
#2  0x00007f04a44681a6 in __assert_fail_base () from /lib64/libc.so.6
#3  0x00007f04a4468252 in __assert_fail () from /lib64/libc.so.6
#4  0x0000000003ca2be4 in field_conv_with_cache (to=0x7f03ec1741b8, from=0x7f03ec1740c8, last_to=0x7f03ec01d948, 
    to_is_memcpyable=0x7f03ec01d954) at /data/code/mysql-server/sql/item.cc:6058
#5  0x0000000003ca2e6f in Item_field::save_in_field_inner (this=0x7f03ec01d840, to=0x7f03ec1741b8, no_conversions=false)
    at /data/code/mysql-server/sql/item.cc:6113
#6  0x0000000003ca2f48 in Item::save_in_field (this=0x7f03ec01d840, field=0x7f03ec1741b8, no_conversions=false)
    at /data/code/mysql-server/sql/item.cc:6151
#7  0x00000000037d4fd3 in fill_record (thd=0x7f03ec000da0, table=0x7f03ec139540, fields=const mem_root_deque<Item*> & = {...}, 
    values=const mem_root_deque<Item*> & = {...}, bitmap=0x0, insert_into_fields_bitmap=0x0, raise_autoinc_has_expl_non_null_val=false)
    at /data/code/mysql-server/sql/sql_base.cc:9536
#8  0x00000000037d5a57 in fill_record_n_invoke_before_triggers (thd=0x7f03ec000da0, optype_info=0x7f04944c1130, 
    fields=const mem_root_deque<Item*> & = {...}, values=const mem_root_deque<Item*> & = {...}, table=0x7f03ec139540, 
    event=TRG_EVENT_UPDATE, num_fields=0, raise_autoinc_has_expl_non_null_val=false, is_row_changed=0x7f04944c0f27)
    at /data/code/mysql-server/sql/sql_base.cc:9850
#9  0x00000000039f7a7e in Sql_cmd_update::update_single_table (this=0x7f03ec01dd90, thd=0x7f03ec000da0)
    at /data/code/mysql-server/sql/sql_update.cc:861
#10 0x00000000039fa732 in Sql_cmd_update::execute_inner (this=0x7f03ec01dd90, thd=0x7f03ec000da0)
    at /data/code/mysql-server/sql/sql_update.cc:1722
#11 0x000000000394859b in Sql_cmd_dml::execute (this=0x7f03ec01dd90, thd=0x7f03ec000da0) at /data/code/mysql-server/sql/sql_select.cc:574
#12 0x00000000038c9868 in mysql_execute_command (thd=0x7f03ec000da0, first_level=true) at /data/code/mysql-server/sql/sql_parse.cc:3450
#13 0x00000000038ce7e7 in dispatch_sql_command (thd=0x7f03ec000da0, parser_state=0x7f04944c2a90)
    at /data/code/mysql-server/sql/sql_parse.cc:5033
#14 0x00000000038c50cc in dispatch_command (thd=0x7f03ec000da0, com_data=0x7f04944c3b40, command=COM_QUERY)
    at /data/code/mysql-server/sql/sql_parse.cc:1863
#15 0x00000000038c3626 in do_command (thd=0x7f03ec000da0) at /data/code/mysql-server/sql/sql_parse.cc:1342
#16 0x0000000003a9e3e7 in handle_connection (arg=0xc002c30)
    at /data/code/mysql-server/sql/conn_handler/connection_handler_per_thread.cc:301
#17 0x000000000580b254 in pfs_spawn_thread (arg=0xc0ce810) at /data/code/mysql-server/storage/perfschema/pfs.cc:2898
#18 0x00007f04a5de2ea5 in start_thread () from /lib64/libpthread.so.0
#19 0x00007f04a4537b0d in clone () from /lib64/libc.so.6