Uploaded image for project: 'Thrift'
  1. Thrift
  2. THRIFT-3473

When "optional' is used with a struct member, C++ server seems to not return it correctly

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 0.9.3
    • Fix Version/s: 0.10.0
    • Component/s: C++ - Library
    • Labels:
      None
    • Environment:

      CentOS 7, GCC 4.8.3, Perl 5.16

      Description

      Any "optional" modifier relates to a list will cause to a null/undef return value.

      Here is thrift file:

      test.thrift
      namespace cpp thrifttest
      namespace perl thrifttest
      
      struct Pair {
          1: optional string a, 
          2: optional string b
      }
      
      struct Result {
          1: optional list<string> strList,
          2: optional list<Pair> pairList
      }
      
      service Test {
      
          Result listTest()
      
      }
      
      

      Here is C++ code (server):

      Test_server.cpp
      #include "gen-cpp/Test.h"
      #include <thrift/protocol/TBinaryProtocol.h>
      #include <thrift/server/TSimpleServer.h>
      #include <thrift/transport/TServerSocket.h>
      #include <thrift/transport/TBufferTransports.h>
      
      #include <iostream>
      
      using namespace std;
      
      using namespace ::apache::thrift;
      using namespace ::apache::thrift::protocol;
      using namespace ::apache::thrift::transport;
      using namespace ::apache::thrift::server;
      
      using boost::shared_ptr;
      
      using namespace  ::thrifttest;
      
      class TestHandler : virtual public TestIf {
          public:
              TestHandler() {
                  // Your initialization goes here
              }
      
              void listTest(Result& _return) {
      
                  _return.strList.push_back("Test");
                  _return.strList.push_back("one level list");
                  cout << "strList size: " << _return.strList.size() << endl;
      
                  Pair pair;
                  pair.a = "Test";
                  pair.b = "two level list";
                  _return.pairList.push_back(pair);
                  cout << "pairList size: " << _return.pairList.size() << endl;
      
                  printf("call listTest\n");
              }
      
      };
      
      int main(int argc, char **argv) {
          int port = 9595;
          shared_ptr<TestHandler> handler(new TestHandler());
          shared_ptr<TProcessor> processor(new TestProcessor(handler));
          shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
          shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
          shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
      
          TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
          server.serve();
          return 0;
      }
      

      Here is perl code (client):

      Test_client.pl
      #!/usr/bin/perl
      
      use v5.12;
      use warnings;
      use autodie;
      
      use utf8;
      use Data::Dumper;
      
      use lib 'gen-perl';
      
      use thrifttest::Test;
      use thrifttest::Constants;
      use thrifttest::Types;
      
      use Thrift;
      use Thrift::BinaryProtocol;
      use Thrift::Socket;
      use Thrift::BufferedTransport;
      
      
      my $socket    = new Thrift::Socket('localhost', 9595);
      my $transport = new Thrift::BufferedTransport($socket, 1024, 1024);
      my $protocol  = new Thrift::BinaryProtocol($transport);
      my $client    = new thrifttest::TestClient($protocol);
      
      
      eval {
          $transport->open();
          my $result = $client->listTest;
          say Dumper($result);
          $transport->close();
      };
      say $@ if $@;
      
      C++ server output
      strList size: 2
      pairList size: 1
      call listTest
      
      perl client output
      $VAR1 = bless( {
                       'pairList' => undef,
                       'strList' => undef
                     }, 'thrifttest::Result' );
      

      In this test case, every "optional" corresponding to a undef return value.

      Only If I delete all the "optional" in the thrift file, I will get right return value.

        Attachments

          Activity

            People

            • Assignee:
              jensg Jens Geyer
              Reporter:
              huache YU Chang
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: