Problem/Motivation
Currently the truncate query does not behave consistently across all DB types: serial IDs are reset on MySQL but not on PgSQL and SQLite.
Proposed resolution
Reset serial IDs by default. Add a new reset_serial_id query option allowing to skip that, if FALSE, or enforce that behavior even inside a transaction.
Remaining tasks
- Validate the proposed solution
Provide a merge request
- Reviews
API changes
None, only additions.
Release notes snippet
A new reset_serial_id query option is available to tweak the behavior of the truncate query.
@Committers: please revert the Drupal CI changes.
Comments
Comment #3
plachComment #4
plachComment #5
daffie commentedThis is to me not a feature request, but just a plain bug. When I truncate a table, I would expect that the value of the primary key would start at 1 again. No new method is needed, just a bugfix and testing.
Comment #6
plachThanks for the feedback! I'm a bit concerned about BC: if this wasn't reported before, couldn't people be relying on the current non-MySQL behaviors?
Comment #7
plachMaybe a change record would be enough, if we only merge this in D12.
Comment #8
daffie commentedDuring the running of a site in production, you will not be calling Connection::truncate() on any table. It is a special operation. And yes, any bug on which code is relaying on to be there, will result in a BC break when you fix the bug. That has not stopped us fixing other bugs. Maybe we can add an option to get the original functionality back, but it default value should be to reset the serial id. We should add a CR for this bug fix.
Comment #9
plachPushed an update resetting serial IDs by default, unless within a transaction or reset skipped explicitly.
Comment #10
plachComment #13
ironnuts commentedRe: #8 and #9, #8 states:
plach, you state at #9 that your commit resets serial ID's by default. So we need a CR, right?
Comment #14
plachI'd say we do need a CR anyway, because we are adding a new option. There we can mention the behavior change, to ensure it's not missed.
Comment #15
plachWe also need an issue summary update, but I'd like to get some feedback on the MR before working on those.
Comment #16
ironnuts commentedRe: #15 Grazie. Comprendo.
Comment #17
daffie commentedI have a single remark on the PR.
The gitlab CI pipeline also needs to run for all the supported databases (MySQL, MariaDB, PostgreSQL and SQLite).
Comment #18
plachImproved readability and run the pipeline all the supported DBs.
Comment #19
plachComment #20
daffie commentedAll changes look good to me.
The IS and CR are good now.
There is testing added.
For me it is RTBC.
Comment #21
catchAdding the option adds a fair amount of complexity here, can we deprecate not resetting the serial ID so that we can eventually remove it? If we do that, then it also looks like we'd need to slightly modify the logic so that when no option is set it always truncates, currently it looks like that's dependent on transaction behaviour?
Comment #22
mondrakeStandardizing the behavior makes a lot of sense, but I am not sure that resetting the sequence by default is the preferable one.
The tests use case is clear - we want to be deterministic so resetting at each test seems fair.
But from a real world data management/archival point view, it would make sense to me NOT to reset the sequence: if I truncate after having taken a snapshot of the data, the sequence reset would block me from reloading parts/all the data should I ever need to.
Comment #23
plach@catch:
Most of the new logic in the MR is about supporting serial ID reset in the SQLite driver. Supporting the option itself is just a couple of lines for each driver. If we get rid of the option, we are preventing PgSQL from clearing tables efficiently without resetting serial IDs, which is what it's being doing so far and seems a valuable feature to retain, although maybe not the default behavior. The option is meant to capture the idea that some DB drivers are able to
TRUNCATEtables without resetting serial IDs, while other ones need to rely onDELETEfor that.Yes, core currently falls back to a
DELETEinside a transaction, to prevent aTRUNCATEfrom causing an implicit commit. PgSql does not need this. The option just lets you get an explicit and predictable behavior with each driver.@mondrake
No strong opinions, but whatever we choose we are going to break someone's workflows, because PgSQL/SQLite have been behaving differently from MySQL so far.
Regardless of the default behavior we pick, I think the use the case mentioned by @mondrake is another argument for keeping the option: both emptying a table without resetting its serial ID and fully truncating it are two valid and common use cases that require driver-specific logic to be implemented properly. I think we should support both. If the option is deemed too complex, we could go back to having different methods as in the initial iterations, but I don't think the complexity of the implementation would change, under the hood.
Or
Comment #24
daffie commentedAll questions have been answered.
Back to RTBC.