Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing compatibility of type definitions #126

Open
mtcalvin opened this issue Sep 23, 2019 · 3 comments
Open

Testing compatibility of type definitions #126

mtcalvin opened this issue Sep 23, 2019 · 3 comments
Labels
question Further information is requested

Comments

@mtcalvin
Copy link

I'm using Ion Schema to allow my customers to describe type definitions for data stored in a database. I have a use case now where customers would like to evolve their type definitions (modeled as Ion Schema "types"), e.g., adding new fields, changing constraints, etc.

Since the existing data in the database matches the original type definition, I'd like to put some kind of safeguard into place to prevent customers from making backwards incompatible changes to their type definitions, i.e., modifying the type definition in such a way that existing data becomes invalid under the new definition (examples include adding a new required field, or adding a new value constraint).

In more abstract terms, I'd like to test whether for a given type definition A and a modified version A', the set of valid values for A' is a superset of those for A.

I'm wondering if you have any suggested approaches or thoughts on how to achieve this using Ion Schema.

@jonwilsdon jonwilsdon added the question Further information is requested label Sep 30, 2019
@mtcalvin
Copy link
Author

Any thoughts on this?

@pbcornell
Copy link

I am sorry for not responding to this sooner. I don't see an easy solution, but will share a few thoughts below....

Ion Schema constraints are primarily oriented toward narrowing the universe of values. The universe of values is narrowed by constraints in type X, type X' further narrows type X with additional constraints, X'' narrows X', etc. This guarantees that code processing a value of type X can also process a value of type X'.

Your schema evolution use case appears to be the opposite--you want to guarantee that A' is broader than A. Ion Schema doesn't really help here, although I do wonder if defining a meta-type with the constraint any_of: [A, A', A'', ...] might be of some assistance--it wouldn't allow you to reject type definition A' if it were narrower, but would define a type that any data in a collection would be valid against.

The behavior of the fields and content constraints deserve a special callout here: if the content constraint is not specified, defining a field narrows an implicitly allowed field Y of type any (open content) to be a value corresponding to the specified type; however, when content: closed is specified, defining a field actually broadens the type by allowing a field which would otherwise be invalid.

Note also that use of constraint such as regex doesn't help things here. Determining whether regex A' allows a superset of the values allowed by regex A is...difficult.

I suspect such a safeguard would have to compare A and A' on a constraint-by-constraint basis and reject A' if any of its constraints are found to narrow A, or if it is unknown whether a constraint in A' narrows A.

@mtcalvin
Copy link
Author

mtcalvin commented Nov 4, 2019

Thanks for the insight Peter.

I do wonder if defining a meta-type with the constraint any_of: [A, A', A'', ...] might be of some assistance

I hadn't considered this. I'll have to think about it some more.

if the content constraint is not specified, defining a field narrows an implicitly allowed field Y of type any (open content) to be a value corresponding to the specified type

Right; In our case we default to populating content: closed (clients define their types in our system through a DSL that compiles to ISL) unless the client explicitly specifies open content. I think in this case we can't consider adding field declarations to an existing open struct to be a "compatible" change.

Note also that use of constraint such as regex doesn't help things here.

Agreed, I would be fine with excluding regex for now (or adopting the any_of solution above in the case of evolving regexes). In general my plan was to default to considering a change "incompatible" until the implementation explicitly recognizes it as compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants