-
Notifications
You must be signed in to change notification settings - Fork 168
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
Encode links in a way the server can understand #5835
Conversation
111c1b7
to
af5ae16
Compare
af5ae16
to
8e028eb
Compare
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.
One other follow-up; on the original ticket description we were talking about two forms of link, one which has the table explicitly set (for a "typed link" or for use in a mixed column) and one which just holds the primary key of the target object, without specifying the target table.
AFAICT this only covers the former case; do we need to also implement the latter as well, or is that a separate task?
src/realm/util/serializer.hpp
Outdated
@@ -109,6 +112,8 @@ struct SerialisationState { | |||
std::string get_variable_name(ConstTableRef table); | |||
std::vector<std::string> subquery_prefix_list; | |||
std::string class_prefix; | |||
Group* group; | |||
ConstTableRef taget_table; |
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.
ConstTableRef taget_table; | |
ConstTableRef target_table; |
src/realm/query_expression.hpp
Outdated
if constexpr (std::is_same_v<T, TypeOfValue>) { | ||
return util::serializer::print_value(val.get_type_of_value()); | ||
} | ||
else if constexpr (std::is_same_v<T, ObjKey>) { | ||
ObjLink link(state.taget_table->get_key(), val.template get<ObjKey>()); |
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.
I'd prefer to have a defensive check in case the target table is null before dereferencing.
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.
OK
src/realm/util/serializer.cpp
Outdated
} | ||
else { | ||
ss << "L" << link.get_table_key().value << ":" << link.get_obj_key().value; | ||
TableRef target_table = g->get_table(link.get_table_key()); |
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.
Let's add a null check on the group and fallback to the "Lx:y" syntax if not found.
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.
Check!
ss << "L" << link.get_table_key().value << ":" << link.get_obj_key().value; | ||
TableRef target_table = g->get_table(link.get_table_key()); | ||
if (ColKey pk_col = target_table ? target_table->get_primary_key_column() : ColKey{}) { | ||
if (auto obj = target_table->try_get_object(link.get_obj_key())) { |
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.
I notice a problem here which is not trivial to solve:
- User A makes a subscription which queries to a link that exists locally.
- User B deletes the target object.
- User A adds another unrelated query to the subscription set.
- Realm serializes User A's subscription queries again, but not finding the original target object locally here uses the
Lx:y
syntax. - Server cannot parse this and sends a subscription error.
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.
We could refuse to serialize this query.
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.
What do you think about giving ObjLink an util::Optional<Mixed> m_pk
member field? Then the serializer would use that info to print the primary key directly without looking up the object key which will work even if the object is deleted.
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.
That would be a hack, I think. But are you sure the scenario will play out as described above? As far as I can tell, the query string is stored as text in the file. Will the query ever be serialized again?
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.
Ok, you are correct. A subscription query is serialized once and the text is stored and reused. So maybe this is not a problem after all. @jbreams can you confirm 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.
Confirmed.
@mpobrien I suggest that we only support the form where we supply both table and object. I don't see any downsides and it makes implementation much easier. |
Sounds good to me. I think there is one additional consideration related to this for when we get to implementing support for this on the server side. The client's query might try to be querying on a link identity like |
…nification * origin/master: Stop forcing enums to be 64 bits unnecessarily clean up documentation of internal fields in config structs SyncConfig should be default constructible Traversal functions use IteratorControl values rather than true/false which is more expressive (#5857) Fix handling of 4-byte UTF8 values on Windows (#5803) Encode links in a way the server can understand (#5835) expose `Group::remove_table` in the C API (#5860) Disable auto refresh for old realm during migration (#5856) Expose `list_find` in the c api (#5848) Do not allow asymmetric tables in pbs (#5853) Refactor link tracing code (#5796) Expose `Obj::get_parent_object` in the C API (#5851) Update app.hpp (#5854) Fix appending to list ignores existing query (#5850)
What, How & Why?
Fixes #5409
☑️ ToDos