Increase affected_range limit on pm_affected_packages to 1024

What does this MR do and why?

Raises the maximum length of affected_range on the pm_affected_packages table from 512 to 1024 characters. A regular migration adds a new check constraint check_e77c8ef7de (char_length(affected_range) <= 1024) and then drops the old check_80dea16c7b (<= 512), following the documented procedure for increasing a text limit. The Rails model validation in ee/app/models/package_metadata/affected_package.rb and its spec are raised to match. The down migration is a no-op: once the new limit is in use, rows longer than 512 characters may exist, so re-adding the old constraint would fail validation. Because of that no-op, the db:check-migrations job cannot see db/structure.sql return to its previous state after rollback, so that job needs the pipeline:skip-check-migrations label, as its own error message suggests.

pm_affected_packages is in the gitlab_pm schema, is marked table_size: small, and is not a high-traffic table. There are no index changes, new columns, or data migrations.

Why

The GitLab Advisory Database (GLAD) v3 exporter drops any package whose affected_range is longer than 512 characters. When that leaves an advisory with no packages, the whole advisory is rejected by the v3 schema, which requires at least one package. In the full GLAD v3 snapshot exported on 2026-09-18 this lost exactly three advisories: npm next (CVE-2025-59472), conan openssl (CVE-2023-3817), and cargo aws-sigv4 (CVE-2023-30610).

The exporter's 512 limit mirrors the Rails validation and database constraint on this column, so it cannot be raised until the Rails side is raised first. Across 53,552 GLAD entries the affected_range length is p90 43, p95 54, p99 89, and p100 595 characters. 1024 gives headroom above the observed maximum. Raising the exporter's own limit is separate follow-up work in the license-exporter project and should land after this MR is released.

Instances that have not run this migration keep rejecting values longer than 512 characters. That is safe: PackageMetadata::Ingestion::Advisory::AffectedPackageIngestionTask already skips invalid records and reports them through Gitlab::ErrorTracking.track_exception, so ingestion continues and only that package is missed.

Migration output

Up

main: == [advisory_lock_connection] object_id: 165460, pg_backend_pid: 13073
main: == 20260921080000 IncreaseAffectedRangeLimitOnPmAffectedPackages: migrating ===
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- execute("ALTER TABLE pm_affected_packages\nADD CONSTRAINT check_e77c8ef7de\nCHECK ( char_length(affected_range) <= 1024 )\nNOT VALID;\n")
main:    -> 0.0026s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0003s
main: -- execute("ALTER TABLE pm_affected_packages VALIDATE CONSTRAINT check_e77c8ef7de;")
main:    -> 0.0025s
main: -- execute("RESET statement_timeout")
main:    -> 0.0003s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- execute("            ALTER TABLE pm_affected_packages\n            DROP CONSTRAINT IF EXISTS check_80dea16c7b\n")
main:    -> 0.0006s
main: == 20260921080000 IncreaseAffectedRangeLimitOnPmAffectedPackages: migrated (0.0586s)
main: == [advisory_lock_connection] object_id: 165460, pg_backend_pid: 13073

Down

main: == [advisory_lock_connection] object_id: 164760, pg_backend_pid: 13328
main: == 20260921080000 IncreaseAffectedRangeLimitOnPmAffectedPackages: reverting ===
main: == 20260921080000 IncreaseAffectedRangeLimitOnPmAffectedPackages: reverted (0.0068s)
main: == [advisory_lock_connection] object_id: 164760, pg_backend_pid: 13328

References

Screenshots or screen recordings

This MR contains no user-facing UI changes.

How to set up and validate locally

  1. Run bundle exec rails db:migrate and confirm in psql that pm_affected_packages has a constraint named check_e77c8ef7de with definition char_length(affected_range) <= 1024, and no longer has check_80dea16c7b. Suggested query: SELECT conname, pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'pm_affected_packages'::regclass AND conname LIKE 'check_%';
  2. In rails console, build a record with a 600-character range and confirm it is valid, for example FactoryBot.build(:pm_affected_package, affected_range: 'a' * 600).valid? returns true, while 'a' * 1025 returns false.
  3. Run bundle exec rspec ee/spec/models/package_metadata/affected_package_spec.rb.

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.

🤖 Generated with Claude Code

Edited by Nick Ilieskou

Merge request reports

Loading
Loading