Skip to content

Commit d4014f3

Browse files
committed
Refactor REF CURSOR fixes
1 parent c555d02 commit d4014f3

File tree

5 files changed

+20
-15
lines changed

5 files changed

+20
-15
lines changed

doc/api.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,8 +2899,10 @@ Oracle REF CURSORS can be fetched in node-oracledb by binding a
28992899
[`getRow()`](#getrow) or [`getRows()`](getrows). When all rows have
29002900
been fetched, or the application does not want to continue getting
29012901
more rows, then the result set must be freed using
2902-
[`close()`](#close). If the cursor is not initialized by the procedure, the
2903-
[`ResultSet`](#resultsetclass) object still requires to be closed.
2902+
[`close()`](#close). If the REF cursor is not set any value or is set to NULL
2903+
in the PL/SQL procedure, the returned [`ResultSet`](#resultsetclass) object
2904+
is an invalid one and methods like getRows() returns an error when invoked
2905+
on this object.
29042906
29052907
When using Oracle Database 11gR2 or greater, then
29062908
[`prefetchRows`](#propdbprefetchrows) can be used to tune the

src/dpi/include/dpiStmt.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,10 @@ typedef enum
103103
/* OCI Stmt Handle state
104104
* For REFCURSORS state should be DpiStmtStateExecuted
105105
*/
106-
typedef enum
107-
{
108-
DpiStmtStateUndefined = -1, /* Undefined */
109-
DpiStmtStateInitialized = 0x001, /* Initialized */
110-
DpiStmtStateExecuted, /* Executed */
111-
DpiStmtStateEndOfFetch /* End-Of-Fetch */
112-
} DpiStmtState;
113-
106+
#define DPI_STMT_STATE_UNDEFINED (0) // Undefined
107+
#define DPI_STMT_STATE_INITIALIZED (1) // Initialized
108+
#define DPI_STMT_STATE_EXECUTED (2) // Executed
109+
#define DPI_STMT_STATE_ENDOFFETCH (3) // End of Fetch
114110

115111

116112
/*

src/njs/src/njsConnection.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,13 @@ void Connection::Async_Execute (uv_work_t *req)
943943
{
944944
bind->flags =
945945
(((Stmt*)bind->value)->getState () == DpiStmtStateExecuted ) ?
946-
BIND_FLAGS_STMT_READY : BIND_FLAGS_STMT_NOT_READY;
946+
NJS_BIND_REF_CURSOR_VALID : NJS_BIND_REF_CURSOR_INVALID ;
947+
if ( ( bind->flags == NJS_BIND_REF_CURSOR_INVALID ) &&
948+
( bind->value != NULL ) )
949+
{
950+
/* Release the invalid REFCURSOR to avoid any leaks */
951+
((Stmt*)bind->value)->release ();
952+
}
947953
}
948954
}
949955

src/njs/src/njsConnection.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class Connection;
6767
class ProtoILob;
6868

6969
/* Flags Constants */
70-
#define BIND_FLAGS_STMT_NOT_READY 0 /* REFCURSOR stmt not-fetch-able */
71-
#define BIND_FLAGS_STMT_READY 1 /* REFCURSOR stmt fetch-able */
70+
#define NJS_BIND_REF_CURSOR_INVALID 0 /*CURSOR not-fetch-able */
71+
#define NJS_BIND_REF_CURSOR_VALID 1 /*CURSOR fetch-able */
7272

7373
/**
7474
* Structure used for binds

src/njs/src/njsResultSet.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,13 @@ void ResultSet::setResultSet ( dpi::Stmt *stmt, eBaton *executeBaton,
7474
this->dpistmt_ = stmt;
7575
this->dpienv_ = executeBaton->dpienv;
7676
this->njsconn_ = executeBaton->njsconn;
77-
if ( ( flags & BIND_FLAGS_STMT_READY ) == BIND_FLAGS_STMT_READY )
77+
if ( flags == NJS_BIND_REF_CURSOR_VALID )
7878
{
7979
this->meta_ = stmt->getMetaData();
8080
this->numCols_ = this->dpistmt_->numCols();
81+
this->state_ = INACTIVE;
8182
}
82-
else if ( ( flags & BIND_FLAGS_STMT_READY ) == BIND_FLAGS_STMT_NOT_READY )
83+
else if ( flags == NJS_BIND_REF_CURSOR_INVALID )
8384
{
8485
/*
8586
* This could happen in REFCURSOR case, when the stored procedure

0 commit comments

Comments
 (0)