I made a simple union of three fields
union example{
1:string STRING,
2:i64 INT64,
3:double DOUBLE
}
And I instantiate the exam
uint32_t type_ex::write(::apache::thrift::protocol::TProtocol* oprot) const {
uint32_t xfer = 0;
apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
xfer += oprot->writeStructBegin("type_ex");
xfer += oprot->writeFieldBegin("STRING", ::apache::thrift::protocol::T_STRING, 1);
xfer += oprot->writeString(this->STRING);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("INT64", ::apache::thrift::protocol::T_I64, 2);
xfer += oprot->writeI64(this->INT64);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("DOUBLE", ::apache::thrift::protocol::T_DOUBLE, 3);
xfer += oprot->writeDouble(this->DOUBLE);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
Looks like a bug with unions. The values are written unconditionally, whcih is right for struct
but not for union
. Consequently, the workaround would be to add an explicit optional
:
union type_ex
{
1 : optional string STRING,
2 : optional i64 INT64,
3 : optional double DOUBLE
}
Which gives us:
uint32_t type_ex::write(::apache::thrift::protocol::TProtocol* oprot) const {
uint32_t xfer = 0;
apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
xfer += oprot->writeStructBegin("type_ex");
if (this->__isset.STRING) {
xfer += oprot->writeFieldBegin("STRING", ::apache::thrift::protocol::T_STRING, 1);
xfer += oprot->writeString(this->STRING);
xfer += oprot->writeFieldEnd();
}
if (this->__isset.INT64) {
xfer += oprot->writeFieldBegin("INT64", ::apache::thrift::protocol::T_I64, 2);
xfer += oprot->writeI64(this->INT64);
xfer += oprot->writeFieldEnd();
}
if (this->__isset.DOUBLE) {
xfer += oprot->writeFieldBegin("DOUBLE", ::apache::thrift::protocol::T_DOUBLE, 3);
xfer += oprot->writeDouble(this->DOUBLE);
xfer += oprot->writeFieldEnd();
}
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
Bug report filed.