[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15879232#comment-15879232
 ] 

Jens Geyer commented on THRIFT-3752:
------------------------------------

I remember having a somewhat lengthy discussion about that during one of the 
last big rewrites of the Thrift Go bindings with the author(s) of that patch. 
Not quite sure what the main reason was, but at the end we decided to implement 
it this way. That being said, I would be happy if we come up with a better 
solution that is more aligned to the usually expected behaviour, there's 
absolutely no question about that. This is Go - so it should be possible, 
shouldn't it ;-)?

> 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.15#6346)

Reply via email to