Skip to content
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

Problem with default values in Go library #7100

Closed
estromenko opened this issue Feb 12, 2022 · 3 comments
Closed

Problem with default values in Go library #7100

estromenko opened this issue Feb 12, 2022 · 3 comments

Comments

@estromenko
Copy link

Mutation methods in Go library do not apply if default value is set. There was the same issue in C++ library, but it looks line it is not still fixed in Go. I use go1.17 and the latest flatbuffers.

Here is some examples:

image

image

image

@CasperN
Copy link
Collaborator

CasperN commented Feb 12, 2022

Flatbuffers has an optimization where if the default value is set, we skip writing the value in the binary. This also means it cannot be mutated, since mutation works by modifying an existing value in place and you can't do that if it's simply not there.

If you require mutation, I suggest making the default some sentinel value, e.g. -1, and always initialize this inside your application. You could also rebuild the flatbuffer if the code isn't performance sensitive.

If you weren't using Go, #6014 allows you to use hp: short = null to avoid the sentinel, but it would make all the types optional and you'd still have to initialize the value in your application before building the flatbuffer to use the mutation api.

@estromenko
Copy link
Author

My problem was solved by removing default value from schema. I think, this behaviour is not explicit. In such cases it is required to define default values outside of schema.
Maybe, I am not right, but for me it looks like a bug

@CasperN
Copy link
Collaborator

CasperN commented Feb 12, 2022

My problem was solved by removing default value from schema.

Cool, resolving. Note that removing the default value from the schema makes the default value implicitly zero, so if you fail to initialize hp, or initialize it to zero, the value won't be written and mutation will fail.

I think, this behaviour is not explicit. In such cases it is required to define default values outside of schema.
Maybe, I am not right, but for me it looks like a bug

I agree that this behavior is mysterious/complex but its the result of organic evolution and our commitment to not having breaking changes in the binary format or schema language. The in-place mutation API came after the default-elision thing.

For what its worth the tutorial does advise on this in the mutation API section

Note that any mutate functions on a table will return a boolean, which is false if the field we're trying to set is not present in the buffer. Fields are not present if they weren't set, or even if they happen to be equal to the default value. For example, in the creation code above, the mana field is equal to 150, which is the default value, so it was never stored in the buffer. Trying to call the corresponding mutate method for mana on such data will return false, and the value won't actually be modified!

One way to solve this is to call ForceDefaults on a FlatBufferBuilder to force all fields you set to actually be written. This, of course, increases the size of the buffer somewhat, but this may be acceptable for a mutable buffer.

@CasperN CasperN closed this as completed Feb 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants