-
Notifications
You must be signed in to change notification settings - Fork 51
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
fix(i): JSON object default value panic #3156
base: develop
Are you sure you want to change the base?
fix(i): JSON object default value panic #3156
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #3156 +/- ##
===========================================
+ Coverage 77.98% 78.14% +0.15%
===========================================
Files 354 354
Lines 34669 34674 +5
===========================================
+ Hits 27036 27093 +57
+ Misses 6003 5966 -37
+ Partials 1630 1615 -15
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 14 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
2b8dceb
to
f42f255
Compare
f42f255
to
e0706db
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.
Context for other reviewers, the panic was caused by the fact that client.FieldDefinition
is used as the key
for a map of properties on encodedDocument
. For a Go type to be used as a map key it has to be comparable. Within client.FieldDefinition
, the DefaultField
struct field is of type any
and until we added support for JSON default, it only ever contained scalar types. But a default JSON value can be an object which is represented as a map[string]any
. A map is not a comparable type and this was causing a runtime panic when trying to create a new doc using the default JSON object. This panic happened in the fetcher code github.com/sourcenetwork/defradb/internal/db/fetcher/fetcher.go:544
when fetching the new document within the creation request.
I'm OK with removing DefaultValue
from client.FieldDefinition
for now although a better fix might be to change the fetcher code. @AndrewSisley might have a stronger opinion for this one.
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.
todo: I do not agree with removing it from here - this object is supposed to be a unified object containing the result of local+global configuration and taking it off this breaks that. It will result in weirdness for users (as well as internal code) where some public functions returning Definitions cannot inform users as to what the default value is.
I feel even more strongly about this given that it is described as a somewhat accidental result from the fix, that this just happened to be the quickest way to fix a bug and wasn't really a long term design choice.
Please either discuss the with the whole team over discord or in the standup.
Furthermore, going by:
the panic was caused by the fact that client.FieldDefinition is used as the key for a map of properties on encodedDocument.
The alternative looks pretty simple and non invasive/internal - just use the field ID or name as the map key - they are identifiers and using the whole object sounds unneeded and error prone anyway.
@@ -68,8 +68,8 @@ type encodedDocument struct { | |||
id []byte | |||
schemaVersionID string | |||
status client.DocumentStatus | |||
properties map[client.FieldDefinition]*encProperty | |||
decodedPropertyCache map[client.FieldDefinition]any | |||
properties map[client.FieldDefinitionKey]*encProperty |
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: Why are you using both field ID and Name here? At a single point in time either will be unique - you can't two fields with the same fieldID or with the same name.
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.
Both the field ID and name are used in the downstream dependencies. If we used only one as the map key then we would need to expand the FieldDefinition
API to support looking up a field by ID or copy paste a lookup function into a few places. I think having the FieldDefinitionKey
is the better alternative.
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 should already be functions to get fields by Name
if you use that as the key - I don't think you'd need to add anything to client
.
Having a (public) FieldDefinitionKey
struct with name
and key
properties suggests that they need to be combined in order to form a unique key - which is incorrect.
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.
The DecodeToDoc
function in the fetcher doesn't have a reference to the definition so it can't lookup the field ID from the name.
I'm fine with changing the struct name but I don't see any issues with the way I implemented it.
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.
DecodeToDoc
just uses the field ID as an index - we could change that too. Or you could change encodedDocument
.properties
to a slice containing field name and value.
There are many ways to solve this internal coding problem that don't involve changing the public types, especially not in a way that seems a little misleading.
Relevant issue(s)
Resolves #3146
Description
This PR fixes an issue where JSON default values containing objects would cause a panic related to a map key hash. Moving the default value off of the FieldDefinition appears to fix the issue.
Tasks
How has this been tested?
Updated integration tests
Specify the platform(s) on which this was tested: