-
Notifications
You must be signed in to change notification settings - Fork 1.6k
ValueUtil changes for FieldValue migration #7991
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
ValueUtil changes for FieldValue migration #7991
Conversation
Generated by 🚫 Danger |
93af3ba
to
cc4d0f1
Compare
@wu-hui Do you have time to take a look at this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor changes requested, almost LGTM.
// An empty blob is represented by a nullptr | ||
return util::Compare(left.bytes_value != nullptr, | ||
right.bytes_value != nullptr); | ||
// An empty blob is represented by a nullptr (or an empty byte array) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: this seems to be a behavior change from below? Can you explain why? Not that I am against..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not meant to be a behavior change but rather a bug fix. When we create an empty bytes array directly with NanoPB, it uses nullptr
and does not actually allocate memory. When we receive documents from the backend, these empty byte arrays are represented using a zero-length array, but one with an actual address in memory. We need these two representations to yield the same comparison behavior so our users don't see any behavior change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, thanks.
|
||
bool IsNaNValue(const google_firestore_v1_Value& value) { | ||
return value.which_value_type == google_firestore_v1_Value_double_value_tag && | ||
isnan(value.double_value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be std::isnan
from cmath
instead.
isnan
is also available because cmath
also include math.h
, but should not be directly used. Just learnt this today from Costa's code review :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice. Hopefully I can use this information in my next code review.
/** | ||
* Generate the canonical ID for the provided field value (as used in Target | ||
* serialization). | ||
*/ | ||
std::string CanonicalId(const google_firestore_v1_Value& value); | ||
|
||
/** | ||
* Generate the canonical ID for the provided array value (as used in Target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Generates"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
bool Contains(google_firestore_v1_ArrayValue haystack, | ||
google_firestore_v1_Value needle); | ||
|
||
/** Returns `nullptr` in its Protobuf representation. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe Returns a null Protobuf value
? nullptr
is pretty specifically a pointer to address 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
/** Returns `nullptr` in its Protobuf representation. */ | ||
google_firestore_v1_Value NullValue(); | ||
|
||
/** Returns `true` if `value` is `nullptr` in its Protobuf representation. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...if given value is a null Protobuf value
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
/** Returns `true` if `value` is `NaN` in its Protobuf representation. */ | ||
bool IsNaNValue(const google_firestore_v1_Value& value); | ||
|
||
google_firestore_v1_Value RefValue(const DatabaseId& database_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review!
// An empty blob is represented by a nullptr | ||
return util::Compare(left.bytes_value != nullptr, | ||
right.bytes_value != nullptr); | ||
// An empty blob is represented by a nullptr (or an empty byte array) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not meant to be a behavior change but rather a bug fix. When we create an empty bytes array directly with NanoPB, it uses nullptr
and does not actually allocate memory. When we receive documents from the backend, these empty byte arrays are represented using a zero-length array, but one with an actual address in memory. We need these two representations to yield the same comparison behavior so our users don't see any behavior change.
|
||
bool IsNaNValue(const google_firestore_v1_Value& value) { | ||
return value.which_value_type == google_firestore_v1_Value_double_value_tag && | ||
isnan(value.double_value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice. Hopefully I can use this information in my next code review.
bool Contains(google_firestore_v1_ArrayValue haystack, | ||
google_firestore_v1_Value needle); | ||
|
||
/** Returns `nullptr` in its Protobuf representation. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
/** Returns `nullptr` in its Protobuf representation. */ | ||
google_firestore_v1_Value NullValue(); | ||
|
||
/** Returns `true` if `value` is `nullptr` in its Protobuf representation. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
/** Returns `true` if `value` is `NaN` in its Protobuf representation. */ | ||
bool IsNaNValue(const google_firestore_v1_Value& value); | ||
|
||
google_firestore_v1_Value RefValue(const DatabaseId& database_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one place you missed to update a comment. But LGTM still!
// An empty blob is represented by a nullptr | ||
return util::Compare(left.bytes_value != nullptr, | ||
right.bytes_value != nullptr); | ||
// An empty blob is represented by a nullptr (or an empty byte array) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, thanks.
This is part of #7904. It will break the feature branch, but I am planning to send out small reviewable chunks with an end goal of a feature branch that passes CI.
This PR adds a couple of new utilities that are used in the FieldValue port (and changes some signatures). They are all based on Android: https://github.com/firebase/firebase-android-sdk/blob/master/firebase-firestore/src/main/java/com/google/firebase/firestore/model/Values.java
The PR also adds logic to treat zero-length strings/bytes the same as
null
bytes and strings, as nanopb uses both representations.