Skip to content

Fix/236 unique index before self fk#705

Open
WillG2001 wants to merge 10 commits intoash-project:mainfrom
WillG2001:fix/236-unique-index-before-self-fk
Open

Fix/236 unique index before self fk#705
WillG2001 wants to merge 10 commits intoash-project:mainfrom
WillG2001:fix/236-unique-index-before-self-fk

Conversation

@WillG2001
Copy link
Contributor

Contributor checklist

Leave anything that you believe does not apply unchecked.

  • I accept the AI Policy, or AI was not used in the creation of this PR.
  • Bug fixes include regression tests
  • Chores
  • Documentation changes
  • Features include unit/acceptance tests
  • Refactoring
  • Update dependencies

@WillG2001
Copy link
Contributor Author

Summary

Background / Motivation

When a resource uses:

  • an identity on :id (creating a unique index on id), and
  • a self-referential belongs_to (e.g. follows pointing to id on the same table),

the migration generator previously produced migrations where the foreign key on follows could be emitted before (or otherwise out of order with respect to) the unique index on id. This could cause migration failures or brittle ordering.

Fixes issue: #236

Implementation

  • In AshPostgres.MigrationGenerator.Operation.AddUniqueIndex, add an insert_after_attribute_order field to track where the identity unique index should sit relative to added attributes.
  • In AshPostgres.MigrationGenerator:
    • Compute insert_after_attribute_order from the resource’s attributes when building %Operation.AddUniqueIndex{}.
    • In do_fetch_operations/4, split attribute operations into:
      • creates_and_adds (create/add operations), and
      • alter_and_rest (alter operations),
        and splice unique_indexes_to_add between these so identity unique indexes are generated after new columns but before alters that add FKs.
    • Extend after?/2 ordering rules so that:
      • CreateTable is always ordered before AddUniqueIndex for the same table.
      • AddUniqueIndex is placed after the last AddAttribute for the table but not after AlterAttribute that introduces a FK which depends on that index.
  • In AshPostgres.MigrationGeneratorTest:
    • Add "unique index is created before dependent foreign key (issue #236)" which defines Template, Phase, and TemplatePhase with:
      • uuid_primary_key :id,
      • an identity on :id,
      • a self-referential belongs_to :template_phase, __MODULE__, source_attribute: :follows.
    • Generate migrations into a tmp dir and assert that:
      • create unique_index(:template_phase, [:id], ...) is present, and
      • it appears before the references(:template_phase, ...) line used for the follows foreign key.

How to test

From the ash_postgres repo root:

Run the focused regression test

mix test test/migration_generator_test.exs --only issue_236

Run the full test suite

mix test

Static analysis (as per project conventions)

mix credo
mix dialyzer

Made-with: Cursor
identity: identity,
schema: snapshot.schema,
table: snapshot.table,
insert_after_attribute_order: max(0, length(snapshot.attributes) - 1),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this just end up placing them at the end if its using the max order?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If its being used to sort after a given attribute then it would make sense to track the name instead I think.

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