[
https://issues.apache.org/jira/browse/THRIFT-5891?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18016378#comment-18016378
]
Jens Geyer edited comment on THRIFT-5891 at 8/26/25 8:47 PM:
-------------------------------------------------------------
The behaviour is in fact not so well defined as one might think. To cite from
[Randy's
book](https://www.manning.com/books/programmers-guide-to-apache-thrift),
emphasis mine:
{quote}
Default values assigned to fields with either default or required requiredness
are set by both the struct writer and the struct reader. Thus, if a default
requiredness field isn’t present when reading a struct, the field’s default
value is used by the reader. Conversely, if a writer and a reader have
different default values for a default/required requiredness field, the
writer’s transmitted value will overwrite the reader’s. This is easiest to
remember by thinking of the simple two-step process that
takes place:
- The reader and writer both initialize their struct fields with their
respective default values.
- The writer transmits its final values to the reader, while the reader
replaces default values for fields received with the received values.
Fields with optional requiredness can be assigned default values. However,
unlike required and default requiredness fields, optional fields holding their
default value *{color:#DE350B}need{color}* not be transmitted. The default
field value will not take up space on the wire, leaving the reader’s locally
initialized default value intact.
{quote}
First, this is not meant to be a spec, it merely describes the current
behaviour at the time of writing. The key point here is, that it has been this
way since basically forever. Next, it says "need", not "should (not)" or "must
(not)" There have been some discussions about default values on optional (or
default-requiredness) fields. The approach where values are written, wether
being defaulted or not, altough potenbtially wasting space is considered the
more robust against IDL changes, compared to omitting such values.
The origins of this change go back to commit 7ff3245bfa implementing the first
version for C++, Java, PHP and Python. The implementations in that commit
simply sets any given default field value for basic types straightforward, if
possible at field init time. No additional checks during write, nothing. IIRC
there are also some JIRA tickets or mailing list threads around.
So my conclusion would be that either behaviour is acceptable. The main issue
with this whole topic is that it was never formally specified and has kind of
evolved or emerged over time.
was (Author: jensg):
The behaviour is in fact not so well defined as one might think. To cite from
[Randy's
book](https://www.manning.com/books/programmers-guide-to-apache-thrift),
emphasis mine:
{quote}
Default values assigned to fields with either default or required requiredness
are set by both the struct writer and the struct reader. Thus, if a default
requiredness field isn’t present when reading a struct, the field’s default
value is used by the reader. Conversely, if a writer and a reader have
different default values for a default/required requiredness field, the
writer’s transmitted value will overwrite the reader’s. This is easiest to
remember by thinking of the simple two-step process that
takes place:
- The reader and writer both initialize their struct fields with their
respective default values.
- The writer transmits its final values to the reader, while the reader
replaces default values for fields received with the received values.
Fields with optional requiredness *{color:#DE350B}can{color}* be assigned
default values. However, unlike required and default requiredness fields,
optional fields holding their default value need not be transmitted. The
default field value will not take up space on the wire, leaving the reader’s
locally initialized default value intact.
{quote}
First, this is not meant to be a spec, it merely describes the current
behaviour at the time of writing. The key point here is, that it has been this
way since basically forever. Next, it says "can", not "should" or "must" There
have been some discussions about default values on optional (or
default-requiredness) fields. The approach where values are written, wether
being defaulted or not, altough potenbtially wasting space is considered the
more robust against IDL changes, compared to omitting such values.
The origins of this change go back to commit 7ff3245bfa implementing the first
version for C++, Java, PHP and Python. The implementations in that commit
simply sets any given default field value for basic types straightforward, if
possible at field init time. No additional checks during write, nothing. IIRC
there are also some JIRA tickets or mailing list threads around.
So my conclusion would be that either behaviour is acceptable. The main issue
with this whole topic is that it was never formally specified and has kind of
evolved or emerged over time.
> Optional fields don't correctly round trip
> ------------------------------------------
>
> Key: THRIFT-5891
> URL: https://issues.apache.org/jira/browse/THRIFT-5891
> Project: Thrift
> Issue Type: Improvement
> Components: Rust - Compiler
> Reporter: Hasnain Lakhani
> Priority: Minor
>
> This was discovered while fuzzing Rust code - see
> https://github.com/apache/thrift/pull/3201
> If you have a structure with an optional field (set to None) in memory, and
> you serialize then deserialize it, it comes back as Some(default_value). This
> seems incorrect, but at the same time it's potentially a breaking change so
> needs some thought before fixing.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)