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 19f5f3e
Browse filesBrowse the repository at this point in the historyBrowse files
feat: a null has an equality term, and a sealed null sits beside one
vitaminc-normalize 0.8 derives an equality term for a null: one term per
context, shared by every null, typed or plain. #1327 dropped it to keep
the old behaviour; this keeps it (#1298).
- stack-encrypt: `EqualityTerm` of a `None`, and `IndexSpec::Equality`
on a null, now derive that term. No other index has one.
- Data plans: `"null": "sealed"` takes a field whose only index is
equality, on the field or on the EQL type it names. The null is sealed
as long as a value and stores the null term beside it, so the absent
rows are one equality group, as any repeated value is, and the column
holds no SQL NULL. An `eq` query whose input is a null derives that
term (`query_term`, `record::query`); a null query of any other field
or operator is the new `Reason::NullQuery`.
- eql-bindings: a type whose only term is equality's (`DateEq`,
`IntegerEq`, ...) and its query twin take an `Option` of the plaintext,
as storage-only types do, and the by-name dispatch encrypts, opens and
queries them through it.
- Go: stashgen defaults to `null=sealed` for a fixed-width field whose
only index is equality, and generates `EqNull`, the `eq` query of nil,
through the new `gensupport.Field.NullTerm`.
Verified in PostgreSQL: `=` with the query of a null finds exactly the
rows of a DateEq column whose value was a sealed null.
Refs #1298.
Claude-Session: https://claude.ai/code/session_01XQN1QpaWVDGjHEg39KEJF3
Copy file name to clipboardExpand all lines: .changeset/eql-bindings-optional-storage-only.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,4 +2,4 @@
2
2
"@cipherstash/eql": patch
3
3
---
4
4
5
-
`eql-bindings` (the Rust crate released with this package): a storage-only EQL v4 type (`Date`, `Integer`, `Text`, and the other types with no term) now also implements `EncryptFrom` and `DecryptInto` for an `Option` of its plaintext. A `None` seals as a typed null as long as a value (vitaminc 0.8), so an optional column does not show which rows are absent, and opens as `None`. A value seals exactly as before. The by-name dispatch (`encryption::targets`) readsand opens these types through the `Option`, so a null frame encrypts and a stored null decrypts to a null; a type with a term still refuses a null. eql-bindings' own `Date`, `Timestamp` and `Decimal` plaintexts declare their fixed width to vitaminc, so their `None` is padded too. The SQL bundle and the TypeScript types do not change.
5
+
`eql-bindings` (the Rust crate released with this package): an EQL v4 type whose terms a null has, a storage-only type (`Date`, `Integer`, `Text`, ...) or one whose only term is equality's (`DateEq`, `IntegerEq`, `TextEq`, ...), now also implements `EncryptFrom` and `DecryptInto` for an `Option` of its plaintext, and its query twin `EncryptFrom` for one. A `None` seals as a typed null as long as a value (vitaminc 0.8), so an optional column does not show which rows are absent, and opens as `None`; its `hm` is the one term every null shares, and the query of a `None` finds the stored nulls with `=`. A value seals exactly as before. The by-name dispatch (`encryption::targets`) reads, opens and queries these types through the `Option`; a type with an order or match term still refuses a null. eql-bindings' own `Date`, `Timestamp` and `Decimal` plaintexts declare their fixed width to vitaminc, so their `None` is padded too. The SQL bundle and the TypeScript types do not change.
Copy file name to clipboardExpand all lines: languages/golang/cmd/stashgen/README.md
+4-3Lines changed: 4 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -113,11 +113,12 @@ A sealed field declared over a pointer to one scalar (`*encrypt.Date`, `*int32`,
113
113
114
114
|`null=`| Stored for `nil`| What a reader of the column sees |
115
115
|---|---|---|
116
-
|`sealed`| a sealed null, as long as a sealed value of the field's type| nothing: an absent value looks like any other|
116
+
|`sealed`| a sealed null, as long as a sealed value of the field's type, and beside an equality index the one term every null of the field shares | nothing in the ciphertext; in an equality column, that the absent rows are one group, as rows holding one repeated value are|
117
117
|`sql`| nothing: the field's columns are `NULL`, and its member in the generated type is `nil`| which rows have no value |
118
118
119
-
A sealed null hides that the value is absent only where its length matches a value's and nothing beside it shows it, so it is the default for a field with no index whose type has a fixed width: a `bool`, a number, `encrypt.Date`, `time.Time`, `encrypt.Decimal`, `encrypt.Int128` and `encrypt.Uint128`, sealed with `encrypt` or into an EQL type with no index (`Date`, `Integer`, `Boolean`, ...).
120
-
A field with an index, and a field of text or bytes, has to write `null=sql`: a null has no index term yet, and text shows its length, so a sealed null would hide nothing there, and `stashgen` will not choose a visible `NULL` for you.
119
+
A sealed null hides that the value is absent only where its length matches a value's and no index beside it shows it, so it is the default for a field whose type has a fixed width (a `bool`, a number, `encrypt.Date`, `time.Time`, `encrypt.Decimal`, `encrypt.Int128` and `encrypt.Uint128`) and whose only index, if it has one, is `equality`: sealed with `encrypt`, `encrypt,index=equality`, or into an EQL type with no index or with equality alone (`Date`, `DateEq`, `Integer`, `IntegerEq`, ...).
120
+
A null has an equality term, so its rows are one equality group and a query finds them: the generated `EqNull` derives the `eq` query of `nil`, which matches every row whose value is absent.
121
+
A null has no order or match term, so a field with any other index, and a field of text or bytes, has to write `null=sql`: an order or match column would show which values are absent, and text shows its length, and `stashgen` will not choose a visible `NULL` for you.
121
122
`null=sealed` on such a field stops `stashgen` with the reason.
122
123
123
124
A `null=sql` field's member in the generated type is a pointer (`*eql.DateEq`, `*EncryptedUserScore`), `nil` when the value was; a `null=sealed` field's is the same type as a non-optional field's, and its column is never `NULL`.
0 commit comments