John Sirois created THRIFT-3752:
-----------------------------------
Summary: 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
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)