Skip to content

Commit 5887218

Browse files
authored
Merge pull request #1267 from cipherstash/feat/eql-v4-smallint
feat(eql-bindings): produce Smallint and SmallintEq from i16
2 parents c612ed4 + 337e882 commit 5887218

26 files changed

Lines changed: 1038 additions & 114 deletions

File tree

‎.changeset/eql-v4-smallint.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@cipherstash/eql': minor
3+
---
4+
5+
**Stack Encrypt produces the EQL v4 types `Smallint` and `SmallintEq`** (`eql-bindings`, `stack-encrypt` feature), from `i16`. `SmallintEq`'s equality term is the integer one, so a smallint and an integer of the same value under one column share it. The `date`, `timestamp` and `numeric` types now say they wait for a choice of Rust plaintext type, not for an engine kind.

‎.github/workflows/tests-golang.yml‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,17 +248,21 @@ jobs:
248248
echo "RLIMIT_MEMLOCK: $(ulimit -l) KiB"
249249
mise run go:test
250250
251-
# The Rust suite opens the committed v4_rows.json, whose ciphertexts the
252-
# Go SDK sealed when the file was last regenerated. This also hands it
253-
# the rows the Go SDK seals in this run, so a Go guest and a native
254-
# Rust build that stop agreeing on today's ciphertexts fail here rather
255-
# than when someone next regenerates the file. The toolchain is the
251+
# The Rust suite opens the committed v4_rows.json and
252+
# v4_smallint_rows.json, whose ciphertexts the Go SDK sealed when each
253+
# file was last regenerated. This also hands it the rows the Go SDK
254+
# seals in this run, so a Go guest and a native Rust build that stop
255+
# agreeing on today's ciphertexts fail here rather than when someone
256+
# next regenerates a file. Both filters are exact, so each test named
257+
# here is one that reads the rows handed to it. The toolchain is the
256258
# root's pin, as for the guests.
257259
- name: Rows the Go SDK seals today open in Rust
258260
run: |
259261
rows="$RUNNER_TEMP/v4_rows.json"
260-
(cd languages/golang && CGO_ENABLED=0 EQL_V4_ROWS_OUT="$rows" go test -count=1 -run TestV4RowsMatchTheCommittedFixture ./encrypt)
261-
EQL_V4_ROWS="$rows" cargo test --locked --manifest-path packages/eql/Cargo.toml -p eql-encryption-tests --test v4_types rows_the_go_sdk_sealed_open_in_rust
262+
smallint_rows="$RUNNER_TEMP/v4_smallint_rows.json"
263+
(cd languages/golang && CGO_ENABLED=0 EQL_V4_ROWS_OUT="$rows" EQL_V4_SMALLINT_ROWS_OUT="$smallint_rows" go test -count=1 -run '^(TestV4RowsMatchTheCommittedFixture|TestV4SmallintRowsMatchTheCommittedFixture)$' ./encrypt)
264+
test -s "$rows" && test -s "$smallint_rows"
265+
EQL_V4_ROWS="$rows" EQL_V4_SMALLINT_ROWS="$smallint_rows" cargo test --locked --manifest-path packages/eql/Cargo.toml -p eql-encryption-tests --test v4_types -- --exact rows_the_go_sdk_sealed_open_in_rust smallint_rows_the_go_sdk_sealed_open_in_rust
262266
263267
# What is encrypted is fixed before the program ships: every generated
264268
# file is committed, and this fails when `go generate` would change

‎languages/golang/CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ listed under **Breaking**. Releases are tagged `languages/golang/vX.Y.Z`.
7070
`float32` or `float64` field tagged `encrypt_into=` one of them gets `Eq`.
7171
`=` compares as PostgreSQL compares the plain types: an integer has one
7272
term whatever its width, and for floats `-0.0 = 0.0` and `NaN = NaN`.
73+
- **`Smallint` and `SmallintEq`**: an `int16` field (or any Go integer
74+
type, range checked as for `Integer`) tagged `encrypt_into=` one of them
75+
seals at 16 bits; `SmallintEq` gets `Eq`, with the same equality term as
76+
an integer of the same value under the same column.
7377
- **stashgen notices an index no generated method queries**: an `ore` or
7478
`ope` index on text, bytes or a float (the engine answers the orderings
7579
over integers only), or the second of two order indexes on an integer.

‎languages/golang/cmd/stashgen/README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,14 @@ The engine produces these EQL types today, each from one Go field type:
159159
| `encrypt_into` | Go field |
160160
|---|---|
161161
| `TextEq`, `Text`, `TextMatch` | `string` |
162+
| `Smallint`, `SmallintEq` | `int16`, or any Go integer type |
162163
| `Integer`, `IntegerEq` | `int32`, or any Go integer type |
163164
| `Bigint`, `BigintEq` | `int64`, or any Go integer type |
164165
| `Boolean` | `bool` |
165166
| `Real`, `RealEq` | `float32` |
166167
| `Double`, `DoubleEq` | `float64` |
167168

168-
The `Eq` types answer `Eq`; `Text`, `Integer`, `Bigint`, `Boolean`, `Real` and `Double` are stored and read only, with no query method.
169+
The `Eq` types answer `Eq`; `Text`, `Smallint`, `Integer`, `Bigint`, `Boolean`, `Real` and `Double` are stored and read only, with no query method.
169170

170171
Any built-in Go integer field takes an integer type (ADR-0002) and seals at the type's width: an `int16` field always fits an `Integer`, and an `int64` field is range checked value by value, `Encrypt` refusing a value that does not fit with `encrypt.ErrEncoding`. `encrypt.Int128` and `encrypt.Uint128` are not converted. A float's width must match: a `float64` field is not a `Real`.
171172
A `TextMatch` field refuses text shorter than three characters, such as an empty string or a two-letter code, because it has no 3-grams to index; its query refuses such text too.

‎languages/golang/encrypt/README.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,8 @@ The EQL types the engine produces, and the Go field types each takes:
434434
| `TextEq` | `string` | `=`, `<>` |
435435
| `TextMatch` | `string` | `@@` (substring match, 3-grams, case-insensitive) |
436436
| `Text` | `string` | none: stored and read only |
437+
| `Smallint` | `int16`, or any Go integer type (see below) | none |
438+
| `SmallintEq` | the same | `=`, `<>` |
437439
| `Integer` | `int32`, or any Go integer type (see below) | none |
438440
| `IntegerEq` | the same | `=`, `<>` |
439441
| `Bigint` | `int64`, or any Go integer type | none |
@@ -446,7 +448,8 @@ The EQL types the engine produces, and the Go field types each takes:
446448

447449
Any built-in Go integer field takes an integer EQL type (ADR-0002): the field
448450
is sealed at the type's width, and opens back into the field's type. A type
449-
every value of which fits (an `int16` or a `uint16` field for `Integer`)
451+
every value of which fits (an `int16` or a `uint16` field for `Integer`, an
452+
`int8` for `Smallint`)
450453
always seals; a wider one (an `int64` or a `uint32` field for `Integer`) is
451454
range checked value by value, and `Encrypt` refuses a value that does not fit
452455
with `ErrEncoding`, naming the field's kind and not the value.

‎languages/golang/encrypt/doc.go‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
// }
2222
//
2323
// encrypt_into names the EQL type the field is stored as. The Go field type
24-
// must match it: TextEq, TextMatch and Text take a string, Integer and
25-
// IntegerEq an int32, Bigint and BigintEq an int64, Boolean a bool, Real and
26-
// RealEq a float32, and Double and DoubleEq a float64. An integer EQL type
24+
// must match it: TextEq, TextMatch and Text take a string, Smallint and
25+
// SmallintEq an int16, Integer and IntegerEq an int32, Bigint and BigintEq
26+
// an int64, Boolean a bool, Real and RealEq a float32, and Double and
27+
// DoubleEq a float64. An integer EQL type
2728
// also takes any other built-in Go integer type, sealed at the type's width:
2829
// one every value of which fits it (an int16 into Integer) always seals, and
2930
// a wider one (an int64 into Integer) is range checked, a value that does not
30-
// fit refused with [ErrEncoding]. The *Eq types answer Eq; Integer, Bigint,
31-
// Boolean, Real, Double and Text are stored and read only.
31+
// fit refused with [ErrEncoding]. The *Eq types answer Eq; Smallint,
32+
// Integer, Bigint, Boolean, Real, Double and Text are stored and read only.
3233
//
3334
// 3. Run the generator. It writes user_stash.go beside the struct:
3435
//

0 commit comments

Comments
 (0)