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.
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 TYPEwith an empty body that PostgreSQL cannot parse.Comparing a source range type against a target enum or composite type of the same name produces:
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:Only lists survive, so the subtype never reaches
type_schema_diff.sqland{% 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:The reverse-engineered SQL path already maps
-toNonebefore rendering (if data[k] == '-': data[k] = NoneinTypeView.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_diffwhilst the suite still reported a pass.