[ https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15213646#comment-15213646 ]
John Sirois commented on THRIFT-3752: ------------------------------------- Noting the not-quite-yet-minted docs are here: https://github.com/Jens-G/thrift/blob/THRIFT-3756/doc/specs/idl.md I'll proceed with a fix that conforms to those docs. > 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)