Fix Release features tables cross-joining `ci_builds` -> Environments dashboards Environment#last_visible_pipeline last_visible_deployable last_deployable
Summary
Code used in environments dashboard pages is causing problems with moving ci_* tables to a new database (ie. the current groupsharding decomposition efforts).
Technical details
The following has_one relations from https://gitlab.com/gitlab-org/gitlab/-/blob/ee956e0dfc4f2e37f4f37fc63b50c3f50376195a/app/models/environment.rb#L30 do cross-joins between ci_* and non ci_* tables:
has_one :last_deployable, through: :last_deployment, source: 'deployable', source_type: 'CommitStatus'
has_one :last_visible_deployable, through: :last_visible_deployment, source: 'deployable', source_type: 'CommitStatus'
has_one :last_visible_pipeline, through: :last_visible_deployable, source: 'pipeline'
These methods are used in a few places but the main tricky part to solve is using them as preload in Dashboard::Environments::ListService.
The last_visible_pipeline chains together all the others.
Possible solutions
I started testing different approaches at !67834 (closed) but it turned out to be a bit trickier than expected so we want to distribute this work to relevant team so that they can
- Similar to !66709 (merged) we can add
disable_joinsto these but my initial testing of this did not seem to work out of the box due to the interesting way these construct results using scopes anddistinct. We could look into whether this is a bug indisable_joinsthat's easily fixed but I fear there may be technically something strange about thesehas_onerelations being used in a way this feature was not intended - In !67834 (closed) I also tried extracting all these
has_oneas a method but I realised later that this won't work with the preload. But it could be possible to write the preloading logic more directly for these relations and still avoid usinghas_onefor this.
You can read more about typical solutions to these types of join problems at https://docs.gitlab.com/ee/development/database/multiple_databases.html#removing-joins-between-ci_-and-non-ci_-tables . It may turn out there is a simpler way to refactor this code that doesn't rely on these has_one or joins.