Skip to content

Commit 86d6001

Browse files
authored
Avoid adding 'prefix' to update mask for transforms used in 'update'. (#8701)
Closes #7215.
1 parent 56accfa commit 86d6001

File tree

6 files changed

+112
-16
lines changed

6 files changed

+112
-16
lines changed

firestore/google/cloud/firestore_v1/_helpers.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -836,10 +836,6 @@ def _get_update_mask(self, allow_empty_mask=False):
836836
for field_path in self.top_level_paths:
837837
if field_path not in self.transform_paths:
838838
mask_paths.append(field_path.to_api_repr())
839-
else:
840-
prefix = FieldPath(*field_path.parts[:-1])
841-
if prefix.parts:
842-
mask_paths.append(prefix.to_api_repr())
843839

844840
return common_pb2.DocumentMask(field_paths=mask_paths)
845841

firestore/google/cloud/firestore_v1beta1/_helpers.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -785,10 +785,6 @@ def _get_update_mask(self, allow_empty_mask=False):
785785
for field_path in self.top_level_paths:
786786
if field_path not in self.transform_paths:
787787
mask_paths.append(field_path.to_api_repr())
788-
else:
789-
prefix = FieldPath(*field_path.parts[:-1])
790-
if prefix.parts:
791-
mask_paths.append(prefix.to_api_repr())
792788

793789
return common_pb2.DocumentMask(field_paths=mask_paths)
794790

firestore/tests/unit/v1/test__helpers.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,10 +2110,7 @@ def _helper(self, option=None, do_transform=False, **write_kwargs):
21102110

21112111
map_pb = document_pb2.MapValue(fields={"yum": _value_pb(bytes_value=value)})
21122112

2113-
if do_transform:
2114-
field_paths = [field_path1, "blog"]
2115-
else:
2116-
field_paths = [field_path1]
2113+
field_paths = [field_path1]
21172114

21182115
expected_update_pb = write_pb2.Write(
21192116
update=document_pb2.Document(
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"tests": [
3+
{
4+
"description": "update: Nested transforms should not affect the field mask, even\nwhen there are other values that do. Transforms should only affect the\nDocumentTransform_FieldTransform list.",
5+
"comment": "For updates, top-level paths in json-like map inputs\nare split on the dot. That is, an input {\"a.b.c\": 7} results in an update to\nfield c of object b of object a with value 7. In order to specify this behavior,\nthe update must use a fieldmask \"a.b.c\". However, fieldmasks are only used for\nconcrete values - transforms are separately encoded in a\nDocumentTransform_FieldTransform array.\n\nThis test exercises a bug found in python (https://github.com/googleapis/google-cloud-python/issues/7215)\nin which nested transforms ({\"a.c\": \"ServerTimestamp\"}) next to nested values\n({\"a.b\": 7}) incorrectly caused the fieldmask \"a\" to be set, which has the\neffect of wiping out all data in \"a\" other than what was specified in the\njson-like input.\n\nInstead, as this test specifies, transforms should not affect the fieldmask.",
6+
"update": {
7+
"docRefPath": "projects/projectID/databases/(default)/documents/C/d",
8+
"jsonData": "{\"a.b\": 7, \"a.c\": \"ServerTimestamp\"}",
9+
"request": {
10+
"database": "projects/projectID/databases/(default)",
11+
"writes": [
12+
{
13+
"update": {
14+
"name": "projects/projectID/databases/(default)/documents/C/d",
15+
"fields": {
16+
"a": {
17+
"mapValue": {
18+
"fields": {
19+
"b": {
20+
"integerValue": "7"
21+
}
22+
}
23+
}
24+
}
25+
}
26+
},
27+
"updateMask": {
28+
"fieldPaths": [
29+
"a.b"
30+
]
31+
},
32+
"currentDocument": {
33+
"exists": true
34+
}
35+
},
36+
{
37+
"transform": {
38+
"document": "projects/projectID/databases/(default)/documents/C/d",
39+
"fieldTransforms": [
40+
{
41+
"fieldPath": "a.c",
42+
"setToServerValue": "REQUEST_TIME"
43+
}
44+
]
45+
}
46+
}
47+
]
48+
}
49+
}
50+
}
51+
]
52+
}

firestore/tests/unit/v1beta1/test__helpers.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,10 +1801,7 @@ def _helper(self, option=None, do_transform=False, **write_kwargs):
18011801

18021802
map_pb = document_pb2.MapValue(fields={"yum": _value_pb(bytes_value=value)})
18031803

1804-
if do_transform:
1805-
field_paths = [field_path1, "blog"]
1806-
else:
1807-
field_paths = [field_path1]
1804+
field_paths = [field_path1]
18081805

18091806
expected_update_pb = write_pb2.Write(
18101807
update=document_pb2.Document(
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# DO NOT MODIFY. This file was generated by
2+
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
3+
4+
# For updates, top-level paths in json-like map inputs are split on the dot. That
5+
# is, an input {"a.b.c": 7} results in an update to field c of object b of object
6+
# a with value 7. In order to specify this behavior, the update must use a
7+
# fieldmask "a.b.c". However, fieldmasks are only used for concrete values -
8+
# transforms are separately encoded in a DocumentTransform_FieldTransform array.
9+
10+
# This test exercises a bug found in python
11+
# (https://github.com/googleapis/google-cloud-python/issues/7215) in which nested
12+
# transforms ({"a.c": "ServerTimestamp"}) next to nested values ({"a.b": 7})
13+
# incorrectly caused the fieldmask "a" to be set, which has the effect of wiping
14+
# out all data in "a" other than what was specified in the json-like input.
15+
16+
# Instead, as this test specifies, transforms should not affect the fieldmask.
17+
18+
description: "update: Nested transforms should not affect the field mask, even\nwhen there are other values that do. Transforms should only affect the\nDocumentTransform_FieldTransform list."
19+
update: <
20+
doc_ref_path: "projects/projectID/databases/(default)/documents/C/d"
21+
json_data: "{\"a.b\": 7, \"a.c\": \"ServerTimestamp\"}"
22+
request: <
23+
database: "projects/projectID/databases/(default)"
24+
writes: <
25+
update: <
26+
name: "projects/projectID/databases/(default)/documents/C/d"
27+
fields: <
28+
key: "a"
29+
value: <
30+
map_value: <
31+
fields: <
32+
key: "b"
33+
value: <
34+
integer_value: 7
35+
>
36+
>
37+
>
38+
>
39+
>
40+
>
41+
update_mask: <
42+
field_paths: "a.b"
43+
>
44+
current_document: <
45+
exists: true
46+
>
47+
>
48+
writes: <
49+
transform: <
50+
document: "projects/projectID/databases/(default)/documents/C/d"
51+
field_transforms: <
52+
field_path: "a.c"
53+
set_to_server_value: REQUEST_TIME
54+
>
55+
>
56+
>
57+
>
58+
>

0 commit comments

Comments
 (0)