Problem/Motivation

This will not be easy at all, but I think it would be good to at least have a discussion.

Passing an arbitrary value to a serial (autoincrement) column has very different outcomes on different database engines.

Supposing the max ID in the db is 1, and the arbitrary value of ID in INSERT is 1000:

  • MySql and SQLite: the INSERT succeeds with ID=1000, and next record will have an ID=1001
  • Postgres: the INSERT succeeds with ID=1000, and next record will have an ID=2 (Drupal currently works around this by adjusting the internal sequence to 1000, but it's rather expensive, as it needs introspecting the table's columns)
  • DB2: the INSERT succeeds with ID=1000, and next record will have an ID=2
  • Oracle: does not support autoincrement columns natively, but triggers can be built to emulate the behaviour
  • MS SQL: the INSERT fails

More info: https://github.com/doctrine/dbal/issues/4725

Proposed resolution

  • Consider prohibiting to pass an arbitrary value to a serial column.
  • Evaluate where this is currently needed and find alternatives for each case.
  • Find a way to fail an INSERT operation if an arbitrary value is passed in for the serial column (i.e. align to the strictest behavior, which is MS Sql's).

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

mondrake created an issue. See original summary.

mondrake’s picture

Issue summary: View changes
mondrake’s picture

Title: Avoid passing arbitrary values to the serial column » Avoid passing arbitrary values to the serial column on INSERT

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

alexpott’s picture

I'm not sure this will ever be possible given the anonymous user. Unless there's a db agnostic way to tell a serial field to start from 0.

mondrake’s picture

Are UID=0 and UID=1 for respectively anonymous user and administrator user the only cases in Drupal (core) where it's necessary to force an arbitrary value to a serial column?

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.