Details
-
Bug
-
Status: In Progress
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
See discussion here: https://reviews.apache.org/r/45193/
This is likely related to THRIFT-3700.
In short, for this struct:
struct TaskQuery { 4: optional set<string> taskIds }
The following go struct is generated:
type TaskQuery struct { TaskIds map[string]bool `thrift:"taskIds,4" json:"taskIds"` }
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:
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 }
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.
Attachments
Issue Links
- relates to
-
THRIFT-3700 Go Map has wrong default value when optional
- Closed
-
THRIFT-3756 Improve requiredness documentation
- Closed