You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/08/10 13:53:25 UTC
[28/30] ignite git commit: IGNITE-5995: ODBC fix for SQLGetData.
IGNITE-5995: ODBC fix for SQLGetData.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0d8d166b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0d8d166b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0d8d166b
Branch: refs/heads/ignite-5872
Commit: 0d8d166b77d37f8740f3e9dd0637c336b77b0c8f
Parents: 3919d80
Author: Igor Sapego <is...@gridgain.com>
Authored: Thu Aug 10 15:31:44 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Thu Aug 10 15:31:44 2017 +0300
----------------------------------------------------------------------
.../impl/cache/query/query_fields_row_impl.h | 2 +-
.../cpp/odbc-test/include/test_utils.h | 9 ++
.../cpp/odbc-test/src/meta_queries_test.cpp | 100 +++++++++++++++++++
.../platforms/cpp/odbc-test/src/test_utils.cpp | 13 +++
.../ignite/odbc/query/column_metadata_query.h | 3 +
.../ignite/odbc/query/table_metadata_query.h | 3 +
.../include/ignite/odbc/query/type_info_query.h | 3 +
.../cpp/odbc/src/query/batch_query.cpp | 7 +-
.../odbc/src/query/column_metadata_query.cpp | 16 ++-
.../platforms/cpp/odbc/src/query/data_query.cpp | 7 +-
.../cpp/odbc/src/query/table_metadata_query.cpp | 16 ++-
.../cpp/odbc/src/query/type_info_query.cpp | 16 ++-
12 files changed, 183 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
index 63e0523..2943625 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
@@ -143,7 +143,7 @@ namespace ignite
int32_t actualLen = reader.ReadInt8Array(dst, len);
- if (actualLen == 0 || dst && len >= actualLen)
+ if (actualLen == 0 || (dst && len >= actualLen))
++processed;
return actualLen;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc-test/include/test_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/test_utils.h b/modules/platforms/cpp/odbc-test/include/test_utils.h
index 6a58e54..5dc6d6e 100644
--- a/modules/platforms/cpp/odbc-test/include/test_utils.h
+++ b/modules/platforms/cpp/odbc-test/include/test_utils.h
@@ -43,6 +43,15 @@ namespace ignite_test
enum { ODBC_BUFFER_SIZE = 1024 };
/**
+ * Extract error state.
+ *
+ * @param handleType Type of the handle.
+ * @param handle Handle.
+ * @return Error state.
+ */
+ std::string GetOdbcErrorState(SQLSMALLINT handleType, SQLHANDLE handle);
+
+ /**
* Extract error message.
*
* @param handleType Type of the handle.
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index 454a989..ff3695d 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -103,6 +103,9 @@ struct MetaQueriesTestSuiteFixture
BOOST_REQUIRE(stmt != NULL);
}
+ /**
+ * Disconnect.
+ */
void Disconnect()
{
// Releasing statement handle.
@@ -116,6 +119,11 @@ struct MetaQueriesTestSuiteFixture
SQLFreeHandle(SQL_HANDLE_ENV, env);
}
+ /**
+ * Start additional node with the specified name.
+ *
+ * @param name Node name.
+ */
static Ignite StartAdditionalNode(const char* name)
{
#ifdef IGNITE_TESTS_32
@@ -126,6 +134,36 @@ struct MetaQueriesTestSuiteFixture
}
/**
+ * Checks single row result set for correct work with SQLGetData.
+ *
+ * @param stmt Statement.
+ */
+ void CheckSingleRowResultSetWithGetData(SQLHSTMT stmt)
+ {
+ SQLRETURN ret = SQLFetch(stmt);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ char buf[1024];
+ SQLLEN bufLen = sizeof(buf);
+
+ ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLFetch(stmt);
+
+ BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
+
+ ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
+
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+ BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "24000");
+ }
+
+ /**
* Constructor.
*/
MetaQueriesTestSuiteFixture() :
@@ -237,4 +275,66 @@ BOOST_AUTO_TEST_CASE(TestColAttributesColumnScale)
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
+BOOST_AUTO_TEST_CASE(TestGetDataWithGetTypeInfo)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_VARCHAR);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithTables)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR empty[] = "";
+ SQLCHAR table[] = "TestType";
+
+ SQLRETURN ret = SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, empty, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithColumns)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR empty[] = "";
+ SQLCHAR table[] = "TestType";
+ SQLCHAR column[] = "strField";
+
+ SQLRETURN ret = SQLColumns(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, column, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithSelectQuery)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR insertReq[] = "insert into TestType(_key, strField) VALUES(1, 'Lorem ipsum')";
+ SQLRETURN ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ SQLCHAR selectReq[] = "select strField from TestType";
+ ret = SQLExecDirect(stmt, selectReq, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/test_utils.cpp b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
index c7aa70a..6e8fe6a 100644
--- a/modules/platforms/cpp/odbc-test/src/test_utils.cpp
+++ b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
@@ -21,6 +21,19 @@
namespace ignite_test
{
+ std::string GetOdbcErrorState(SQLSMALLINT handleType, SQLHANDLE handle)
+ {
+ SQLCHAR sqlstate[7] = {};
+ SQLINTEGER nativeCode;
+
+ SQLCHAR message[ODBC_BUFFER_SIZE];
+ SQLSMALLINT reallen = 0;
+
+ SQLGetDiagRec(handleType, handle, 1, sqlstate, &nativeCode, message, ODBC_BUFFER_SIZE, &reallen);
+
+ return std::string(reinterpret_cast<char*>(sqlstate));
+ }
+
std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle)
{
SQLCHAR sqlstate[7] = {};
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
index 878a4be..875b1ce 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
@@ -130,6 +130,9 @@ namespace ignite
/** Query executed. */
bool executed;
+ /** Fetched flag. */
+ bool fetched;
+
/** Fetched metadata. */
meta::ColumnMetaVector meta;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
index cef963c..acd3f49 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
@@ -134,6 +134,9 @@ namespace ignite
/** Query executed. */
bool executed;
+ /** Fetched flag. */
+ bool fetched;
+
/** Fetched metadata. */
meta::TableMetaVector meta;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
index a7cee92..00cca08 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
@@ -105,6 +105,9 @@ namespace ignite
/** Executed flag. */
bool executed;
+ /** Fetched flag. */
+ bool fetched;
+
/** Requested types. */
std::vector<int8_t> types;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/batch_query.cpp b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
index df9fb05..46447c0 100644
--- a/modules/platforms/cpp/odbc/src/query/batch_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
@@ -112,7 +112,12 @@ namespace ignite
}
if (dataRetrieved)
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
if (columnIdx != 1)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
index 8ba9323..b9c08f5 100644
--- a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
@@ -83,6 +83,7 @@ namespace ignite
table(table),
column(column),
executed(false),
+ fetched(false),
meta(),
columnsMeta()
{
@@ -125,6 +126,7 @@ namespace ignite
if (result == SqlResult::AI_SUCCESS)
{
executed = true;
+ fetched = false;
cursor = meta.begin();
}
@@ -146,6 +148,11 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ if (!fetched)
+ fetched = true;
+ else
+ ++cursor;
+
if (cursor == meta.end())
return SqlResult::AI_NO_DATA;
@@ -154,8 +161,6 @@ namespace ignite
for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
GetColumn(it->first, it->second);
- ++cursor;
-
return SqlResult::AI_SUCCESS;
}
@@ -169,7 +174,12 @@ namespace ignite
}
if (cursor == meta.end())
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
const meta::ColumnMeta& currentColumn = *cursor;
uint8_t columnType = currentColumn.GetDataType();
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/data_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp
index 23d5240..f14d004 100644
--- a/modules/platforms/cpp/odbc/src/query/data_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp
@@ -125,7 +125,12 @@ namespace ignite
Row* row = cursor->GetRow();
if (!row)
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
SqlResult::Type result = row->ReadColumnToBuffer(columnIdx, buffer);
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
index 401a1d2..e66b281 100644
--- a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
@@ -63,6 +63,7 @@ namespace ignite
table(table),
tableType(tableType),
executed(false),
+ fetched(false),
meta(),
columnsMeta()
{
@@ -98,6 +99,7 @@ namespace ignite
if (result == SqlResult::AI_SUCCESS)
{
executed = true;
+ fetched = false;
cursor = meta.begin();
}
@@ -119,6 +121,11 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ if (!fetched)
+ fetched = true;
+ else
+ ++cursor;
+
if (cursor == meta.end())
return SqlResult::AI_NO_DATA;
@@ -127,8 +134,6 @@ namespace ignite
for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
GetColumn(it->first, it->second);
- ++cursor;
-
return SqlResult::AI_SUCCESS;
}
@@ -142,7 +147,12 @@ namespace ignite
}
if (cursor == meta.end())
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
const meta::TableMeta& currentColumn = *cursor;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
index f6b3990..b4efca0 100644
--- a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
@@ -122,6 +122,7 @@ namespace ignite
Query(diag, QueryType::TYPE_INFO),
columnsMeta(),
executed(false),
+ fetched(false),
types(),
cursor(types.end())
{
@@ -185,6 +186,7 @@ namespace ignite
cursor = types.begin();
executed = true;
+ fetched = false;
return SqlResult::AI_SUCCESS;
}
@@ -203,6 +205,11 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ if (!fetched)
+ fetched = true;
+ else
+ ++cursor;
+
if (cursor == types.end())
return SqlResult::AI_NO_DATA;
@@ -211,8 +218,6 @@ namespace ignite
for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
GetColumn(it->first, it->second);
- ++cursor;
-
return SqlResult::AI_SUCCESS;
}
@@ -228,7 +233,12 @@ namespace ignite
}
if (cursor == types.end())
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
int8_t currentType = *cursor;