rfcs/identity-columns.md
---
authors: Philip Lykke Carlsen <[email protected]>
discussion:
https://github.com/hasura/graphql-engine-mono/issues/2407
https://github.com/hasura/graphql-engine-mono/pull/2507
state: pending answers to unresolved questions
---
This RFC collects discussion and decisions on how we want Identity Columns to work in the GraphQL Engine.
Identity Columns are an SQL standard database feature that attempts to solve the problem of generating row identifiers in a more sound way than naive auto-incrementing columns. This works by imposing restrictions on how such columns may be updated.
This means that, in order for the GraphQL engine to correctly deal with tables that have identity columns it has to observe these restrictions, specifically when updating and inserting.
It is also possible to sometimes override the constraints imposed by Identity Columns, and we need to decide what we want to support and how we want to support it.
Overall, there are two flavors of identity columns we may encounter:
(Postgres only) Identity columns declared GENERATED BY DEFAULT AS IDENTITY
work just like regular SERIAL columns and impose no further constraints.
We can view these as being identity-columns-in-name-only.
The more "true" Identity Columns, supported by both MSSQL and PostgreSQL, are not updatable and only insertable using and override mechanism:
IDENTITY(..) may be inserted into only when SET IDENTITY_INSERT is applied to that table.GENERATED ALWAYS AS IDENTITY
may be inserted into by giving the clause OVERRIDING SYSTEM VALUE in an
INSERT statement.We need to decide how/when/if we want to expose the overriding mechanism in our GraphQL API (see the Unresolved Questions section below).
Implementing the handling of identity columns should apply the architecture described in Column Mutability.
If we go with the non-overriding policy described above there should not be any changes necessary to SQL translation for either MSSQL or PostgreSQL.
The only necessary change then ought to be amending the table metadata extraction (for both MSSQL and PostgreSQL) to identify identity columns and set column mutability accordingly (i.e. not insertable, not updatable).
When, if ever, should we make use of the constraints overriding mechanisms described above? Do we want to never override? Always? Make it configurable?
Note that:
The purpose of this appendix is to collect relevant information on the concept of Identity Columns and inform the implementation of GraphQL Engine.
In a sentence:
Identity columns are immutable, sequentially distinct values provided only by the DBMS
INSERT values for Identity Columns, but guarded by a SET INSERT_IDENTITY <tablename> ON statement.UPDATE values for Identity Columns.column IDENTITY(type, seed, increment).PG Create table syntax (including GENERATED)
column GENERATED BY DEFAULT AS IDENTITY, column GENERATED ALWAYS AS IDENTITY.series.GENERATED BY DEFAULT may be both INSERTed and and UPDATEd.GENERATED ALWAYS may be INSERTed (guarded by an OVERRIDE SYSTEM VALUE keyword), but never UPDATEd.For new applications, identity columns should be used instead.
Why not?
The serial types have some weird behaviors that make schema, dependency, and permission management unnecessarily cumbersome.