Improve dynamodb query case sensitivity (#3799) (#3800)

* between clause is not case-sensitive anymore

* begins_with will raise an exception unless lower-case is used

Co-authored-by: David Pedrosa <d.pedrosa@indizen.com>
This commit is contained in:
David Pedrosa 2021-03-25 21:22:36 +01:00 committed by GitHub
parent 5aa8d03a59
commit ba0f0bd513
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 1 deletions

View File

@ -510,7 +510,7 @@ class DynamoHandler(BaseResponse):
range_key_expression_components = range_key_expression.split()
range_comparison = range_key_expression_components[1]
if "AND" in range_key_expression:
if " and " in range_key_expression.lower():
range_comparison = "BETWEEN"
range_values = [
value_alias_map[range_key_expression_components[2]],
@ -521,6 +521,18 @@ class DynamoHandler(BaseResponse):
range_values = [
value_alias_map[range_key_expression_components[-1]]
]
elif "begins_with" in range_key_expression.lower():
function_used = range_key_expression[
range_key_expression.lower().index("begins_with") : len(
"begins_with"
)
]
return self.error(
"com.amazonaws.dynamodb.v20111205#ValidationException",
"Invalid KeyConditionExpression: Invalid function name; function: {}".format(
function_used
),
)
else:
range_values = [value_alias_map[range_key_expression_components[2]]]
else:

View File

@ -1082,6 +1082,72 @@ def test_boto3_conditions():
results["Count"].should.equal(1)
@mock_dynamodb2
def test_boto3_conditions_ignorecase():
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
# Create the DynamoDB table.
dynamodb.create_table(
TableName="users",
KeySchema=[
{"AttributeName": "forum_name", "KeyType": "HASH"},
{"AttributeName": "subject", "KeyType": "RANGE"},
],
AttributeDefinitions=[
{"AttributeName": "forum_name", "AttributeType": "S"},
{"AttributeName": "subject", "AttributeType": "S"},
],
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
)
dynamodb.put_item(
TableName="users",
Item={"forum_name": {"S": "the-key"}, "subject": {"S": "100"}},
)
dynamodb.put_item(
TableName="users",
Item={"forum_name": {"S": "the-key"}, "subject": {"S": "199"}},
)
dynamodb.put_item(
TableName="users",
Item={"forum_name": {"S": "the-key"}, "subject": {"S": "250"}},
)
between_expressions = [
"BETWEEN :start AND :end",
"between :start and :end",
"Between :start and :end",
"between :start AnD :end",
]
for expr in between_expressions:
results = dynamodb.query(
TableName="users",
KeyConditionExpression="forum_name = :forum_name and subject {}".format(
expr
),
ExpressionAttributeValues={
":forum_name": {"S": "the-key"},
":start": {"S": "100"},
":end": {"S": "200"},
},
)
results["Count"].should.equal(2)
with pytest.raises(ClientError) as ex:
dynamodb.query(
TableName="users",
KeyConditionExpression="forum_name = :forum_name and BegIns_WiTh(subject, :subject )",
ExpressionAttributeValues={
":forum_name": {"S": "the-key"},
":subject": {"S": "1"},
},
)
ex.value.response["Error"]["Code"].should.equal("ValidationException")
ex.value.response["Error"]["Message"].should.equal(
"Invalid KeyConditionExpression: Invalid function name; function: BegIns_WiTh"
)
@mock_dynamodb2
def test_boto3_put_item_with_conditions():
import botocore