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

json-api: field equality query, with nesting #2778

S11001001 opened this issue Sep 5, 2019 · 0 comments · Fixed by #2826


Copy link

commented Sep 5, 2019

Building on #2777 .

Fallback rule

Unless otherwise required by one of the other rules below or to follow, values are interpreted according to the #2519 definition of LF values' JSON format, and compared for equality.

Simple equality

Match documents having at least all the (potentially nested) keys expressed in the query. The result document may contain additional properties.

Example: { person: { name: "Bob" }, city: "London" }

  • Match: { person: { name: "Bob", dob: "1956-06-21" }, city: "London", createdAt: "2019-04-30T12:34:12Z" }
  • No match: { person: { name: "Bob" }, city: "Zurich" }
  • Typecheck failure: { person: { name: ["Bob", "Sue"] }, city: "London" }

Example: { favorites: ["vanilla", "chocolate"] }

  • Match: { favorites: ["vanilla", "chocolate"] }
  • No match: { favorites: ["chocolate", "vanilla"] }
  • No match: { favorites: ["vanilla", "strawberry"] }
  • No match: { favorites: ["vanilla", "chocolate", "strawberry"] }

A JSON object, when considered with a record type, is always interpreted as a field equality query. Its type context is thus mutually exclusive with #2780.

Type-aware queries

This is not a JSON query language, it is a DAML LF query language. So, while we could theoretically treat queries (where not otherwise interpreted by the "may contain additional properties" rule above) without concern for what LF type (i.e. template) we're considering, we will not do so.

Consider the subquery{"foo": "bar"}. This query conforms to types, among an unbounded number of others:

record A ↦ { foo : Text }
record B ↦ { foo : Optional Text }
variant C ↦ foo : Party | bar : Unit

// NB: LF does not require any particular case for VariantCon or Field;
// these are perfectly legal types in DAML-LF packages

In the cases of A and B, "foo" is part of the query language, and only "bar" is treated as an LF value; in the case of C, the whole query is treated as an LF value. The wide variety of ambiguous interpretations about what elements are interpreted, and what elements treated as literal, and how those elements are interpreted or compared, would preclude many techniques for efficient query compilation and LF value representation that we might otherwise consider.

Additionally, it would be extremely easy to overlook unintended meanings of queries when writing them, and impossible in many cases to suppress those unintended meanings within the query language. For example, there is no way that the above query could be written to match A but never C.

For these reasons, as with LF value input via JSON, queries written in JSON are also always interpreted with respect to some specified LF types (e.g. template IDs). As #2777 implies, for example:

{"%template": [{"moduleName": "Foo", "entityName": "A"},
               {"moduleName": "Foo", "entityName": "B"},
               {"moduleName": "Foo", "entityName": "C"}],
 "foo": "bar"}

will treat "foo" as a field equality query for A and B, and (supposing templates' associated data types were permitted to be variants, which they are not, but for the sake of argument) as a whole value equality query for C.

The above "Typecheck failure" happens because there is no LF type to which both "Bob" and ["Bob", "Sue"] conform; this would be caught when interpreting the query, before considering any contracts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
2 participants
You can’t perform that action at this time.