Add Namespaces::StatePropagationIterator

What does this MR do and why?

Adds Namespaces::StatePropagationIterator, a subclass of Gitlab::Database::NamespaceEachBatch, as part of Phase 2: Build state-aware tree iterator with boundary enforcement.

The iterator extends the existing DFS traversal with a state_filter parameter. It overrides walk_down and next_elements to inject a WHERE state IN (...) clause into the LATERAL subqueries, so the traversal prunes entire subtrees rooted at namespaces whose state is not in the filter — without visiting or modifying them.

This is the boundary enforcement layer from ADR 003: for example, an archive propagation will skip over a deletion_scheduled subgroup and all of its descendants, leaving them untouched.

Relates to #599293 (closed)

References

Query plans

The iterator reuses the recursive CTE structure from NamespaceEachBatch. The only SQL difference is the state IN (...) predicate added to the two LATERAL subqueries.

walk_down — descend to first matching child: https://postgres.ai/console/gitlab/gitlab-production-main/sessions/52047/commands/153336

next_elements — advance to next matching sibling: https://postgres.ai/console/gitlab/gitlab-production-main/sessions/52047/commands/153338

Screenshots or screen recordings

Not applicable — no UI changes.

How to set up and validate locally

Run the model specs:

bundle exec rspec spec/models/namespaces/state_propagation_iterator_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.

Related to #599293 (closed)

Edited by Shane Maglangit

Merge request reports

Loading