Skip to content

feat(rds): beginsWith, between and size conditions, from table alias - #284

Merged
bentsku merged 2 commits into
mainfrom
implement-missing-operators
Aug 20, 2026
Merged

feat(rds): beginsWith, between and size conditions, from table alias#284
bentsku merged 2 commits into
mainfrom
implement-missing-operators

Conversation

@bentsku

@bentsku bentsku commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Motivation

Validating the empty-input fix (#283) against EvaluateCode turned up three where conditions and one select key that AWS supports and this library does not, so a resolver using any of them hits Unhandled condition type or a TypeError on the missing table:

  • beginsWith: "x""n" LIKE :P0 bound as "x%"
  • between: [1, 9]"n" BETWEEN :P0 AND :P1
  • size: { eq: 3 }LENGTH ("n") = :P0
  • select({ from: "t" })from as an alias for table

Changes

rds/index.js:

  • buildCondition dispatches before binding a value, since between needs two variables and size a different target expression. The simple comparisons now come from a shared COMPARISON_OPERATORS map, used by both the direct form ({ eq: 1 }) and the size form ({ size: { eq: 1 } }).
  • beginsWith joins contains as a wildcard case, binding value% rather than %value%.
  • between guards its arity with the two distinct messages used upstream — one for a value that is not an array, another for an array of the wrong length — and binds each bound through renderValue, so a nullish bound inlines NULL and type hints survive.
  • size renders LENGTH (col) once per operator, accepting eq/ne/gt/ge/lt/le and a nested between. A nullish value is inlined here, unlike a direct comparison where it is rejected. An empty object renders nothing.
  • from is an alias for table in select() only: insert/update/remove ignore the key entirely and do not reject it alongside table. One shared resolveTableName covers all four statement types, which also gets them the 'table' or 'from' key is required. message in place of a TypeError.
  • contains and notContains now require string values, as beginsWith does. notContains looked like it might be permissive — it is the one wildcard condition whose value is not wrapped — but it rejects non-strings too.
  • buildWhereStatement no longer wraps an empty body in the grouping parens. An empty size is the first condition that can render to nothing inside a column, which would otherwise produce WHERE ().

in stays unimplemented: it is not supported upstream either.

__tests__/resolvers.test.js: 48 tests in a new block, of which 33 are snapshots recorded from AWS.

The other 15 assert rejected inputs. Worth being explicit about these: they call the module directly and never reach checkResolverValid, so they are not compared against AWS under either TEST_TARGET — they pin string literals that were checked against EvaluateCode by hand. Converting them to recorded snapshots needs the harness to capture a thrown error and strip the code.js:<line>:<col> prefix AWS puts in front of its message, which is queued on the error-parity ticket. The same caveat applies to the four such assertions #283 added, and their comment is corrected here too.

No version bump or changelog line here — both land with v0.1.5.

🤖 Generated with Claude Code

bentsku and others added 2 commits August 20, 2026 18:42
Real AWS supports three `where` conditions and one `select` key that this
library did not, so a resolver using any of them hit `Unhandled condition
type` or a TypeError on the missing table.

- `beginsWith` binds its value with a trailing wildcard (`LIKE 'x%'`)
- `between` binds two values (`BETWEEN :P0 AND :P1`), guarding the arity
  with the two distinct messages AWS uses
- `size` compares `LENGTH (col)` and accepts eq/ne/gt/ge/lt/le plus a
  nested `between`, repeating the target once per operator
- `from` is accepted as an alias for `table`, in select() only: AWS
  ignores the key entirely in insert/update/remove, and rejects it
  alongside `table` only in select()
- `contains` and `notContains` now require string values, as
  `beginsWith` does
- an empty `size` renders nothing, so buildWhereStatement no longer wraps
  an empty body in the grouping parens

Verified against real AWS AppSync EvaluateCode: 156 inputs match
byte-for-byte across both dialects, including the #283 regression set.
Snapshots recorded from AWS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The `toThrow` assertions call the module directly and never reach
`checkResolverValid`, so they are unaffected by TEST_TARGET and compare
against string literals rather than AWS. The previous comments said the
messages "come back from AWS", which reads as though the suite verifies
them - it does not, under either target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bentsku
bentsku marked this pull request as ready for review August 20, 2026 18:10
@bentsku
bentsku merged commit 6df78f1 into main Aug 20, 2026
4 checks passed
@bentsku
bentsku deleted the implement-missing-operators branch August 20, 2026 18:10
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