Skip to content

Commit f94b900

Browse files
authored
DDB: parity fix for JS clients (#12083)
1 parent 41ffa76 commit f94b900

File tree

5 files changed

+59
-0
lines changed

5 files changed

+59
-0
lines changed

localstack-core/localstack/services/dynamodb/provider.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,11 @@ def execute_statement(
13101310
# find a way to make it better, same way as the other operations, by using returnvalues
13111311
# see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.update.html
13121312
statement = execute_statement_input["Statement"]
1313+
# We found out that 'Parameters' can be an empty list when the request comes from the AWS JS client.
1314+
if execute_statement_input.get("Parameters", None) == []: # noqa
1315+
raise ValidationException(
1316+
"1 validation error detected: Value '[]' at 'parameters' failed to satisfy constraint: Member must have length greater than or equal to 1"
1317+
)
13131318
table_name = extract_table_name_from_partiql_update(statement)
13141319
existing_items = None
13151320
stream_type = table_name and get_table_stream_type(

localstack-core/localstack/services/dynamodb/v2/provider.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,12 @@ def execute_statement(
889889
# TODO: this operation is still really slow with streams enabled
890890
# find a way to make it better, same way as the other operations, by using returnvalues
891891
# see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.update.html
892+
893+
# We found out that 'Parameters' can be an empty list when the request comes from the AWS JS client.
894+
if execute_statement_input.get("Parameters", None) == []: # noqa
895+
raise ValidationException(
896+
"1 validation error detected: Value '[]' at 'parameters' failed to satisfy constraint: Member must have length greater than or equal to 1"
897+
)
892898
return self.forward_request(context)
893899

894900
#

tests/aws/services/dynamodb/test_dynamodb.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import pytest
1010
import requests
1111
from boto3.dynamodb.types import STRING
12+
from botocore.config import Config
1213
from botocore.exceptions import ClientError
1314
from localstack_snapshot.snapshots.transformer import SortingTransformer
1415

@@ -746,6 +747,35 @@ def test_dynamodb_batch_execute_statement(
746747

747748
aws_client.dynamodb.delete_table(TableName=table_name)
748749

750+
@markers.aws.validated
751+
def test_dynamodb_execute_statement_empy_parameter(
752+
self, dynamodb_create_table_with_parameters, snapshot, aws_client_factory
753+
):
754+
ddb_client = aws_client_factory(config=Config(parameter_validation=False)).dynamodb
755+
table_name = f"test_table_{short_uid()}"
756+
dynamodb_create_table_with_parameters(
757+
TableName=table_name,
758+
KeySchema=[
759+
{"AttributeName": "Artist", "KeyType": "HASH"},
760+
{"AttributeName": "SongTitle", "KeyType": "RANGE"},
761+
],
762+
AttributeDefinitions=[
763+
{"AttributeName": "Artist", "AttributeType": "S"},
764+
{"AttributeName": "SongTitle", "AttributeType": "S"},
765+
],
766+
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
767+
)
768+
769+
ddb_client.put_item(
770+
TableName=table_name,
771+
Item={"Artist": {"S": "The Queen"}, "SongTitle": {"S": "Bohemian Rhapsody"}},
772+
)
773+
774+
statement = f"SELECT * FROM {table_name}"
775+
with pytest.raises(ClientError) as e:
776+
ddb_client.execute_statement(Statement=statement, Parameters=[])
777+
snapshot.match("invalid-param-error", e.value.response)
778+
749779
@markers.aws.validated
750780
def test_dynamodb_partiql_missing(
751781
self, dynamodb_create_table_with_parameters, snapshot, aws_client

tests/aws/services/dynamodb/test_dynamodb.snapshot.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,5 +1456,20 @@
14561456
"Status": "ENABLED"
14571457
}
14581458
}
1459+
},
1460+
"tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_execute_statement_empy_parameter": {
1461+
"recorded-date": "03-01-2025, 09:24:27",
1462+
"recorded-content": {
1463+
"invalid-param-error": {
1464+
"Error": {
1465+
"Code": "ValidationException",
1466+
"Message": "1 validation error detected: Value '[]' at 'parameters' failed to satisfy constraint: Member must have length greater than or equal to 1"
1467+
},
1468+
"ResponseMetadata": {
1469+
"HTTPHeaders": {},
1470+
"HTTPStatusCode": 400
1471+
}
1472+
}
1473+
}
14591474
}
14601475
}

tests/aws/services/dynamodb/test_dynamodb.validation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
"tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_create_table_with_partial_sse_specification": {
3030
"last_validated_date": "2024-01-10T12:59:50+00:00"
3131
},
32+
"tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_execute_statement_empy_parameter": {
33+
"last_validated_date": "2025-01-03T09:24:27+00:00"
34+
},
3235
"tests/aws/services/dynamodb/test_dynamodb.py::TestDynamoDB::test_dynamodb_execute_transaction": {
3336
"last_validated_date": "2023-08-23T14:32:44+00:00"
3437
},

0 commit comments

Comments
 (0)