polardbxengine/unittest/gunit/xplugin/xcl/query_t.cc

746 lines
25 KiB
C++

/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0,
* as published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an additional
* permission to link the program and your derivative works with the
* separately licensed software that they have included with MySQL.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <memory>
#include <stdexcept>
#include "plugin/x/client/context/xcontext.h"
#include "plugin/x/client/mysqlxclient/xquery_result.h"
#include "plugin/x/client/xquery_result_impl.h"
#include "unittest/gunit/xplugin/xcl/message_helpers.h"
#include "unittest/gunit/xplugin/xcl/mock/protocol.h"
#include "unittest/gunit/xplugin/xcl/mock/query_instance.h"
namespace xcl {
namespace test {
using ::testing::_;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::Throw;
const Query_instances::Instance_id TEST_INSTANCE_ID = 1001;
const xcl::XProtocol::Handler_id TEST_NOTICE_HANDLER_ID = 1002;
class Query_test_suite : public ::testing::Test {
public:
using Mock_query_instances_ptr = std::shared_ptr<Mock_query_instances>;
using Mock_protocol_ptr = std::shared_ptr<Mock_protocol>;
using Context_ptr = std::shared_ptr<Context>;
public:
void SetUp() override {
ON_CALL(*m_mock_protocol, recv_single_message_raw(_, _))
.WillByDefault(Throw(std::logic_error("Unexpected mock calls")));
EXPECT_CALL(*m_mock_protocol, add_notice_handler(_, Handler_position::Begin,
Handler_priority_medium))
.WillOnce(Return(TEST_NOTICE_HANDLER_ID));
EXPECT_CALL(*m_mock_query_instances, instances_fetch_begin())
.WillOnce(Return(TEST_INSTANCE_ID));
m_sut.reset(new Query_result(m_mock_protocol, m_mock_query_instances.get(),
m_context));
}
void verifyMocks() {
Mock::VerifyAndClearExpectations(m_mock_query_instances.get());
Mock::VerifyAndClearExpectations(m_mock_protocol.get());
}
Context_ptr m_context = std::make_shared<Context>();
Mock_query_instances_ptr m_mock_query_instances =
std::make_shared<StrictMock<Mock_query_instances>>();
Mock_protocol_ptr m_mock_protocol =
std::make_shared<StrictMock<Mock_protocol>>();
std::unique_ptr<XQuery_result> m_sut;
};
class Query_non_active_test_suite : public Query_test_suite {
public:
void SetUp() override {
Query_test_suite::SetUp();
EXPECT_CALL(*m_mock_query_instances, is_instance_active(TEST_INSTANCE_ID))
.WillRepeatedly(Return(false));
}
};
TEST_F(Query_non_active_test_suite, last_insert_id_not_initialized) {
uint64_t out_result;
ASSERT_FALSE(m_sut->try_get_last_insert_id(&out_result));
ASSERT_FALSE(m_sut->try_get_last_insert_id(nullptr));
}
TEST_F(Query_non_active_test_suite, affected_rows_not_initialized) {
uint64_t out_result;
ASSERT_FALSE(m_sut->try_get_affected_rows(&out_result));
ASSERT_FALSE(m_sut->try_get_affected_rows(nullptr));
}
TEST_F(Query_non_active_test_suite, info_message_not_initialized) {
std::string out_result;
ASSERT_FALSE(m_sut->try_get_info_message(&out_result));
ASSERT_FALSE(m_sut->try_get_info_message(nullptr));
}
TEST_F(Query_non_active_test_suite, get_warnings_not_initialized) {
ASSERT_EQ(0, m_sut->get_warnings().size());
}
TEST_F(Query_non_active_test_suite, get_metadata_previous_not_finished) {
XError out_error;
ASSERT_EQ(0, m_sut->get_metadata(&out_error).size());
ASSERT_EQ(0, m_sut->get_metadata(nullptr).size());
ASSERT_EQ(CR_X_LAST_COMMAND_UNFINISHED, out_error.error());
}
TEST_F(Query_non_active_test_suite, get_next_row2_previous_not_finished) {
const XRow *out_xrow;
XError out_error;
ASSERT_FALSE(m_sut->get_next_row(&out_xrow, &out_error));
ASSERT_EQ(CR_X_LAST_COMMAND_UNFINISHED, out_error.error());
ASSERT_FALSE(m_sut->get_next_row(nullptr, nullptr));
}
TEST_F(Query_non_active_test_suite, get_next_row1_previous_not_finished) {
XError out_error;
ASSERT_EQ(nullptr, m_sut->get_next_row(&out_error));
ASSERT_EQ(CR_X_LAST_COMMAND_UNFINISHED, out_error.error());
ASSERT_EQ(nullptr, m_sut->get_next_row(nullptr));
}
TEST_F(Query_non_active_test_suite, get_next_row_raw_previous_not_finished) {
XError out_error;
ASSERT_EQ(nullptr, m_sut->get_next_row_raw(&out_error).get());
ASSERT_EQ(CR_X_LAST_COMMAND_UNFINISHED, out_error.error());
ASSERT_EQ(nullptr, m_sut->get_next_row_raw(nullptr).get());
}
TEST_F(Query_non_active_test_suite, next_resultset_previous_not_finished) {
XError out_error;
ASSERT_FALSE(m_sut->next_resultset(&out_error));
ASSERT_EQ(CR_X_LAST_COMMAND_UNFINISHED, out_error.error());
}
TEST_F(Query_non_active_test_suite, has_resultset_previous_not_finished) {
XError out_error;
ASSERT_FALSE(m_sut->has_resultset(&out_error));
ASSERT_EQ(CR_X_LAST_COMMAND_UNFINISHED, out_error.error());
}
class Query_active_test_suite : public Query_test_suite {
public:
using Message_id = xcl::XProtocol::Server_message_type_id;
public:
void SetUp() override {
Query_test_suite::SetUp();
EXPECT_CALL(*m_mock_query_instances, is_instance_active(TEST_INSTANCE_ID))
.WillRepeatedly(Return(true));
}
void expect_query_finish() {
EXPECT_CALL(*m_mock_query_instances, instances_fetch_end());
EXPECT_CALL(*m_mock_protocol,
remove_notice_handler(TEST_NOTICE_HANDLER_ID));
EXPECT_CALL(*m_mock_query_instances, is_instance_active(TEST_INSTANCE_ID))
.WillRepeatedly(Return(true));
}
template <typename Message_type>
void expect_recv_message(const std::string &msg_text) {
auto *message = new Message_from_str<Message_type>(msg_text);
const auto &message_options = message->get().descriptor()->options();
const auto server_id = static_cast<int>(
message_options.GetExtension(Mysqlx::server_message_id));
EXPECT_CALL(*m_mock_protocol, recv_single_message_raw(_, _))
.WillOnce(Invoke([message, server_id](
xcl::XProtocol::Server_message_type_id *out_mid,
XError *out_error) -> xcl::XProtocol::Message * {
if (out_mid) *out_mid = static_cast<Message_id>(server_id);
if (out_error) *out_error = XError();
return &message->get();
}));
}
template <typename Message_type>
void expect_recv_message() {
auto *message =
new Message_type(Server_message<Message_type>::make_required());
const auto &message_options = message->descriptor()->options();
const auto server_id = static_cast<int>(
message_options.GetExtension(Mysqlx::server_message_id));
EXPECT_CALL(*m_mock_protocol, recv_single_message_raw(_, _))
.WillOnce(Invoke([message, server_id](
xcl::XProtocol::Server_message_type_id *out_mid,
XError *out_error) -> xcl::XProtocol::Message * {
if (out_mid) *out_mid = static_cast<Message_id>(server_id);
if (out_error) *out_error = XError();
return message;
}));
}
void verifyQuery_state_is_done(const int warnings_count = 0,
const bool is_last_insert = false,
const bool is_affected_rows = false,
const bool is_info_message = false) {
ASSERT_FALSE(m_sut->has_resultset(nullptr));
ASSERT_FALSE(m_sut->next_resultset(nullptr));
ASSERT_EQ(nullptr, m_sut->get_next_row(nullptr));
ASSERT_EQ(warnings_count, m_sut->get_warnings().size());
ASSERT_EQ(is_last_insert, m_sut->try_get_last_insert_id(nullptr));
ASSERT_EQ(is_affected_rows, m_sut->try_get_affected_rows(nullptr));
ASSERT_EQ(is_info_message, m_sut->try_get_info_message(nullptr));
}
};
using Done_messages = ::testing::Types<::Mysqlx::Resultset::FetchDone,
::Mysqlx::Resultset::FetchSuspended>;
template <typename T>
class Query_active_destructor_cleanup_test_suite
: public Query_active_test_suite {};
TYPED_TEST_CASE(Query_active_destructor_cleanup_test_suite, Done_messages);
TYPED_TEST(Query_active_destructor_cleanup_test_suite,
consumes_stmt_execute_ok) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite, consumes_done_and_ok) {
InSequence s;
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite,
consumes_meta_data_and_done_and_ok) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT");
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite,
consumes_meta_data_and_row_and_done_and_ok) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:''");
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite,
consumes_two_resultsets) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:''");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreResultsets>("");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1111'");
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite,
consumes_resultset_outparams) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:''");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreOutParams>("");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1111'");
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite,
consumes_multiple_resultset_outparams) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT name:'first'");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:UINT name:'second'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>(
"field:'1' field:'2'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>(
"field:'3' field:'4'");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreResultsets>("");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT name:'next_1'");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:UINT name:'next_2'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>(
"field:'5' field:'6'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>(
"field:'8' field:'8'");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreOutParams>("");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'2'");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreOutParams>("");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'2'");
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite, consumes_error) {
this->template expect_recv_message<::Mysqlx::Error>(
"code:1 sql_state:'' msg:'error'");
this->expect_query_finish();
}
TYPED_TEST(Query_active_destructor_cleanup_test_suite,
consumes_error_after_meta) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT name:'first'");
this->template expect_recv_message<::Mysqlx::Error>(
"code:1 sql_state:'' msg:'error'");
this->expect_query_finish();
}
using Unexpected_messages =
::testing::Types<::Mysqlx::Ok, ::Mysqlx::Connection::Capabilities,
::Mysqlx::Session::AuthenticateOk,
::Mysqlx::Session::AuthenticateContinue>;
template <typename T>
class Typed_query_active_test_suite : public Query_active_test_suite {
public:
using Unexpected_message = T;
};
TYPED_TEST_CASE(Typed_query_active_test_suite, Unexpected_messages);
TYPED_TEST(Typed_query_active_test_suite,
destructor_consumes_until_unexpected_message1) {
InSequence s;
// unexpected message breaks flow
this->template expect_recv_message<TypeParam>();
this->expect_query_finish();
}
TYPED_TEST(Typed_query_active_test_suite,
destructor_consumes_until_unexpected_message2) {
InSequence s;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT name:'first'");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT name:'second'");
// unexpected message breaks flow
this->template expect_recv_message<TypeParam>();
this->expect_query_finish();
}
// Issue reproduction
// Query_result was not deregistring its instance after
// reception of StmtExecuteOk
TEST_F(Query_active_test_suite, no_resultset_at_call_has_resultset) {
InSequence s;
expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
expect_query_finish();
ASSERT_FALSE(m_sut->has_resultset());
verifyMocks();
verifyQuery_state_is_done();
}
TEST_F(Query_active_test_suite, no_resultset_at_call_get_metadata) {
InSequence s;
XError out_error;
expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
expect_query_finish();
ASSERT_EQ(0, m_sut->get_metadata(&out_error).size());
ASSERT_FALSE(out_error);
verifyMocks();
verifyQuery_state_is_done();
}
TEST_F(Query_active_test_suite, no_resultset_at_call_next_resultset) {
InSequence s;
XError out_error;
expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
expect_query_finish();
ASSERT_FALSE(m_sut->next_resultset(&out_error));
ASSERT_FALSE(out_error);
verifyMocks();
ASSERT_FALSE(m_sut->has_resultset(&out_error));
ASSERT_FALSE(m_sut->next_resultset(nullptr));
ASSERT_EQ(nullptr, m_sut->get_next_row(nullptr));
}
TEST_F(Query_active_test_suite, no_resultset_at_call_get_next_row) {
InSequence s;
XError out_error;
expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
expect_query_finish();
ASSERT_EQ(nullptr, m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
verifyMocks();
verifyQuery_state_is_done();
}
template <typename T>
class Query_active_test_suite_typed_param : public Query_active_test_suite {};
TYPED_TEST_CASE(Query_active_test_suite_typed_param, Done_messages);
TYPED_TEST(Query_active_test_suite_typed_param, fetch_one_resultset) {
InSequence s;
XError out_error;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:''");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1111'");
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
ASSERT_TRUE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(this->m_sut->is_out_parameter_resultset());
ASSERT_FALSE(out_error);
ASSERT_EQ(2, this->m_sut->get_metadata(&out_error).size());
ASSERT_FALSE(out_error);
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_FALSE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->is_out_parameter_resultset());
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
this->verifyMocks();
this->verifyQuery_state_is_done();
}
TYPED_TEST(Query_active_test_suite_typed_param, fetch_two_resultsets) {
InSequence s;
XError out_error;
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreResultsets>();
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(0, this->m_sut->get_metadata(&out_error).size());
ASSERT_FALSE(out_error);
ASSERT_FALSE(this->m_sut->is_out_parameter_resultset());
ASSERT_EQ(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_TRUE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(this->m_sut->is_out_parameter_resultset());
ASSERT_FALSE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(this->m_sut->is_out_parameter_resultset());
this->verifyMocks();
this->verifyQuery_state_is_done();
}
TYPED_TEST(Query_active_test_suite_typed_param,
fetch_empty_resultset_and_empty_out_param) {
InSequence s;
XError out_error;
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreOutParams>();
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(this->m_sut->is_out_parameter_resultset());
ASSERT_FALSE(out_error);
ASSERT_EQ(0, this->m_sut->get_metadata(&out_error).size());
ASSERT_FALSE(out_error);
ASSERT_EQ(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_TRUE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
ASSERT_TRUE(this->m_sut->is_out_parameter_resultset());
ASSERT_FALSE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
this->verifyMocks();
this->verifyQuery_state_is_done();
}
TYPED_TEST(Query_active_test_suite_typed_param,
fetch_resultset_and_empty_out_param) {
InSequence s;
XError out_error;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'2'");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreOutParams>();
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1'");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
ASSERT_TRUE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(this->m_sut->is_out_parameter_resultset());
ASSERT_FALSE(out_error);
ASSERT_EQ(1, this->m_sut->get_metadata(&out_error).size());
ASSERT_FALSE(out_error);
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_TRUE(this->m_sut->next_resultset(&out_error));
ASSERT_TRUE(this->m_sut->has_resultset(&out_error));
ASSERT_TRUE(this->m_sut->is_out_parameter_resultset());
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_FALSE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
this->verifyMocks();
this->verifyQuery_state_is_done();
}
TYPED_TEST(Query_active_test_suite_typed_param,
fetch_resultset_and_empty_out_param_skip_data) {
InSequence s;
XError out_error;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1'");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'2'");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreOutParams>();
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>("field:'1'");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
ASSERT_TRUE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(out_error);
ASSERT_TRUE(this->m_sut->next_resultset(&out_error));
ASSERT_TRUE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
this->verifyMocks();
this->verifyQuery_state_is_done();
}
TYPED_TEST(Query_active_test_suite_typed_param, fetch_two_resultsetss) {
InSequence s;
XError out_error;
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::Row>(
"field:'' field:''");
this->template expect_recv_message<::Mysqlx::Resultset::Row>(
"field:'1111' field:''");
this->template expect_recv_message<
::Mysqlx::Resultset::FetchDoneMoreResultsets>("");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:SINT");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:DOUBLE");
this->template expect_recv_message<::Mysqlx::Resultset::ColumnMetaData>(
"type:UINT");
this->template expect_recv_message<::Mysqlx::Resultset::Row>(
"field:'' field:'' field:''");
this->template expect_recv_message<TypeParam>("");
this->template expect_recv_message<::Mysqlx::Sql::StmtExecuteOk>("");
this->expect_query_finish();
// First resultset
ASSERT_TRUE(this->m_sut->has_resultset(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(2, this->m_sut->get_metadata(&out_error).size());
ASSERT_FALSE(out_error);
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
// Second resultset
ASSERT_TRUE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(3, this->m_sut->get_metadata(&out_error).size());
ASSERT_FALSE(out_error);
ASSERT_NE(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_EQ(nullptr, this->m_sut->get_next_row(&out_error));
ASSERT_FALSE(out_error);
ASSERT_FALSE(this->m_sut->next_resultset(&out_error));
ASSERT_FALSE(this->m_sut->has_resultset(&out_error));
this->verifyMocks();
this->verifyQuery_state_is_done();
}
} // namespace test
} // namespace xcl