Skip to content

[V4] Update DocumentModel to handle expressions without variables #3804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions generator/.DevConfigs/6d15fac7-b782-42ab-a6b8-e2ff4c240df3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"services": [
{
"serviceName": "DynamoDBv2",
"type": "patch",
"changeLogMessages": [
"Fix regression where an `Expression` could not be used without `ExpressionAttributeValues` (https://github.com/aws/aws-sdk-net/issues/3802)"
]
}
]
}
38 changes: 20 additions & 18 deletions sdk/src/Services/DynamoDBv2/Custom/DocumentModel/Expression.cs
Original file line number Diff line number Diff line change
@@ -218,27 +218,29 @@ internal static void ApplyExpression(QueryRequest request, Table table,
internal static Dictionary<string, AttributeValue> ConvertToAttributeValues(
Dictionary<string, DynamoDBEntry> valueMap, Table table)
{
if (valueMap == null || valueMap.Count == 0)
{
return null;
}

var convertedValues = new Dictionary<string, AttributeValue>();
if (valueMap != null)
foreach (var kvp in valueMap)
{
foreach (var kvp in valueMap)
var attributeName = kvp.Key;
var entry = kvp.Value;

if (entry == null)
convertedValues[attributeName] = new AttributeValue { NULL = true };
else
{
var attributeName = kvp.Key;
var entry = kvp.Value;

if (entry == null)
convertedValues[attributeName] = new AttributeValue { NULL = true };
else
{
if (table.StoreAsEpoch.Contains(attributeName))
entry = Document.DateTimeToEpochSeconds(entry, attributeName);

if (table.StoreAsEpochLong.Contains(attributeName))
entry = Document.DateTimeToEpochSecondsLong(entry, attributeName);

var attributeConversionConfig = new DynamoDBEntry.AttributeConversionConfig(table.Conversion, table.IsEmptyStringValueEnabled);
convertedValues[attributeName] = entry.ConvertToAttributeValue(attributeConversionConfig);
}
if (table.StoreAsEpoch.Contains(attributeName))
entry = Document.DateTimeToEpochSeconds(entry, attributeName);

if (table.StoreAsEpochLong.Contains(attributeName))
entry = Document.DateTimeToEpochSecondsLong(entry, attributeName);

var attributeConversionConfig = new DynamoDBEntry.AttributeConversionConfig(table.Conversion, table.IsEmptyStringValueEnabled);
convertedValues[attributeName] = entry.ConvertToAttributeValue(attributeConversionConfig);
}
}

23 changes: 23 additions & 0 deletions sdk/test/Services/DynamoDBv2/IntegrationTests/DocumentTests.cs
Original file line number Diff line number Diff line change
@@ -58,6 +58,7 @@ public void TestTableOperations()

// Test expressions for put
TestExpressionPut(hashTable);
TestExpressionPutWithoutValues(hashTable);

// Test expressions for delete
TestExpressionsOnDelete(hashTable);
@@ -137,6 +138,7 @@ public void TestTableOperationsViaBuilder()

// Test expressions for put
TestExpressionPut(hashTable);
TestExpressionPutWithoutValues(hashTable);

// Test expressions for delete
TestExpressionsOnDelete(hashTable);
@@ -1755,6 +1757,27 @@ private void TestExpressionPut(ITable hashTable)
hashTable.DeleteItem(doc);
}

private void TestExpressionPutWithoutValues(ITable hashTable)
{
var doc = new Document
{
["Id"] = DateTime.UtcNow.Ticks
};

var expression = new Expression
{
ExpressionStatement = "attribute_not_exists(Id)"
};

var config = new PutItemOperationConfig
{
ConditionalExpression = expression
};

Assert.IsTrue(hashTable.TryPutItem(doc, config));
hashTable.DeleteItem(doc);
}

private void TestExpressionUpdate(ITable hashTable)
{
Document doc = new Document();