Skip to content

Schema Diff: generated script is no longer ordered by dependency (dependLevel is never set since the React port) #10295

Description

@dpage

Bug Description

Schema Diff no longer orders the script it generates by object dependency, so a script that contains an object and something that object depends on can easily be written the wrong way round and fails when it is run.

getGenerateScriptData() in web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffCompare.jsx buckets each selected row by data.dependLevel:

        if (!(data.dependLevel in script_array)) script_array[data.dependLevel] = [];
        checkAndGetSchemaQuery(data, script_array);
        script_array[data.dependLevel].push(data.diff_ddl);

and generateFinalScript() then walks those buckets in reverse so that the deepest dependencies are written first. The catch is that nothing assigns dependLevel any more: it is read in exactly one file and written in none, so it is always undefined, every object lands in a single undefined bucket, and the script comes out in whatever order the rows happen to be in.

dependLevel used to be computed in web/pgadmin/tools/schema_diff/static/js/schema_diff_dependency.js, added for #5730, which walked each checked row's dependencies and assigned levels. That file was deleted wholesale by e1942d8 ("Port schema diff to React"), and the calculation was never reinstated, so the ordering half of #5730 has been silently absent since. The data it needs is still there: each row carries dependencies and dependenciesOid.

To Reproduce

Comparing two databases where a range type differs in kind (say a range in the source against an enum of the same name in the target) produces a script whose very first statement is the cast that the range's multirange type needs:

CREATE CAST (test_schema_diff.typ_range_enum_diff AS test_schema_diff.typ_multirange_enum_diff)
	WITH FUNCTION typ_multirange_enum_diff(test_schema_diff.typ_range_enum_diff);

whilst the DROP TYPE/CREATE TYPE that creates those very types appears several hundred lines further down, so running the script fails with:

ERROR:  type "test_schema_diff.typ_multirange_enum_diff" does not exist

Expected Behaviour

The generated script should be ordered so that dependencies are created before the objects that need them, as it was before the React port. The header already warns that circular dependencies may make the order less than optimal, which rather understates the current position: there is no dependency ordering at all.

Context

Found whilst making the Schema Diff regression test assert that its generated script actually applies (#10293). The test cannot be made strict about the script as a whole until this is fixed, so it will be made strict about each object's SQL being valid in the meantime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions