MDEV-38830: SIGSEGV and UBSAN null-pointer-use in TABLE::evaluate_upd…#4907
Open
MDEV-38830: SIGSEGV and UBSAN null-pointer-use in TABLE::evaluate_upd…#4907
Conversation
…ate_default_function on UPDATE MDEV-38716 fixes were incomplete. It still allowed a table's default_fields to be left un-restored after an ALTER table finished its copy_data_between_fields(). This patch actually matches the original conception of MDEV-38716. It was later changed after finding a test failure in maria.alter, where I thought the patch broke that test. But actually, maria.alter itself relies on somewhat broken/inconsistent server behavior. It is the MDEV-19055 extension of the test which broke. To summarize the broken part of the test, first, it creates a temporary table t2, adds a new column of type DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, and adds a constraint check on that new type: CREATE TEMPORARY TABLE t2 (a TIME) ENGINE=Aria; ALTER TABLE t2 ADD b DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP; ALTER TABLE t2 ADD CHECK (b = 4); The next part results in inconsistent behavior: INSERT IGNORE INTO t2 () VALUES (),(),(),(); What is not defined is "what should this do"? Prior to this patch / MDEV-38716, this would create 4 new rows, each with a zeroed out timestamp for `b`. This is due to a the default_field not resetting after the ALTER TABLE, thus the DEFAULT CURRENT_TIMESTAMP clause is lost after the ALTER TABLE ADD CHECK. With this patch, because the default_field is restored after the ALTER, there is no affect of the INSERT IGNORE INTO t2. I.e., t2 is empty after this insert. This change in results further changes how an ALTER TABLE behaves later in the test: SET SQL_MODE= 'STRICT_ALL_TABLES'; SELECT count(a),sum(a) FROM t2; --error ER_TRUNCATED_WRONG_VALUE ALTER TABLE t2 CHANGE IF EXISTS d c INT; Without this patch, there are rows in t2, and so this ALTER TABLE results in an error. With this patch, t2 is empty, and therefore there is no data that was truncated to warn about. Also note, the result of INSERT IGNORE INTO t2 () VALUES (),(),(),(); is very inconsistent overall. For example, if t2 is a regular table (rather than a temporary table), the pre-patch result is also NULL. However, if values are explicitly provided (in any case), the result is truncated and rows are added to the table. E.g. INSERT IGNORE INTO t2 (b) VALUES (1),(2),(3),(5); will result in 4 rows with truncated timestamps in any case. See also MDEV-30115 for more problems with INSERT IGNORE and CHECK. Reviewed-by: Monty <monty@mariadb.com> Signed-off-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MDEV-38716 fixes were incomplete. It still allowed a table's default_fields to be left un-restored after an ALTER table finished its copy_data_between_fields().
This patch actually matches the original conception of MDEV-38716. It was later changed after finding a test failure in maria.alter, where I thought the patch broke that test. But actually, maria.alter itself relies on somewhat broken/inconsistent server behavior.
It is the MDEV-19055 extension of the test which broke. To summarize the broken part of the test, first, it creates a temporary table t2, adds a new column of type DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, and adds a constraint check on that new type:
The next part results in inconsistent behavior:
What is not defined is "what should this do"?
Prior to this patch / MDEV-38716, this would create 4 new rows, each with a zeroed out timestamp for
b. This is due to a the default_field not resetting after the ALTER TABLE, thus the DEFAULT CURRENT_TIMESTAMP clause is lost after the ALTER TABLE ADD CHECK.With this patch, because the default_field is restored after the ALTER, there is no affect of the INSERT IGNORE INTO t2. I.e., t2 is empty after this insert.
This change in results further changes how an ALTER TABLE behaves later in the test:
Without this patch, there are rows in t2, and so this ALTER TABLE results in an error. With this patch, t2 is empty, and therefore there is no data that was truncated to warn about.
Also note, the result of
is very inconsistent overall. For example, if t2 is a regular table (rather than a temporary table), the pre-patch result is also NULL. However, if values are explicitly provided (in any case), the result is truncated and rows are added to the table. E.g.
will result in 4 rows with truncated timestamps in any case.
See also MDEV-30115 for more problems with INSERT IGNORE and CHECK.