IGNITE-9367: Fixed crash in ODBC on executing query with closed connection This closes #4621
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/186b2d6f Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/186b2d6f Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/186b2d6f Branch: refs/heads/ignite-9273 Commit: 186b2d6f9d8ae57f75a2dc006392343d7e8cc10f Parents: 3f18491 Author: Roman Guseinov <gromc...@gmail.com> Authored: Tue Aug 28 14:41:09 2018 +0300 Committer: Igor Sapego <isap...@apache.org> Committed: Tue Aug 28 14:41:09 2018 +0300 ---------------------------------------------------------------------- modules/platforms/cpp/odbc-test/Makefile.am | 1 + .../cpp/odbc-test/project/vs/odbc-test.vcxproj | 1 + .../project/vs/odbc-test.vcxproj.filters | 3 + .../cpp/odbc-test/src/connection_test.cpp | 133 +++++++++++++++++++ modules/platforms/cpp/odbc/src/connection.cpp | 3 + 5 files changed, 141 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/186b2d6f/modules/platforms/cpp/odbc-test/Makefile.am ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am index 87e3c89..f412403 100644 --- a/modules/platforms/cpp/odbc-test/Makefile.am +++ b/modules/platforms/cpp/odbc-test/Makefile.am @@ -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 \ http://git-wip-us.apache.org/repos/asf/ignite/blob/186b2d6f/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj index e4af960..87b6559 100644 --- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj +++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj @@ -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" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/186b2d6f/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters index e2749ca..3d2fcc6 100644 --- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters +++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters @@ -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> http://git-wip-us.apache.org/repos/asf/ignite/blob/186b2d6f/modules/platforms/cpp/odbc-test/src/connection_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/connection_test.cpp b/modules/platforms/cpp/odbc-test/src/connection_test.cpp new file mode 100644 index 0000000..5badda6 --- /dev/null +++ b/modules/platforms/cpp/odbc-test/src/connection_test.cpp @@ -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() http://git-wip-us.apache.org/repos/asf/ignite/blob/186b2d6f/modules/platforms/cpp/odbc/src/connection.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp index 4a28bbf..894efb7 100644 --- a/modules/platforms/cpp/odbc/src/connection.cpp +++ b/modules/platforms/cpp/odbc/src/connection.cpp @@ -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)