You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/11/22 11:39:52 UTC

[03/50] [abbrv] ignite git commit: IGNITE-4183: ODBC Fixed null-values fetching issue.

IGNITE-4183: ODBC Fixed null-values fetching issue.


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

Branch: refs/heads/master
Commit: ac660dcaa5bf8eb20e7dd4e442e97c1cf548a827
Parents: d88f422
Author: Igor Sapego <is...@gridgain.com>
Authored: Wed Nov 9 15:29:06 2016 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Wed Nov 9 15:29:06 2016 +0300

----------------------------------------------------------------------
 .../platforms/cpp/odbc-test/include/test_type.h |  42 ++++--
 .../cpp/odbc-test/src/queries_test.cpp          | 139 +++++++++++++++++--
 .../cpp/odbc-test/src/sql_outer_join_test.cpp   |   2 +-
 .../odbc/src/app/application_data_buffer.cpp    |  34 ++++-
 4 files changed, 187 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ac660dca/modules/platforms/cpp/odbc-test/include/test_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/test_type.h b/modules/platforms/cpp/odbc-test/include/test_type.h
index 2a4a979..0e08251 100644
--- a/modules/platforms/cpp/odbc-test/include/test_type.h
+++ b/modules/platforms/cpp/odbc-test/include/test_type.h
@@ -28,6 +28,7 @@ namespace ignite
     struct TestType
     {
         TestType() :
+            allNulls(false),
             i8Field(0),
             i16Field(0),
             i32Field(0),
@@ -45,6 +46,7 @@ namespace ignite
             int64_t i64Field, const std::string& strField, float floatField,
             double doubleField, bool boolField, const Guid& guidField,
             const Date& dateField, const Timestamp& timestampField) :
+            allNulls(false),
             i8Field(i8Field),
             i16Field(i16Field),
             i32Field(i32Field),
@@ -60,6 +62,7 @@ namespace ignite
             // No-op.
         }
 
+        bool allNulls;
         int8_t i8Field;
         int16_t i16Field;
         int32_t i32Field;
@@ -91,17 +94,34 @@ namespace ignite
 
             void Write(BinaryWriter& writer, TestType obj)
             {
-                writer.WriteInt8("i8Field", obj.i8Field);
-                writer.WriteInt16("i16Field", obj.i16Field);
-                writer.WriteInt32("i32Field", obj.i32Field);
-                writer.WriteInt64("i64Field", obj.i64Field);
-                writer.WriteString("strField", obj.strField);
-                writer.WriteFloat("floatField", obj.floatField);
-                writer.WriteDouble("doubleField", obj.doubleField);
-                writer.WriteBool("boolField", obj.boolField);
-                writer.WriteGuid("guidField", obj.guidField);
-                writer.WriteDate("dateField", obj.dateField);
-                writer.WriteTimestamp("timestampField", obj.timestampField);
+                if (!obj.allNulls)
+                {
+                    writer.WriteInt8("i8Field", obj.i8Field);
+                    writer.WriteInt16("i16Field", obj.i16Field);
+                    writer.WriteInt32("i32Field", obj.i32Field);
+                    writer.WriteInt64("i64Field", obj.i64Field);
+                    writer.WriteString("strField", obj.strField);
+                    writer.WriteFloat("floatField", obj.floatField);
+                    writer.WriteDouble("doubleField", obj.doubleField);
+                    writer.WriteBool("boolField", obj.boolField);
+                    writer.WriteGuid("guidField", obj.guidField);
+                    writer.WriteDate("dateField", obj.dateField);
+                    writer.WriteTimestamp("timestampField", obj.timestampField);
+                }
+                else
+                {
+                    writer.WriteNull("i8Field");
+                    writer.WriteNull("i16Field");
+                    writer.WriteNull("i32Field");
+                    writer.WriteNull("i64Field");
+                    writer.WriteNull("strField");
+                    writer.WriteNull("floatField");
+                    writer.WriteNull("doubleField");
+                    writer.WriteNull("boolField");
+                    writer.WriteNull("guidField");
+                    writer.WriteNull("dateField");
+                    writer.WriteNull("timestampField");
+                }
             }
 
             TestType Read(BinaryReader& reader)

http://git-wip-us.apache.org/repos/asf/ignite/blob/ac660dca/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 82e9972..a7fc7a9 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -250,14 +250,14 @@ struct QueriesTestSuiteFixture
         BOOST_CHECK_EQUAL(columns[9], 0);
         BOOST_CHECK_EQUAL(columns[10], 0);
 
-        BOOST_CHECK_EQUAL(columnLens[0], 0);
-        BOOST_CHECK_EQUAL(columnLens[1], 0);
-        BOOST_CHECK_EQUAL(columnLens[2], 0);
-        BOOST_CHECK_EQUAL(columnLens[3], 0);
-        BOOST_CHECK_EQUAL(columnLens[4], 0);
-        BOOST_CHECK_EQUAL(columnLens[5], 0);
-        BOOST_CHECK_EQUAL(columnLens[6], 0);
-        BOOST_CHECK_EQUAL(columnLens[7], 0);
+        BOOST_CHECK_EQUAL(columnLens[0], static_cast<SQLLEN>(sizeof(T)));
+        BOOST_CHECK_EQUAL(columnLens[1], static_cast<SQLLEN>(sizeof(T)));
+        BOOST_CHECK_EQUAL(columnLens[2], static_cast<SQLLEN>(sizeof(T)));
+        BOOST_CHECK_EQUAL(columnLens[3], static_cast<SQLLEN>(sizeof(T)));
+        BOOST_CHECK_EQUAL(columnLens[4], static_cast<SQLLEN>(sizeof(T)));
+        BOOST_CHECK_EQUAL(columnLens[5], static_cast<SQLLEN>(sizeof(T)));
+        BOOST_CHECK_EQUAL(columnLens[6], static_cast<SQLLEN>(sizeof(T)));
+        BOOST_CHECK_EQUAL(columnLens[7], static_cast<SQLLEN>(sizeof(T)));
         BOOST_CHECK_EQUAL(columnLens[8], SQL_NO_TOTAL);
         BOOST_CHECK_EQUAL(columnLens[9], SQL_NO_TOTAL);
         BOOST_CHECK_EQUAL(columnLens[10], SQL_NO_TOTAL);
@@ -296,32 +296,32 @@ BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_1_6_0)
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsInt8)
 {
-    CheckTwoRowsInt<int8_t>(SQL_C_STINYINT);
+    CheckTwoRowsInt<signed char>(SQL_C_STINYINT);
 }
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsUint8)
 {
-    CheckTwoRowsInt<uint8_t>(SQL_C_UTINYINT);
+    CheckTwoRowsInt<unsigned char>(SQL_C_UTINYINT);
 }
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsInt16)
 {
-    CheckTwoRowsInt<int16_t>(SQL_C_SSHORT);
+    CheckTwoRowsInt<signed short>(SQL_C_SSHORT);
 }
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsUint16)
 {
-    CheckTwoRowsInt<uint16_t>(SQL_C_USHORT);
+    CheckTwoRowsInt<unsigned short>(SQL_C_USHORT);
 }
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsInt32)
 {
-    CheckTwoRowsInt<int32_t>(SQL_C_SLONG);
+    CheckTwoRowsInt<signed long>(SQL_C_SLONG);
 }
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsUint32)
 {
-    CheckTwoRowsInt<uint32_t>(SQL_C_ULONG);
+    CheckTwoRowsInt<unsigned long>(SQL_C_ULONG);
 }
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsInt64)
@@ -674,4 +674,115 @@ BOOST_AUTO_TEST_CASE(TestDataAtExecution)
     BOOST_CHECK(ret == SQL_NO_DATA);
 }
 
+BOOST_AUTO_TEST_CASE(TestNullFields)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache");
+
+    SQLRETURN ret;
+
+    TestType in(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9), BinaryUtils::MakeDateGmt(1987, 6, 5),
+        BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456));
+
+    TestType inNull;
+
+    inNull.allNulls = true;
+
+    testCache.Put(1, in);
+    testCache.Put(2, inNull);
+    testCache.Put(3, in);
+
+    const size_t columnsCnt = 10;
+
+    SQLLEN columnLens[columnsCnt] = { 0 };
+
+    int8_t i8Column;
+    int16_t i16Column;
+    int32_t i32Column;
+    int64_t i64Column;
+    char strColumn[ODBC_BUFFER_SIZE];
+    float floatColumn;
+    double doubleColumn;
+    bool boolColumn;
+    SQL_DATE_STRUCT dateColumn;
+    SQL_TIMESTAMP_STRUCT timestampColumn;
+
+    // Binding columns.
+    ret = SQLBindCol(stmt, 1, SQL_C_STINYINT, &i8Column, 0, &columnLens[0]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SSHORT, &i16Column, 0, &columnLens[1]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 3, SQL_C_SLONG, &i32Column, 0, &columnLens[2]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 4, SQL_C_SBIGINT, &i64Column, 0, &columnLens[3]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 5, SQL_C_CHAR, &strColumn, ODBC_BUFFER_SIZE, &columnLens[4]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 6, SQL_C_FLOAT, &floatColumn, 0, &columnLens[5]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 7, SQL_C_DOUBLE, &doubleColumn, 0, &columnLens[6]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 8, SQL_C_BIT, &boolColumn, 0, &columnLens[7]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 9, SQL_C_DATE, &dateColumn, 0, &columnLens[8]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 10, SQL_C_TIMESTAMP, &timestampColumn, 0, &columnLens[9]);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT i8Field, i16Field, i32Field, i64Field, strField, "
+        "floatField, doubleField, boolField, dateField, timestampField FROM TestType ORDER BY _key";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    // Fetching the first non-null row.
+    ret = SQLFetch(stmt);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    // Checking that columns are not null.
+    for (SQLSMALLINT i = 0; i < columnsCnt; ++i)
+        BOOST_CHECK_NE(columnLens[i], SQL_NULL_DATA);
+
+    // Fetching null row.
+    ret = SQLFetch(stmt);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    // Checking that columns are null.
+    for (SQLSMALLINT i = 0; i < columnsCnt; ++i)
+        BOOST_CHECK_EQUAL(columnLens[i], SQL_NULL_DATA);
+
+    // Fetching the last non-null row.
+    ret = SQLFetch(stmt);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    // Checking that columns are not null.
+    for (SQLSMALLINT i = 0; i < columnsCnt; ++i)
+        BOOST_CHECK_NE(columnLens[i], SQL_NULL_DATA);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/ac660dca/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp b/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp
index 426041b..56f5219 100644
--- a/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp
@@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE(TestOuterJoinOpsLess)
     BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
     BOOST_CHECK_EQUAL(columns[0], 30);
 
-    BOOST_CHECK_EQUAL(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
 
     ret = SQLFetch(stmt);
     BOOST_CHECK(ret == SQL_NO_DATA);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ac660dca/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp
index 1438b0c..078e691 100644
--- a/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp
+++ b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp
@@ -182,6 +182,10 @@ namespace ignite
 
                             memcpy(out->val, &uval, std::min<int>(SQL_MAX_NUMERIC_LEN, sizeof(uval)));
                         }
+
+                        if (resLenPtr)
+                            *resLenPtr = static_cast<SqlLen>(sizeof(SQL_NUMERIC_STRUCT));
+
                         break;
                     }
 
@@ -237,12 +241,16 @@ namespace ignite
             void ApplicationDataBuffer::PutNumToNumBuffer(Tin value)
             {
                 void* dataPtr = GetData();
+                SqlLen* resLenPtr = GetResLen();
 
                 if (dataPtr)
                 {
                     Tbuf* out = reinterpret_cast<Tbuf*>(dataPtr);
                     *out = static_cast<Tbuf>(value);
                 }
+
+                if (resLenPtr)
+                    *resLenPtr = static_cast<SqlLen>(sizeof(Tbuf));
             }
 
             template<typename CharT, typename Tin>
@@ -448,6 +456,8 @@ namespace ignite
             {
                 using namespace type_traits;
 
+                SqlLen* resLenPtr = GetResLen();
+
                 switch (type)
                 {
                     case IGNITE_ODBC_C_TYPE_CHAR:
@@ -476,13 +486,14 @@ namespace ignite
                         for (size_t i = 0; i < sizeof(guid->Data4); ++i)
                             guid->Data4[i] = (lsb >> (sizeof(guid->Data4) - i - 1) * 8) & 0xFF;
 
+                        if (resLenPtr)
+                            *resLenPtr = static_cast<SqlLen>(sizeof(SQLGUID));
+
                         break;
                     }
 
                     default:
                     {
-                        SqlLen* resLenPtr = GetResLen();
-
                         if (resLenPtr)
                             *resLenPtr = SQL_NO_TOTAL;
                     }
@@ -573,6 +584,8 @@ namespace ignite
             {
                 using namespace type_traits;
 
+                SqlLen* resLenPtr = GetResLen();
+
                 switch (type)
                 {
                     case IGNITE_ODBC_C_TYPE_SIGNED_TINYINT:
@@ -637,6 +650,9 @@ namespace ignite
                         numeric->sign = unscaled.GetSign() < 0 ? 0 : 1;
                         numeric->precision = unscaled.GetPrecision();
 
+                        if (resLenPtr)
+                            *resLenPtr = static_cast<SqlLen>(sizeof(SQL_NUMERIC_STRUCT));
+
                         break;
                     }
 
@@ -644,8 +660,6 @@ namespace ignite
                     case IGNITE_ODBC_C_TYPE_BINARY:
                     default:
                     {
-                        SqlLen* resLenPtr = GetResLen();
-
                         if (resLenPtr)
                             *resLenPtr = SQL_NO_TOTAL;
                     }
@@ -716,6 +730,9 @@ namespace ignite
                         buffer->month = tmTime.tm_mon + 1;
                         buffer->day = tmTime.tm_mday;
 
+                        if (resLenPtr)
+                            *resLenPtr = static_cast<SqlLen>(sizeof(SQL_DATE_STRUCT));
+
                         break;
                     }
 
@@ -731,6 +748,9 @@ namespace ignite
                         buffer->second = tmTime.tm_sec;
                         buffer->fraction = 0;
 
+                        if (resLenPtr)
+                            *resLenPtr = static_cast<SqlLen>(sizeof(SQL_TIMESTAMP_STRUCT));
+
                         break;
                     }
 
@@ -830,6 +850,9 @@ namespace ignite
                         buffer->month = tmTime.tm_mon + 1;
                         buffer->day = tmTime.tm_mday;
 
+                        if (resLenPtr)
+                            *resLenPtr = static_cast<SqlLen>(sizeof(SQL_DATE_STRUCT));
+
                         break;
                     }
 
@@ -845,6 +868,9 @@ namespace ignite
                         buffer->second = tmTime.tm_sec;
                         buffer->fraction = value.GetSecondFraction();
 
+                        if (resLenPtr)
+                            *resLenPtr = static_cast<SqlLen>(sizeof(SQL_TIMESTAMP_STRUCT));
+
                         break;
                     }