Skip to content

Restore trigger-based primary key generation as opt-in primary_key_trigger: option #2597

@yahonda

Description

@yahonda

Background

Trigger-based primary key generation was removed in 61f8a305 (2018, Rails 6 / adapter 6.0) without a prior deprecation cycle. Since then, several users have run into the missing functionality and reverse-engineered the fix in user space:

In retrospect, the 2018 removal was a breaking change without notice, and there is still demand for the trigger-based path — especially on Oracle 11.2 where GENERATED AS IDENTITY is not available, and for legacy schemas with custom triggers.

Relationship to identity work

Proposal

Add a primary_key_trigger: true option to create_table, mirroring the shape of identity: true:

create_table :foo                              # sequence + prefetch (current default)
create_table :foo, identity: true              # identity column (Phase 1, Oracle 12.1+)
create_table :foo, primary_key_trigger: true   # sequence + BEFORE INSERT trigger + RETURNING

Behavior

  • Creates the table with a NUMBER PK column
  • Creates the backing <table>_seq sequence (same as today)
  • Creates a BEFORE INSERT FOR EACH ROW trigger that populates :NEW.id from <table>_seq.NEXTVAL when the inserted value is NULL
  • prefetch_primary_key? returns false for the table (so Rails issues INSERT without computing the id)
  • INSERT uses RETURNING <pk> INTO :returning_id to round-trip the generated id

Validation (symmetric with identity:)

  • primary_key_trigger: true + id: falseArgumentError
  • primary_key_trigger: true + non-:primary_key id: (e.g., :uuid, :integer) → ArgumentError
  • primary_key_trigger: true + composite primary_key:ArgumentError
  • primary_key_trigger: true + identity: trueArgumentError (mutually exclusive)

Detection / round-trip

  • prefetch_primary_key? needs to detect trigger-based tables in addition to identity ones — query all_triggers for BEFORE INSERT FOR EACH ROW triggers tied to the PK column, and cache the result in @do_not_prefetch_primary_key alongside the identity check
  • schema_dumper should emit , primary_key_trigger: true for round-trip
  • structure_dump already supports trigger emission via structure_dump: db_stored_code

Implementation notes

Why now

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions