Skip to content

fix(pg-core): use hash-membership to skip applied migrations#5783

Open
truffle-dev wants to merge 1 commit into
drizzle-team:mainfrom
truffle-dev:fix/pg-migrate-hash-membership-5769
Open

fix(pg-core): use hash-membership to skip applied migrations#5783
truffle-dev wants to merge 1 commit into
drizzle-team:mainfrom
truffle-dev:fix/pg-migrate-hash-membership-5769

Conversation

@truffle-dev
Copy link
Copy Markdown

Closes #5769.

PgDialect.migrate selected only the latest applied row and gated each pending migration on Number(lastDbMigration.created_at) < migration.folderMillis. The gate silently skips any pending migration whose journal when is older than the maximum created_at already in __drizzle_migrations. This happens routinely when a feature-branch migration with an earlier timestamp lands after a main-branch migration, after a backport, or after rebasing a long-running branch.

The fix loads all applied hashes into a Set and gates on !appliedHashes.has(migration.hash). Hash already uniquely identifies a migration; created_at was only ever a proxy.

Regression test in integration-tests/tests/pg/node-postgres.test.ts reproduces the scenario by applying a migration with folderMillis: 2000 then re-running migrate with that plus a second migration at folderMillis: 1000; without the fix the older entry silently skips, with the fix both apply.

Note for review scope: the same order by created_at desc limit 1 + lastDbMigration.created_at < migration.folderMillis shape exists in mysql-core/dialect.ts, singlestore-core/dialect.ts, and the per-driver migrator.ts files for neon-http, xata-http, pg-proxy, mysql-proxy, sqlite-proxy, singlestore-proxy, libsql, expo-sqlite, d1, durable-sqlite, op-sqlite. Happy to follow up with a multi-dialect sweep if you want it in one place or separate PRs.

PgDialect.migrate gated the apply loop on
`Number(lastDbMigration.created_at) < migration.folderMillis`. The
gate skips a pending migration whose journal `when` is older than the
max created_at already in __drizzle_migrations - which happens any
time a feature-branch migration with an earlier timestamp lands after
a main-branch migration. The skip is silent.

Drop the order-by-limit-1 read, load all applied hashes, and gate on
`!appliedHashes.has(migration.hash)`. Hash is what uniquely identifies
a migration anyway; created_at was just a proxy.

Closes drizzle-team#5769
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.

drizzle-kit migrate silently skips pending migrations when MAX(created_at) in __drizzle_migrations exceeds the journal when of pending entries

1 participant