[ 
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:51 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", 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:

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 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.

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", 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.

> 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)

Reply via email to