[ 
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)

Reply via email to