[MDEV-15364] FOREIGN CASCADE operations in system versioned referenced tables Created: 2018-02-20 Updated: 2020-12-12 Resolved: 2018-04-09 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB, Versioned Tables |
| Affects Version/s: | 10.3.4 |
| Fix Version/s: | 10.3.6 |
| Type: | Bug | Priority: | Major |
| Reporter: | Eugene Kosov (Inactive) | Assignee: | Thirunarayanan Balathandayuthapani |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||
| Description |
|
Last SELECT returns this:
So, history row was not inserted on UPDATE. This is a bug. MS SQL produces a history in that case: http://sqlfiddle.com/#!18/a073b/15 |
| Comments |
| Comment by Eugene Kosov (Inactive) [ 2018-02-21 ] | |||||||||||||||
|
Logic on versioned delete (which is UPDATE SET ROW_END=CURRENT_TIMESTAMP) is implemented inside row_update_cascade_for_mysql(). This also looks like a right place to implement versioned UPDATE (which is UPDATE current row + INSERT historical row).
| |||||||||||||||
| Comment by Eugene Kosov (Inactive) [ 2018-02-26 ] | |||||||||||||||
|
I will try to insert a historical row just after `row_upd_step` in `row_update_cascade_for_mysql`. | |||||||||||||||
| Comment by Eugene Kosov (Inactive) [ 2018-03-13 ] | |||||||||||||||
|
row_update_cascade_for_mysql() calls row_upd_step() It's possible to insert historical row before updating. But I think this will result in extra BTree search because we need to read current row values. Second search will be performed in subsequent row_upd_step() I've tried to make row_upd_step() set row_end = CURRENT_TIMESTAMP only and after that insert a new row with updated values. This broke recursive CASCADE UPDATE because it is triggered on update of foreign fields. Now I make upd_node_t save old row_start to upd_node_t::upd_t::vers_sys_value. After row_upd_step() historical row is created and inserted. Foreign values can be updated from parent upd_node_t which is in progress at that moment and have old rows values. | |||||||||||||||
| Comment by Eugene Kosov (Inactive) [ 2018-03-13 ] | |||||||||||||||
|
I was wrong. At the moment of row_upd_step()` call we have a *btr_pcur_t` which point to a record to update. So we can easily read that record, set *row_end=current_timestamp and insert it before it's updated. | |||||||||||||||
| Comment by Eugene Kosov (Inactive) [ 2018-03-19 ] | |||||||||||||||
|
Corresponding PR https://github.com/MariaDB/server/pull/667 | |||||||||||||||
| Comment by Marko Mäkelä [ 2018-03-20 ] | |||||||||||||||
|
I requested some changes. | |||||||||||||||
| Comment by Marko Mäkelä [ 2018-04-06 ] | |||||||||||||||
|
The revised code looks OK to me, with only one bigger issue: the memory for historical_row is allocated from row_prebuilt_t::heap and thus will not be freed before the end of the statement. The actual needed lifetime should only be until the end of the current row operation. Because I will be away next week, thiru will do the final approval. |