IGNITE-5396: ODBC server cursor cleaned when last result piece is transmitted


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

Branch: refs/heads/ignite-2.1.2-exchange
Commit: c507152089c598c56994b7ab35ed3079a69a8094
Parents: f58b222
Author: Igor Sapego <[email protected]>
Authored: Tue Jun 20 18:49:25 2017 +0300
Committer: Igor Sapego <[email protected]>
Committed: Tue Jun 20 18:49:25 2017 +0300

----------------------------------------------------------------------
 .../odbc/odbc/OdbcQueryFetchResult.java         |  4 +-
 .../odbc/odbc/OdbcRequestHandler.java           | 50 ++++++++++++++------
 .../platforms/cpp/odbc/src/query/data_query.cpp |  5 +-
 modules/platforms/cpp/odbc/src/result_page.cpp  |  2 +-
 4 files changed, 42 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c5071520/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryFetchResult.java
----------------------------------------------------------------------
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 f8075f3..612ac02 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 class OdbcQueryFetchResult {
     }
 
     /**
-     * @return Flag indicating the query has no unfetched results.
+     * @return Flag indicating the query has no non-fetched results.
      */
     public boolean last() {
         return last;

http://git-wip-us.apache.org/repos/asf/ignite/blob/c5071520/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 0c65edd..46f6ace 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 @@ public class OdbcRequestHandler implements 
SqlListenerRequestHandler {
      * @return Response.
      */
     private SqlListenerResponse closeQuery(OdbcQueryCloseRequest req) {
+        long queryId = req.queryId();
+
         try {
-            IgniteBiTuple<QueryCursor, Iterator> tuple = 
qryCursors.get(req.queryId());
+            IgniteBiTuple<QueryCursor, Iterator> 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 @@ public class OdbcRequestHandler implements 
SqlListenerRequestHandler {
      */
     private SqlListenerResponse fetchQuery(OdbcQueryFetchRequest req) {
         try {
-            IgniteBiTuple<QueryCursor, Iterator> tuple = 
qryCursors.get(req.queryId());
+            long queryId = req.queryId();
+            IgniteBiTuple<QueryCursor, Iterator> 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 @@ public class OdbcRequestHandler implements 
SqlListenerRequestHandler {
             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);
         }
@@ -509,6 +514,21 @@ public class OdbcRequestHandler implements 
SqlListenerRequestHandler {
     }
 
     /**
+     * Close cursor.
+     * @param tuple Query map element.
+     * @param queryId Query ID.
+     */
+    private void CloseCursor(IgniteBiTuple<QueryCursor, Iterator> 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).
      *
      * @param sqlType SQL type.

http://git-wip-us.apache.org/repos/asf/ignite/blob/c5071520/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 3cd3b16..23d5240 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)
                 {

http://git-wip-us.apache.org/repos/asf/ignite/blob/c5071520/modules/platforms/cpp/odbc/src/result_page.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/result_page.cpp 
b/modules/platforms/cpp/odbc/src/result_page.cpp
index 4464481..764770d 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();
 

Reply via email to