Skip to content

DynamoDbEnhanced queries fail on attributes that contain + sign. #3058

Closed
@lakmehdi

Description

@lakmehdi

Describe the bug

Queries on attribute names that contain + sign (for example FirstName+LastName) fail when using the DynamoDbEnhanced client.

Expected behavior

Querying on attribute names that contain + sign should be possible.

Current behavior

Users get the following exception

software.amazon.awssdk.services.dynamodb.model.DynamoDbException: ExpressionAttributeNames contains invalid key: Syntax error; key: "#AMZN_MAPPED_FirstName+LastName" 

Steps to Reproduce

Create a table

Run a query with a key that includes + sign. Example

aws dynamodb query \
    --table-name MyTable \
    --key-condition-expression "#AMZN_MAPPED_FirstName+LastName = :AMZN_MAPPED_FirstName+LastName" \
    --expression-attribute-names '{"#AMZN_MAPPED_FirstName+LastName": "Table's PK"}'
    --expression-attribute-values  '{":AMZN_MAPPED_FirstName+LastName":{"S":"AnyValue"}}' 

The outcome will be

software.amazon.awssdk.services.dynamodb.model.DynamoDbException: ExpressionAttributeNames contains invalid key: Syntax error; key: "#AMZN_MAPPED_Node+Operation" 

The same applies for the attribute values key. In that case the exception will be

software.amazon.awssdk.services.dynamodb.model.DynamoDbException: ExpressionAttributeValues contains invalid key: Syntax error; key: ":AMZN_MAPPED_Node+Operation" 

Note, the example I was running was on a GSI but I think the same would apply on any query.

Possible Solution

The EnhancedDynamoDbClient uses "#AMZN_MAPPED_" + cleanAttributeName(<attributeName>)" and ":#AMZN_MAPPED_" + cleanAttributeName(<attributeName>)" as placeholders in query expressions.
https://github.com/aws/aws-sdk-java-v2/blob/584ccb59e770177aeaa4c3b6bda4e24015b8ece9/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/conditional/EqualToConditional.java

+ does not seem to be allowed in those keys.

The cleanAttributeName method should also escape + signs.
https://github.com/aws/aws-sdk-java-v2/blob/584ccb59e770177aeaa4c3b6bda4e24015b8ece9/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/EnhancedClientUtils.java

Note: The same method is also used for projection expressions. My guess is that also does not allow + signs but I have not tested.
https://github.com/aws/aws-sdk-java-v2/blob/6eb75be0be780319e491e2f37a61c83d33a58885/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/ProjectionExpression.java

Context

We had to recreate our table and GSIs as to not use + in the attribute names. We replaced them with #.

AWS Java SDK version used

2.0

JDK version used

JDK 11

Operating System and version

Any

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions