Details
Description
UPDATE FOR PORTION OF creates leftover rows whose stored generated column does not reflect changes made by a BEFORE INSERT trigger. The statement succeeds, but both leftovers retain g='g-old' after the trigger changes a to 'trigger'.
This occurs when an application-time period update splits a row in a table with a stored generated column and a BEFORE INSERT trigger that changes its input.
Reproduction
Execute the following SQL in one MariaDB client session with permission to create a database, table and trigger. The database name must be unused. The initial row is inserted before the trigger is created; the subsequent ordinary INSERT provides a control for generated-column calculation after the trigger.
CREATE DATABASE period_demo; |
USE period_demo; |
CREATE TABLE t1 (id INT, a VARCHAR(20), s DATE, e DATE, |
PERIOD FOR app_time(s,e), |
g TEXT AS (CONCAT('g-',a)) STORED) ENGINE=InnoDB; |
INSERT INTO t1 (id,a,s,e) VALUES (1,'old','2000-01-01','2020-01-01'); |
CREATE TRIGGER bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a='trigger'; |
INSERT INTO t1 (id,a,s,e) VALUES (2,'control','2000-01-01','2020-01-01'); |
SELECT 'control',a,g,g=CONCAT('g-',a) AS ok FROM t1 WHERE id=2; |
UPDATE t1 FOR PORTION OF app_time FROM '2005-01-01' TO '2010-01-01' SET a='new' WHERE id=1; |
SELECT id,a,s,e,g,g=CONCAT('g-',a) AS ok FROM t1 ORDER BY id,s; |
SELECT 'oracle',COUNT(*) AS rows_seen,SUM(NOT(g <=> CONCAT('g-',a))) AS mismatches FROM t1; |
Actual result
The SQL completes without errors and returns:
control a g ok
|
control trigger g-trigger 1
|
id a s e g ok
|
1 trigger 2000-01-01 2005-01-01 g-old 0
|
1 new 2005-01-01 2010-01-01 g-new 1
|
1 trigger 2010-01-01 2020-01-01 g-old 0
|
2 trigger 2000-01-01 2020-01-01 g-trigger 1
|
oracle rows_seen mismatches
|
oracle 4 2
|
Expected result
Every stored g must equal CONCAT('g-',a), its declared generation expression. Both leftover rows should therefore contain a='trigger', g='g-trigger', and ok=1. The middle portion should remain a='new', g='g-new', and the ordinary INSERT control should remain a='trigger', g='g-trigger'. The final aggregate should report four rows and zero mismatches.
The trigger changing a in the leftover rows is expected; retaining a generated value calculated from the previous a is the defect.
Attachments
Issue Links
- relates to
-
MDEV-40480 LOAD DATA leaves a stale STORED generated column after a BEFORE INSERT trigger changes its base column
-
- Closed
-