You're going to run into problems using sets of non-primitive types in general. 
In Python, as the message describes, the reason is because Thrift objects do 
not know how to hash themselves for placement in the container. To accomplish 
this we'd have to generate hashing functions. It's not obvious that this is a 
smart thing to do for complex types.

Is there a strong reason why you need a set rather than a list?

-----Original Message-----
From: Balanagireddy Mudiam [mailto:[email protected]] 
Sent: Thursday, March 11, 2010 6:47 PM
To: [email protected]
Subject: Re: PHP error calling thrift method

Hi,

After it was suggested that set cannot be used in php, I changed from php to
python. Even in python, am facing the same issue (I think).

Traceback (most recent call last):
  File "depository.py", line 52, in <module>
    responses = client.findValue(request)
  File "/home/shraddha/dev/python/packages/mvr/MyServer.py", line 40, in
findValue
    return self.recv_findValue()
  File "/home/shraddha/dev/python/packages/mvr/MyServer.py", line 58, in
recv_findValue
    result.read(self._iprot)
  File "/home/shraddha/dev/python/packages/mvr/MyServer.py", line 194, in
read
    self.success.add(_elem21)
TypeError: unhashable instance


Below is the python thrift code generated.

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec
is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__,
self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.SET:
          self.success = set()
          (_etype19, _size16) = iprot.readSetBegin()
          for _i20 in xrange(_size16):
            _elem21 = MVRResponse()
            _elem21.read(iprot)
            self.success.add(_elem21)
          iprot.readSetEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ex = MVRException()
          self.ex.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

AFAIK, support supports set. Any idea, how to resolve it.

Regards
Bala Mudiam




On Tue, Mar 9, 2010 at 6:15 PM, Balanagireddy Mudiam <
[email protected]> wrote:

> Thank you Mark Slee. I will make the suggested changes.
>
> Regards
> Bala Mudiam
>
>
>
>
>
> On Tue, Mar 9, 2010 at 5:51 PM, Mark Slee <[email protected]> wrote:
> > Ah yes, here's the issue:
> >
> > service MyServer {
> >  set<MyResponse> findValue(1: MyRequest request )
> >    throws (1: MyException ex)
> >
> > Thrift/PHP does not support sets of objects. This is because in PHP
> Thrift implements sets as a dictionary hash, and PHP arrays only support
> scalar keys.
> >
> > You should probably just use list<MyResponse> instead of set.
> >
> > -----Original Message-----
> > From: Balanagireddy Mudiam [mailto:[email protected]]
> > Sent: Tuesday, March 09, 2010 2:45 PM
> > To: [email protected]
> > Subject: Re: PHP error calling thrift method
> >
> > Hi,
> >
> > The reason I kept the request was, I thought set type was creating the
> problem.
> >
> > Here is the complete thrift file.
> >
> >  struct MyResponse {
> >   1: i64 totalValue,
> >   2: i64 Value1,
> >   3: i64 Value2,
> >   4: i64 Value3,
> >   5: map<string,i64> sourceValMap
> >  }
> >
> > struct MyRequest {
> >  1: set<string> name,
> >  2: i32 startDate,
> >  3: i32 endDate,
> >  }
> >
> > service MyServer {
> >  set<MyResponse> findValue(1: MyRequest request )
> >    throws (1: MyException ex)
> >
> > }
> >
> >
> > Here is the read method for response, generated by thrift.
> >
> >  public function read($input)
> >  {
> >    $xfer = 0;
> >    $fname = null;
> >    $ftype = 0;
> >    $fid = 0;
> >    $xfer += $input->readStructBegin($fname);
> >    while (true)
> >    {
> >      $xfer += $input->readFieldBegin($fname, $ftype, $fid);
> >      if ($ftype == TType::STOP) {
> >        break;
> >      }
> >      switch ($fid)
> >      {
> >        case 0:
> >          if ($ftype == TType::SET) {
> >            $this->success = array();
> >            $_size16 = 0;
> >            $_etype19 = 0;
> >            $xfer += $input->readSetBegin($_etype19, $_size16);
> >            for ($_i20 = 0; $_i20 < $_size16; ++$_i20)
> >            {
> >              $elem21 = null;
> >              $elem21 = new MyResponse();
> >              $xfer += $elem21->read($input);
> > -->              $this->success[$elem21] = true;
> >            }
> >            $xfer += $input->readSetEnd();
> >          } else {
> >            $xfer += $input->skip($ftype);
> >          }
> >          break;
> >        case 1:
> >          if ($ftype == TType::STRUCT) {
> >            $this->ex = new MyException();
> >            $xfer += $this->ex->read($input);
> >          } else {
> >            $xfer += $input->skip($ftype);
> >          }
> >          break;
> >        default:
> >          $xfer += $input->skip($ftype);
> >          break;
> >      }
> >      $xfer += $input->readFieldEnd();
> >    }
> >    $xfer += $input->readStructEnd();
> >    return $xfer;
> >  }
> >
> > Here is how I am invoking it.
> >
> > $vals['name'] = array("USA");
> > $vals['startDate'] = '20100201';
> > $vals['endDate'] = '20100120';
> >
> > $myrequest = new MyRequest($vals);
> >
> > $results = $mvr->findValue($myrequest);
> >
> > Thank you.
> >
> > Regards
> > Bala Mudiam
> >
> >
> >
> >
> >
> > On Tue, Mar 9, 2010 at 5:34 PM, Mark Slee <[email protected]> wrote:
> >> I think something is missing here. The struct you show is MyRequest but
> this generated code is dealing with a MyResponse.
> >>
> >> Can you send over your full .thrift file, more context in the generated
> code, and how you're invoking it?
> >>
> >> -----Original Message-----
> >> From: Balanagireddy Mudiam [mailto:[email protected]]
> >> Sent: Tuesday, March 09, 2010 2:20 PM
> >> To: [email protected]
> >> Subject: PHP error calling thrift method
> >>
> >> Hi,
> >>
> >> I am having the below request object and I am calling a method using
> >> thrift from php.
> >>
> >>  struct MyRequest {
> >>   1: set<string> name,
> >>   2: i32 startDate,
> >>   3: i32 endDate,
> >>  }
> >>
> >> When I execute my php, I get the following error. This warning is
> >> thrown from thrift generated code. The reason for the warning is
> >> $elem21(object) cannot be used as a key.
> >>
> >> Warning: Illegal offset type in Server.php on line 226
> >>
> >> 223               $elem21 = null;
> >> 224               $elem21 = new MyResponse();
> >> 225               $xfer += $elem21->read($input);
> >> 226               $this->success[$elem21] = true;
> >>
> >> Any idea, how to resolve this issue.
> >>
> >> Thank you.
> >>
> >> Regards
> >> Bala Mudiam
> >>
> >
>

Reply via email to