Skip to content

Commit

Permalink
[Cosmos] Fixes falsy value partitionKey values in Bulk operations (#1…
Browse files Browse the repository at this point in the history
…1747)

* Stop mutating body in items.create

* Stops mutating body in items.create

* Fixes undefined/null

* fix undefined in test, unaccepted by cosmos api

* Remove mutation change

* remove changelog line

* undefined and 0 tests

* Adds undefined and 0 tests

* Fix all special cases
  • Loading branch information
zfoster authored Oct 19, 2020
1 parent 07e6492 commit 1ea97ab
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
1 change: 1 addition & 0 deletions sdk/cosmosdb/cosmos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 3.9.3 (Unreleased)

- BUGFIX: Fixes bulk operations with top level partitionKey values that are undefined or null.

## 3.9.2 (2020-09-16)

Expand Down
11 changes: 9 additions & 2 deletions sdk/cosmosdb/cosmos/src/utils/batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,19 @@ export function hasResource(
export function getPartitionKeyToHash(operation: Operation, partitionProperty: string) {
const toHashKey = hasResource(operation)
? (operation.resourceBody as any)[partitionProperty]
: operation.partitionKey.replace(/[\[\]\"\']/g, "");
: (operation.partitionKey && operation.partitionKey.replace(/[[\]"']/g, "")) ||
operation.partitionKey;
// We check for empty object since replace will stringify the value
// The second check avoids cases where the partitionKey value is actually the string '{}'
if (toHashKey === "{}" && operation.partitionKey === "[{}]") {
return {};
}
if (toHashKey === "null" && operation.partitionKey === "[null]") {
return null;
}
if (toHashKey === "0" && operation.partitionKey === "[0]") {
return 0;
}
return toHashKey;
}

Expand All @@ -151,7 +158,7 @@ export function decorateOperation(
operation.resourceBody.id = uuid();
}
}
if (operation.partitionKey) {
if ("partitionKey" in operation) {
const extracted = extractPartitionKey(operation, { paths: ["/partitionKey"] });
return { ...operation, partitionKey: JSON.stringify(extracted) } as Operation;
} else if (
Expand Down
39 changes: 39 additions & 0 deletions sdk/cosmosdb/cosmos/test/functional/item.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,45 @@ describe("bulk item operations", function() {
const response = await v2Container.items.bulk(operations);
assert.equal(response[0].statusCode, 201);
});
it("handles operations with null, undefined, and 0 partition keys", async function() {
const item1Id = addEntropy("item1");
const item2Id = addEntropy("item2");
const item3Id = addEntropy("item2");
await v2Container.items.create({
id: item1Id,
key: null,
class: "2010"
});
await v2Container.items.create({
id: item2Id,
key: 0
});
await v2Container.items.create({
id: item3Id,
key: undefined
});
const operations: OperationInput[] = [
{
operationType: BulkOperationType.Read,
id: item1Id,
partitionKey: null
},
{
operationType: BulkOperationType.Read,
id: item2Id,
partitionKey: 0
},
{
operationType: BulkOperationType.Read,
id: item3Id,
partitionKey: undefined
}
];
const response = await v2Container.items.bulk(operations);
assert.equal(response[0].statusCode, 200);
assert.equal(response[1].statusCode, 200);
assert.equal(response[2].statusCode, 200);
});
});
describe("v2 single partition container", async function() {
let container: Container;
Expand Down

0 comments on commit 1ea97ab

Please sign in to comment.