[MDEV-25370] Update for portion changes autoincrement key in period table Created: 2021-04-08 Updated: 2024-02-06 Resolved: 2024-01-31 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Versioned Tables |
| Affects Version/s: | 10.4.14, 10.5 |
| Fix Version/s: | 11.3.2, 10.5.25, 10.6.18, 10.11.8, 11.0.6, 11.1.5, 11.2.4 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Enrica Ruedin | Assignee: | Nikita Malyavin |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | PORTION, application_time, autoincrement | ||
| Environment: |
Windows |
||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Description |
|
I use a bi-temp table (application time period and system time versioning) with an autoincrement id. If I update a record with "FOR PORTION OF" the part of id in primary key changes automatically. I think, this isn't correct. The id expresses the associated business fact. Example and reproduction: Starting Position:
Enter one record, result Behaviour of using FOR PORTION OF:
Given result: Line 1 is old versiones record as expected. Line 3 is new price record under id = 1 valid from 2021-04-01 as expected. But the old price which was valid between 2021-01-01 and 2021-04-01 has been stored automatically under id = 2 instead of id = 1 (it's still the price for procuct 1) Think what would happen if this table had a related child table. The fk reference is broken. Expected result:
expected result: Now, the same business fact has a correct application time line and the change is versioned correctly. |
| Comments |
| Comment by Sergei Golubchik [ 2021-04-14 ] | ||||||||||||||||||||||||||||||||
|
I'd expect the correct key definition should be
but this doesn't help, new auto-inc value is still generated. | ||||||||||||||||||||||||||||||||
| Comment by Enrica Ruedin [ 2021-04-14 ] | ||||||||||||||||||||||||||||||||
|
serg: | ||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2021-04-14 ] | ||||||||||||||||||||||||||||||||
|
If you've tried different variants of your table definition and they delivered unexpected results — please, mention everything that you tried here. Perhaps that all also can be fixed as a part of this bug, if the underlying code problem is the same. | ||||||||||||||||||||||||||||||||
| Comment by Enrica Ruedin [ 2023-06-10 ] | ||||||||||||||||||||||||||||||||
|
Hi Sergei After more than 1.5 years I tried it again. Until now I worked without bi-temp tables that's why it was not so urgent. Last week I startet to implement bi-temp in a Laravel package. That's how I remembered my bug report. I investigated a little bit more. So SYSTEM VERSION based tables are working fine and the autoincrement id is not incremented. The problem is with APPLICATION PERIOD based tables or bi-temp only. I saw that your examples and those on the internet only work without autoincrement keys. (see KB MariaDB Application-Time Periods) So I create a simple table with two dates defined as PERIOD FOR. see:
Remark: the column 'id' is AUTOINCREMENT and part of the PK. I add a record. The result is
In this step all is OK and the key is set automatically to the value 1. Then I add a new record using PORTION OF like
A "normal" update would never change the id (PK). The result what I get is:
It is clear that minimum one of these two must be in the PK. This is ensured. It seems that MariaDB is updated the "new" record correctly but the "old" one is inserted as a complete new record. In this case autoincrement must be avoided. Autoincrementing the "id" must be allowed for INSERT not for UPDATE. Strangely enough this works with System Versioned columns. Unique WITHOUT OVERLAPS has no influence on this behaviour. Conclusion: If a developer relies on UUID keys or self-generated increment keys, then Application-Time Period works, otherwise not. Thank you for your investigation and correction. | ||||||||||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2023-12-15 ] | ||||||||||||||||||||||||||||||||
|
Well, the standard says that a corresponding internally generated INSERT statement should contain a DEFAULT value for the identity column (that is, AUTO_INCREMENT in our implementation). Though I agree: for this case, as well as the case like PRIMARY KEY(id, p WITHOUT OVERLAPS) this behavior is not usable. So, at least for this feature, let's treat identity column as AUTO_INCREMENT, but only if it's a part of a unique key, that does not feature WITHOUT OVERLAPS | ||||||||||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2023-12-20 ] | ||||||||||||||||||||||||||||||||
|
I have made more research around identity column in the standard: it makes no exceptions to the usage. Even for WITHOUT OVERLAPS. And for the rest of the queries the same field would have an effect of identity column. I still agree that it's simply not practically usable this way, just I can't call it our reading, but a step aside. After looking at some configurations I decided that the best way is to make an exception for all AUTO_INCREMENT columns that are part of keys, that include WITHOUT OVERLAPS. No matter if it's part of any other keys or not. Pros:
Cons:
serg please review my approach and the solution on branch bb-10.5-periods-autoinc. | ||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2024-01-03 ] | ||||||||||||||||||||||||||||||||
|
You're right that the standard says "statement should contain a DEFAULT value for the identity column", for the reference, it's in SQL:2016, Part 2, 15.13 Effect of replacing rows in base tables, paragraph 10) b) i) But there's no concept of "IDENTITY WITHOUT OVERLAPS" in the standard, this is our extension and we can define its behavior as we want. So, fine, let's try to make it to keep old values when a row is split. | ||||||||||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2024-01-03 ] | ||||||||||||||||||||||||||||||||
|
It's not IDENTITY WITHOUT OVERLAPS. It's IDENTITY, <period> WITHOUT OVERLAPS. And IDENTITY is not forbidden to be a part of such a key anywhere. | ||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2024-01-03 ] | ||||||||||||||||||||||||||||||||
|
IDENTITY can be part of the key, and the key can be WITHOUT OVERLAPS. But this key doesn't determine how values are generated, it's simply a constraint. While values are generated by a completely separate sequence generator which knows nothing about the period and its overlaps. So, above I meant that there's no IDENTITY column in the standard that can be declared to know about overlaps. There can be a totally unrelated unique constraint WITHOUT OVERLAPS though. | ||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2024-01-23 ] | ||||||||||||||||||||||||||||||||
|
09bf45a89ee2 is ok to push. Please, make sure this behavior is clearly documented. | ||||||||||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2024-01-31 ] | ||||||||||||||||||||||||||||||||
|
Fix pushed to the 10.5 branch. The new behavior will be documented in scope of MDEV-33346. Would be good to make it blocker, so that we'd definitely have it updated to the release day. |