IGNITE-6245: Implemented return of affected rows number.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e8819939 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e8819939 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e8819939 Branch: refs/heads/ignite-3484 Commit: e8819939590891d334830c59eca0b9912c13ce10 Parents: b10117d Author: Igor Sapego <[email protected]> Authored: Thu Sep 7 17:47:14 2017 +0300 Committer: Igor Sapego <[email protected]> Committed: Thu Sep 7 17:47:14 2017 +0300 ---------------------------------------------------------------------- .../processors/odbc/odbc/OdbcMessageParser.java | 4 +- .../odbc/odbc/OdbcQueryExecuteResult.java | 24 ++++++-- .../odbc/odbc/OdbcRequestHandler.java | 14 ++++- .../cpp/odbc-test/src/queries_test.cpp | 58 ++++++++++++++++++++ .../cpp/odbc/include/ignite/odbc/message.h | 12 ++++ .../odbc/include/ignite/odbc/query/data_query.h | 3 + modules/platforms/cpp/odbc/src/message.cpp | 7 ++- .../platforms/cpp/odbc/src/query/data_query.cpp | 21 +++++-- 8 files changed, 126 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java index 08cce1e..e1f3f82 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java @@ -214,7 +214,7 @@ public class OdbcMessageParser implements SqlListenerMessageParser { writer.writeLong(res.queryId()); - Collection<OdbcColumnMeta> metas = res.getColumnsMetadata(); + Collection<OdbcColumnMeta> metas = res.columnsMetadata(); assert metas != null; @@ -222,6 +222,8 @@ public class OdbcMessageParser implements SqlListenerMessageParser { for (OdbcColumnMeta meta : metas) meta.write(writer); + + writer.writeLong(res.affectedRows()); } else if (res0 instanceof OdbcQueryExecuteBatchResult) { OdbcQueryExecuteBatchResult res = (OdbcQueryExecuteBatchResult) res0; http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteResult.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteResult.java index 4b8ecbe..38dd0b4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteResult.java @@ -27,15 +27,20 @@ public class OdbcQueryExecuteResult { private final long queryId; /** Fields metadata. */ - private final Collection<OdbcColumnMeta> columnsMeta; + private final Collection<OdbcColumnMeta> columnsMetadata; + + /** Rows affected by the query. */ + private final long affectedRows; /** * @param queryId Query ID. - * @param columnsMeta Columns metadata. + * @param columnsMetadata Columns metadata. + * @param affectedRows Affected rows. */ - public OdbcQueryExecuteResult(long queryId, Collection<OdbcColumnMeta> columnsMeta) { + public OdbcQueryExecuteResult(long queryId, Collection<OdbcColumnMeta> columnsMetadata, long affectedRows) { this.queryId = queryId; - this.columnsMeta = columnsMeta; + this.columnsMetadata = columnsMetadata; + this.affectedRows = affectedRows; } /** @@ -48,7 +53,14 @@ public class OdbcQueryExecuteResult { /** * @return Columns metadata. */ - public Collection<OdbcColumnMeta> getColumnsMetadata() { - return columnsMeta; + public Collection<OdbcColumnMeta> columnsMetadata() { + return columnsMetadata; + } + + /** + * @return Number of rows affected by the query. + */ + public long affectedRows() { + return affectedRows; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java index 7677c03..19fe796 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java @@ -216,13 +216,21 @@ public class OdbcRequestHandler implements SqlListenerRequestHandler { SqlFieldsQuery qry = makeQuery(req.schema(), sql, req.arguments()); - QueryCursor qryCur = ctx.query().querySqlFieldsNoCache(qry, true); + QueryCursorImpl<List<?>> qryCur = (QueryCursorImpl<List<?>>)ctx.query().querySqlFieldsNoCache(qry, true); + + long rowsAffected = 0; - qryCursors.put(qryId, new IgniteBiTuple<QueryCursor, Iterator>(qryCur, null)); + if (!qryCur.isQuery()) { + rowsAffected = getRowsAffected(qryCur); + + qryCur.close(); + } + else + qryCursors.put(qryId, new IgniteBiTuple<QueryCursor, Iterator>(qryCur, null)); List<?> fieldsMeta = ((QueryCursorImpl) qryCur).fieldsMeta(); - OdbcQueryExecuteResult res = new OdbcQueryExecuteResult(qryId, convertMetadata(fieldsMeta)); + OdbcQueryExecuteResult res = new OdbcQueryExecuteResult(qryId, convertMetadata(fieldsMeta), rowsAffected); return new OdbcResponse(res); } http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/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 3dc538b..e7168fe 100644 --- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp @@ -360,6 +360,14 @@ struct QueriesTestSuiteFixture if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + SQLLEN affected = 0; + ret = SQLRowCount(stmt, &affected); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL(affected, 1); + ret = SQLMoreResults(stmt); if (ret != SQL_NO_DATA) @@ -2118,4 +2126,54 @@ BOOST_AUTO_TEST_CASE(TestErrorMessage) BOOST_FAIL("'" + error + "' does not match '" + pattern + "'"); } +BOOST_AUTO_TEST_CASE(TestAffectedRows) +{ + Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache"); + + const int recordsNum = 100; + + // Inserting values. + InsertTestStrings(recordsNum); + + int64_t key = 0; + char strField[1024] = { 0 }; + SQLLEN strFieldLen = 0; + + SQLCHAR updateReq[] = "UPDATE TestType SET strField = 'Updated value' WHERE _key > 20 AND _key < 40"; + + SQLRETURN ret = SQLExecDirect(stmt, updateReq, SQL_NTS); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + SQLLEN affected = 0; + ret = SQLRowCount(stmt, &affected); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL(affected, 19); + + ret = SQLFreeStmt(stmt, SQL_CLOSE); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + // Just selecting everything to make sure everything is OK + SQLCHAR selectReq[] = "SELECT _key, strField FROM TestType ORDER BY _key"; + + ret = SQLExecDirect(stmt, selectReq, sizeof(selectReq)); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + affected = -1; + ret = SQLRowCount(stmt, &affected); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL(affected, 0); +} + BOOST_AUTO_TEST_SUITE_END() http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/modules/platforms/cpp/odbc/include/ignite/odbc/message.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h index 836f2b6..fd7897f 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h @@ -576,6 +576,15 @@ namespace ignite return meta; } + /** + * Get affected rows number. + * @return Number of rows affected by the query. + */ + int64_t GetAffectedRows() + { + return affectedRows; + } + private: /** * Read response using provided reader. @@ -588,6 +597,9 @@ namespace ignite /** Columns metadata. */ meta::ColumnMetaVector meta; + + /** Number of affected rows. */ + int64_t affectedRows; }; /** http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h index b2edbdd..5a4a978 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h @@ -161,6 +161,9 @@ namespace ignite /** Cursor. */ std::auto_ptr<Cursor> cursor; + + /** Number of rows affected. */ + int64_t rowsAffected; }; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/modules/platforms/cpp/odbc/src/message.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/message.cpp b/modules/platforms/cpp/odbc/src/message.cpp index 1bd0be5..9930290 100644 --- a/modules/platforms/cpp/odbc/src/message.cpp +++ b/modules/platforms/cpp/odbc/src/message.cpp @@ -275,7 +275,10 @@ namespace ignite queryId = reader.ReadInt64(); } - QueryExecuteResponse::QueryExecuteResponse(): queryId(0), meta() + QueryExecuteResponse::QueryExecuteResponse(): + queryId(0), + meta(), + affectedRows(0) { // No-op. } @@ -290,6 +293,8 @@ namespace ignite queryId = reader.ReadInt64(); meta::ReadColumnMetaVector(reader, meta); + + affectedRows = reader.ReadInt64(); } QueryExecuteBatchResponse::QueryExecuteBatchResponse(): http://git-wip-us.apache.org/repos/asf/ignite/blob/e8819939/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 b9d551b..245e0bd 100644 --- a/modules/platforms/cpp/odbc/src/query/data_query.cpp +++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp @@ -32,7 +32,10 @@ namespace ignite Query(diag, QueryType::DATA), connection(connection), sql(sql), - params(params) + params(params), + resultMeta(), + cursor(), + rowsAffected(0) { // No-op. } @@ -176,8 +179,7 @@ namespace ignite int64_t DataQuery::AffectedRows() const { - // We are only support SELECT statements so we can not affect any row. - return 0; + return rowsAffected; } SqlResult::Type DataQuery::MakeRequestExecute() @@ -207,11 +209,13 @@ namespace ignite return SqlResult::AI_ERROR; } - cursor.reset(new Cursor(rsp.GetQueryId())); - resultMeta.assign(rsp.GetMeta().begin(), rsp.GetMeta().end()); - LOG_MSG("Query id: " << cursor->GetQueryId()); + rowsAffected = rsp.GetAffectedRows(); + + LOG_MSG("Query id: " << rsp.GetQueryId()); + LOG_MSG("Affected Rows: " << rowsAffected); + for (size_t i = 0; i < resultMeta.size(); ++i) { LOG_MSG("\n[" << i << "] SchemaName: " << resultMeta[i].GetSchemaName() @@ -220,6 +224,11 @@ namespace ignite << "\n[" << i << "] ColumnType: " << static_cast<int32_t>(resultMeta[i].GetDataType())); } + if (rowsAffected > 0) + cursor.reset(); + else + cursor.reset(new Cursor(rsp.GetQueryId())); + return SqlResult::AI_SUCCESS; }
