[
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15213669#comment-15213669
]
John Sirois commented on THRIFT-3752:
-------------------------------------
Actually [~jensg] - I can't make sense of the spec you added for this case. If
I look at the java generated serialization code for a no-requiredness set<i32>
I find:
{noformat}
if (struct.instanceIds != null) {
oprot.writeFieldBegin(INSTANCE_IDS_FIELD_DESC);
{
oprot.writeSetBegin(new
org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32,
struct.instanceIds.size()));
for (int _iter143 : struct.instanceIds)
{
oprot.writeI32(_iter143);
}
oprot.writeSetEnd();
}
oprot.writeFieldEnd();
}
{noformat}
Your spec in THRIFT-3756 says "Write: Like required, the fields are always
written.". In the java case though, the field is only written when non-null -
which is a good thing, since it allows the read-side of the wire to correctly
interpret this field as unset.
> nil collections are serialized as empty collections
> ---------------------------------------------------
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
> Issue Type: Bug
> Components: Go - Compiler
> Reporter: John Sirois
> Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set<string> taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
> TaskIds map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
> if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
> return thrift.PrependError(fmt.Sprintf("%T write field begin
> error 4:taskIds: ", p), err)
> }
> if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err !=
> nil {
> return thrift.PrependError("error writing set begin: ", err)
> }
> for v, _ := range p.TaskIds {
> if err := oprot.WriteString(string(v)); err != nil {
> return thrift.PrependError(fmt.Sprintf("%T. (0) field
> write error: ", p), err)
> }
> }
> if err := oprot.WriteSetEnd(); err != nil {
> return thrift.PrependError("error writing set end: ", err)
> }
> if err := oprot.WriteFieldEnd(); err != nil {
> return thrift.PrependError(fmt.Sprintf("%T write field end
> error 4:taskIds: ", p), err)
> }
> return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an
> empty collection and so unset-ness cannot be distinguished from set but empty.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)