Skip to content

Commit bc1c3e9

Browse files
committed
Handle multiple OUT binds with DbObject type (Issue #1464)
1 parent a4faa25 commit bc1c3e9

File tree

5 files changed

+127
-5
lines changed

5 files changed

+127
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
**This release is under development and information may be incomplete**
66

7+
- Added code to handle multiple out-binds with ([DbObject](https://oracle.github.io/node-oracledb/doc/api.html#dbobjectclass)) correctly, earlier only
8+
the first one was processed and was resulting in a crash.
9+
([Issue #1464](https://github.com/oracle/node-oracledb/issues/1464))
710

811
- Added a [`connection.isHealthy()`](https://oracle.github.io/node-oracledb/doc/api.html#ishealthy)
912
function to perform a local connection health check

src/njsVariable.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -921,12 +921,15 @@ bool njsVariable_processJS(njsVariable *vars, uint32_t numVars, napi_env env,
921921
if (var->bindDir != NJS_BIND_OUT &&
922922
var->varTypeNum != DPI_ORACLE_TYPE_STMT)
923923
continue;
924-
if (!var->dmlReturningBuffers)
925-
return njsVariable_processBufferJS(var, var->buffer, env, baton);
926-
for (j = 0; j < var->numDmlReturningBuffers; j++) {
927-
buffer = &var->dmlReturningBuffers[j];
928-
if (!njsVariable_processBufferJS(var, buffer, env, baton))
924+
if (!var->dmlReturningBuffers) {
925+
if (!njsVariable_processBufferJS(var, var->buffer, env, baton))
929926
return false;
927+
} else {
928+
for (j = 0; j < var->numDmlReturningBuffers; j++) {
929+
buffer = &var->dmlReturningBuffers[j];
930+
if (!njsVariable_processBufferJS(var, buffer, env, baton))
931+
return false;
932+
}
930933
}
931934
}
932935

test/dbObjectOutBind.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. */
2+
3+
/******************************************************************************
4+
*
5+
* You may not use the identified files except in compliance with the Apache
6+
* License, Version 2.0 (the "License.")
7+
*
8+
* You may obtain a copy of the License at
9+
* http://www.apache.org/licenses/LICENSE-2.0.
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, withOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
*
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License
17+
* The node-oracledb test suite uses 'mocha', 'assert' and 'async'.
18+
* See LICENSE.md for relevant licenses.
19+
*
20+
* NAME
21+
* 262. dbObjectOutBind.js
22+
*
23+
* DESCRIPTION
24+
* Test cases to check the OUT Binds with DBObject Type not crashing
25+
*
26+
*****************************************************************************/
27+
'use strict';
28+
29+
const oracledb = require('oracledb');
30+
const assert = require('assert');
31+
const dbConfig = require('./dbconfig.js');
32+
33+
describe('262. dbObjectOutBind.js', function() {
34+
let conn = null;
35+
let proc1 =
36+
`create or replace procedure nodb_getDataCursor1(p_cur out sys_refcursor) is
37+
begin
38+
open p_cur for
39+
select
40+
level
41+
from
42+
dual
43+
connect by level < 10;
44+
end; `;
45+
let proc2 =
46+
`create or replace procedure nodb_getDataCursor2(p_cur out sys_refcursor) is
47+
begin
48+
open p_cur for
49+
select
50+
group_by,
51+
cast(collect(lvl) as sys.odcinumberlist) group_values
52+
from (
53+
select
54+
mod(level, 3) group_by,
55+
level lvl
56+
from
57+
dual
58+
connect by level < 10
59+
)
60+
group by group_by;
61+
end;`;
62+
let proc3 =
63+
`create or replace procedure nodb_getDataCursor3(
64+
p_cur1 out sys_refcursor,
65+
p_cur2 out sys_refcursor
66+
) is
67+
begin
68+
nodb_getDataCursor1(p_cur1);
69+
nodb_getDataCursor2(p_cur2);
70+
end;`;
71+
72+
before(async function() {
73+
try {
74+
conn = await oracledb.getConnection(dbConfig);
75+
await conn.execute(proc1);
76+
await conn.execute(proc2);
77+
await conn.execute(proc3);
78+
} catch (e) {
79+
assert.fail(e);
80+
}
81+
});
82+
83+
after(async function() {
84+
try {
85+
await conn.execute(`DROP PROCEDURE nodb_getDataCursor3`);
86+
await conn.execute(`DROP PROCEDURE nodb_getDataCursor2`);
87+
await conn.execute(`DROP PROCEDURE nodb_getDataCursor1`);
88+
await conn.close();
89+
} catch (e) {
90+
assert.fail(e);
91+
}
92+
});
93+
94+
it('262.1 call procedure with 2 OUT binds of DbObject', async function() {
95+
try {
96+
let result = await conn.execute(
97+
`BEGIN nodb_getDataCursor3(p_cur1 => :p_cur1,
98+
p_cur2 => :p_cur2); end;`,
99+
{
100+
p_cur1: {type: oracledb.CURSOR, dir: oracledb.BIND_OUT},
101+
p_cur2: {type: oracledb.CURSOR, dir: oracledb.BIND_OUT}
102+
}
103+
);
104+
result.outBinds.p_cur1.close();
105+
result.outBinds.p_cur2.close();
106+
} catch (e) {
107+
assert.fail(e);
108+
}
109+
});
110+
111+
});
112+

test/list.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,3 +5296,6 @@ oracledb.OUT_FORMAT_OBJECT and resultSet = true
52965296
261.1 connection health on stand alone connections
52975297
261.1.1 connection health on good connection
52985298
261.1.2 connection health on closed connection
5299+
5300+
262. dbObjectOutBind.js
5301+
262.1 call procedure with 2 OUT binds of DbObject

test/opts/.mocharc.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,4 @@ spec:
248248
- test/tpc.js
249249
- test/tpcResume.js
250250
- test/connHealthy.js
251+
- test/dbObjectOutBind.js

0 commit comments

Comments
 (0)