fix: transaction key size validation - return types and values - #211
Open
LeeroyHannigan wants to merge 4 commits into
Open
fix: transaction key size validation - return types and values#211LeeroyHannigan wants to merge 4 commits into
LeeroyHannigan wants to merge 4 commits into
Conversation
LeeroyHannigan
requested review from
amrith,
c33howard,
jcshepherd,
pdf-amzn and
yesyayen
as code owners
July 13, 2026 10:58
pdf-amzn
previously approved these changes
Jul 15, 2026
jcshepherd
reviewed
Jul 15, 2026
| // No projection and no AttributesToGet -> rejected. | ||
| assert!( | ||
| validate_select_projection(Some(Select::SpecificAttributes), false, false, false) | ||
| validate_select_projection(Some(Select::SpecificAttributes), false, false, false, true) |
Collaborator
There was a problem hiding this comment.
My kingdom for some IS_QUERY = true; IS_SCAN = false constants ...
Collaborator
Author
There was a problem hiding this comment.
Done in 071629e — added IS_QUERY/IS_SCAN constants in the validation module and used them at the Query/Scan call sites (and in these tests) instead of bare true/false.
jcshepherd
reviewed
Jul 15, 2026
|
|
||
| // Select=ALL_ATTRIBUTES requires an ALL-projection GSI (a GSI that does not | ||
| // project all attributes cannot serve ALL_ATTRIBUTES). Matches real DynamoDB. | ||
| if matches!(input.select, Some(Select::AllAttributes)) |
Collaborator
There was a problem hiding this comment.
Any reason not to pull this up to 'validation' and use it from both query and scan?
Collaborator
Author
There was a problem hiding this comment.
Done in 071629e — pulled it up into validation::validate_all_attributes_index_support, now called from both query.rs and scan.rs (the block was duplicated verbatim in both).
jcshepherd
previously approved these changes
Jul 15, 2026
jcshepherd
left a comment
Collaborator
There was a problem hiding this comment.
Couple minor comments below but nothing blocking.
LeeroyHannigan
added a commit
that referenced
this pull request
Jul 17, 2026
…BUTES-on-GSI check Address review nits on PR #211: - Introduce IS_QUERY/IS_SCAN constants for validate_select_projection's is_query flag instead of bare true/false at call sites. - Extract the duplicated Select=ALL_ATTRIBUTES-on-non-ALL-GSI rejection from query.rs and scan.rs into a shared validate_all_attributes_index_support in the validation module. No behavior change. Signed-off-by: Lee Hannigan <lhnng@amazon.com>
pdf-amzn
previously approved these changes
Jul 17, 2026
Oversized primary keys (hash > 2048 bytes, range > 1024 bytes) are now rejected on the transaction APIs, matching DynamoDB: - An oversized key in any TransactWriteItems sub-op (Put, Delete, Update, ConditionCheck) or in TransactGetItems cancels the transaction with a per-item TransactionCanceledException carrying a ValidationError cancellation reason for the offending item. - An EMPTY key value remains a top-level ValidationException (unchanged), preserving the distinct error class DynamoDB uses for that case. The size check is split from the empty-key check (validate_key_size_limits / validate_key_not_empty) so the transaction path surfaces size as a per-item cancellation while keeping emptiness top-level. Single-item paths (validate_key_sizes) are unchanged. Adds unit + integration coverage. Signed-off-by: Lee Hannigan <lhnng@amazon.com>
…th DynamoDB Three request-validation parity fixes, each verified against DynamoDB: - PutItem/DeleteItem ReturnValues: a valid enum value not allowed for these operations (e.g. UPDATED_OLD) now returns "ReturnValues can only be ALL_OLD or NONE"; a non-enum value returns the generic constraint error listing the full enum set [ALL_NEW, UPDATED_OLD, ALL_OLD, NONE, UPDATED_NEW]. - Query/Scan Select + ProjectionExpression rejection now carries the "1 validation error detected: " prefix. - Query/Scan Select=ALL_ATTRIBUTES against a GSI whose projection type is not ALL is now rejected (previously accepted). Adds unit + Rust + Python integration coverage. Signed-off-by: Lee Hannigan <lhnng@amazon.com>
Real DynamoDB prepends "1 validation error detected: " to the Select vs ProjectionExpression rejection for Query but NOT for Scan. The prefix had been added to the shared validator, which incorrectly applied it to Scan too. Thread an is_query flag so only Query prepends the prefix; Scan keeps the bare message. Adds Scan (no-prefix) integration coverage at both layers. Signed-off-by: Lee Hannigan <lhnng@amazon.com>
…BUTES-on-GSI check Address review nits on PR #211: - Introduce IS_QUERY/IS_SCAN constants for validate_select_projection's is_query flag instead of bare true/false at call sites. - Extract the duplicated Select=ALL_ATTRIBUTES-on-non-ALL-GSI rejection from query.rs and scan.rs into a shared validate_all_attributes_index_support in the validation module. No behavior change. Signed-off-by: Lee Hannigan <lhnng@amazon.com>
LeeroyHannigan
force-pushed
the
fix/transaction-key-size-validation
branch
from
July 17, 2026 16:23
071629e to
a541b37
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Four DynamoDB request-validation parity fixes:
Transaction-API primary-key size limit. An oversized primary key (hash > 2048 bytes, range > 1024 bytes) in any transaction sub-op —
TransactGetItems(Get) andTransactWriteItemsPut/Delete/Update/ConditionChecknow cancels the transaction with a per-itemTransactionCanceledExceptioncarrying aValidationErrorcancellation reason for the offending item. Previously the write sub-ops raised a top-levelValidationException(wrong class for transactions) andTransactGetItemsdid no size check at all. An empty key value remains a top-levelValidationException, matching the distinct error class DynamoDB uses for that case.PutItem/DeleteItem
ReturnValues. A value that is a validReturnValuesenum member but is not allowed for these operations (e.g.UPDATED_OLD) now returnsReturnValues can only be ALL_OLD or NONE; a non-enum value returns the generic constraint error listing the full set[ALL_NEW, UPDATED_OLD, ALL_OLD, NONE, UPDATED_NEW].Query/Scan
Select+ProjectionExpression. The rejection now carries the1 validation error detected:prefix for Query, but not for Scan matching DynamoDB, which prefixes one and not the other.Query/Scan
Select=ALL_ATTRIBUTESon a non-ALL GSI. Now rejected withSelect type ALL_ATTRIBUTES is not supported for global secondary index <name> because its projection type is not ALL(previously silently accepted).Why
ExtendDB diverged from the AWS DynamoDB service on these validation paths: some invalid inputs were accepted, and some rejections used the wrong error class or message. Each behavior and exact message was captured from the live
AWS DynamoDB service (us-east-1) before implementing, and verified to match verbatim.
Closes #
Testing done
Each case was captured from the live AWS DynamoDB service first, implemented to match, then verified end-to-end against a local server.
cargo test -p extenddb-core --lib): 345 passed — new key-size, ReturnValues, and Select-projection (Query vs Scan prefix) cases.TransactWriteItemsoversized key →TransactionCanceledException [ValidationError];PutItemReturnValues=UPDATED_OLD→ReturnValues can only be ALL_OLD or NONE; QuerySelect=COUNT+ProjectionExpression→1 validation error detected: ...while Scan returns the same message without the prefix;Select=ALL_ATTRIBUTESon aKEYS_ONLYGSI → rejected.cargo fmt --all -- --checkclean;cargo clippy --workspace --all-targets -- -D warningsclean.Checklist
cargo test --workspace)cargo fmt --check)cargo clippy -- -W clippy::pedantic)parity with DynamoDB; no user-facing docs affected)
Storagetrait, auth model, on-disk format, or public CLI surface, an RFC has been accepted or is linked below. Otherwise, an ADR captures the decision (link below). — none of these change; request-validation only.ADR / RFC: n/a — request-validation/error-parity fixes. No change to the wire protocol,
Storagetrait, auth model, on-disk format, or CLI surface.Breaking changes
None to the wire protocol or response shapes for valid requests. Validation is stricter: inputs that AWS DynamoDB rejects — oversized transaction keys, disallowed
ReturnValueson Put/Delete, andSelect=ALL_ATTRIBUTESon a non-ALL GSI are now rejected (some were previously accepted, or returned a different error class/message). A client relying on ExtendDB's previous lenient behavior will now receive the same error AWS DynamoDB returns.By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache License 2.0 and I agree to the Developer Certificate of
Origin (DCO). See CONTRIBUTING.md for details.