Skip to content

Schema Diff: recreating a range type as part of a kind change generates CREATE TYPE ... AS RANGE () #10304

Description

@dpage

Bug Description

Where a type has to be dropped and recreated because its kind changed, and the source side is a range type, Schema Diff generates a CREATE TYPE with an empty body that PostgreSQL cannot parse.

Comparing a source range type against a target enum or composite type of the same name produces:

-- WARNING:
-- We have found the difference in either of Type or SubType or Collation,
-- so we need to drop the existing type first and re-create it.
DROP TYPE test_schema_diff.typ_range_enum_diff CASCADE;

CREATE TYPE test_schema_diff.typ_range_enum_diff AS RANGE
(
    
);

which fails with ERROR: syntax error at or near ")". Recreating a range against a range works, because both sides then carry the subtype.

There are two causes. The first is that a range type's subtype, collation and support functions are plain values on the properties dictionary, whilst enum and composite types have no equivalent keys at all, and directory_diff() drops a plain value that only one side has:

        elif key in src_only:
            # Source only values in the newly added list
            if isinstance(source_dict[key], list):
                difference[key] = {}
                difference[key]['added'] = source_dict[key]

Only lists survive, so the subtype never reaches type_schema_diff.sql and {% if typname %}SUBTYPE=...{% endif %} renders nothing.

The second surfaces once the first is fixed: the catalogue stores - for a range type with no canonical or subtype-diff function, and the template happily writes it out:

CREATE TYPE test_schema_diff.typ_range_enum_diff AS RANGE
(
    SUBTYPE=text,
    COLLATION = pg_catalog."C",
    SUBTYPE_OPCLASS = text_ops,
    CANONICAL = -
);

The reverse-engineered SQL path already maps - to None before rendering (if data[k] == '-': data[k] = None in TypeView.sql()); the comparison path does not.

Expected Behaviour

Recreating a range type should emit its full definition, and should never write the catalogue's - placeholder into SQL.

Context

Found by making the Schema Diff regression test assert that the SQL it generates actually applies (#10293). This was the failure that had been printing syntax error at or near ")" on every run of --pkg tools.schema_diff whilst the suite still reported a pass.

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