fix(dynamodb): accept newline as UpdateExpression clause separator#449
Merged
hectorvent merged 1 commit intofloci-io:mainfrom Apr 15, 2026
Merged
Conversation
Go AWS SDK v2 expression.Builder joins top-level UpdateExpression clauses with '\n' (e.g. "SET #a = :a\nADD #b :b"). Two bugs in the clause walker silently dropped clauses on these inputs: 1. indexOfKeyword only accepted a literal space as the left word boundary, so a keyword preceded by \n/\t/\r was rejected. This meant findNextClauseKeyword returned -1 for the next clause, and the current clause helper consumed the next clause's text as its own operand. For "SET x = :a\nADD y :b" applySetClause swallowed ":a\nADD y :b" as the SET value, failed the placeholder lookup, and neither SET nor ADD ran. Relaxed the boundary check to accept any whitespace via Character.isWhitespace. 2. indexOfKeyword returned -1 at the first non-boundary occurrence of a keyword, even when a valid match existed later. An attribute named oldSET in "REMOVE oldSET SET newAttr = :v" masked the real SET. Looped past non-boundary hits until a boundary match or end of string. 3. applyRemoveClause, applyAddClause, and applyDeleteClause advanced on the next comma before checking for a clause keyword, so an intra-clause comma in a following SET (e.g. "ADD a :v SET b = :b, c = :c") consumed the SET keyword. Aligned all three helpers with applySetClause's "earlier of next clause keyword or next comma wins" rule. Closes floci-io#430.
hectorvent
approved these changes
Apr 15, 2026
Collaborator
hectorvent
left a comment
There was a problem hiding this comment.
@hampsterx Thanks! This is a great addition to floci.
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.
Summary
Go AWS SDK v2
expression.Builderjoins top-levelUpdateExpressionclauses with\n(e.g."SET #a = :a\nADD #b :b"). Floci silently dropped clauses on these inputs because the clause-boundary parser only accepted a literal space as a word boundary. Fixes #430.Three related fixes in
DynamoDbService:indexOfKeywordword-boundary relaxation. Accept any whitespace (space, tab, CR, LF) before a clause keyword viaCharacter.isWhitespace, not just' '. Before the fix,SET x = :a\nADD y :blost both clauses:applySetClausegreedily consumed":a\nADD y :b"as the SET value, failed the placeholder lookup, and neither SET nor ADD ran.indexOfKeywordloops past non-boundary hits.String.indexOfon the first non-boundary occurrence used to return-1even when a later valid occurrence existed. An attribute namedoldSETin"REMOVE oldSET SET newAttr = :v"masked the realSET. Loop until a boundary match is found or the string ends.applyAddClause/applyDeleteClause/applyRemoveClauseclause advancement alignment. Before this PR they advanced on the next comma before checking for a clause keyword, so an intra-clause comma in a following SET (e.g."ADD a :v SET b = :b, c = :c") consumed theSETkeyword. Aligned withapplySetClause's existing "earlier of next clause keyword or next comma wins" rule.Test cases added
All in
DynamoDbServiceTest.java:SET #n = :n\nADD #c :incADD #c :inc\nSET #n = :nSET #n = :n\tADD #c :incSET #n = :n\r\nADD #c :incSET #a = :a, #b = :b\nADD #c :inc\nDELETE #d :dREMOVE #t\nSET #n = :nDELETE #tag :d\nADD #c :incADD #c :inc SET #n = :n, extra = :oREMOVE #t SET #n = :n, extra = :oDELETE #tag :d SET #n = :n, extra = :oREMOVE oldSET SET newAttr = :vindexOfKeywordloops pastoldSETsuffixSET prefixSET = :v1, other = :v2SETnot mis-parsedTest plan
./mvnw test -Dtest=DynamoDbServiceTest(57 tests pass, 12 new)./mvnw testfull suite (2062 tests pass)Out of scope
applyUpdateExpression(lines 892-904) still hardcodes a trailing literal space, soSET\t#a = :aat the start of an expression is still unsupported. No known SDK emits that shape and Go SDK only emits\nbetween clauses, not leading.indexOfKeyword("SET ","REMOVE ", etc.) keep the trailing literal space. Switching to regex-based whitespace matching is a larger refactor and not needed to fix [BUG] DynamoDB UpdateExpression parser fails when clause types are separated by newline #430.Backwards compatibility
DynamoDbServiceTestcases still pass unchanged.