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