Skip to content

Commit f31af6b

Browse files
committed
Minor optimization for binary vectors
1 parent bc01781 commit f31af6b

File tree

5 files changed

+30
-18
lines changed

5 files changed

+30
-18
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ node-oracledb `v6.6.0 <https://github.com/oracle/node-oracledb/compare/v6.5.1...
1313
Common Changes
1414
++++++++++++++
1515

16+
#) Added support for binary vector datatype (Oracle Database 23ai feature)
17+
1618
#) Added support for Centralized Configuration Providers (Azure App
1719
Configuration Store and OCI Object Storage). Node-oracledb extracts
1820
configuration information from the supported provider and uses it to

lib/impl/datahandlers/vector.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ class VectorDecoder extends BaseBuffer {
7373
} else {
7474
errors.throwErr(errors.ERR_VECTOR_FORMAT_NOT_SUPPORTED, vectorFormat);
7575
}
76-
if (flags & constants.TNS_VECTOR_FLAG_NORM)
76+
77+
// For binary vector, NORM will never be present but space for NORM is reserved to keep
78+
// same header lengh across the different vector formats.
79+
if (vectorFormat === constants.VECTOR_FORMAT_BINARY || flags & constants.TNS_VECTOR_FLAG_NORM)
7780
this.skipBytes(8);
7881

7982
// parse data
@@ -107,6 +110,8 @@ class VectorEncoder extends GrowableBuffer {
107110
let writeFn = this.writeBinaryFloat.bind(this);
108111
let numElements = value.length;
109112
let vectorVersion = constants.TNS_VECTOR_VERSION_BASE;
113+
let flags = constants.TNS_VECTOR_FLAG_NORMSRC
114+
| constants.TNS_VECTOR_FLAG_NORM; // NORM is present and reserve space.
110115

111116
if (Array.isArray(value) || value instanceof Float64Array) {
112117
vectorFormat = constants.VECTOR_FORMAT_FLOAT64;
@@ -119,13 +124,10 @@ class VectorEncoder extends GrowableBuffer {
119124
// The number of dimensions are assumed to be multiple of 8.
120125
numElements = numElements * 8;
121126
vectorVersion = constants.TNS_VECTOR_VERSION_WITH_BINARY;
127+
flags = constants.TNS_VECTOR_FLAG_NORMSRC; // only space is reserved.
122128
writeFn = this.writeUInt8.bind(this);
123129
}
124130

125-
// Let server generate the norm (TNS_VECTOR_FLAG_NORMSRC)
126-
const flags = constants.TNS_VECTOR_FLAG_NORM
127-
| constants.TNS_VECTOR_FLAG_NORMSRC;
128-
129131
// write header
130132
this.writeUInt8(constants.TNS_VECTOR_MAGIC_BYTE);
131133
this.writeUInt8(vectorVersion);

lib/oracledb.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,7 @@ module.exports = {
10601060
VECTOR_FORMAT_FLOAT32: constants.VECTOR_FORMAT_FLOAT32,
10611061
VECTOR_FORMAT_FLOAT64: constants.VECTOR_FORMAT_FLOAT64,
10621062
VECTOR_FORMAT_INT8: constants.VECTOR_FORMAT_INT8,
1063+
VECTOR_FORMAT_BINARY: constants.VECTOR_FORMAT_BINARY,
10631064

10641065
// database type aliases
10651066
BLOB: types.DB_TYPE_BLOB,

src/njsJsonBuffer.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -224,21 +224,26 @@ static bool njsJsonBuffer_populateNode(njsJsonBuffer *buf, dpiJsonNode *node,
224224
NJS_CHECK_NAPI(env, napi_is_typedarray(env, value, &isTyped))
225225
if (isTyped) {
226226
NJS_CHECK_NAPI(env, napi_get_global(env, &global))
227-
NJS_CHECK_NAPI(env, napi_get_named_property(env, global, "Uint8Array",
228-
&uint8Val))
229-
NJS_CHECK_NAPI(env, napi_get_named_property(env, uint8Val, "prototype",
230-
&uint8Proto))
231-
NJS_CHECK_NAPI(env, napi_get_prototype(env, value, &valProto))
232-
233-
// See if the value prototype matches with Uint8Array.
234-
// The Buffer and JsonId return true for Uint8Array instance, so
235-
// using prototype check to see if the value is instance of Uint8Array.
236-
NJS_CHECK_NAPI(env, napi_strict_equals(env, uint8Proto, valProto,
237-
&check))
238227
NJS_CHECK_NAPI(env, napi_get_typedarray_info(env, value, &type,
239-
NULL, NULL, NULL, NULL))
228+
NULL, NULL, NULL, NULL))
240229
if ((type == napi_float64_array) || (type == napi_float32_array)
241-
|| (type == napi_int8_array) || (check)) {
230+
|| (type == napi_int8_array)) {
231+
check = true;
232+
} else {
233+
NJS_CHECK_NAPI(env, napi_get_named_property(env, global,
234+
"Uint8Array", &uint8Val))
235+
NJS_CHECK_NAPI(env, napi_get_named_property(env, uint8Val,
236+
"prototype", &uint8Proto))
237+
NJS_CHECK_NAPI(env, napi_get_prototype(env, value, &valProto))
238+
239+
// See if the value prototype matches with Uint8Array.
240+
// The Buffer and JsonId return true for Uint8Array instance, so
241+
// using prototype check to see if the value is
242+
// instance of Uint8Array.
243+
NJS_CHECK_NAPI(env, napi_strict_equals(env, uint8Proto, valProto,
244+
&check))
245+
}
246+
if (check) {
242247
node->oracleTypeNum = DPI_ORACLE_TYPE_VECTOR;
243248
node->nativeTypeNum = DPI_NATIVE_TYPE_BYTES;
244249
NJS_CHECK_NAPI(env, napi_call_function(env, global,

test/dataTypeJson.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ describe('244.dataTypeJson.js', function() {
205205
KeyBinary: new Uint8Array([240, 120]),
206206
keyBuf: Buffer.from("A Raw")
207207
};
208+
const jsonVal22 = { "key22": [new Uint8Array([20, 10])]};
208209
const binds = [
209210
[1, jsonVal1],
210211
[2, jsonVal2],
@@ -234,6 +235,7 @@ describe('244.dataTypeJson.js', function() {
234235
}
235236
if (await testsUtil.isVectorBinaryRunnable()) {
236237
binds.push([21, jsonVal21]);
238+
binds.push([22, jsonVal22]);
237239
}
238240
binds.forEach((element, index) => {
239241
binds[index].push(connection.encodeOSON(element[1]));

0 commit comments

Comments
 (0)