Add NOT NULL constraint to oauth_applications.organization_id

What does this MR do and why?

Enforces non-nullability of oauth_applications.organization_id. This column is the sharding key for this table.

  • Make the model association non-optional
  • Add the DB-level NOT NULL constraint
  • Promote organization_id from a desired sharding key to a sharding key in the DB doc for this table

Why this is safe

This MR is the final step that sets the constraint and closes the issue.

References

Screenshots or screen recordings

How to set up and validate locally

db:migrate up

Command results
 % gdk rails db:migrate
main: == [advisory_lock_connection] object_id: 141240, pg_backend_pid: 41379
main: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: migrating
main: -- current_schema(nil)
main:    -> 0.0014s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- execute("ALTER TABLE oauth_applications\nADD CONSTRAINT check_77eda6baaa\nCHECK ( organization_id IS NOT NULL )\nNOT VALID;\n")
main:    -> 0.0007s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0003s
main: -- execute("ALTER TABLE oauth_applications VALIDATE CONSTRAINT check_77eda6baaa;")
main:    -> 0.0007s
main: -- execute("RESET statement_timeout")
main:    -> 0.0003s
main: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: migrated (0.0772s)

main: == [advisory_lock_connection] object_id: 141240, pg_backend_pid: 41379
ci: == [advisory_lock_connection] object_id: 141240, pg_backend_pid: 41381
ci: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: migrating
ci: -- current_schema(nil)
ci:    -> 0.0002s
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- execute("ALTER TABLE oauth_applications\nADD CONSTRAINT check_77eda6baaa\nCHECK ( organization_id IS NOT NULL )\nNOT VALID;\n")
ci:    -> 0.0008s
ci: -- execute("SET statement_timeout TO 0")
ci:    -> 0.0002s
ci: -- execute("ALTER TABLE oauth_applications VALIDATE CONSTRAINT check_77eda6baaa;")
ci:    -> 0.0007s
ci: -- execute("RESET statement_timeout")
ci:    -> 0.0002s
ci: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: migrated (0.0210s)

ci: == [advisory_lock_connection] object_id: 141240, pg_backend_pid: 41381
sec: == [advisory_lock_connection] object_id: 141240, pg_backend_pid: 41383
sec: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: migrating
sec: -- current_schema(nil)
sec:    -> 0.0001s
sec: -- transaction_open?(nil)
sec:    -> 0.0000s
sec: -- transaction_open?(nil)
sec:    -> 0.0000s
sec: -- execute("ALTER TABLE oauth_applications\nADD CONSTRAINT check_77eda6baaa\nCHECK ( organization_id IS NOT NULL )\nNOT VALID;\n")
sec:    -> 0.0007s
sec: -- execute("SET statement_timeout TO 0")
sec:    -> 0.0003s
sec: -- execute("ALTER TABLE oauth_applications VALIDATE CONSTRAINT check_77eda6baaa;")
sec:    -> 0.0006s
sec: -- execute("RESET statement_timeout")
sec:    -> 0.0002s
sec: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: migrated (0.0189s)

sec: == [advisory_lock_connection] object_id: 141240, pg_backend_pid: 41383

db migrate:down

Command result
% gdk rails db:migrate:down:main VERSION=20260417155126
main: == [advisory_lock_connection] object_id: 140440, pg_backend_pid: 43485
main: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: reverting
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- execute("            ALTER TABLE oauth_applications\n            DROP CONSTRAINT IF EXISTS check_77eda6baaa\n")
main:    -> 0.0007s
main: == 20260417155126 AddNotNullConstraintToOauthApplicationsOrganizationId: reverted (0.0201s)

main: == [advisory_lock_connection] object_id: 140440, pg_backend_pid: 43485

Rollback plan

  • Before the post-deployment migration has executed: revert this MR
  • After the post-deployment migration has executed: ship a new MR that reverts the model validation and/or removes the DB constraint

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #579291 (closed)

Edited by Jason Knabl

Merge request reports

Loading