Skip to content

chore(stack): upgrade EQL v3 bundle (timestamptz → timestamp) + cast_as fix#542

Open
tobyhede wants to merge 2 commits into
feat/eql-v3-types-modulefrom
feat/eql-v3-timestamp-bundle
Open

chore(stack): upgrade EQL v3 bundle (timestamptz → timestamp) + cast_as fix#542
tobyhede wants to merge 2 commits into
feat/eql-v3-types-modulefrom
feat/eql-v3-timestamp-bundle

Conversation

@tobyhede

@tobyhede tobyhede commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Stacked on #541. Tracks encrypt-query-language@2e64ca73, which renames the eql_v3.timestamptz* domains to eql_v3.timestamp*, and fixes the time-of-day truncation those domains suffered.

1. Bundle rename — timestamptztimestamp

import { encryptedTable, types } from "@cipherstash/stack/eql/v3";

const events = encryptedTable("events", {
  occurredAt: types.Timestamp("occurred_at"),      // was types.Timestamptz
});
  • types.Timestamptz*types.Timestamp*; domain consts / classes / eqlType (eql_v3.timestamptz*eql_v3.timestamp*); barrel re-exports.
  • Regenerated the vendored SQL fixture (cipherstash-encrypt-v3.sql).
  • Install tooling: the stale-install sentinel moves from eql_v3.text_search (present in both bundle generations) to eql_v3.timestamp (new this bundle), so a DB carrying an older install is detected as stale and reinstalled.

2. cast_as fix — preserve time-of-day

The native protect-ffi CastAs has a distinct timestamp variant (full date+time) separate from date (calendar-date only). Every timestamp domain was set to cast_as: 'date', so the native layer truncated the time-of-day to midnight on decrypt. Now:

types.Timestamp("t").build().cast_as    // 'timestamp'  (was 'date')
types.Date("d").build().cast_as         // 'date'       (unchanged)
  • castAsEnum (SDK/native) and eqlCastAsEnum (wasm, via toEqlCastAs) gain timestamp; toEqlCastAs('timestamp') → 'timestamp'.
  • PlaintextKind gains timestamp (decrypts to Date, like date); the four TIMESTAMP* domain consts set castAs: 'timestamp'.
  • Typed client reconstructRow rebuilds Date for timestamp as well as date.
  • Re-enables the previously-skipped schema-v3-client occurredAt round-trip (a ms-zeroed 12:34:56 instant) to pin time-of-day preservation live in CI.

Verified

  • SDK level: timestamp columns emit cast_as: 'timestamp', date stays date, encryptConfigSchema validates, full pnpm build typechecks (incl. toEqlCastAs exhaustiveness).
  • 210 v3 runtime + 58 type tests pass; no regressions. The live SQL/round-trip tests (incl. the re-enabled occurredAt) run in CI with credentials.

Note: the base commit on this branch (test(stack): v3 lock-context coverage …) belongs to #541 and will drop from this diff once #541 merges.

tobyhede added 2 commits July 3, 2026 15:21
Track encrypt-query-language@2e64ca73, which renames the `eql_v3.timestamptz*`
domains to `eql_v3.timestamp*`. Regenerate the vendored SQL fixture and
propagate the rename through the SDK and tests:

- src/eql/v3: TIMESTAMPTZ* domain consts + eqlType `eql_v3.timestamptz*` ->
  TIMESTAMP* / `eql_v3.timestamp*`; classes `EncryptedTimestamptz*Column` ->
  `EncryptedTimestamp*Column`; `types.Timestamptz*` -> `types.Timestamp*`;
  barrel re-exports.
- Regenerate __tests__/fixtures/eql-v3/cipherstash-encrypt-v3.sql (new bundle).
- Install tooling: the stale-install sentinel moves from `eql_v3.text_search`
  (present in both generations) to `eql_v3.timestamp` (new this bundle), so a DB
  carrying an older install is detected as stale and reinstalled
  (hasEqlV3TextSearch -> hasCurrentEqlV3).
- Propagate the rename through the v3 tests, catalog, changesets.

Stacked on feat/eql-v3-types-module. NOTE: TIMESTAMP still sets castAs 'date';
if this bundle is meant to fix the time-of-day truncation, a `cast_as:'timestamp'`
and re-enabling the schema-v3-client occurredAt skip are still to do.
…ime-of-day)

The native protect-ffi CastAs has a distinct `timestamp` variant (full
date+time) separate from `date` (calendar-date only). Every v3 timestamp domain
was set to `cast_as: 'date'`, so the native layer truncated the time-of-day to
midnight on decrypt.

Add `timestamp` through the cast_as type system and point the timestamp domains
at it:
- schema: `castAsEnum` (SDK/native) and `eqlCastAsEnum` (wasm, via toEqlCastAs)
  gain `timestamp`; `toEqlCastAs('timestamp') -> 'timestamp'`.
- eql/v3: `PlaintextKind` gains `timestamp` (decrypts to `Date`, like `date`);
  the four `TIMESTAMP*` domain consts set `castAs: 'timestamp'`.
- typed client: `reconstructRow` rebuilds `Date` for `timestamp` as well as
  `date`.

TDD: timestamp domains' build() now emits `cast_as: 'timestamp'` (date stays
`date`); catalog + matrix build() assertions updated; the schema-v3-client
`occurredAt` round-trip (a ms-zeroed 12:34:56 instant) is re-enabled to pin
time-of-day preservation live in CI.
@tobyhede tobyhede requested a review from a team as a code owner July 3, 2026 05:34
@changeset-bot

changeset-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 61b52df

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 6 packages
Name Type
@cipherstash/stack Minor
@cipherstash/bench Patch
@cipherstash/prisma-next Patch
@cipherstash/basic-example Patch
@cipherstash/prisma-next-example Patch
@cipherstash/e2e Patch

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2cc59dbe-f887-4374-86a3-638628b70f7d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/eql-v3-timestamp-bundle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant