[MDEV-18042] Server crashes in mysql_alter_table upon adding a non-null date column under NO_ZERO_DATE with ALGORITHM=INPLACE Created: 2018-12-20  Updated: 2020-07-31  Resolved: 2020-07-31

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table, Temporal Types
Affects Version/s: 10.5.3, 10.2, 10.3, 10.4
Fix Version/s: 10.2.33, 10.3.24, 10.4.14, 10.5.5

Type: Bug Priority: Critical
Reporter: Elena Stepanova Assignee: Nikita Malyavin
Resolution: Fixed Votes: 0
Labels: affects-tests, not-10.1

Issue Links:
Duplicate
is duplicated by MDEV-18555 Server crashes in mysql_alter_table w... Closed
is duplicated by MDEV-22381 SIGSEGV in mysql_alter_table on ALTER... Closed

 Description   

CREATE TABLE t1 (i INT) ENGINE=MyISAM;
SET SQL_MODE= 'NO_ZERO_DATE';
ALTER TABLE t1 ADD COLUMN d DATE NOT NULL, ALGORITHM=INPLACE;
 
# Cleanup
DROP TABLE t1;

10.2 0c2fc9b3da4

#3  <signal handler called>
#4  0x000055efbda4556e in mysql_alter_table (thd=0x7f29dc000b00, new_db=0x7f29dc0051c8, new_name=0x7f29dc005598, create_info=0x7f29eead04d0, table_list=0x7f29dc0150c0, alter_info=0x7f29eead0410, order_num=0, order=0x0, ignore=false) at /data/src/10.4/sql/sql_table.cc:10109
#5  0x000055efbdace69b in Sql_cmd_alter_table::execute (this=0x7f29dc015820, thd=0x7f29dc000b00) at /data/src/10.4/sql/sql_alter.cc:497
#6  0x000055efbd96b9b9 in mysql_execute_command (thd=0x7f29dc000b00) at /data/src/10.4/sql/sql_parse.cc:6302
#7  0x000055efbd9708e4 in mysql_parse (thd=0x7f29dc000b00, rawbuf=0x7f29dc014f98 "ALTER TABLE t1 ADD COLUMN d DATE NOT NULL, ALGORITHM=INPLACE", length=60, parser_state=0x7f29eead1600, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:8104
#8  0x000055efbd95db0e in dispatch_command (command=COM_QUERY, thd=0x7f29dc000b00, packet=0x7f29dc00b421 "ALTER TABLE t1 ADD COLUMN d DATE NOT NULL, ALGORITHM=INPLACE", packet_length=60, is_com_multi=false, is_next_command=false) at /data/src/10.4/sql/sql_parse.cc:1851
#9  0x000055efbd95c532 in do_command (thd=0x7f29dc000b00) at /data/src/10.4/sql/sql_parse.cc:1396
#10 0x000055efbdac86de in do_handle_one_connection (connect=0x55efc08f26a0) at /data/src/10.4/sql/sql_connect.cc:1402
#11 0x000055efbdac8462 in handle_one_connection (arg=0x55efc08f26a0) at /data/src/10.4/sql/sql_connect.cc:1308
#12 0x000055efbdf87338 in pfs_spawn_thread (arg=0x55efc0836960) at /data/src/10.4/storage/perfschema/pfs.cc:1862
#13 0x00007f29f63fb494 in start_thread (arg=0x7f29eead2700) at pthread_create.c:333
#14 0x00007f29f49fc93f in clone () from /lib/x86_64-linux-gnu/libc.so.6

Reproducible with at least MyISAM and Aria.
Not reproducible with InnoDB.
Not reproducible on 10.1, ALTER instead produces an error that ALGORITHM=INPLACE is not supported for this.

All of debug, non-debug and ASAN builds are affected.



 Comments   
Comment by Alexander Barkov [ 2019-03-21 ]

The problem happens because of a NULL pointer:

(gdb) p	new_table
$5 = (TABLE *) 0x0

If I remove the ALGORIGHTM=INPLACE part, the query works fine, and the crash line with make_truncated_value_warning is never reached:

CREATE OR REPLACE TABLE t1 (i INT) ENGINE=MyISAM;
SET SQL_MODE= 'NO_ZERO_DATE';
ALTER TABLE t1 ADD COLUMN d DATE NOT NULL;

If I additionally insert one record, the query correctly returns with an error, and new_table is a non-null pointer on the line with make_truncated_value_warning:

CREATE OR REPLACE TABLE t1 (i INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1);
SET SQL_MODE= 'NO_ZERO_DATE';
ALTER TABLE t1 ADD COLUMN d DATE NOT NULL;

ERROR 1292 (22007): Incorrect date value: '0000-00-00' for column `test`.`t1`.`d` at row 1

Comment by Elena Stepanova [ 2019-03-30 ]

Here is a test case for InnoDB. I don't know whether it's the same, as INPLACE doesn't play a role here, but it's impossible to distinguish by the stack trace, so I'm adding it here.

--source include/have_innodb.inc
 
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
SET SQL_MODE= 'NO_ZERO_DATE';
ALTER TABLE t1 ADD d DATETIME NOT NULL CHECK (f <= 0);

or

--source include/have_innodb.inc
 
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
SET SQL_MODE= 'NO_ZERO_DATE';
ALTER TABLE t1 ADD d DATETIME NOT NULL CHECK (f <= 0), ALGORITHM=COPY;

10.2 ASAN 8fcd9478

==11298==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x55ebd548ff05 sp 0x7f1229fb7510 bp 0x7f1229fb8e70 T27)
    #0 0x55ebd548ff04 in mysql_alter_table(THD*, char*, char*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool) /data/src/10.2/sql/sql_table.cc:9828
    #1 0x55ebd55ba57a in Sql_cmd_alter_table::execute(THD*) /data/src/10.2/sql/sql_alter.cc:327
    #2 0x55ebd5282c62 in mysql_execute_command(THD*) /data/src/10.2/sql/sql_parse.cc:6226
    #3 0x55ebd528d7cb in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.2/sql/sql_parse.cc:8013
    #4 0x55ebd5268373 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.2/sql/sql_parse.cc:1832
    #5 0x55ebd52653e2 in do_command(THD*) /data/src/10.2/sql/sql_parse.cc:1386
    #6 0x55ebd55ac094 in do_handle_one_connection(CONNECT*) /data/src/10.2/sql/sql_connect.cc:1335
    #7 0x55ebd55abaa9 in handle_one_connection /data/src/10.2/sql/sql_connect.cc:1241
    #8 0x55ebd5fcb129 in pfs_spawn_thread /data/src/10.2/storage/perfschema/pfs.cc:1862
    #9 0x7f123abe5493 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7493)
    #10 0x7f1238db393e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xe893e)
 
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /data/src/10.2/sql/sql_table.cc:9828 mysql_alter_table(THD*, char*, char*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool)
Thread T27 created by T0 here:
    #0 0x7f123ae1ebba in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x23bba)
    #1 0x55ebd5fcb6f1 in spawn_thread_v1 /data/src/10.2/storage/perfschema/pfs.cc:1912
    #2 0x55ebd506182e in inline_mysql_thread_create /data/src/10.2/include/mysql/psi/mysql_thread.h:1239
    #3 0x55ebd5076896 in create_thread_to_handle_connection(CONNECT*) /data/src/10.2/sql/mysqld.cc:6482
    #4 0x55ebd5076f9b in create_new_thread /data/src/10.2/sql/mysqld.cc:6552
    #5 0x55ebd5077fb2 in handle_connections_sockets() /data/src/10.2/sql/mysqld.cc:6827
    #6 0x55ebd5075deb in mysqld_main(int, char**) /data/src/10.2/sql/mysqld.cc:6101
    #7 0x55ebd505fbcf in main /data/src/10.2/sql/main.cc:25
    #8 0x7f1238ceb2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
 
==11298==ABORTING

Comment by Alice Sherepa [ 2019-04-30 ]

reproducible also with ALGORITHM=NOCOPY or ALGORITHM=INSTANT

Comment by Alice Sherepa [ 2019-08-01 ]

set sql_mode='NO_ZERO_DATE';
CREATE TABLE t1 (a int);
ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE;

Comment by Roel Van de Paar [ 2020-04-28 ]

MDEV-22381 confirmed duplicate with some additional 10.5 info etc.

Comment by Oleksandr Byelkin [ 2020-07-10 ]

In error reporting some how supposed to be used "new table" which shoud not be created in case of INPLACE alter, so I have no idea how it shoud work.

Comment by Oleksandr Byelkin [ 2020-07-10 ]

IMHO it is incorrect error handling, the error does not connected with a field

Comment by Alexander Barkov [ 2020-07-29 ]

This patch looks generally OK for me:
https://github.com/MariaDB/server/commit/1998cd91f08a9370cbf500d81efc7b2361503d1a

I have only some minor suggestions:
1. this call is used 10 times in the new code:

  make_truncated_value_warning(current_thd,
                                     Sql_condition::WARN_LEVEL_WARN,
                                     val_begin, length,
				     cached_timestamp_type, NULL, NULL, NULL);

Please add an overloaded function so one can use:

  make_truncated_value_warning(current_thd,
                                     Sql_condition::WARN_LEVEL_WARN,
                                     val_begin, length,
				     cached_timestamp_type, NULL, NULL, NULL);

2. Please add all reported test cases from this MDEV.

Comment by Alexander Barkov [ 2020-07-29 ]

As discussed on Slack, make_truncated_value_warning() is already overloaded in 10.2. So no need to add 2 more overloads. Ok to pass 3 NULLs.

Comment by Alexander Barkov [ 2020-07-29 ]

Ok to push after adding all tests from this MDEV.

Don't forget to remove the not-needed #include <table.h> from sql_time.h.

Comment by Marko Mäkelä [ 2020-07-31 ]

In the merge from 10.3 to 10.4 I had to refactor Temporal::Warn_push warn() and THD::push_warning_truncated_priv() and many other functions accordingly.

For merging to 10.5, there are even more conflicts to be resolved.

It would have been much better if a separate patch for 10.4 and 10.5 had been pushed for test and review before anything was pushed to 10.2. Merges are not reviewed.

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