Skip to content

Commit 6911d52

Browse files
authored
[#9407]Enable Firestore data bundle to support empty array (#9467)
* Change the require condition to optional in some data bundle decode functions
1 parent 64c81c0 commit 6911d52

File tree

4 files changed

+53
-14
lines changed

4 files changed

+53
-14
lines changed

Firestore/core/src/bundle/bundle_serializer.cc

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* http://www.apache.org/licenses/LICENSE-2.0
99
*
10-
* Unless Requiredd by applicable law or agreed to in writing, software
10+
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
* See the License for the specific language governing permissions and
@@ -393,6 +393,16 @@ const nlohmann::json& JsonReader::RequiredObject(const char* child_name,
393393
return json_object.at(child_name);
394394
}
395395

396+
const nlohmann::json& JsonReader::OptionalObject(
397+
const char* child_name,
398+
const json& json_object,
399+
const nlohmann::json& default_value) {
400+
if (json_object.contains(child_name)) {
401+
return json_object.at(child_name);
402+
}
403+
return default_value;
404+
}
405+
396406
double JsonReader::RequiredDouble(const char* name, const json& json_object) {
397407
if (json_object.contains(name)) {
398408
double result = DecodeDouble(json_object.at(name));
@@ -614,11 +624,22 @@ FilterList BundleSerializer::DecodeCompositeFilter(JsonReader& reader,
614624
return {};
615625
}
616626

617-
auto filters = reader.RequiredArray("filters", filter);
627+
const std::vector<json> default_filters;
628+
const auto& filters =
629+
reader.OptionalArray("filters", filter, default_filters);
630+
631+
const json default_objects;
618632
FilterList result;
619633
for (const auto& f : filters) {
620-
result = result.push_back(
621-
DecodeFieldFilter(reader, reader.RequiredObject("fieldFilter", f)));
634+
const json& field_filter =
635+
reader.OptionalObject("fieldFilter", f, default_objects);
636+
if (!field_filter.empty()) {
637+
result = result.push_back(DecodeFieldFilter(reader, field_filter));
638+
} else {
639+
result = result.push_back(DecodeUnaryFilter(
640+
reader, reader.OptionalObject("unaryFilter", f, default_objects)));
641+
}
642+
622643
if (!reader.ok()) {
623644
return {};
624645
}
@@ -636,8 +657,10 @@ Bound BundleSerializer::DecodeBound(JsonReader& reader,
636657
return default_bound;
637658
}
638659

660+
std::vector<json> default_values;
639661
const json& bound_json = reader.RequiredObject(bound_name, query);
640-
std::vector<json> values = reader.RequiredArray("values", bound_json);
662+
std::vector<json> values =
663+
reader.OptionalArray("values", bound_json, default_values);
641664
bool before = reader.OptionalBool("before", bound_json);
642665

643666
auto positions = MakeSharedMessage<google_firestore_v1_ArrayValue>({});
@@ -737,7 +760,9 @@ Message<google_firestore_v1_MapValue> BundleSerializer::DecodeMapValue(
737760

738761
Message<google_firestore_v1_ArrayValue> BundleSerializer::DecodeArrayValue(
739762
JsonReader& reader, const json& array_json) const {
740-
const auto& values = reader.RequiredArray("values", array_json);
763+
std::vector<json> default_values;
764+
const auto& values =
765+
reader.OptionalArray("values", array_json, default_values);
741766

742767
Message<google_firestore_v1_ArrayValue> array_value;
743768
SetRepeatedField(

Firestore/core/src/bundle/bundle_serializer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ class JsonReader : public util::ReadContext {
6464
const char* name,
6565
const nlohmann::json& json_object,
6666
const std::vector<nlohmann::json>& default_value);
67+
6768
const nlohmann::json& RequiredObject(const char* child_name,
6869
const nlohmann::json& json_object);
70+
const nlohmann::json& OptionalObject(const char* child_name,
71+
const nlohmann::json& json_object,
72+
const nlohmann::json& default_value);
6973

7074
double RequiredDouble(const char* name, const nlohmann::json& json_object);
7175
double OptionalDouble(const char* name,

Firestore/core/test/unit/bundle/bundle_reader_test.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,12 @@ class BundleReaderTest : public ::testing::Test {
229229
value2.set_string_value("okok");
230230
ProtoValue value3;
231231
value3.set_null_value(google::protobuf::NULL_VALUE);
232+
ProtoValue value4;
233+
value4.mutable_array_value();
232234
document.mutable_fields()->insert({"\0\ud7ff\ue000\uffff\"", value1});
233235
document.mutable_fields()->insert({"\"(╯°□°)╯︵ ┻━┻\"", value2});
234236
document.mutable_fields()->insert({"nValue", value3});
237+
document.mutable_fields()->insert({"emptyArray", value4});
235238

236239
return document;
237240
}

Firestore/core/test/unit/bundle/bundle_serializer_test.cc

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -826,14 +826,6 @@ TEST_F(BundleSerializerTest, DecodeInvalidFieldFilterOperatorFails) {
826826
EXPECT_NOT_OK(reader.status());
827827
}
828828

829-
{
830-
auto json_copy =
831-
ReplacedCopy(json_string, "\"stringValue\"", "\"arrayValue\"");
832-
JsonReader reader;
833-
bundle_serializer.DecodeNamedQuery(reader, Parse(json_copy));
834-
EXPECT_NOT_OK(reader.status());
835-
}
836-
837829
{
838830
auto json_copy = ReplacedCopy(json_string, "\"op\"", "\"Op\"");
839831
JsonReader reader;
@@ -850,6 +842,14 @@ TEST_F(BundleSerializerTest, DecodeInvalidFieldFilterOperatorFails) {
850842
}
851843

852844
TEST_F(BundleSerializerTest, DecodesCompositeFilter) {
845+
core::Query original = testutil::Query("colls")
846+
.AddingFilter(Filter("f1", "==", nullptr))
847+
.AddingFilter(Filter("f2", "==", true))
848+
.AddingFilter(Filter("f3", "==", 50.3));
849+
VerifyNamedQueryRoundtrip(original);
850+
}
851+
852+
TEST_F(BundleSerializerTest, DecodesCompositeNotNullFilter) {
853853
core::Query original =
854854
testutil::Query("colls")
855855
.AddingFilter(Filter("f1", "not-in", Array(1, "2", 3.0)))
@@ -858,6 +858,13 @@ TEST_F(BundleSerializerTest, DecodesCompositeFilter) {
858858
VerifyNamedQueryRoundtrip(original);
859859
}
860860

861+
TEST_F(BundleSerializerTest, DecodesCompositeNullFilter) {
862+
core::Query original = testutil::Query("colls")
863+
.AddingFilter(Filter("f1", "==", nullptr))
864+
.AddingFilter(Filter("f2", "==", nullptr));
865+
VerifyNamedQueryRoundtrip(original);
866+
}
867+
861868
TEST_F(BundleSerializerTest, DecodeInvalidCompositeFilterOperatorFails) {
862869
std::string json_string = NamedQueryJsonString(
863870
testutil::Query("colls")

0 commit comments

Comments
 (0)