pub fn schema_content_changed(
target: &SchemaDescriptor,
previous: Option<&SchemaDescriptor>,
) -> boolExpand description
True when target differs from previous in ANY way at all — not just
the DDL-visible parts diff_schema_steps/diff_schema_ops can see.
Some schema semantics have zero physical Postgres footprint: a
property/link’s is_readonly flag, mutation rewrites, computed
pointers, session/computed globals, and (once added) pub/sub Channel
declarations are all enforced purely by pylon-core’s own compiler
consulting SchemaDescriptor — there is no column, constraint, or
catalog object for live-database introspection (DbState) to ever see,
no matter how they change. Before this function existed, a schema edit
confined to one of these was structurally invisible to migration create/watch: diff_schema_steps/diff_schema_ops would report zero
DDL, the CLI would print “No schema changes detected” and exit, and
_pylon."Schema" (what every connecting client actually compiles
against — see pylon.client._install_migrated_schema) would never be
updated. That’s not “changing it doesn’t require a migration” (the
intended, documented behavior for e.g. readonly) — it’s “changing it
can never be migrated at all,” permanently, until some unrelated
DDL-visible change happens to piggyback one through.
Deliberately does not enumerate which fields are DDL-invisible —
that list has already grown twice (readonly/rewrites, then Channel)
and would silently miss the next one. Instead this compares the two
schemas’ full JSON content (the same serde_json round-trip already
used for _pylon."Schema" storage — see SchemaDescriptor::to_json/
from_json in pylon-py), so any field on any descriptor —
present now or added later — is covered automatically. Callers combine
this with diff_schema_steps/diff_schema_ops’s own result: if there
are DDL steps, this check is redundant (a migration is already
happening); it only changes behavior in the previously-broken case,
zero DDL steps but real content drift.
previous = None (no migration has ever been applied to this database
yet) compares against an empty SchemaDescriptor — matches target
only when target itself is completely empty.