IGNITE-6211: ODBC: SQLBindParameter now does not unbind parameter if the
ParameterValuePtr is NULL


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/72608a50
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/72608a50
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/72608a50

Branch: refs/heads/ignite-3478
Commit: 72608a50856cda9fcc8e44e2a9e5349eb6a9616e
Parents: bd7bd22
Author: Igor Sapego <[email protected]>
Authored: Fri Sep 1 16:24:04 2017 +0300
Committer: Igor Sapego <[email protected]>
Committed: Fri Sep 1 16:24:04 2017 +0300

----------------------------------------------------------------------
 .../cpp/odbc-test/src/queries_test.cpp          | 51 ++++++++++++++++++++
 modules/platforms/cpp/odbc/src/statement.cpp    | 32 +++++++-----
 2 files changed, 70 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/72608a50/modules/platforms/cpp/odbc-test/src/queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/queries_test.cpp 
b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
index 263993c..5d10a66 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -1996,4 +1996,55 @@ BOOST_AUTO_TEST_CASE(TestExecuteAfterCursorClose)
     BOOST_CHECK_EQUAL(ret, SQL_NO_DATA);
 }
 
+BOOST_AUTO_TEST_CASE(TestBindNullParameter)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLLEN paramInd = SQL_NULL_DATA;
+
+    // Binding NULL parameter.
+    SQLRETURN ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, 
SQL_CHAR, 100, 100, 0, 0, &paramInd);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    // Just selecting everything to make sure everything is OK
+    SQLCHAR insertReq[] = "INSERT INTO TestType(_key, strField) VALUES(1, ?)";
+
+    ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    // Unbindning parameter.
+    ret = SQLFreeStmt(stmt, SQL_RESET_PARAMS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    // Selecting inserted column to make sure that everything is OK
+    SQLCHAR selectReq[] = "SELECT strField FROM TestType";
+
+    char strField[1024] = { 0 };
+    SQLLEN strFieldLen = 0;
+
+    // Binding column.
+    ret = SQLBindCol(stmt, 1, SQL_C_CHAR, &strField, sizeof(strField), 
&strFieldLen);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLExecDirect(stmt, selectReq, sizeof(selectReq));
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_EQUAL(strFieldLen, SQL_NULL_DATA);
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/72608a50/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp 
b/modules/platforms/cpp/odbc/src/statement.cpp
index 38a1e2e..a74a413 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -139,13 +139,14 @@ namespace ignite
         }
 
         void Statement::BindParameter(uint16_t paramIdx, int16_t ioType, 
int16_t bufferType, int16_t paramSqlType,
-                                      SqlUlen columnSize, int16_t decDigits, 
void* buffer, SqlLen bufferLen, SqlLen* resLen)
+            SqlUlen columnSize, int16_t decDigits, void* buffer, SqlLen 
bufferLen, SqlLen* resLen)
         {
-            IGNITE_ODBC_API_CALL(InternalBindParameter(paramIdx, ioType, 
bufferType, paramSqlType, columnSize, decDigits, buffer, bufferLen, resLen));
+            IGNITE_ODBC_API_CALL(InternalBindParameter(paramIdx, ioType, 
bufferType, paramSqlType, columnSize,
+                decDigits, buffer, bufferLen, resLen));
         }
 
-        SqlResult::Type Statement::InternalBindParameter(uint16_t paramIdx, 
int16_t ioType, int16_t bufferType, int16_t paramSqlType,
-                                                   SqlUlen columnSize, int16_t 
decDigits, void* buffer, SqlLen bufferLen, SqlLen* resLen)
+        SqlResult::Type Statement::InternalBindParameter(uint16_t paramIdx, 
int16_t ioType, int16_t bufferType,
+            int16_t paramSqlType, SqlUlen columnSize, int16_t decDigits, void* 
buffer, SqlLen bufferLen, SqlLen* resLen)
         {
             using namespace type_traits;
             using app::ApplicationDataBuffer;
@@ -154,7 +155,8 @@ namespace ignite
             if (paramIdx == 0)
             {
                 std::stringstream builder;
-                builder << "The value specified for the argument 
ParameterNumber was less than 1. [ParameterNumber=" << paramIdx << ']';
+                builder << "The value specified for the argument 
ParameterNumber was less than 1. [ParameterNumber=" 
+                    << paramIdx << ']';
 
                 AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE, 
builder.str());
 
@@ -164,7 +166,8 @@ namespace ignite
             if (ioType != SQL_PARAM_INPUT)
             {
                 std::stringstream builder;
-                builder << "The value specified for the argument 
InputOutputType was not SQL_PARAM_INPUT. [ioType=" << ioType << ']';
+                builder << "The value specified for the argument 
InputOutputType was not SQL_PARAM_INPUT. [ioType=" 
+                    << ioType << ']';
 
                 AddStatusRecord(SqlState::SHY105_INVALID_PARAMETER_TYPE, 
builder.str());
 
@@ -193,16 +196,19 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            if (buffer)
+            if (!buffer && !resLen)
             {
-                ApplicationDataBuffer dataBuffer(driverType, buffer, 
bufferLen, resLen);
-
-                Parameter param(dataBuffer, paramSqlType, columnSize, 
decDigits);
+                AddStatusRecord(SqlState::SHY009_INVALID_USE_OF_NULL_POINTER,
+                    "ParameterValuePtr and StrLen_or_IndPtr are both null 
pointers.");
 
-                parameters.BindParameter(paramIdx, param);
+                return SqlResult::AI_ERROR;
             }
-            else
-                parameters.UnbindParameter(paramIdx);
+
+            ApplicationDataBuffer dataBuffer(driverType, buffer, bufferLen, 
resLen);
+
+            Parameter param(dataBuffer, paramSqlType, columnSize, decDigits);
+
+            parameters.BindParameter(paramIdx, param);
 
             return SqlResult::AI_SUCCESS;
         }

Reply via email to