Skip to content

feat: implement HSETEX command (#299) - #334

Merged
fatal10110 merged 2 commits into
mainfrom
feat/hsetex-command
Jul 1, 2026
Merged

feat: implement HSETEX command (#299)#334
fatal10110 merged 2 commits into
mainfrom
feat/hsetex-command

Conversation

@fatal10110

Copy link
Copy Markdown
Owner

Summary

  • Adds HSETEX key [FNX|FXX] [EX seconds|PX ms|EXAT unix-s|PXAT unix-ms|KEEPTTL] FIELDS numfields field value [field value ...], gated redis-8.0+/valkey-9.0+.
  • Matches real Redis 8.0 semantics: FNX/FXX require all-or-nothing field existence; the condition/expiration tokens may appear in either order; overwriting a field without an expiration clause clears its TTL (like plain HSET), KEEPTTL retains it, and EX 0/past EXAT/PXAT delete the field immediately; deleting the last field removes the key.
  • Error strings (unknown argument: X, Only one of FXX or FNX..., Only one of EX, PX, EXAT, PXAT or KEEPTTL..., invalid number of fields, generic wrong-arity for numfields/pair-count mismatches) were verified against a live redis:8.0 container — several diverge from HGETEX's wording, which is intentional (matches real Redis, not just internal consistency).
  • This is part of compat: implement Redis 8.0 command and behavior deltas #299, a large umbrella issue also covering unrelated Redis Stack module families (Search, JSON, Time Series, Bloom, Cuckoo, CMS, Top-K, t-digest, Vector sets) that are out of scope here and left for follow-up issues, per the issue's own acceptance criteria ("track as follow-up sub-issues instead of silently pretending parity"). compat: implement Redis 8.0 command and behavior deltas #299 stays open.

Test plan

  • New ioredis + node-redis integration tests in tests-integration/{ioredis,node-redis}/hash/hsetex.test.ts cover: basic set, TTL-clear-on-overwrite, KEEPTTL, EX/PX/EXAT/PXAT (including immediate-expiry and last-field-removes-key), FNX/FXX all-or-nothing semantics, flexible token order, and the full error matrix (arity, WRONGTYPE, unknown token, mutual exclusion, invalid numfields, numfields/pair mismatch, invalid expire time, ordering of expire-time validation vs. condition).
  • Tests pass against real Redis 8.0 (TEST_BACKEND=real)
  • Tests pass against mock (TEST_BACKEND=mock)
  • npm run build, npm run lint, npm run test:all all pass (1102/1102 tests)
  • docs/COMMANDS.md and docs/API.md (compatibility gate table) updated

Adds the Redis 8.0 HSETEX command for setting one or more hash fields
with optional FNX/FXX existence conditions and EX/PX/EXAT/PXAT/KEEPTTL
expiration handling, gated to redis-8.0+/valkey-9.0+. Part of the
redis-8.0 compatibility delta tracked by #299 (a large umbrella issue
covering unrelated Redis Stack module families that are out of scope
for this change).
ctx.db.getHash() returns the raw hash shape (no .hasField()); the
previous FNX/FXX check reimplemented field-expiry logic against it
instead of reusing TrackedHashData, which already handles this and is
available inside ctx.db.updateHash(). Checking the condition inside
that same callback also means a failed condition on a missing key
never persists an empty hash, without a separate getHash() pass.
@fatal10110
fatal10110 merged commit 465f8e0 into main Jul 1, 2026
12 checks passed
@fatal10110
fatal10110 deleted the feat/hsetex-command branch July 2, 2026 05:17
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