[ 
https://issues.apache.org/jira/browse/THRIFT-3473?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

YU Chang updated THRIFT-3473:
-----------------------------
    Description: 
Any "optional" modifier relates to a list will cause to a null/undef return 
value.

Here is thrift file:
{code:title=test.thrift|borderStyle=solid}
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()

}

{code}

Here is C++ code (server):
{code:title=Test_server.cpp|borderStyle=solid}
#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;
}
{code}


Here is perl code (client):
{code:title=Test_client.pl|borderStyle=solid}
#!/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 $@;
{code}

{code:title=C++ server output|borderStyle=solid}
strList size: 2
pairList size: 1
call listTest
{code}

{code:title=perl client output|borderStyle=solid}
$VAR1 = bless( {
                 'pairList' => undef,
                 'strList' => undef
               }, 'thrifttest::Result' );
{code}

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. 

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

Here is thrift file:
{code:title=WordAligner.thrift|borderStyle=solid}
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()

}

{code}

Here is C++ code (server):
{code:title=Test_server.cpp|borderStyle=solid}
#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;
}
{code}


Here is perl code (client):
{code:title=Test_client.pl|borderStyle=solid}
#!/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 $@;
{code}

{code:title=C++ server output|borderStyle=solid}
strList size: 2
pairList size: 1
call listTest
{code}

{code:title=perl client output|borderStyle=solid}
$VAR1 = bless( {
                 'pairList' => undef,
                 'strList' => undef
               }, 'thrifttest::Result' );
{code}

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. 


> When use "optional' before a list, C++ server cannot return it correctly 
> -------------------------------------------------------------------------
>
>                 Key: THRIFT-3473
>                 URL: https://issues.apache.org/jira/browse/THRIFT-3473
>             Project: Thrift
>          Issue Type: Bug
>          Components: C++ - Library
>    Affects Versions: 0.9.3
>         Environment: CentOS 7, GCC 4.8.3, Perl 5.16
>            Reporter: YU Chang
>
> Any "optional" modifier relates to a list will cause to a null/undef return 
> value.
> Here is thrift file:
> {code:title=test.thrift|borderStyle=solid}
> 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()
> }
> {code}
> Here is C++ code (server):
> {code:title=Test_server.cpp|borderStyle=solid}
> #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;
> }
> {code}
> Here is perl code (client):
> {code:title=Test_client.pl|borderStyle=solid}
> #!/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 $@;
> {code}
> {code:title=C++ server output|borderStyle=solid}
> strList size: 2
> pairList size: 1
> call listTest
> {code}
> {code:title=perl client output|borderStyle=solid}
> $VAR1 = bless( {
>                  'pairList' => undef,
>                  'strList' => undef
>                }, 'thrifttest::Result' );
> {code}
> 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. 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to