From 6f5cae98ad3e2b2e1c600fdd7b2ca465fafb71a3 Mon Sep 17 00:00:00 2001 From: Vincent Barbaresi Date: Thu, 28 Oct 2021 12:10:11 +0200 Subject: [PATCH] fix incomplete LastEvaluatedKey when using Global Secondary Index (#4488) --- moto/dynamodb2/models/__init__.py | 4 +- tests/test_dynamodb2/test_dynamodb.py | 60 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/moto/dynamodb2/models/__init__.py b/moto/dynamodb2/models/__init__.py index 88b00eaf1..64d25111c 100644 --- a/moto/dynamodb2/models/__init__.py +++ b/moto/dynamodb2/models/__init__.py @@ -825,7 +825,7 @@ class Table(CloudFormationModel): result.filter(projection_expression) results, last_evaluated_key = self._trim_results( - results, limit, exclusive_start_key + results, limit, exclusive_start_key, scanned_index=index_name ) return results, scanned_count, last_evaluated_key @@ -917,7 +917,7 @@ class Table(CloudFormationModel): result.filter(projection_expression) results, last_evaluated_key = self._trim_results( - results, limit, exclusive_start_key, index_name + results, limit, exclusive_start_key, scanned_index=index_name ) return results, scanned_count, last_evaluated_key diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py index e396a7ef0..31a2a0c8e 100644 --- a/tests/test_dynamodb2/test_dynamodb.py +++ b/tests/test_dynamodb2/test_dynamodb.py @@ -5965,3 +5965,63 @@ def test_batch_write_item(): table = conn.Table(f"table-{idx}") scan = table.scan() assert scan["Count"].should.equal(0) + + +@mock_dynamodb2 +def test_gsi_lastevaluatedkey(): + # github.com/spulec/moto/issues/3968 + conn = boto3.resource("dynamodb", region_name="us-west-2") + name = "test-table" + table = conn.Table(name) + + conn.create_table( + TableName=name, + KeySchema=[{"AttributeName": "main_key", "KeyType": "HASH"}], + AttributeDefinitions=[ + {"AttributeName": "main_key", "AttributeType": "S"}, + {"AttributeName": "index_key", "AttributeType": "S"}, + ], + ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}, + GlobalSecondaryIndexes=[ + { + "IndexName": "test_index", + "KeySchema": [{"AttributeName": "index_key", "KeyType": "HASH"}], + "Projection": {"ProjectionType": "ALL",}, + "ProvisionedThroughput": { + "ReadCapacityUnits": 1, + "WriteCapacityUnits": 1, + }, + } + ], + ) + + table.put_item( + Item={ + "main_key": "testkey1", + "extra_data": "testdata", + "index_key": "indexkey", + }, + ) + table.put_item( + Item={ + "main_key": "testkey2", + "extra_data": "testdata", + "index_key": "indexkey", + }, + ) + + response = table.query( + Limit=1, + KeyConditionExpression=Key("index_key").eq("indexkey"), + IndexName="test_index", + ) + + items = response["Items"] + items.should.have.length_of(1) + items[0].should.equal( + {"main_key": "testkey1", "extra_data": "testdata", "index_key": "indexkey"} + ) + + last_evaluated_key = response["LastEvaluatedKey"] + last_evaluated_key.should.have.length_of(2) + last_evaluated_key.should.equal({"main_key": "testkey1", "index_key": "indexkey"})