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)

Reply via email to