Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.0, 13.1, 13.2
Description
Likely cause: old code in part_val_int(), not a recent change. MySQL 5.5, 5.6 and 5.7 also keep the row and the new value.
--source include/have_partition.inc
|
CREATE TABLE t1 (a BIGINT) ENGINE=MyISAM PARTITION BY HASH (-a) PARTITIONS 3; |
--error ER_DATA_OUT_OF_RANGE
|
INSERT INTO t1 VALUES (-9223372036854775808); |
--let $n= `SELECT COUNT(*) FROM t1`
|
if ($n) |
{
|
--die The INSERT fails with an out of range error from the partition function, but the row is stored |
}
|
INSERT INTO t1 VALUES (5); |
--error ER_DATA_OUT_OF_RANGE
|
UPDATE t1 SET a = -9223372036854775808; |
--let $n= `SELECT COUNT(*) FROM t1 WHERE a = 5`
|
if (!$n) |
{
|
--die The UPDATE fails with an out of range error from the partition function, but the new value is stored |
}
|
DROP TABLE t1; |
Leads to:
|
CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Optimized, Clang 22.1.8-20260622) Build 06/10/2026 |
mysqltest: At line 8: The INSERT fails with an out of range error from the partition function, but the row is stored
|
The INSERT gives ERROR 1690, but the row is stored. An UPDATE that fails in the same way keeps the new value. On debug builds, the INSERT asserts:
|
CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 06/10/2026 |
mariadbd: /tmp/TODO-6010_partition/13.1_dbg/sql/sql_error.cc:357: void Diagnostics_area::set_ok_status(ulonglong, ulonglong, const char *): Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failed.
|
|
CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 06/10/2026 |
Core was generated by `/tmp/TODO-6010_partition/MD061026-mariadb-13.1.2-linux-x86_64-dbg/bin/mariadbd'.
|
Program terminated with signal SIGABRT, Aborted.
|
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>)at ./nptl/pthread_kill.c:44
|
 |
[Current thread is 1 (LWP 127731)]
|
(gdb) bt
|
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>)at ./nptl/pthread_kill.c:44
|
#1 __pthread_kill_internal (signo=6, threadid=<optimized out>)at ./nptl/pthread_kill.c:78
|
#2 __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6)at ./nptl/pthread_kill.c:89
|
#3 0x00007c4b6b44527e in __GI_raise (sig=sig@entry=6)at ../sysdeps/posix/raise.c:26
|
#4 0x00007c4b6b4288ff in __GI_abort () at ./stdlib/abort.c:79
|
#5 0x00007c4b6b42881b in __assert_fail_base (fmt=0x7c4b6b5d1208 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x573e353e4e1e "!is_set() || (m_status == DA_OK_BULK && is_bulk_op())", file=file@entry=0x573e353e4cad "/tmp/TODO-6010_partition/13.1_dbg/sql/sql_error.cc", line=line@entry=357, function=function@entry=0x573e353e4e54 "void Diagnostics_area::set_ok_status(ulonglong, ulonglong, const char *)") at ./assert/assert.c:96
|
#6 0x00007c4b6b43b517 in __assert_fail (assertion=0x573e353e4e1e "!is_set() || (m_status == DA_OK_BULK && is_bulk_op())", file=0x573e353e4cad "/tmp/TODO-6010_partition/13.1_dbg/sql/sql_error.cc", line=357, function=0x573e353e4e54 "void Diagnostics_area::set_ok_status(ulonglong, ulonglong, const char *)") at ./assert/assert.c:105
|
#7 0x0000573e3436f06b in Diagnostics_area::set_ok_status (this=0x7c4b38007210, affected_rows=1, last_insert_id=0, message=0x0)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_error.cc:357
|
#8 0x0000573e343063cf in my_ok (thd=0x7c4b38000d60, affected_rows_arg=1, id=0, message=0x0)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_class.h:6640
|
#9 0x0000573e3437741f in mysql_insert (thd=0x7c4b38000d60, table_list=0x7c4b38017190, fields=@0x7c4b380062d0: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x573e360f4da0 <end_of_list>, last = 0x7c4b380062d0, elements = 0}, <No data fields>}, values_list=@0x7c4b38006318: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x7c4b38017fa0, last = 0x7c4b38017fa0, elements = 1}, <No data fields>}, update_fields=@0x7c4b38006300: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x573e360f4da0 <end_of_list>, last = 0x7c4b38006300, elements = 0}, <No data fields>}, update_values=@0x7c4b380062e8: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x573e360f4da0 <end_of_list>, last = 0x7c4b380062e8, elements = 0}, <No data fields>}, duplic=DUP_ERROR, ignore=false, result=0x0)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_insert.cc:1467
|
#10 0x0000573e343dda56 in mysql_execute_command (thd=0x7c4b38000d60, is_called_from_prepared_stmt=false)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_parse.cc:4500
|
#11 0x0000573e343d4828 in mysql_parse (thd=0x7c4b38000d60, rawbuf=0x7c4b38017060 "INSERT INTO t1 VALUES (-9223372036854775808)", length=44, parser_state=0x7c4b69d209c0)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_parse.cc:7955
|
#12 0x0000573e343d1fde in dispatch_command (command=COM_QUERY, thd=0x7c4b38000d60, packet=0x7c4b381d3a61 "INSERT INTO t1 VALUES (-9223372036854775808)", packet_length=44, blocking=true)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_parse.cc:1903
|
#13 0x0000573e343d52aa in do_command (thd=0x7c4b38000d60, blocking=true)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_parse.cc:1437
|
#14 0x0000573e345ad3fe in do_handle_one_connection (connect=0x573e604da780, put_in_cache=true)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_connect.cc:1514
|
#15 0x0000573e345ad1e1 in handle_one_connection (arg=0x573e604c6320)at /tmp/TODO-6010_partition/13.1_dbg/sql/sql_connect.cc:1426
|
#16 0x00007c4b6b49cb84 in start_thread (arg=<optimized out>)at ./nptl/pthread_create.c:447
|
#17 0x00007c4b6b529ecc in clone3 ()at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
|
REPLACE and INSERT IGNORE also keep the row. The same happens with RANGE and LIST partitioning and with subpartitions, for example PARTITION BY RANGE (a - b) on two INT UNSIGNED columns when b > a. InnoDB gives the same error and keeps no row.
From the code it seems that raise_integer_overflow() (sql/item_func.h) gives the error and returns 0 without setting null_value. part_val_int() (sql/sql_partition.cc) checks thd->is_error() only when null_value is set. So the row goes to the partition for 0, and the statement ends with the error already in the diagnostics area.