Projection expression with list item throws error using DynamoDB Enhanced client
- Dominant language
- Java
- Stars
- 2.6k
- Forks
- 1k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 51
Description
### Describe the bug
DynamoDB Enhanced Client: An object contains an attribute that is a list. That list has 2 items in it. When I attempt to project an attribute of one of the list items, I get this error:
```
ExpressionAttributeNames contains invalid key: Syntax error; key: "#AMZN_MAPPED_phoneNumbers[1]" (Service: DynamoDb, Status Code: 400, Request ID: A93OVV2TS1G41T9U8G8U84QKAJVV4KQNSO5AEMVJF66Q9ASUAAJG)
```
`phoneNumbers` is the name of the object's property that is a list.
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Expected Behavior
Return the same results that the following CLI command does:
```
aws dynamodb scan --table-name PersonTable \
--filter-expression "phoneNumbers[1].#type = :type" \
--expression-attribute-values '{":type":{"S":"cell"}}' \
--expression-attribute-names '{"#type": "type"}' \
--projection-expression "firstName, lastName, id, phoneNumbers[1].#type"
```
but using this Java code:
```
Expression phoneFilter = Expression.builder()
.expression("phoneNumbers[1].#type = :type")
.putExpressionName("#type", "type")
.putExpressionValue(":type", AttributeValue.builder().s("cell").build())
.build();
PageIterable phoneFilterResults = personDynamoDbTable.scan(rb -> rb
.filterExpression(phoneFilter)
.attributesToProject("id", "firstName", "lastName")
.addNestedAttributesToProject(NestedAttributeName.create("phoneNumbers[1]", "#type")));
```
which is:
```
{
"Items": [
{
"phoneNumbers": {
"L": [
{
"M": {
"type": {
"S": "cell"
}
}
}
]
},
"id": {
"N": "2"
},
"firstName": {
"S": "FirstName2"
},
"lastName": {
"S": "LastName2"
}
}
],
"Count": 1,
"ScannedCount": 2,
"ConsumedCapacity": null
}
```
### Current Behavior
This is the error:
```
ExpressionAttributeNames contains invalid key: Syntax error; key: "#AMZN_MAPPED_phoneNumbers[1]"
```
produced by:
```
Expression phoneFilter = Expression.builder()
.expression("phoneNumbers[1].#type = :type")
.putExpressionName("#type", "type")
.putExpressionValue(":type", AttributeValue.builder().s("cell").build())
.build();
PageIterable phoneFilterResults = personDynamoDbTable.scan(rb -> rb
.filterExpression(phoneFilter)
.attributesToProject("id", "firstName", "lastName")
.addNestedAttributesToProject(NestedAttributeName.create("phoneNumbers[1]", "#type")));
```
### Reproduction Steps
I can give you access to a repo to reproduce the example.
### Possible Solution
. I don't have any suggestions.
### Additional Information/Context
I am working on the section of the DynamoDB Enhanced Client documentation of the Java Dev. Guide. This section discusses how to filter and project based on attributes that are beans, maps or lists.
The SDK [Javadoc](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/NestedAttributeName.html) also indicates that this should work:
```
Examples of creating NestedAttributeNames:
Simple attribute Level0 can be created as NestedAttributeName.create("Level0")
Nested attribute Level0.Level1 can be created as NestedAttributeName.create("Level0", "Level1")
Nested attribute Level0.Level-2 can be created as NestedAttributeName.create("Level0", "Level-2")
List item 0 of ListAttribute can be created as NestedAttributeName.create("ListAttribute[0]")
```
### AWS Java SDK version used
2.26.6
### JDK version used
17
### Operating System and version
Mac - Sonoma 14.5
Contributor guide
Assessment
This issue has not been assessed yet.