Skip to content

2.4.4

Latest

Choose a tag to compare

@lakhansamani lakhansamani released this 01 Nov 09:17
· 32 commits to main since this release
b0f6b62

Four of the SQL backends in the supported list could not create their own schema,
and PostgreSQL was rewriting four tables on every restart. Upgrading is
recommended for every SQL deployment.
The first boot after this release emits a
small, one-time set of ALTER COLUMN statements and nothing on every boot after;
see the upgrade notes at the end.

Fixed

  • char(36) columns were retyped on every single boot, and that was fatal on CockroachDB (#826). GORM's postgres driver reads these columns back from information_schema as bpchar, which never prefix-matches the declared char(36), so AutoMigrate re-emitted the same no-op type change at every startup: ALTER TABLE "authorizer_sessions" ALTER COLUMN "user_id" TYPE char(36) USING "user_id"::char(36). On PostgreSQL that is a silent table rewrite under ACCESS EXCLUSIVE on four tables at every restart. On CockroachDB it is fatal — ALTER COLUMN TYPE sits behind an experimental flag (SQLSTATE XCEXF) — so the server started once and never started again. Five non-PK columns now declare varchar(36), which is what the catalog reports; values are 36-character uuids either way. Measured on PostgreSQL 18 with log_statement=all: 5 alters on the upgrade boot, 0 on every boot after.
  • CockroachDB aborted at startup dropping a constraint it never had (#826). CockroachDB lists unique indexes in information_schema.table_constraints, and MySQL reports COLUMN_KEY='UNI' for them, so GORM saw every gorm:"uniqueIndex" field as a constraint the model no longer wants and issued DROP CONSTRAINT "uni_<table>_<column>" — a name it only ever creates from a unique tag. Startup died on constraint "uni_authorizer_oauth_states_state_key" ... does not exist (SQLSTATE 42704), and on MySQL on Error 1091: Can't DROP. Those indexes are declared by the models and are meant to be there, so the drop is skipped; the create direction is delegated untouched.
  • The pre-2.3.0 uniqueness cleanup silently did nothing on CockroachDB (#826). ALTER TABLE ... DROP CONSTRAINT on a UNIQUE is rejected outright there (unimplemented: ... use DROP INDEX CASCADE instead, SQLSTATE 0A000), and the failure was logged at debug level and swallowed. Releases before 2.3.0 declared authorizer_users.email and authorizer_otps.phone_number as UNIQUE; v2 keeps plain indexes and enforces uniqueness in the application layer, writing the empty string into phone_number for every email OTP — so on an upgraded CockroachDB database the second email OTP was rejected and email OTP login was broken. The drop now goes through DROP INDEX ... CASCADE.
  • MySQL and MariaDB had never worked at all, on three separate aborts (#826). Nothing had ever run the storage suite against them. (1) GORM's mysql driver widens an unsized string to varchar(191) when the field carries index or unique, but it checks only those two tags — a field tagged uniqueIndex, named or composite, is missed and becomes longtext, which MySQL refuses to index: Error 1170: BLOB/TEXT column 'client_id' used in key specification without a key length, so the schema could not be created. (2) Then the phantom DROP CONSTRAINT above, as Error 1091. (3) Then DeleteSessionTokensByUserID used a backslash as its LIKE escape character, which MySQL rejects as Error 1064; the escape character is now ! and the escaping is portable across engines, pinned by a new metacharacter test case.
  • SQL Server could not create its schema since 2.3.0-rc.10 (#826). gorm.io/driver/sqlserver has the identical two-tag gap as the mysql driver, so ten unsized uniqueIndex strings became nvarchar(MAX): mssql: Column 'client_id' in table 'authorizer_clients' is of a type that is invalid for use as a key column in an index. Fixed at the driver's own indexed-string width. Two upsert tests remain red on an unrelated driver bug — MergeCreate builds its MERGE predicate from the primary key and ignores clause.OnConflict.Columns, so an upsert keyed on a composite unique index inserts a second row instead of replacing one. make test-sqlserver therefore exists but is deliberately outside make test-all-db.
  • TestDeleteUserCascadesAllUserOwnedRows could not be run twice against a persistent database (#826). Fixed fixture ids and no cleanup, so a second run collided on rows the first left behind. Pre-existing — it failed identically on PostgreSQL — and it masked real failures behind a false one on every re-run.

Changed

  • make test-all-db now covers 12 databases, with new make test-cockroachdb, test-mysql, test-mariadb and test-sqlserver targets (#826). CI runs SQLite only, so a backend with no target had most likely never been executed — which is how four of them shipped unable to boot. Readiness is gated by a new scripts/wait-for-sql.sh, because nc -z connects to Docker Desktop's published-port proxy the instant docker run -p returns, and MySQL binds its port, runs its init scripts and then restarts — mysqladmin ping answers during that window, so the probe now runs a real query against the test database instead.

Upgrade notes

  • One-time DDL on the first boot. Five columns move from char(36) to varchar(36): audit_logs.actor_id, audit_logs.resource_id, authenticators.user_id, sessions.user_id and webhook_logs.webhook_id. Stored values are unchanged — a 36-character uuid is identical in both types — and nothing is narrowed. On PostgreSQL this is five rewrites on the upgrade boot and zero thereafter; take the usual care if authorizer_audit_logs is large.
  • MySQL/MariaDB and SQL Server column widths. An unsized string column under a uniqueIndex is now created as varchar(191) / nvarchar(256) instead of longtext / nvarchar(MAX). Every affected column lives in a table introduced in 2.3.0-rc.10 (clients, organizations, org_memberships, federated_identities, scim_endpoints, trusted_issuers, webauthn_credentials), so no existing data is narrowed.
  • A SQL Server database left behind by a failed boot must be dropped. The unsized uniqueIndex columns and the composite index over authenticators.user_id both arrived in 2.3.0-rc.10, so the two never coexist in a database that completed AutoMigrate. A database touched by a 2.3.0-rc.10 or later SQL Server boot has user_id as char(36) inside that index, and SQL Server will not retype an indexed column. No boot there ever finished, so such a database holds no data. Databases from 2.0.0 through 2.3.0 did boot, carry no index over any widened column, and upgrade in one boot with rows intact.
  • PlanetScale and Yugabyte were not executed. PlanetScale is hosted MySQL-wire and shares the MySQL code path verbatim; Yugabyte keeps the unchanged postgres.Open path and the same bpchar catalog, so the varchar(36) change covers it.