Skip to content

Commit

Permalink
IGNITE-9367: Fixed crash in ODBC on executing query with closed conne…
Browse files Browse the repository at this point in the history
…ction

This closes #4621
  • Loading branch information
gromtech authored and isapego committed Aug 28, 2018
1 parent 3f18491 commit 186b2d6
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 0 deletions.
1 change: 1 addition & 0 deletions modules/platforms/cpp/odbc-test/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ ignite_odbc_tests_SOURCES = \
src/parser_test.cpp \
src/cursor_test.cpp \
src/connection_info_test.cpp \
src/connection_test.cpp \
src/application_data_buffer_test.cpp \
src/column_test.cpp \
src/configuration_test.cpp \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@
<ClCompile Include="..\..\src\column_test.cpp" />
<ClCompile Include="..\..\src\configuration_test.cpp" />
<ClCompile Include="..\..\src\connection_info_test.cpp" />
<ClCompile Include="..\..\src\connection_test.cpp" />
<ClCompile Include="..\..\src\cursor_test.cpp" />
<ClCompile Include="..\..\src\errors_test.cpp" />
<ClCompile Include="..\..\src\meta_queries_test.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<ClCompile Include="..\..\src\connection_info_test.cpp">
<Filter>Code</Filter>
</ClCompile>
<ClCompile Include="..\..\src\connection_test.cpp">
<Filter>Code</Filter>
</ClCompile>
<ClCompile Include="..\..\src\parser_test.cpp">
<Filter>Code</Filter>
</ClCompile>
Expand Down
133 changes: 133 additions & 0 deletions modules/platforms/cpp/odbc-test/src/connection_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* 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.
*/

#ifdef _WIN32
# include <windows.h>
#endif

#include <sql.h>
#include <sqlext.h>

#include <string>

#ifndef _MSC_VER
# define BOOST_TEST_DYN_LINK
#endif

#include <boost/test/unit_test.hpp>

#include "ignite/ignite.h"
#include "ignite/ignition.h"

#include "test_type.h"
#include "test_utils.h"
#include "odbc_test_suite.h"

using namespace ignite;
using namespace ignite::common;
using namespace ignite_test;

using namespace boost::unit_test;

/**
* Test setup fixture.
*/
struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite
{
/**
* Constructor.
*/
ConnectionTestSuiteFixture() :
OdbcTestSuite()
{
StartNode();
}

/**
* Start a node.
*/
void StartNode()
{
StartTestNode("queries-test.xml", "NodeMain");
}

/**
* Execute the query and return an error code.
*/
std::string ExecQueryAndReturnError()
{
SQLCHAR selectReq[] = "select count(*) from TestType";

SQLRETURN ret = SQLExecDirect(stmt, selectReq, sizeof(selectReq));

std::string err;

if (!SQL_SUCCEEDED(ret))
err = ExtractErrorCode(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));

return err;
}

/**
* Extract code from ODBC error message.
*/
std::string ExtractErrorCode(std::string err)
{
std::string code;

int idx = err.find(':');

if ((idx != std::string::npos) && (idx > 0))
code = err.substr(0, idx);

return code;
}

/**
* Destructor.
*/
~ConnectionTestSuiteFixture()
{
// No-op.
}
};

BOOST_FIXTURE_TEST_SUITE(ConnectionTestSuite, ConnectionTestSuiteFixture)

BOOST_AUTO_TEST_CASE(TestConnectionRestore)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");

// Check that query was successfully executed.
BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "");

// Stop node.
Ignition::StopAll(true);

// Query execution should throw ODBC error.
BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08S01");

// Reusing a closed connection should not crash an application.
BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08001");

StartNode();

// Check that connection was restored.
BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "");
}

BOOST_AUTO_TEST_SUITE_END()
3 changes: 3 additions & 0 deletions modules/platforms/cpp/odbc/src/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,9 @@ namespace ignite

CollectAddresses(config, addrs);

if (socket.get() == 0)
socket.reset(new system::TcpSocketClient());

bool connected = false;

while (!addrs.empty() && !connected)
Expand Down

0 comments on commit 186b2d6

Please sign in to comment.