Skip to content

Fix materialized view dependency ordering - alphabetical sort breaks schema loads #2

@tesote-dfranco

Description

@tesote-dfranco

Problem

better_structure_sql sorts materialized views (and regular views) alphabetically when dumping db/schema/. This breaks when one view depends on another that sorts later alphabetically — loading the schema fails:

ERROR: relation "reconciliation_daily_summaries" does not exist

Real-world example: reconciliation_account_summaries depends on reconciliation_daily_summaries, but sorts first alphabetically, so the CREATE statement comes before its dependency exists.

Even when IF NOT EXISTS prevents hard failures, every db:migrate can flip the order, creating noisy diffs in PRs.

Root Cause

File: lib/better_structure_sql/adapters/postgresql_adapter.rb

  • Line ~190: ORDER BY matviewname — alphabetical, ignores dependencies
  • Line ~165: ORDER BY viewname — same issue for regular views

The gem already has a DependencyResolver class (lib/better_structure_sql/dependency_resolver.rb) with topological sorting. It just isn't wired into the view/materialized view fetching pipeline.

Reproduction Steps

  1. Create a PostgreSQL database with two materialized views where one depends on the other
  2. Name them such that the dependent view sorts alphabetically before its dependency
    • Example: reconciliation_account_summaries depends on reconciliation_daily_summaries
  3. Run better_structure_sql to dump the schema
  4. Try to reload the schema:
    psql -f db/schema.sql
  5. Result: ERROR: relation "reconciliation_daily_summaries" does not exist

Proposed Solution

Query PostgreSQL's pg_depend + pg_rewrite catalogs to discover inter-view dependencies, then feed results into the existing DependencyResolver for topological sorting.

Steps:

  1. Add sort_by_dependencies(connection, objects, relkind) helper method that queries dependencies
  2. Update fetch_materialized_views to remove ORDER BY matviewname and apply sort_by_dependencies instead
  3. Update fetch_views to remove ORDER BY viewname and apply sort_by_dependencies instead
  4. Add RSpec tests for dependency ordering scenarios (matview→matview, view→view, circular dependencies, no dependencies)

Related Files

  • lib/better_structure_sql/adapters/postgresql_adapter.rb - where changes are needed
  • lib/better_structure_sql/dependency_resolver.rb - existing class with topological sorting

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions