blob: 21aa92bc60bd42090eae15d9f1999408a1c9a923 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ignite_runner_suite.h"
#include "ignite/client/ignite_client.h"
#include "ignite/client/ignite_client_configuration.h"
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include <chrono>
using namespace ignite;
const std::string LONG_QUERY{"SELECT * FROM system_range(0, 10000000000)"};
/**
* Test suite.
*/
class sql_test : public ignite_runner_suite {
protected:
static void SetUpTestSuite() {
ignite_client_configuration cfg{get_node_addrs()};
cfg.set_logger(get_logger());
auto client = ignite_client::start(cfg, std::chrono::seconds(30));
client.get_sql().execute(nullptr, nullptr, {"DROP TABLE IF EXISTS TEST"}, {});
client.get_sql().execute(nullptr, nullptr, {"DROP TABLE IF EXISTS execute_script_success"}, {});
client.get_sql().execute(nullptr, nullptr, {"DROP TABLE IF EXISTS execute_script_fail"}, {});
client.get_sql().execute(nullptr, nullptr, {"CREATE TABLE TEST(ID INT PRIMARY KEY, VAL VARCHAR)"}, {});
for (std::int32_t i = 0; i < 10; ++i) {
client.get_sql().execute(nullptr, nullptr, {"INSERT INTO TEST VALUES (?, ?)"}, {i, "s-" + std::to_string(i)});
}
client.get_sql().execute(nullptr, nullptr,
{"INSERT INTO TBL_ALL_COLUMNS_SQL("
R"(STR, INT8, KEY, INT16, INT32, INT64, FLOAT, DOUBLE, "UUID", "DATE", "TIME", TIME2, "DATETIME", DATETIME2, )"
R"("TIMESTAMP", TIMESTAMP2, "BLOB", "DECIMAL", "BOOLEAN"))"
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
{std::string("test"), std::int8_t(1), std::int64_t(42), std::int16_t(2), std::int32_t(3), std::int64_t(4),
.5f, .6, uuid(0x123e4567e89b12d3, 0x7456426614174000), ignite_date(2023, 2, 7),
ignite_time(17, 4, 12, 3543634), ignite_time(17, 4, 12, 3543634),
ignite_date_time({2020, 7, 28}, {2, 15, 52, 6349879}),
ignite_date_time({2020, 7, 28}, {2, 15, 52, 6349879}), ignite_timestamp(3875238472, 248760634),
ignite_timestamp(3875238472, 248760634),
std::vector<std::byte>{std::byte(1), std::byte(2), std::byte(42)}, big_decimal(123456789098765), true});
}
static void TearDownTestSuite() {
ignite_client_configuration cfg{get_node_addrs()};
cfg.set_logger(get_logger());
auto client = ignite_client::start(cfg, std::chrono::seconds(30));
client.get_sql().execute(nullptr, nullptr, {"DELETE FROM TBL_ALL_COLUMNS_SQL"}, {});
client.get_sql().execute(nullptr, nullptr, {"DROP TABLE TEST"}, {});
client.get_sql().execute(nullptr, nullptr, {"DROP TABLE IF EXISTS execute_script_success"}, {});
}
void SetUp() override {
ignite_client_configuration cfg{get_node_addrs()};
cfg.set_logger(get_logger());
m_client = ignite_client::start(cfg, std::chrono::seconds(30));
}
void TearDown() override {
// remove all
}
primitive execute_statement_one_result(const sql_statement &statement) {
auto result_set0 = m_client.get_sql().execute(nullptr, nullptr, statement, {});
EXPECT_TRUE(result_set0.has_rowset());
return result_set0.current_page().front().get(0);
}
/** Ignite client. */
ignite_client m_client;
};
static void check_columns(
const result_set_metadata &meta, std::initializer_list<std::tuple<std::string, ignite_type>> columns) {
ASSERT_EQ(columns.size(), meta.columns().size());
size_t i = 0;
for (auto &column : columns) {
EXPECT_EQ(i, meta.index_of(std::get<0>(column)));
EXPECT_EQ(meta.columns()[i].name(), std::get<0>(column));
EXPECT_EQ(meta.columns()[i].type(), std::get<1>(column));
++i;
}
}
TEST_F(sql_test, sql_simple_select) {
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"select 42, 'Lorem'"}, {});
EXPECT_FALSE(result_set.was_applied());
EXPECT_TRUE(result_set.has_rowset());
EXPECT_EQ(-1, result_set.affected_rows());
check_columns(result_set.metadata(), {{"42", ignite_type::INT32}, {"'Lorem'", ignite_type::STRING}});
auto page = std::move(result_set).current_page();
EXPECT_EQ(1, page.size());
EXPECT_EQ(42, page.front().get(0).get<std::int32_t>());
EXPECT_EQ("Lorem", page.front().get(1).get<std::string>());
EXPECT_FALSE(result_set.has_more_pages());
EXPECT_EQ(0, result_set.current_page().size());
}
TEST_F(sql_test, sql_table_select) {
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"select id, val from TEST order by id"}, {});
EXPECT_FALSE(result_set.was_applied());
EXPECT_TRUE(result_set.has_rowset());
EXPECT_EQ(-1, result_set.affected_rows());
check_columns(result_set.metadata(), {{"ID", ignite_type::INT32}, {"VAL", ignite_type::STRING}});
auto page = result_set.current_page();
EXPECT_EQ(10, page.size());
for (std::int32_t i = 0; i < std::int32_t(page.size()); ++i) {
EXPECT_EQ(i, page[i].get(0).get<std::int32_t>());
EXPECT_EQ("s-" + std::to_string(i), page[i].get(1).get<std::string>());
}
EXPECT_FALSE(result_set.has_more_pages());
EXPECT_EQ(10, result_set.current_page().size());
}
TEST_F(sql_test, sql_select_multiple_pages) {
sql_statement statement{"select id, val from TEST order by id"};
statement.page_size(1);
auto result_set = m_client.get_sql().execute(nullptr, nullptr, statement, {});
EXPECT_FALSE(result_set.was_applied());
EXPECT_TRUE(result_set.has_rowset());
EXPECT_EQ(-1, result_set.affected_rows());
check_columns(result_set.metadata(), {{"ID", ignite_type::INT32}, {"VAL", ignite_type::STRING}});
for (std::int32_t i = 0; i < 10; ++i) {
auto page = result_set.current_page();
EXPECT_EQ(1, page.size()) << "i=" << i;
EXPECT_EQ(i, page.front().get(0).get<std::int32_t>());
EXPECT_EQ("s-" + std::to_string(i), page.front().get(1).get<std::string>());
if (i < 9) {
ASSERT_TRUE(result_set.has_more_pages());
result_set.fetch_next_page();
}
}
EXPECT_FALSE(result_set.has_more_pages());
}
TEST_F(sql_test, sql_close_non_empty_cursor) {
sql_statement statement{"select id, val from TEST order by id"};
statement.page_size(3);
auto result_set = m_client.get_sql().execute(nullptr, nullptr, statement, {});
EXPECT_FALSE(result_set.was_applied());
EXPECT_TRUE(result_set.has_rowset());
EXPECT_EQ(-1, result_set.affected_rows());
auto page = result_set.current_page();
ASSERT_TRUE(result_set.has_more_pages());
result_set.close();
}
TEST_F(sql_test, sql_ddl_dml) {
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"DROP TABLE IF EXISTS SQL_DDL_DML_TEST"}, {});
EXPECT_FALSE(result_set.has_rowset());
EXPECT_EQ(-1, result_set.affected_rows());
EXPECT_TRUE(result_set.metadata().columns().empty());
result_set =
m_client.get_sql().execute(nullptr, nullptr, {"CREATE TABLE SQL_DDL_DML_TEST(ID BIGINT PRIMARY KEY, VAL VARCHAR)"}, {});
EXPECT_TRUE(result_set.was_applied());
EXPECT_FALSE(result_set.has_rowset());
EXPECT_EQ(-1, result_set.affected_rows());
EXPECT_TRUE(result_set.metadata().columns().empty());
result_set = m_client.get_sql().execute(
nullptr, nullptr, {"INSERT INTO SQL_DDL_DML_TEST VALUES (?, ?)"}, {std::int64_t(13), std::string("Hello")});
EXPECT_FALSE(result_set.was_applied());
EXPECT_FALSE(result_set.has_rowset());
EXPECT_EQ(1, result_set.affected_rows());
EXPECT_TRUE(result_set.metadata().columns().empty());
result_set = m_client.get_sql().execute(
nullptr, nullptr, {"INSERT INTO SQL_DDL_DML_TEST VALUES (?, ?)"}, {std::int64_t(14), std::string("World")});
EXPECT_FALSE(result_set.was_applied());
EXPECT_FALSE(result_set.has_rowset());
EXPECT_EQ(1, result_set.affected_rows());
EXPECT_TRUE(result_set.metadata().columns().empty());
result_set = m_client.get_sql().execute(nullptr, nullptr, {"UPDATE SQL_DDL_DML_TEST SET VAL = ?"}, {std::string("Test")});
EXPECT_FALSE(result_set.was_applied());
EXPECT_FALSE(result_set.has_rowset());
EXPECT_EQ(2, result_set.affected_rows());
EXPECT_TRUE(result_set.metadata().columns().empty());
result_set = m_client.get_sql().execute(nullptr, nullptr, {"DROP TABLE SQL_DDL_DML_TEST"}, {});
EXPECT_TRUE(result_set.was_applied());
EXPECT_FALSE(result_set.has_rowset());
EXPECT_EQ(-1, result_set.affected_rows());
EXPECT_TRUE(result_set.metadata().columns().empty());
}
TEST_F(sql_test, sql_insert_null) {
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"DROP TABLE IF EXISTS SQL_INSERT_NULL_TEST"}, {});
result_set =
m_client.get_sql().execute(nullptr, nullptr, {"CREATE TABLE SQL_INSERT_NULL_TEST(ID INT PRIMARY KEY, VAL VARCHAR)"}, {});
ASSERT_TRUE(result_set.was_applied());
result_set = m_client.get_sql().execute(nullptr, nullptr, {"INSERT INTO SQL_INSERT_NULL_TEST VALUES (13, NULL)"}, {});
EXPECT_FALSE(result_set.was_applied());
EXPECT_FALSE(result_set.has_rowset());
EXPECT_EQ(1, result_set.affected_rows());
EXPECT_TRUE(result_set.metadata().columns().empty());
result_set = m_client.get_sql().execute(nullptr, nullptr, {"DROP TABLE SQL_INSERT_NULL_TEST"}, {});
EXPECT_TRUE(result_set.was_applied());
}
TEST_F(sql_test, sql_invalid_query) {
EXPECT_THROW(
{
try {
m_client.get_sql().execute(nullptr, nullptr, {"not a query"}, {});
} catch (const ignite_error &e) {
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Failed to parse query: Non-query expression"));
throw;
}
},
ignite_error);
}
TEST_F(sql_test, sql_unknown_table) {
EXPECT_THROW(
{
try {
m_client.get_sql().execute(nullptr, nullptr, {"select id from unknown_table"}, {});
} catch (const ignite_error &e) {
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Object 'UNKNOWN_TABLE' not found"));
throw;
}
},
ignite_error);
}
TEST_F(sql_test, sql_unknown_column) {
EXPECT_THROW(
{
try {
m_client.get_sql().execute(nullptr, nullptr, {"select unknown_column from test"}, {});
} catch (const ignite_error &e) {
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Column 'UNKNOWN_COLUMN' not found in any table"));
throw;
}
},
ignite_error);
}
TEST_F(sql_test, sql_create_existing_table) {
EXPECT_THROW(
{
try {
m_client.get_sql().execute(nullptr, nullptr, {"CREATE TABLE TEST(ID INT PRIMARY KEY, VAL VARCHAR)"}, {});
} catch (const ignite_error &e) {
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Table with name 'PUBLIC.TEST' already exists"));
// TODO: IGNITE-21217 Check STMT_VALIDATION error code usage
EXPECT_THAT(e.get_status_code(), ignite::error::code::STMT_VALIDATION);
throw;
}
},
ignite_error);
}
TEST_F(sql_test, sql_add_existing_column) {
EXPECT_THROW(
{
try {
m_client.get_sql().execute(nullptr, nullptr, {"ALTER TABLE TEST ADD COLUMN ID INT"}, {});
} catch (const ignite_error &e) {
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Column with name 'ID' already exists"));
// TODO: IGNITE-21217 Check STMT_VALIDATION error code usage
EXPECT_THAT(e.get_status_code(), ignite::error::code::STMT_VALIDATION);
throw;
}
},
ignite_error);
}
TEST_F(sql_test, sql_alter_nonexisting_table) {
EXPECT_THROW(
{
try {
m_client.get_sql().execute(nullptr, nullptr, {"ALTER TABLE UNKNOWN_TABLE ADD COLUMN ID INT"}, {});
} catch (const ignite_error &e) {
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Table with name 'PUBLIC.UNKNOWN_TABLE' not found"));
// TODO: IGNITE-21217 Check STMT_VALIDATION error code usage
EXPECT_THAT(e.get_status_code(), ignite::error::code::STMT_VALIDATION);
throw;
}
},
ignite_error);
}
TEST_F(sql_test, sql_statement_defaults) {
sql_statement statement;
EXPECT_EQ(statement.page_size(), sql_statement::DEFAULT_PAGE_SIZE);
EXPECT_EQ(statement.schema(), sql_statement::DEFAULT_SCHEMA);
EXPECT_EQ(statement.timeout(), sql_statement::DEFAULT_TIMEOUT);
}
TEST_F(sql_test, decimal_literal) {
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"SELECT CAST('12345.6789' AS DECIMAL(9, 4))"}, {});
EXPECT_TRUE(result_set.has_rowset());
auto value = result_set.current_page().front().get(0).get<big_decimal>();
EXPECT_EQ(4, value.get_scale());
EXPECT_EQ(9, value.get_precision());
std::stringstream ss;
ss << value;
auto value_str = ss.str();
EXPECT_EQ("12345.6789", value_str);
}
TEST_F(sql_test, all_type_arguments) {
auto result_set = m_client.get_sql().execute(nullptr, nullptr,
{"select str,int8,int16,int32,int64,\"FLOAT\",\"DOUBLE\",\"UUID\",\"DATE\",\"TIME\",time2,"
"\"DATETIME\",datetime2,\"TIMESTAMP\",timestamp2,\"BLOB\",\"DECIMAL\",\"BOOLEAN\" from TBL_ALL_COLUMNS_SQL"},
{});
EXPECT_TRUE(result_set.has_rowset());
auto row = result_set.current_page().front();
EXPECT_EQ(row.get(0).get<std::string>(), "test");
EXPECT_EQ(row.get(1).get<std::int8_t>(), 1);
EXPECT_EQ(row.get(2).get<std::int16_t>(), 2);
EXPECT_EQ(row.get(3).get<std::int32_t>(), 3);
EXPECT_EQ(row.get(4).get<std::int64_t>(), 4);
EXPECT_FLOAT_EQ(row.get(5).get<float>(), 0.5f);
EXPECT_DOUBLE_EQ(row.get(6).get<double>(), 0.6);
EXPECT_EQ(row.get(7).get<uuid>(), uuid(0x123e4567e89b12d3, 0x7456426614174000));
EXPECT_EQ(row.get(8).get<ignite_date>(), ignite_date(2023, 2, 7));
EXPECT_EQ(row.get(9).get<ignite_time>(), ignite_time(17, 4, 12, 3000000));
EXPECT_EQ(row.get(10).get<ignite_time>(), ignite_time(17, 4, 12, 3000000));
EXPECT_EQ(row.get(11).get<ignite_date_time>(), ignite_date_time({2020, 7, 28}, {2, 15, 52, 6000000}));
EXPECT_EQ(row.get(12).get<ignite_date_time>(), ignite_date_time({2020, 7, 28}, {2, 15, 52, 6000000}));
EXPECT_EQ(row.get(13).get<ignite_timestamp>(), ignite_timestamp(3875238472, 248000000));
EXPECT_EQ(row.get(14).get<ignite_timestamp>(), ignite_timestamp(3875238472, 248000000));
EXPECT_EQ(row.get(16).get<big_decimal>(), big_decimal(123456789098765));
EXPECT_EQ(row.get(17).get<bool>(), true);
auto blob = row.get(15).get<std::vector<std::byte>>();
EXPECT_EQ(blob[0], std::byte(1));
EXPECT_EQ(blob[1], std::byte(2));
EXPECT_EQ(blob[2], std::byte(42));
}
TEST_F(sql_test, uuid_literal) {
auto result_set =
m_client.get_sql().execute(nullptr, nullptr, {"SELECT CAST('df6bbb13-f2d2-42b4-bef9-7ab8524a0704' AS UUID)"}, {});
EXPECT_TRUE(result_set.has_rowset());
auto value = result_set.current_page().front().get(0).get<uuid>();
std::stringstream ss;
ss << value;
auto value_str = ss.str();
EXPECT_EQ("df6bbb13-f2d2-42b4-bef9-7ab8524a0704", value_str);
}
TEST_F(sql_test, uuid_argument) {
uuid req{0x123e4567e89b12d3, 0x7456426614174000};
auto result_set =
m_client.get_sql().execute(nullptr, nullptr, {R"(select MAX("UUID") from TBL_ALL_COLUMNS_SQL WHERE "UUID" = ?)"}, {req});
EXPECT_TRUE(result_set.has_rowset());
auto value = result_set.current_page().front().get(0).get<uuid>();
EXPECT_EQ(req, value);
}
TEST_F(sql_test, null_column) {
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"select NULL"}, {});
EXPECT_TRUE(result_set.has_rowset());
auto &columns = result_set.metadata().columns();
EXPECT_EQ(1, columns.size());
EXPECT_EQ(ignite_type::NIL, columns.at(0).type());
auto value = result_set.current_page().front().get(0);
EXPECT_EQ(ignite_type::NIL, value.get_type());
EXPECT_TRUE(value.is_null());
}
TEST_F(sql_test, execute_script_success) {
m_client.get_sql().execute_script(nullptr,
{"CREATE TABLE execute_script_success (id INT PRIMARY KEY, step INTEGER); "
"INSERT INTO execute_script_success VALUES(1, 0); "
"UPDATE execute_script_success SET step = 1; "
"UPDATE execute_script_success SET step = 2; "},
{});
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"SELECT step FROM execute_script_success"}, {});
EXPECT_TRUE(result_set.has_rowset());
EXPECT_FALSE(result_set.has_more_pages());
auto &columns = result_set.metadata().columns();
EXPECT_EQ(1, columns.size());
EXPECT_EQ(ignite_type::INT32, columns.at(0).type());
ASSERT_EQ(1, result_set.current_page().size());
auto value = result_set.current_page().front().get(0);
EXPECT_EQ(ignite_type::INT32, value.get_type());
EXPECT_EQ(2, value.get<std::int32_t>());
}
TEST_F(sql_test, execute_script_fail) {
EXPECT_THROW(
{
try {
m_client.get_sql().execute_script(nullptr,
{"CREATE TABLE execute_script_fail (id INT PRIMARY KEY, step INTEGER); "
"INSERT INTO execute_script_fail VALUES(1, 0); "
"UPDATE execute_script_fail SET step = 1; "
"UPDATE execute_script_fail SET step = 3 WHERE step > 1/0; "
"UPDATE execute_script_fail SET step = 2; "},
{});
} catch (const ignite_error &e) {
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("Division by zero"));
throw;
}
},
ignite_error);
auto result_set = m_client.get_sql().execute(nullptr, nullptr, {"SELECT step FROM execute_script_fail"}, {});
EXPECT_TRUE(result_set.has_rowset());
EXPECT_FALSE(result_set.has_more_pages());
auto &columns = result_set.metadata().columns();
EXPECT_EQ(1, columns.size());
EXPECT_EQ(ignite_type::INT32, columns.at(0).type());
ASSERT_EQ(1, result_set.current_page().size());
auto value = result_set.current_page().front().get(0);
EXPECT_EQ(ignite_type::INT32, value.get_type());
EXPECT_EQ(1, value.get<std::int32_t>());
}
TEST_F(sql_test, timezone_passed) {
sql_statement statement{"SELECT CURRENT_TIMESTAMP"};
statement.timezone_id("UTC+8");
auto ts0 = execute_statement_one_result(statement);
EXPECT_EQ(ignite_type::TIMESTAMP, ts0.get_type());
statement.timezone_id("UTC-2");
auto ts1 = execute_statement_one_result(statement);
EXPECT_EQ(ignite_type::TIMESTAMP, ts1.get_type());
EXPECT_NE(ts0.get<ignite_timestamp>(), ts1.get<ignite_timestamp>());
}
/**
* Execute and cancel request.
* @param sql SQL facade.
* @pagram tx Transaction.
* @param query Query.
* @param token Cancellation token.
* @return Result set.
*/
std::future<result_set> execute_fut(sql sql, transaction *tx, const std::string &query, cancellation_token *token) {
auto promise = std::make_shared<std::promise<result_set>>();
sql.execute_async(tx, token, {query}, {}, result_promise_setter(promise));
return promise->get_future();
}
/**
* Execute and cancel request.
* @param sql SQL facade.
* @pagram tx Transaction.
* @param query Query.
* @return Result set.
*/
result_set execute_and_cancel(sql sql, transaction *tx, const std::string &query) {
auto handle = cancel_handle::create();
auto token = handle->get_token();
auto fut = execute_fut(sql, tx, query, token.get());
handle->cancel();
return fut.get();
}
TEST_F(sql_test, cancel_statement) {
EXPECT_THROW(
{
try {
execute_and_cancel(m_client.get_sql(), nullptr, LONG_QUERY);
} catch (const ignite_error &e) {
EXPECT_EQ(e.get_status_code(), error::code::EXECUTION_CANCELLED);
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("The query was cancelled while executing"));
throw;
}
},
ignite_error);
}
TEST_F(sql_test, cancel_statement_tx) {
auto tx = m_client.get_transactions().begin();
EXPECT_THROW(
{
try {
execute_and_cancel(m_client.get_sql(), &tx, LONG_QUERY);
} catch (const ignite_error &e) {
EXPECT_EQ(e.get_status_code(), error::code::EXECUTION_CANCELLED);
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("The query was cancelled while executing"));
throw;
}
},
ignite_error);
}
TEST_F(sql_test, cancel_query_before_execution) {
auto handle = cancel_handle::create();
auto token = handle->get_token();
handle->cancel();
EXPECT_THROW(
{
try {
m_client.get_sql().execute(nullptr, token.get(), {"SELECT 1"}, {});
} catch (const ignite_error &e) {
EXPECT_EQ(e.get_status_code(), error::code::EXECUTION_CANCELLED);
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("The query was cancelled while executing"));
throw;
}
},
ignite_error);
}
TEST_F(sql_test, cancel_multiple_queries_using_same_token) {
auto handle = cancel_handle::create();
auto token = handle->get_token();
std::array<result_set, 3> results;
for (int i = 0; i < 3; i++) {
results[i] = m_client.get_sql().execute(nullptr,token.get(), {LONG_QUERY}, {});
results[i].fetch_next_page();
}
handle->cancel();
for (int i = 0; i < 3; i++) {
EXPECT_THROW(
{
try {
while (results[i].has_more_pages()) {
results[i].fetch_next_page();
}
} catch (const ignite_error &e) {
EXPECT_EQ(e.get_status_code(), error::code::EXECUTION_CANCELLED);
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("The query was cancelled while executing"));
throw;
}
},
ignite_error);
}
}
TEST_F(sql_test, cancel_query_multiple_times) {
auto handle = cancel_handle::create();
auto token = handle->get_token();
auto res = m_client.get_sql().execute(nullptr,token.get(), {LONG_QUERY}, {});
handle->cancel();
handle->cancel();
handle->cancel();
handle->cancel();
EXPECT_THROW(
{
try {
while (res.has_more_pages()) {
res.fetch_next_page();
}
} catch (const ignite_error &e) {
EXPECT_EQ(e.get_status_code(), error::code::EXECUTION_CANCELLED);
EXPECT_THAT(e.what_str(), ::testing::HasSubstr("The query was cancelled while executing"));
throw;
}
},
ignite_error);
handle->cancel();
handle->cancel();
handle->cancel();
handle->cancel();
}