Bug #111377 int mysql_execute_command(THD*, bool): Assertion `!thd->in_sub_stmt' failed
Submitted: 13 Jun 2023 2:40 Modified: 13 Jun 2023 7:54
Reporter: Yu Liang Email Updates:
Status: Verified 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)

[13 Jun 2023 2:40] Yu Liang
Description:
The latest version of the MySQL Server (version 8.0.33) (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(c1 INT);
INSERT DELAYED IGNORE v0 SET c1 = DEFAULT AS v2 ON DUPLICATE KEY UPDATE c1 = DEFAULT ;
CREATE TRIGGER t2 AFTER UPDATE ON v0 FOR EACH ROW CREATE FUNCTION f3 RETURNS REAL SONAME 'any_name' ;
UPDATE IGNORE v0 SET c1 = DEFAULT ;
```

The last query returns error: 

```
mysql> UPDATE IGNORE v0 SET c1 = DEFAULT ;
mysqld: /home/mysql/mysql-server/sql/sql_parse.cc:3241: int mysql_execute_command(THD *, bool): Assertion `!thd->in_sub_stmt' failed.
2023-06-13T02:40:01Z 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: 0xffff04001040
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 = ffffa0216538 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) [0xffffab9b17a0]
/lib/aarch64-linux-gnu/libc.so.6(gsignal+0xe0) [0xffffab025d78]
/lib/aarch64-linux-gnu/libc.so.6(abort+0x114) [0xffffab012aac]
/lib/aarch64-linux-gnu/libc.so.6(+0x2d490) [0xffffab01f490]
/lib/aarch64-linux-gnu/libc.so.6(+0x2d4f4) [0xffffab01f4f4]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(mysql_execute_command(THD*, bool)+0xc7d4) [0x1635c90]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(sp_instr_stmt::exec_core(THD*, unsigned int*)+0xc4) [0x13f8984]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(sp_lex_instr::reset_lex_and_exec_core(THD*, unsigned int*, bool)+0x50c) [0x13f46bc]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(sp_lex_instr::validate_lex_and_execute_core(THD*, unsigned int*, bool)+0x29c) [0x13f652c]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(sp_instr_stmt::execute(THD*, unsigned int*)+0x3d0) [0x13f7458]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(sp_head::execute(THD*, bool)+0xbbc) [0x13dc358]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(sp_head::execute_trigger(THD*, MYSQL_LEX_CSTRING const&, MYSQL_LEX_CSTRING const&, GRANT_INFO*)+0x470) [0x13de09c]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Trigger::execute(THD*)+0x158) [0x1984e3c]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Trigger_chain::execute_triggers(THD*)+0xcc) [0x1988960]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Table_trigger_dispatcher::process_triggers(THD*, enum_trigger_event_type, enum_trigger_action_time_type, bool)+0x1fc) [0x196eda8]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Sql_cmd_update::update_single_table(THD*)+0x4268) [0x18c133c]
/home/mysql/mysql-server/bld/runtime_output_directory/mysqld(Sql_cmd_update::execute_inner(THD*)+0x1b4) [0x18c9714]
/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) [0xffffab957624]
/lib/aarch64-linux-gnu/libc.so.6(+0xd149c) [0xffffab0c349c]

Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (ffff041f3080): CREATE FUNCTION f3 RETURNS REAL SONAME 'any_name'
Connection ID (thread ID): 8
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 -DUSE_LD_GOLD=1 -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(c1 INT);
INSERT DELAYED IGNORE v0 SET c1 = DEFAULT AS v2 ON DUPLICATE KEY UPDATE c1 = DEFAULT ;
CREATE TRIGGER t2 AFTER UPDATE ON v0 FOR EACH ROW CREATE FUNCTION f3 RETURNS REAL SONAME 'any_name' ;
UPDATE IGNORE v0 SET c1 = DEFAULT ;
```

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

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

regards,
Umesh
[13 Jun 2023 7:55] MySQL Verification Team
-- release build
 ./mtr bug111377 --nocheck-testcases
Logging: ./mtr  bug111377 --nocheck-testcases
MySQL Version 8.0.33
Checking supported features
Using 'all' suites
Collecting tests
Checking leftover processes
Removing old var directory
Creating var directory '/export/home/tmp/ushastry/binaries/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(c1 INT);
INSERT DELAYED IGNORE v0 SET c1 = DEFAULT AS v2 ON DUPLICATE KEY UPDATE c1 = DEFAULT ;
Warnings:
Warning 3005    INSERT DELAYED is no longer supported. The statement was converted to INSERT.
CREATE TRIGGER t2 AFTER UPDATE ON v0 FOR EACH ROW CREATE FUNCTION f3 RETURNS REAL SONAME 'any_name' ;
UPDATE IGNORE v0 SET c1 = DEFAULT ;
[ 50%] main.bug111377                            [ fail ]
        Test ended at 2023-06-13 09:52:12

CURRENT_TEST: main.bug111377
mysqltest: At line 7: Query 'UPDATE IGNORE v0 SET c1 = DEFAULT ' failed.
ERROR 1422 (HY000): Explicit or implicit commit is not allowed in stored function or trigger.

-- debug build - affected
 ./mtr bug111377 --nocheck-testcases --debug-server
Logging: ./mtr  bug111377 --nocheck-testcases --debug-server
MySQL Version 8.0.33
Checking supported features
 - Binaries are debug compiled
Using 'all' suites
Collecting tests
Checking leftover processes
Removing old var directory
Creating var directory '/export/home/tmp/ushastry/binaries/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(c1 INT);
INSERT DELAYED IGNORE v0 SET c1 = DEFAULT AS v2 ON DUPLICATE KEY UPDATE c1 = DEFAULT ;
Warnings:
Warning 3005    INSERT DELAYED is no longer supported. The statement was converted to INSERT.
CREATE TRIGGER t2 AFTER UPDATE ON v0 FOR EACH ROW CREATE FUNCTION f3 RETURNS REAL SONAME 'any_name' ;
UPDATE IGNORE v0 SET c1 = DEFAULT ;
[ 50%] main.bug111377                            [ fail ]
        Test ended at 2023-06-13 09:52:56

CURRENT_TEST: main.bug111377
mysqltest: At line 7: Query 'UPDATE IGNORE v0 SET c1 = DEFAULT ' failed.
ERROR 2013 (HY000): Lost connection to MySQL server during query

-bt

#0  0x00007fb1a3269aa1 in pthread_kill () from /lib64/libpthread.so.0
#1  0x0000000004005426 in my_write_core(int) ()
#2  0x00000000032b0166 in handle_fatal_signal ()
#3  <signal handler called>
#4  0x00007fb1a172a387 in raise () from /lib64/libc.so.6
#5  0x00007fb1a172ba78 in abort () from /lib64/libc.so.6
#6  0x00007fb1a17231a6 in __assert_fail_base () from /lib64/libc.so.6
#7  0x00007fb1a1723252 in __assert_fail () from /lib64/libc.so.6
#8  0x000000000313c414 in mysql_execute_command(THD*, bool) ()
#9  0x000000000307cc53 in sp_instr_stmt::exec_core(THD*, unsigned int*) ()
#10 0x000000000307e489 in sp_lex_instr::reset_lex_and_exec_core(THD*, unsigned int*, bool) ()
#11 0x000000000307e9b9 in sp_lex_instr::validate_lex_and_execute_core(THD*, unsigned int*, bool) ()
#12 0x000000000307f19c in sp_instr_stmt::execute(THD*, unsigned int*) ()
#13 0x000000000307455d in sp_head::execute(THD*, bool) ()
#14 0x0000000003074db8 in sp_head::execute_trigger(THD*, MYSQL_LEX_CSTRING const&, MYSQL_LEX_CSTRING const&, GRANT_INFO*) ()
#15 0x000000000325beaf in Trigger::execute(THD*) ()
#16 0x000000000325d54b in Trigger_chain::execute_triggers(THD*) ()
#17 0x000000000325460e in Table_trigger_dispatcher::process_triggers(THD*, enum_trigger_event_type, enum_trigger_action_time_type, bool) ()
#18 0x00000000032153c1 in Sql_cmd_update::update_single_table(THD*) ()
#19 0x0000000003215ae3 in Sql_cmd_update::execute_inner(THD*) ()
#20 0x000000000319e6cc in Sql_cmd_dml::execute(THD*) ()
#21 0x000000000313d2da in mysql_execute_command(THD*, bool) ()
#22 0x0000000003140bc8 in dispatch_sql_command(THD*, Parser_state*) ()
#23 0x00000000031421fb in dispatch_command(THD*, COM_DATA const*, enum_server_command) ()
#24 0x0000000003143e97 in do_command(THD*) ()
#25 0x00000000032a219e in handle_connection ()
#26 0x00000000047b1601 in pfs_spawn_thread ()
#27 0x00007fb1a3264ea5 in start_thread () from /lib64/libpthread.so.0
#28 0x00007fb1a17f2b2d in clone () from /lib64/libc.so.6