Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.7] Add support for identity columns in PostgreSQL 10+ #26096

Merged
merged 1 commit into from
Oct 12, 2018

Conversation

pmatseykanets
Copy link
Contributor

Since PostgreSQL 10 the preferred method of defining auto increment
columns is to use SQL standard identity columns instead of SERIAL pseudo-types

COLUMN TYPE GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]

See https://www.postgresql.org/docs/10/static/sql-createtable.html

Identity columns fix issues with SERIAL pseudo-types:

  • CREATE TABLE / LIKE copies default but refers to same sequence
  • cannot add/drop serialness with ALTER TABLE
  • dropping default does not drop sequence
  • need to grant separate privileges to sequence
  • other slight weirdnesses because serial is some kind of special macro

as explained by the author of the patch

PostgreSQL 10 has a pretty wide adoption and is a default version on Forge. More over the next major version PostgreSQL 11 is coming in a week or two.


This PR allows to define an identity column without introducing BC.

$table->increments('id')->generatedAs();

produces

id integer generated by default as identity primary key not null

always() can be optionally used to make sure that a sequence value takes precedence over the user input

$table->increments('id')->always()->generatedAs();

gives us

id integer generated always as identity primary key not null

generatedAs() optionally accepts a string or an Expression containing sequence options, i.e.

$table->increments('id')->generatedAs('start with 1000 increment by 10');

produces

id integer generated by default as identity (start with 1000 increment by 10) primary key not null

An identity column does not necessarily have to be an increments one (PK)

$table->bigIteger('id')->generatedAs();

produces

id integer generated by default as identity not null

Since PostgreSQL 10 the preferred method of defining auto increment
columns is to use SQL standard identity columns instead of SERIAL psedo-types
COLUMN TYPE GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]
See https://www.postgresql.org/docs/10/static/sql-createtable.html

It fixes issues with SERIAL psudo-types:
- CREATE TABLE / LIKE copies default but refers to same sequence
- cannot add/drop serialness with ALTER TABLE
- dropping default does not drop sequence
- need to grant separate privileges to sequence
- other slight weirdnesses because serial is some kind of special macro
As explained by author of the patch in
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=3217327053638085d24dd4d276e7c1f7ac2c4c6b
@taylorotwell
Copy link
Member

This breaks support on Postgres < 10?

@pmatseykanets
Copy link
Contributor Author

It doesn't. But these two new column modifiers make sense only for PostgreSQL 10+, meaning increments() and all of its variants will still produce a corresponding SERIAL type even on PostgreSQL 10+ if generatedAs() is not applied.

$table->increments('id')
// still compiles to - id serial primary key not null

where as

$table->increments('id')->always()->generatedAs();
// gives us - id integer generated always as identity primary key not null

It's an opt-in approach that that is consistent with how other column modifiers are currently used in Laravel and exactly why this approach was taken. I.e. virtualAs() or storedAs() make sense and supported only by MySQL 5.7+ and therefore are incompatible with MySQL 5.6.

@taylorotwell taylorotwell merged commit 3cad372 into laravel:5.7 Oct 12, 2018
@taylorotwell
Copy link
Member

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants