You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 52802ef
Browse filesBrowse the repository at this point in the historyBrowse files
docs(go): show the element match in the references and the JSON example
The stashgen README's "Encrypted JSON documents" table gets the Match
row and its SQL, with when Elements is generated, how a member is
written, what is refused before the engine, the folded equality and
the 22023 bound. The SDK README and package doc show the call, and the
CHANGELOG records it under Unreleased.
The typed-document example orders each visit's at and place, and finds
the customer with one visit at home after 15: Ada has a visit at home
and a visit after 15, but no one visit that is both. Its generated file
is regenerated from the new tag.
Refs #1442
`At` has one accessor per ordered path, named for its keys (`$.visits[*].at` is `At.VisitsAt`, `$.a.1` is `At.A1`); two paths with one name, or one path given twice, stop `stashgen`.
183
184
An ordering compares the value `->` extracts at its path, and EQL's `<` compares ordering terms alone, so take the selector from the same accessor (`At.Age.Selector`) rather than spelling the path again.
@@ -193,6 +194,32 @@ SELECT id FROM customers ORDER BY (
193
194
```
194
195
195
196
with `$1` from `At.VisitsAt.Selector(ctx, c)` and `$2` from `At.VisitsAt.Gt(ctx, c, v)`; for the latest visit, order by `ORDER BY 1 DESC NULLS LAST` inside and `DESC` outside.
197
+
198
+
Two queries at a wildcard path, an `EqAt` and an ordering say, can each be answered by a different element.
199
+
To test several members of one element together, use `Match` under `Elements`.
200
+
`Elements` has one accessor per array whose elements have an ordered member, named for the array's keys as `At` names a path: with `ordered=$.visits[*].at;$.visits[*].place`, `$.visits[*]` is `Elements.Visits`, with the members `at` and `place`.
201
+
A root array (`ordered=$[*].name`) is `Elements.Root`.
202
+
An ordered path that ends at its wildcard (`$.tags[*]`), or has none, gives no accessor, and a field without one has no `Elements`.
203
+
Two arrays whose keys give one name (`$.a_b[*]` and `$.aB[*]` are both `AB`), and an array whose keys give no name, get no accessor: `stashgen` still writes the field and its `At`, and prints a notice naming the ordered paths, which the generated file repeats in a comment.
204
+
205
+
```go
206
+
// rows with one visit that is at home and after 15
207
+
q, err:= customers.Fields.Profile.Elements.Visits.Match(ctx, cipher, encrypt.ElementPredicates{
208
+
encrypt.MemberEq("place", "home"),
209
+
encrypt.MemberGt("at", 15),
210
+
}, encrypt.JSONReadOptions{})
211
+
```
212
+
213
+
```sql
214
+
SELECT id FROM customers WHEREeql_v4.json_tree_element_match(profile, $1::eql_v4.query_json_elements)
215
+
```
216
+
217
+
The predicates are `encrypt.MemberEq`, `MemberLt`, `MemberLte`, `MemberGt`, `MemberGte` and `MemberBetween` (inclusive), each with a member written as it is below the array in the tag (`place`, or `address.city`) and Go values, as the orderings take.
218
+
A member the field does not order is refused before the engine is asked, with `encrypt.ErrTerm`, naming the member, the array and the members it orders; no predicates, and a member with a wildcard, are refused with `encrypt.ErrEncoding`.
219
+
Each comparison is of the member's ordering term, so `MemberEq` is an equality of folded values: text compares case- and accent-folded (`"home"` equals `"Home"`), and integers past 2^53 can tie.
220
+
`EqAt` at the member's full path is exact, of any element.
221
+
`Match` reads each array to `opts.WildcardBound` elements, 64 when it is 0, and a row whose array is longer fails the query with SQLSTATE 22023 rather than answer over part of it: set the bound past the longest array.
222
+
The function runs on each row a scan gives it, so narrow the rows first with an indexed predicate, such as `@>` on the same values.
196
223
`OpenOne` reads one value and refuses a read whose path has a wildcard before anything is opened; open a wildcard read with `Open`.
197
224
A needle and a value are Go values: a `json.RawMessage` of JSON text crosses as it is, and anything else is marshalled with `encoding/json`.
198
225
`EqAt` and the orderings take a scalar: a string, a number, a bool, or `nil` for JSON `null`.
|`JsonSearch` (`eql.JSONSearch`) | struct, map, slice, or `json.RawMessage`| containment, equality at a path, ordering at declared paths, selection, subtree reads; see [Encrypted JSON documents](#encrypted-json-documents)|
523
+
|`JsonSearch` (`eql.JSONSearch`) | struct, map, slice, or `json.RawMessage`| containment, equality at a path, ordering at declared paths, several members of one array element, selection, subtree reads; see [Encrypted JSON documents](#encrypted-json-documents)|
524
524
525
525
Any built-in Go integer field takes an integer EQL type (ADR-0002): the field
526
526
is sealed at the type's width, and opens back into the field's type. A type
@@ -658,6 +658,26 @@ element of each row, so an ordering over every element is written over
658
658
`eql_v4.json_tree_path_query(col, $sel)`, its matches (the stashgen README
659
659
shows the SQL).
660
660
661
+
Two such queries can each be answered by a different element. To test
662
+
several members of one array element together, use `Match` on the array's
663
+
accessor under `Elements`. A field has one for each array whose elements
664
+
have an ordered member (`ordered=$.visits[*].at;$.visits[*].place`):
665
+
666
+
```go
667
+
q, err:= users.Fields.Profile.Elements.Visits.Match(ctx, cipher, encrypt.ElementPredicates{
668
+
encrypt.MemberEq("place", "home"),
669
+
encrypt.MemberGt("at", 15),
670
+
}, encrypt.JSONReadOptions{})
671
+
rows, err:= db.QueryContext(ctx, `SELECT id FROM users WHERE eql_v4.json_tree_element_match(profile, $1::eql_v4.query_json_elements)`, q)
672
+
```
673
+
674
+
Each comparison is of the member's ordering term, so `MemberEq` compares
675
+
text case- and accent-folded, and integers past 2^53 can tie; `EqAt` is
676
+
exact. A member the field does not order is refused before the engine is
677
+
asked, naming it. A row whose array is longer than
678
+
`JSONReadOptions.WildcardBound` (64 by default) fails the query with
679
+
SQLSTATE 22023.
680
+
661
681
## Building
662
682
663
683
The package embeds `wasm/stack_encrypt_guest.wasm`, a build artefact of the
0 commit comments