diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryFetchResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryFetchResult.java index f8075f3d48476..612ac0269e2a3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryFetchResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryFetchResult.java @@ -29,7 +29,7 @@ public class OdbcQueryFetchResult { /** Query result rows. */ private final Collection items; - /** Flag indicating the query has no unfetched results. */ + /** Flag indicating the query has no non-fetched results. */ private final boolean last; /** @@ -58,7 +58,7 @@ public Collection items() { } /** - * @return Flag indicating the query has no unfetched results. + * @return Flag indicating the query has no non-fetched results. */ public boolean last() { return last; 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 0c65edd9ab55c..46f6ace0adfeb 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 @@ -296,29 +296,25 @@ private static long getRowsAffected(QueryCursor> qryCur) { * @return Response. */ private SqlListenerResponse closeQuery(OdbcQueryCloseRequest req) { + long queryId = req.queryId(); + try { - IgniteBiTuple tuple = qryCursors.get(req.queryId()); + IgniteBiTuple tuple = qryCursors.get(queryId); if (tuple == null) return new OdbcResponse(SqlListenerResponse.STATUS_FAILED, - "Failed to find query with ID: " + req.queryId()); - - QueryCursor cur = tuple.get1(); - - assert(cur != null); - - cur.close(); + "Failed to find query with ID: " + queryId); - qryCursors.remove(req.queryId()); + CloseCursor(tuple, queryId); - OdbcQueryCloseResult res = new OdbcQueryCloseResult(req.queryId()); + OdbcQueryCloseResult res = new OdbcQueryCloseResult(queryId); return new OdbcResponse(res); } catch (Exception e) { - qryCursors.remove(req.queryId()); + qryCursors.remove(queryId); - U.error(log, "Failed to close SQL query [reqId=" + req.requestId() + ", req=" + req.queryId() + ']', e); + U.error(log, "Failed to close SQL query [reqId=" + req.requestId() + ", req=" + queryId + ']', e); return new OdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); } @@ -332,17 +328,20 @@ private SqlListenerResponse closeQuery(OdbcQueryCloseRequest req) { */ private SqlListenerResponse fetchQuery(OdbcQueryFetchRequest req) { try { - IgniteBiTuple tuple = qryCursors.get(req.queryId()); + long queryId = req.queryId(); + IgniteBiTuple tuple = qryCursors.get(queryId); if (tuple == null) return new OdbcResponse(SqlListenerResponse.STATUS_FAILED, - "Failed to find query with ID: " + req.queryId()); + "Failed to find query with ID: " + queryId); Iterator iter = tuple.get2(); if (iter == null) { QueryCursor cur = tuple.get1(); + assert(cur != null); + iter = cur.iterator(); tuple.put(cur, iter); @@ -353,7 +352,13 @@ private SqlListenerResponse fetchQuery(OdbcQueryFetchRequest req) { for (int i = 0; i < req.pageSize() && iter.hasNext(); ++i) items.add(iter.next()); - OdbcQueryFetchResult res = new OdbcQueryFetchResult(req.queryId(), items, !iter.hasNext()); + boolean lastPage = !iter.hasNext(); + + // Automatically closing cursor if no more data is available. + if (lastPage) + CloseCursor(tuple, queryId); + + OdbcQueryFetchResult res = new OdbcQueryFetchResult(queryId, items, lastPage); return new OdbcResponse(res); } @@ -508,6 +513,21 @@ private SqlListenerResponse getParamsMeta(OdbcQueryGetParamsMetaRequest req) { } } + /** + * Close cursor. + * @param tuple Query map element. + * @param queryId Query ID. + */ + private void CloseCursor(IgniteBiTuple tuple, long queryId) { + QueryCursor cur = tuple.get1(); + + assert(cur != null); + + cur.close(); + + qryCursors.remove(queryId); + } + /** * Convert {@link java.sql.Types} to binary type constant (See {@link GridBinaryMarshaller} constants). * diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp index 3cd3b16d7d4f9..23d524047eb84 100644 --- a/modules/platforms/cpp/odbc/src/query/data_query.cpp +++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp @@ -149,7 +149,10 @@ namespace ignite if (!cursor.get()) return SqlResult::AI_SUCCESS; - SqlResult::Type result = MakeRequestClose(); + SqlResult::Type result = SqlResult::AI_SUCCESS; + + if (cursor->HasData()) + result = MakeRequestClose(); if (result == SqlResult::AI_SUCCESS) { diff --git a/modules/platforms/cpp/odbc/src/result_page.cpp b/modules/platforms/cpp/odbc/src/result_page.cpp index 44644812c4813..764770db6f596 100644 --- a/modules/platforms/cpp/odbc/src/result_page.cpp +++ b/modules/platforms/cpp/odbc/src/result_page.cpp @@ -40,7 +40,7 @@ namespace ignite last = reader.ReadBool(); size = reader.ReadInt32(); - ignite::impl::interop::InteropInputStream& stream = *reader.GetStream(); + impl::interop::InteropInputStream& stream = *reader.GetStream(); int32_t dataToRead = stream.Remaining();