Skip to content

Commit 9df01ab

Browse files
committed
Fix a bug in Thick mode which inserted invalid value if an unacceptable out of bound number is given (Issue #1659)
1 parent 418d2a5 commit 9df01ab

File tree

6 files changed

+104
-14
lines changed

6 files changed

+104
-14
lines changed

doc/src/release_notes.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ Thin Mode Changes
2828
#) Added support for Oracle Database 23c
2929
:ref:`Implicit Connection Pooling <implicitpool>` in DRCP and PRCP.
3030

31+
Thick Mode Changes
32+
+++++++++++++++++++
33+
34+
#) Fix bug which inserted invalid value `~` if an unacceptable out of bound number is given.
35+
Now, numbers like 1.0e+128, -1e128, etc. will throw an error ``NJS-115: value cannot be represented
36+
as an Oracle Database number``
37+
Additionally, it resolves the issue related to JS numbers with precisions where
38+
`2.3` is returned as `2.300003`.
39+
3140
node-oracledb `v6.4.0 <https://github.com/oracle/node-oracledb/compare/v6.3.0...v6.4.0>`__ (11 Mar 2024)
3241
--------------------------------------------------------------------------------------------------------
3342

src/njsVariable.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ bool njsVariable_createBuffer(njsVariable *var, njsConnection *conn,
6363
case DPI_ORACLE_TYPE_LONG_VARCHAR:
6464
case DPI_ORACLE_TYPE_LONG_RAW:
6565
case DPI_ORACLE_TYPE_XMLTYPE:
66+
case DPI_ORACLE_TYPE_NUMBER:
6667
var->nativeTypeNum = DPI_NATIVE_TYPE_BYTES;
6768
break;
6869
case DPI_ORACLE_TYPE_NATIVE_FLOAT:
6970
var->nativeTypeNum = DPI_NATIVE_TYPE_FLOAT;
7071
break;
7172
case DPI_ORACLE_TYPE_NATIVE_DOUBLE:
72-
case DPI_ORACLE_TYPE_NUMBER:
7373
var->nativeTypeNum = DPI_NATIVE_TYPE_DOUBLE;
7474
break;
7575
case DPI_ORACLE_TYPE_DATE:
@@ -382,6 +382,7 @@ bool njsVariable_getScalarValue(njsVariable *var, njsConnection *conn,
382382
const char *rowidValue;
383383
dpiJsonNode *topNode;
384384
dpiData *data;
385+
napi_value numStr;
385386

386387
// get the value from ODPI-C
387388
bufferRowIndex = baton->bufferRowIndex + pos;
@@ -413,19 +414,26 @@ bool njsVariable_getScalarValue(njsVariable *var, njsConnection *conn,
413414
value))
414415
break;
415416
case DPI_NATIVE_TYPE_BYTES:
416-
if (data->value.asBytes.length > var->maxSize)
417-
return njsBaton_setErrorInsufficientBufferForBinds(baton);
418-
if (data->value.asBytes.length == 0) {
419-
NJS_CHECK_NAPI(env, napi_get_null(env, value))
420-
} else if (var->varTypeNum == DPI_ORACLE_TYPE_RAW ||
421-
var->varTypeNum == DPI_ORACLE_TYPE_LONG_RAW) {
422-
NJS_CHECK_NAPI(env, napi_create_buffer_copy(env,
423-
data->value.asBytes.length, data->value.asBytes.ptr,
424-
NULL, value))
425-
} else {
417+
if (var->varTypeNum == DPI_ORACLE_TYPE_NUMBER) {
426418
NJS_CHECK_NAPI(env, napi_create_string_utf8(env,
427419
data->value.asBytes.ptr, data->value.asBytes.length,
428-
value))
420+
&numStr))
421+
NJS_CHECK_NAPI(env, napi_coerce_to_number(env, numStr, value))
422+
} else {
423+
if (data->value.asBytes.length > var->maxSize)
424+
return njsBaton_setErrorInsufficientBufferForBinds(baton);
425+
if (data->value.asBytes.length == 0) {
426+
NJS_CHECK_NAPI(env, napi_get_null(env, value))
427+
} else if (var->varTypeNum == DPI_ORACLE_TYPE_RAW ||
428+
var->varTypeNum == DPI_ORACLE_TYPE_LONG_RAW) {
429+
NJS_CHECK_NAPI(env, napi_create_buffer_copy(env,
430+
data->value.asBytes.length, data->value.asBytes.ptr,
431+
NULL, value))
432+
} else {
433+
NJS_CHECK_NAPI(env, napi_create_string_utf8(env,
434+
data->value.asBytes.ptr, data->value.asBytes.length,
435+
value))
436+
}
429437
}
430438
break;
431439
case DPI_NATIVE_TYPE_LOB:
@@ -760,6 +768,7 @@ bool njsVariable_setScalarValue(njsVariable *var, uint32_t pos, napi_env env,
760768
napi_typedarray_type type;
761769
void *rawdata = NULL;
762770
size_t numElem = 0;
771+
napi_value numStr;
763772

764773
// initialization
765774
data = &var->buffer->dpiVarData[pos];
@@ -815,6 +824,11 @@ bool njsVariable_setScalarValue(njsVariable *var, uint32_t pos, napi_env env,
815824

816825
// handle binding numbers
817826
if (valueType == napi_number) {
827+
if (var->varTypeNum == DPI_ORACLE_TYPE_NUMBER) {
828+
NJS_CHECK_NAPI(env, napi_coerce_to_string(env, value, &numStr));
829+
return njsVariable_setFromString(var, pos, env, numStr, baton);
830+
}
831+
818832
NJS_CHECK_NAPI(env, napi_get_value_double(env, value, &tempDouble))
819833
if (var->varTypeNum == DPI_ORACLE_TYPE_NATIVE_FLOAT) {
820834
data->value.asFloat = (float) tempDouble;

test/dataTypeAssist.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
1+
/* Copyright (c) 2015, 2024, Oracle and/or its affiliates. */
22

33
/******************************************************************************
44
*
@@ -178,6 +178,8 @@ assist.data = {
178178
-8,
179179
1234,
180180
-1234,
181+
2.3,
182+
-2.3,
181183
9876.54321,
182184
-9876.54321,
183185
0.01234,

test/invalidNumber.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* Copyright (c) 2024, Oracle and/or its affiliates. */
2+
3+
/******************************************************************************
4+
*
5+
* This software is dual-licensed to you under the Universal Permissive License
6+
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7+
* 2.0 as shown at https://www.apache.org/licenses/LICENSE-2.0. You may choose
8+
* either license.
9+
*
10+
* If you elect to accept the software under the Apache License, Version 2.0,
11+
* the following applies:
12+
*
13+
* Licensed under the Apache License, Version 2.0 (the `License`);
14+
* you may not use this file except in compliance with the License.
15+
* You may obtain a copy of the License at
16+
*
17+
* https://www.apache.org/licenses/LICENSE-2.0
18+
*
19+
* Unless required by applicable law or agreed to in writing, software
20+
* distributed under the License is distributed on an `AS IS` BASIS,
21+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
* See the License for the specific language governing permissions and
23+
* limitations under the License.
24+
*
25+
* NAME
26+
* 299. invalidNumber.js
27+
*
28+
* DESCRIPTION
29+
* Testing insertion of invalid numbers to the database
30+
*
31+
*****************************************************************************/
32+
'use strict';
33+
34+
const oracledb = require('oracledb');
35+
const assert = require('assert');
36+
const dbConfig = require('./dbconfig.js');
37+
38+
describe('299. invalidNumber.js', function() {
39+
let conn;
40+
41+
before(async function() {
42+
conn = await oracledb.getConnection(dbConfig);
43+
await conn.execute('CREATE TABLE nodb_num(id NUMBER)');
44+
});
45+
46+
after(async function() {
47+
await conn.execute('DROP TABLE nodb_num PURGE');
48+
await conn.close();
49+
});
50+
51+
it('299.1 throws error for invalid numbers', async () => {
52+
const idv = 1e+131;
53+
const sql = 'INSERT INTO nodb_num VALUES(:cid)';
54+
const binds = { cid: { val: idv, type: oracledb.NUMBER}};
55+
await assert.rejects(
56+
async () => await conn.execute(sql, binds),
57+
/NJS-115:/
58+
);
59+
}); //299.1
60+
61+
});

test/list.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5795,4 +5795,7 @@ oracledb.OUT_FORMAT_OBJECT and resultSet = true
57955795
298.7 average vector distance function vector columns with parallel execution
57965796
298.8 aggregate functions on vector columns vector columns with parallel execution
57975797
298.9 parallel delete operation on vector columns
5798-
298.10 no parallel delete operation on vector columns
5798+
298.10 no parallel delete operation on vector columns
5799+
5800+
299. invalidNumber.js
5801+
299.1 throws error for invalid numbers

test/opts/.mocharc.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,4 @@ spec:
280280
- test/dataTypeVector2.js
281281
- test/dataTypeVector3.js
282282
- test/jsonDualityViews7.js
283+
- test/invalidNumber.js

0 commit comments

Comments
 (0)