Browse Source

Fix migration correctness for org policy revision_date

Caught by review: SQLite rejects non-constant defaults in ALTER TABLE
ADD COLUMN, so the sqlite migration would fail outright on every
existing installation (vaultwarden's default backend) rather than the
postgresql setup this was developed against.

- sqlite/mysql: add the column with a constant placeholder default,
  then backfill via UPDATE, since neither allows a volatile default
  in ALTER TABLE ADD COLUMN (mysql does allow it, but a constant
  keeps the three backends' migrations symmetric).
- mysql: use DATETIME instead of TIMESTAMP, matching this repo's
  existing revision_date columns, and backfill with UTC_TIMESTAMP()
  instead of a session-timezone-dependent CURRENT_TIMESTAMP.
- postgresql: backfill with `now() AT TIME ZONE 'utc'` instead of a
  DEFAULT now(), since assigning timestamptz now() into this naive
  TIMESTAMP column would otherwise cast through the server's TimeZone
  GUC and store local wall-clock instead of UTC on non-UTC servers.
- mysql/postgresql: add a real down.sql (DROP COLUMN) instead of
  leaving it empty.
pull/7571/head
Will Lotto 5 days ago
parent
commit
7049ec72a7
  1. 1
      migrations/mysql/2026-08-10-120000_add_org_policy_revision_date/down.sql
  2. 7
      migrations/mysql/2026-08-10-120000_add_org_policy_revision_date/up.sql
  3. 1
      migrations/postgresql/2026-08-10-120000_add_org_policy_revision_date/down.sql
  4. 9
      migrations/postgresql/2026-08-10-120000_add_org_policy_revision_date/up.sql
  5. 6
      migrations/sqlite/2026-08-10-120000_add_org_policy_revision_date/up.sql

1
migrations/mysql/2026-08-10-120000_add_org_policy_revision_date/down.sql

@ -0,0 +1 @@
ALTER TABLE org_policies DROP COLUMN revision_date;

7
migrations/mysql/2026-08-10-120000_add_org_policy_revision_date/up.sql

@ -1,2 +1,7 @@
-- DATETIME (not TIMESTAMP) to match this repo's convention for revision_date
-- columns elsewhere, and to avoid MySQL's implicit session-timezone
-- conversion and 2038 range limit on TIMESTAMP.
ALTER TABLE org_policies ALTER TABLE org_policies
ADD COLUMN revision_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; ADD COLUMN revision_date DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00';
UPDATE org_policies SET revision_date = UTC_TIMESTAMP();

1
migrations/postgresql/2026-08-10-120000_add_org_policy_revision_date/down.sql

@ -0,0 +1 @@
ALTER TABLE org_policies DROP COLUMN revision_date;

9
migrations/postgresql/2026-08-10-120000_add_org_policy_revision_date/up.sql

@ -1,2 +1,9 @@
-- Backfill via `now() AT TIME ZONE 'utc'` rather than a DEFAULT of now():
-- assigning timestamptz now() into a naive TIMESTAMP column casts through
-- the server's TimeZone GUC, so a DEFAULT now() would store local wall-clock
-- instead of UTC on non-UTC servers, unlike every other naive-UTC timestamp
-- column in this schema.
ALTER TABLE org_policies ALTER TABLE org_policies
ADD COLUMN revision_date TIMESTAMP NOT NULL DEFAULT now(); ADD COLUMN revision_date TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:00';
UPDATE org_policies SET revision_date = (now() AT TIME ZONE 'utc');

6
migrations/sqlite/2026-08-10-120000_add_org_policy_revision_date/up.sql

@ -1,2 +1,6 @@
-- SQLite forbids non-constant defaults in ALTER TABLE ... ADD COLUMN, so add
-- the column with a constant placeholder and backfill separately.
ALTER TABLE org_policies ALTER TABLE org_policies
ADD COLUMN revision_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP; ADD COLUMN revision_date DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00';
UPDATE org_policies SET revision_date = CURRENT_TIMESTAMP;

Loading…
Cancel
Save