oracledb 7.0.0 → 26.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +16 -6
  2. package/build/Release/oracledb-26.0.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-26.0.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-26.0.0-js-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-26.0.0-linux-arm64.node +0 -0
  6. package/build/Release/oracledb-26.0.0-linux-arm64.node-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-26.0.0-linux-x64.node +0 -0
  8. package/build/Release/oracledb-26.0.0-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-26.0.0-win32-x64.node +0 -0
  10. package/build/Release/oracledb-26.0.0-win32-x64.node-buildinfo.txt +1 -0
  11. package/lib/aqDeqOptions.js +4 -4
  12. package/lib/aqEnqOptions.js +2 -2
  13. package/lib/aqQueue.js +11 -6
  14. package/lib/connection.js +73 -18
  15. package/lib/constants.js +4 -0
  16. package/lib/endUserSecurityContext.js +30 -25
  17. package/lib/errors.js +92 -5
  18. package/lib/impl/connection.js +36 -0
  19. package/lib/impl/datahandlers/buffer.js +91 -18
  20. package/lib/impl/datahandlers/oson.js +3 -2
  21. package/lib/impl/parserHelpers.js +6 -2
  22. package/lib/impl/resultset.js +32 -11
  23. package/lib/oracledb.js +34 -0
  24. package/lib/pool.js +6 -2
  25. package/lib/queryStream.js +13 -5
  26. package/lib/resultset.js +10 -3
  27. package/lib/securityContextProvider.js +206 -0
  28. package/lib/thin/aq.js +2 -3
  29. package/lib/thin/connection.js +380 -24
  30. package/lib/thin/dbObject.js +20 -11
  31. package/lib/thin/pool.js +4 -3
  32. package/lib/thin/protocol/capabilities.js +37 -4
  33. package/lib/thin/protocol/constants.js +49 -1
  34. package/lib/thin/protocol/messages/aqArray.js +2 -2
  35. package/lib/thin/protocol/messages/aqBase.js +2 -2
  36. package/lib/thin/protocol/messages/auth.js +17 -6
  37. package/lib/thin/protocol/messages/base.js +75 -17
  38. package/lib/thin/protocol/messages/dataType.js +46 -0
  39. package/lib/thin/protocol/messages/directPathLoadStream.js +3 -2
  40. package/lib/thin/protocol/messages/execute.js +10 -4
  41. package/lib/thin/protocol/messages/index.js +4 -0
  42. package/lib/thin/protocol/messages/notification.js +281 -0
  43. package/lib/thin/protocol/messages/subscribe.js +181 -0
  44. package/lib/thin/protocol/messages/withData.js +23 -10
  45. package/lib/thin/protocol/packet.js +2 -4
  46. package/lib/thin/protocol/protocol.js +7 -4
  47. package/lib/thin/resultSet.js +40 -20
  48. package/lib/thin/sqlnet/ezConnectResolver.js +9 -2
  49. package/lib/thin/sqlnet/navNodes.js +7 -5
  50. package/lib/thin/sqlnet/networkSession.js +17 -11
  51. package/lib/thin/sqlnet/ntTcp.js +24 -8
  52. package/lib/thin/sqlnet/packet.js +24 -4
  53. package/lib/thin/sqlnet/sessionAtts.js +2 -2
  54. package/lib/thin/statement.js +6 -1
  55. package/lib/thin/statementCache.js +34 -6
  56. package/lib/thin/subscr.js +363 -0
  57. package/lib/transformer.js +60 -17
  58. package/lib/util.js +46 -8
  59. package/lib/version.js +1 -1
  60. package/package.json +1 -1
  61. package/plugins/configProviders/gcpstorage/index.js +121 -0
  62. package/plugins/configProviders/ociobject/index.js +1 -1
  63. package/plugins/token/cache.js +154 -0
  64. package/plugins/token/endUserSecurityProvider/index.js +377 -0
  65. package/plugins/token/extensionAzure/index.js +160 -28
  66. package/plugins/token/extensionOci/index.js +221 -16
  67. package/plugins/vectorsdk/OracleVecDB.js +346 -0
  68. package/plugins/vectorsdk/index.js +49 -0
  69. package/plugins/vectorsdk/utils.js +370 -0
  70. package/plugins/vectorsdk/vectorEmbedding.js +223 -0
  71. package/plugins/vectorsdk/vectorIndex.js +177 -0
  72. package/plugins/vectorsdk/vectorRecords.js +406 -0
  73. package/plugins/vectorsdk/vectorSchema.js +408 -0
  74. package/plugins/vectorsdk/vectorSearch.js +538 -0
  75. package/build/Release/oracledb-7.0.0-darwin-arm64.node +0 -0
  76. package/build/Release/oracledb-7.0.0-darwin-arm64.node-buildinfo.txt +0 -1
  77. package/build/Release/oracledb-7.0.0-js-buildinfo.txt +0 -1
  78. package/build/Release/oracledb-7.0.0-linux-arm64.node +0 -0
  79. package/build/Release/oracledb-7.0.0-linux-arm64.node-buildinfo.txt +0 -1
  80. package/build/Release/oracledb-7.0.0-linux-x64.node +0 -0
  81. package/build/Release/oracledb-7.0.0-linux-x64.node-buildinfo.txt +0 -1
  82. package/build/Release/oracledb-7.0.0-win32-x64.node +0 -0
  83. package/build/Release/oracledb-7.0.0-win32-x64.node-buildinfo.txt +0 -1
  84. package/eslint.config.js +0 -39
package/lib/errors.js CHANGED
@@ -27,6 +27,8 @@
27
27
 
28
28
  const util = require('util');
29
29
 
30
+ const constants = require('./constants.js');
31
+
30
32
  // define error prefix for all messages
31
33
  const ERR_PREFIX = "NJS";
32
34
 
@@ -198,6 +200,16 @@ const ERR_INVALID_END_USER_SECURITY_CONTEXT_LENGTH = 189;
198
200
  const ERR_END_USER_SECURITY_CONTEXT_REQUIRES_TCPS = 190;
199
201
  const ERR_UNSUPPORTED_DEEP_DATA_SECURITY_FEATURE = 191;
200
202
  const ERR_CHAR_CS_NOT_SUPPORTED = 192;
203
+ const ERR_INVALID_PROPERTY_LENGTH = 193;
204
+ const ERR_UNSUPPORTED_JSON_VALUE_TYPE = 194;
205
+ const ERR_NON_FINITE_JSON_NUMBER = 195;
206
+ const ERR_UNSUPPORTED_JSON_FIELD_NAME = 196;
207
+ const ERR_UNSUPPORTED_DB_OTEL_FEATURE = 197;
208
+ const ERR_END_USER_SECURITY_CONTEXT_PROVIDER = 198;
209
+ const ERR_INVALID_SECURITY_CONTEXT_METADATA = 199;
210
+ const ERR_INVALID_SECURITY_CONTEXT_CALLBACK = 200;
211
+ const ERR_TIMESTAMP_LTZ_REGION_NOT_SUPPORTED = 201;
212
+ const ERR_CONFLICTING_SECURITY_CONTEXT_IDENTITIES = 202;
201
213
 
202
214
  // Oracle Net layer errors start from 500
203
215
  const ERR_CONNECTION_CLOSED = 500;
@@ -232,6 +244,8 @@ const ERR_ANO_NEGOTIATION = 533;
232
244
  const ERR_DATA_COMPRESSION = 534;
233
245
  const ERR_CONFIG_PROVIDER_PARAM_TYPE = 535;
234
246
  const ERR_TOO_MANY_REDIRECTS = 536;
247
+ const ERR_TXN_PRIORITY_NOT_SUPPORTED = 537;
248
+ const ERR_INVALID_TXN_PRIORITY = 538;
235
249
 
236
250
  // Oracle SUCCESS_WITH_INFO warning start from 700
237
251
  const WRN_COMPILATION_CREATE = 700;
@@ -246,6 +260,7 @@ adjustErrorXref.set("DPI-1055", ERR_NAN_VALUE);
246
260
  adjustErrorXref.set("DPI-1063", ERR_EXEC_MODE_ONLY_FOR_DML);
247
261
  adjustErrorXref.set("DPI-1067", [ERR_CALL_TIMEOUT_EXCEEDED, "call timeout of ([0-9]+) ms"]);
248
262
  adjustErrorXref.set("DPI-1080", ERR_CONNECTION_CLOSED);
263
+ adjustErrorXref.set("DPI-1087", ERR_NOT_A_QUERY);
249
264
  adjustErrorXref.set("OCI-22303", [ERR_INVALID_OBJECT_TYPE_NAME, 'type "([^"]*"."[^"]*)"']);
250
265
  adjustErrorXref.set("OCI-22164", ERR_DELETE_ELEMENTS_OF_VARRAY);
251
266
  adjustErrorXref.set("OCI-22165", [ERR_INVALID_COLL_INDEX_SET, /index \[([0-9]+)\] must be in the range of \[([0-9]+)\] to \[([0-9]+)\]/]);
@@ -275,6 +290,7 @@ adjustErrorXref.set("ORA-12570", ERR_CONNECTION_CLOSED);
275
290
  adjustErrorXref.set("ORA-12583", ERR_CONNECTION_CLOSED);
276
291
  adjustErrorXref.set("ORA-27146", ERR_CONNECTION_CLOSED);
277
292
  adjustErrorXref.set("ORA-28511", ERR_CONNECTION_CLOSED);
293
+ adjustErrorXref.set("ORA-29970", ERR_INVALID_SUBSCR);
278
294
  adjustErrorXref.set("ORA-56600", ERR_CONNECTION_CLOSED);
279
295
  adjustErrorXref.set("ORA-24315", ERR_APP_CONTEXT_EMPTY_NAMESPACE);
280
296
  adjustErrorXref.set("ORA-24338", ERR_INVALID_REF_CURSOR);
@@ -283,6 +299,7 @@ adjustErrorXref.set("ORA-24344", WRN_COMPILATION_CREATE);
283
299
  adjustErrorXref.set("ORA-26202", ERR_SESSIONLESS_INACTIVE);
284
300
  adjustErrorXref.set("ORA-26211", ERR_SESSIONLESS_DIFFERING_METHODS);
285
301
  adjustErrorXref.set("ORA-26216", ERR_SESSIONLESS_ALREADY_ACTIVE);
302
+ adjustErrorXref.set("ORA-24562", ERR_TXN_PRIORITY_NOT_SUPPORTED);
286
303
  adjustErrorXref.set("DPI-1071", ERR_PAYLOAD_CANNOT_BE_ENQUEUED);
287
304
 
288
305
  // define mapping for error messages
@@ -534,19 +551,19 @@ messages.set(ERR_OPERATION_ONLY_SUPPORTED_ON_BFILE, // NJS-156
534
551
  messages.set(ERR_EXECMANY_NOT_ALLOWED_ON_QUERIES, // NJS-157
535
552
  'executeMany() cannot be used with SELECT statement or WITH SQL clause');
536
553
  messages.set(ERR_VECTOR_SPARSE_INDICES_IS_NOT_ARRAY, // NJS-158
537
- 'SPARSE VECTOR indices is not Uint32Array or an Array');
554
+ 'SPARSE VECTOR indices must be of type Uint32Array or a regular JavaScript array');
538
555
  messages.set(ERR_VECTOR_SPARSE_VALUES_IS_NOT_ARRAY, // NJS-159
539
- 'SPARSE VECTOR values is not an Array');
556
+ 'SPARSE VECTOR values is not an array');
540
557
  messages.set(ERR_VECTOR_SPARSE_DIMS_IS_NOT_INTEGER, // NJS-160
541
- 'SPARSE VECTOR dimensions is not an Positive Integer');
558
+ 'SPARSE VECTOR dimensions must be a positive integer value');
542
559
  messages.set(ERR_VECTOR_SPARSE_INDICES_VALUES_NOT_EQUAL, // NJS-161
543
560
  'SPARSE VECTOR indices and values must be of same length');
544
561
  messages.set(ERR_VECTOR_SPARSE_INVALID_JSON, // NJS-162
545
562
  'SPARSE VECTOR string data is not valid JSON');
546
563
  messages.set(ERR_VECTOR_SPARSE_INVALID_STRING, // NJS-163
547
- 'SPARSE VECTOR string data Array should have exactly 3 elements');
564
+ 'SPARSE VECTOR string data array should have exactly 3 elements');
548
565
  messages.set(ERR_VECTOR_SPARSE_INVALID_INPUT, // NJS-164
549
- 'SPARSE VECTOR Invalid Input Data');
566
+ 'SPARSE VECTOR: Invalid input data');
550
567
  messages.set(ERR_VECTOR_SPARSE_INDICES_ELEM_IS_NOT_VALID, // NJS-165
551
568
  'SPARSE VECTOR indices element at index %d is not valid');
552
569
  messages.set(ERR_DB_FETCH_TYPE_HANDLER_CONVERTER, // NJS-166
@@ -603,6 +620,26 @@ messages.set(ERR_UNSUPPORTED_DEEP_DATA_SECURITY_FEATURE, // NJS-191
603
620
  'database version does not support the Oracle Deep Data Security feature');
604
621
  messages.set(ERR_CHAR_CS_NOT_SUPPORTED, // NJS-192
605
622
  'Character set id %d is not supported by node-oracledb in Thin mode');
623
+ messages.set(ERR_INVALID_PROPERTY_LENGTH, // NJS-193
624
+ 'The length of the parameter %s exceeds the maximum allowed length of %d');
625
+ messages.set(ERR_UNSUPPORTED_JSON_VALUE_TYPE, // NJS-194
626
+ 'Unsupported JavaScript type "%s" in JSON value');
627
+ messages.set(ERR_NON_FINITE_JSON_NUMBER, // NJS-195
628
+ 'Non-finite numbers are not supported in JSON value');
629
+ messages.set(ERR_UNSUPPORTED_JSON_FIELD_NAME, // NJS-196
630
+ 'Unsupported JSON field name "%s"');
631
+ messages.set(ERR_UNSUPPORTED_DB_OTEL_FEATURE, // NJS-197
632
+ 'The current database version does not support Oracle Database OpenTelemetry tracing');
633
+ messages.set(ERR_END_USER_SECURITY_CONTEXT_PROVIDER, // NJS-198
634
+ 'end user security context provider failed');
635
+ messages.set(ERR_INVALID_SECURITY_CONTEXT_METADATA, // NJS-199
636
+ 'runWithContext() expects a non-null metadata object');
637
+ messages.set(ERR_INVALID_SECURITY_CONTEXT_CALLBACK, // NJS-200
638
+ 'runWithContext() expects a function callback');
639
+ messages.set(ERR_TIMESTAMP_LTZ_REGION_NOT_SUPPORTED, // NJS-201
640
+ 'TIMESTAMP WITH LOCAL TIME ZONE is not supported in Thin mode when DBTIMEZONE is a region: %s. Use a fixed-offset DBTIMEZONE, such as +00:00, to use this type in Thin mode.');
641
+ messages.set(ERR_CONFLICTING_SECURITY_CONTEXT_IDENTITIES, // NJS-202
642
+ 'runWithContext() metadata cannot combine endUserToken with endUserName or key');
606
643
 
607
644
  // Oracle Net layer errors
608
645
 
@@ -670,6 +707,10 @@ messages.set(ERR_CONFIG_PROVIDER_PARAM_TYPE, // NJS-535
670
707
  'Parameter does not have a valid type: %s\n');
671
708
  messages.set(ERR_TOO_MANY_REDIRECTS, // NJS-536
672
709
  'Too many connect redirects (limit: %d)');
710
+ messages.set(ERR_TXN_PRIORITY_NOT_SUPPORTED, // NJS-537
711
+ 'Server does not support changing the transaction priority.');
712
+ messages.set(ERR_INVALID_TXN_PRIORITY, // NJS-538
713
+ 'Invalid value for parameter txnPriority.');
673
714
  messages.set(WRN_COMPILATION_CREATE, // NJS-700
674
715
  'creation succeeded with compilation errors');
675
716
 
@@ -793,6 +834,21 @@ function assertParamValue(condition, parameterNum) {
793
834
  assert(condition, ERR_INVALID_PARAMETER_VALUE, parameterNum);
794
835
  }
795
836
 
837
+ //-----------------------------------------------------------------------------
838
+ // assertPropLength()
839
+ //
840
+ // Asserts that the property value is of specified type and doesn't exceed
841
+ // maximum specified length
842
+ //-----------------------------------------------------------------------------
843
+ function assertPropLength(value, propType, propMaxLength, propName) {
844
+ if (propType !== 'array')
845
+ assertPropValue(typeof value === propType, propName);
846
+ else
847
+ assertPropValue(Array.isArray(value), propName);
848
+ assert(value.length <= propMaxLength, ERR_INVALID_PROPERTY_LENGTH, propName,
849
+ propMaxLength);
850
+ }
851
+
796
852
  //-----------------------------------------------------------------------------
797
853
  // assertPropValue()
798
854
  //
@@ -802,6 +858,21 @@ function assertPropValue(condition, propName) {
802
858
  assert(condition, ERR_INVALID_PROPERTY_VALUE, propName);
803
859
  }
804
860
 
861
+ //-----------------------------------------------------------------------------
862
+ // assertTxnPriority()
863
+ //
864
+ // Asserts that the transaction priority is a supported value.
865
+ //-----------------------------------------------------------------------------
866
+ function assertTxnPriority(value) {
867
+ assert(typeof value === 'string', ERR_INVALID_TXN_PRIORITY);
868
+ const normalizedValue = value.toUpperCase();
869
+ assert(normalizedValue === constants.TXN_PRIORITY_HIGH ||
870
+ normalizedValue === constants.TXN_PRIORITY_MEDIUM ||
871
+ normalizedValue === constants.TXN_PRIORITY_LOW ||
872
+ normalizedValue === constants.TXN_PRIORITY_DEFAULT,
873
+ ERR_INVALID_TXN_PRIORITY);
874
+ }
875
+
805
876
  //-----------------------------------------------------------------------------
806
877
  // getErr()
807
878
  //
@@ -816,6 +887,9 @@ function getErr(errorNum) {
816
887
  errorNum = ERR_INVALID_ERR_NUM;
817
888
  baseText = messages.get(errorNum);
818
889
  }
890
+ if (errorNum === ERR_INVALID_PACKET && args.length > 1) {
891
+ baseText += '. Cause: %s';
892
+ }
819
893
  const errorNumStr = errorNum.toString().padStart(3, '0');
820
894
  const code = `${ERR_PREFIX}-${errorNumStr}`;
821
895
  args[0] = `${code}: ${baseText}`;
@@ -1106,6 +1180,17 @@ module.exports = {
1106
1180
  ERR_PIPELINE_EXEC_OPTION_NOT_SUPPORTED,
1107
1181
  ERR_INVALID_SQL_NAME,
1108
1182
  ERR_CHAR_CS_NOT_SUPPORTED,
1183
+ ERR_UNSUPPORTED_JSON_VALUE_TYPE,
1184
+ ERR_NON_FINITE_JSON_NUMBER,
1185
+ ERR_UNSUPPORTED_JSON_FIELD_NAME,
1186
+ ERR_UNSUPPORTED_DB_OTEL_FEATURE,
1187
+ ERR_TXN_PRIORITY_NOT_SUPPORTED,
1188
+ ERR_INVALID_TXN_PRIORITY,
1189
+ ERR_END_USER_SECURITY_CONTEXT_PROVIDER,
1190
+ ERR_INVALID_SECURITY_CONTEXT_METADATA,
1191
+ ERR_INVALID_SECURITY_CONTEXT_CALLBACK,
1192
+ ERR_TIMESTAMP_LTZ_REGION_NOT_SUPPORTED,
1193
+ ERR_CONFLICTING_SECURITY_CONTEXT_IDENTITIES,
1109
1194
  WRN_COMPILATION_CREATE,
1110
1195
  assert,
1111
1196
  assertArgCount,
@@ -1117,7 +1202,9 @@ module.exports = {
1117
1202
  assertParamPropUnsignedIntNonZero,
1118
1203
  assertParamPropValue,
1119
1204
  assertParamValue,
1205
+ assertPropLength,
1120
1206
  assertPropValue,
1207
+ assertTxnPriority,
1121
1208
  getErr,
1122
1209
  throwErr,
1123
1210
  throwErrWithORAError,
@@ -238,6 +238,15 @@ class ConnectionImpl {
238
238
  errors.throwNotImplemented("getting current schema");
239
239
  }
240
240
 
241
+ //---------------------------------------------------------------------------
242
+ // getDatabaseOpenTelemetryTracing()
243
+ //
244
+ // Returns the database OpenTelemetry trace propagation flag.
245
+ //---------------------------------------------------------------------------
246
+ getDatabaseOpenTelemetryTracing() {
247
+ errors.throwNotImplemented("getting database OpenTelemetry trace propagation");
248
+ }
249
+
241
250
  //---------------------------------------------------------------------------
242
251
  // getDbDomain()
243
252
  //
@@ -430,6 +439,15 @@ class ConnectionImpl {
430
439
  errors.throwNotImplemented("getting information about warning");
431
440
  }
432
441
 
442
+ //---------------------------------------------------------------------------
443
+ // getTxnPriority()
444
+ //
445
+ // Returns the transaction priority associated with the connection.
446
+ //---------------------------------------------------------------------------
447
+ getTxnPriority() {
448
+ errors.throwNotImplemented("getting transaction priority");
449
+ }
450
+
433
451
  //---------------------------------------------------------------------------
434
452
  // isHealthy()
435
453
  //
@@ -515,6 +533,15 @@ class ConnectionImpl {
515
533
  errors.throwNotImplemented("setting end-to-end attribute 'dbOp'");
516
534
  }
517
535
 
536
+ //---------------------------------------------------------------------------
537
+ // setDatabaseOpenTelemetryTracing()
538
+ //
539
+ // Sets the database OpenTelemetry trace propagation flag.
540
+ //---------------------------------------------------------------------------
541
+ setDatabaseOpenTelemetryTracing() {
542
+ errors.throwNotImplemented("setting database OpenTelemetry trace propagation");
543
+ }
544
+
518
545
  //---------------------------------------------------------------------------
519
546
  // setECID()
520
547
  //
@@ -587,6 +614,15 @@ class ConnectionImpl {
587
614
  errors.throwNotImplemented("setting the tag for the connection");
588
615
  }
589
616
 
617
+ //---------------------------------------------------------------------------
618
+ // setTxnPriority()
619
+ //
620
+ // Sets the transaction priority associated with the connection.
621
+ //---------------------------------------------------------------------------
622
+ setTxnPriority() {
623
+ errors.throwNotImplemented("setting transaction priority");
624
+ }
625
+
590
626
  //---------------------------------------------------------------------------
591
627
  // shutdown()
592
628
  //
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2025, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2026, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -44,7 +44,7 @@ class BaseBuffer {
44
44
  // The initializer is either an integer specifying the size of the buffer, or
45
45
  // an existing Buffer, which is used directly.
46
46
  //---------------------------------------------------------------------------
47
- constructor(initializer) {
47
+ constructor(initializer, caps) {
48
48
  if (typeof initializer === 'number') {
49
49
  this.buf = Buffer.alloc(initializer);
50
50
  this.size = 0;
@@ -54,6 +54,7 @@ class BaseBuffer {
54
54
  this.size = this.maxSize = initializer.length;
55
55
  }
56
56
  this.pos = 0;
57
+ this.caps = caps;
57
58
  }
58
59
 
59
60
  //---------------------------------------------------------------------------
@@ -84,29 +85,42 @@ class BaseBuffer {
84
85
  // Read an integer from the buffer of the specified maximum size and returns
85
86
  // it. The signed flag indicates whether the value is allowed to be signed or
86
87
  // not and the skip flag indicates whether the data should simply be skipped.
88
+ // The asBigInt flag indicates whether the value should be returned as a
89
+ // BigInt instead of a Number.
87
90
  //---------------------------------------------------------------------------
88
- _readInteger(maxSize, signed, skip) {
91
+ _readInteger(maxSize, signed, skip, asBigInt = false) {
89
92
  let isNegative = false;
90
93
  let size = this.readUInt8();
91
94
  if (size === 0) {
92
- return 0;
95
+ return asBigInt ? 0n : 0;
93
96
  } else if (size & 0x80) {
94
97
  if (!signed) {
95
- errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER, this.pos, this.packetNum);
98
+ errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER, this.pos,
99
+ this.packetNum);
96
100
  }
97
101
  isNegative = true;
98
102
  size = size & 0x7f;
99
103
  }
100
104
  if (size > maxSize) {
101
- errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize, this.pos, this.packetNum);
105
+ errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize, this.pos,
106
+ this.packetNum);
102
107
  }
103
108
  if (skip) {
104
109
  this.skipBytes(size);
110
+ return;
111
+ }
112
+
113
+ const buf = this.readBytes(size);
114
+ let value;
115
+ if (asBigInt) {
116
+ value = 0n;
117
+ for (const byte of buf) {
118
+ value = (value << 8n) | BigInt(byte);
119
+ }
105
120
  } else {
106
- const buf = this.readBytes(size);
107
- const value = buf.readUIntBE(0, size);
108
- return (isNegative) ? -value : value;
121
+ value = buf.readUIntBE(0, size);
109
122
  }
123
+ return isNegative ? -value : value;
110
124
  }
111
125
 
112
126
  //---------------------------------------------------------------------------
@@ -175,17 +189,22 @@ class BaseBuffer {
175
189
  // assumed at this point that the size of the buffer is either 7 bytes (date
176
190
  // or compressed timestamp), 11 bytes (timestamp) or 13 bytes (timestamp with
177
191
  // time zone). Time zone information is discarded because Node.js uses UTC
178
- // timestamps and the server returns the data in that format, too. The Date
179
- // type in Node.js doesn't support time zone information.
192
+ // timestamps. TIMESTAMP WITH LOCAL TIME ZONE is returned in the database
193
+ // time zone and needs its offset to produce the original UTC instant.
180
194
  //---------------------------------------------------------------------------
181
- parseOracleDate(buf, useLocalTime = true) {
195
+ parseOracleDate(buf, useLocalTime = true, useDbTz = false) {
182
196
  let fseconds = 0;
183
197
  if (buf.length >= 11) {
184
198
  fseconds = Math.floor(buf.readUInt32BE(7) / (1000 * 1000));
185
199
  }
186
200
  const year = (buf[0] - 100) * 100 + buf[1] - 100;
201
+ if (useDbTz && this.caps?.dbTzRegion) {
202
+ errors.throwErr(errors.ERR_TIMESTAMP_LTZ_REGION_NOT_SUPPORTED,
203
+ this.caps.dbTzRegion);
204
+ }
205
+ const offset = useDbTz ? this.caps?.dbTzOffset ?? 0 : 0;
187
206
  return nodbUtil.makeDate(useLocalTime, year, buf[2], buf[3], buf[4] - 1,
188
- buf[5] - 1, buf[6] - 1, fseconds, 0);
207
+ buf[5] - 1, buf[6] - 1, fseconds, offset);
189
208
  }
190
209
 
191
210
  //---------------------------------------------------------------------------
@@ -475,12 +494,12 @@ class BaseBuffer {
475
494
  // Reads an Oracle date from the buffer and returns a Date or a String,
476
495
  // depending on the desired type.
477
496
  //---------------------------------------------------------------------------
478
- readOracleDate(useLocalTime) {
497
+ readOracleDate(useLocalTime, useDbTz = false) {
479
498
  const buf = this.readBytesWithLength();
480
499
  if (!buf) {
481
500
  return null;
482
501
  }
483
- return this.parseOracleDate(buf, useLocalTime);
502
+ return this.parseOracleDate(buf, useLocalTime, useDbTz);
484
503
  }
485
504
 
486
505
  //---------------------------------------------------------------------------
@@ -609,6 +628,17 @@ class BaseBuffer {
609
628
  return this._readInteger(8, false, false);
610
629
  }
611
630
 
631
+ //---------------------------------------------------------------------------
632
+ // readUB8BigInt()
633
+ //
634
+ // Reads an unsigned, variable length integer of up to 8 bytes in length as
635
+ // a BigInt. This preserves values that cannot safely be represented by a
636
+ // JavaScript Number.
637
+ //---------------------------------------------------------------------------
638
+ readUB8BigInt() {
639
+ return this._readInteger(8, false, false, true);
640
+ }
641
+
612
642
  //---------------------------------------------------------------------------
613
643
  // readUInt8()
614
644
  //
@@ -856,6 +886,16 @@ class BaseBuffer {
856
886
  writeOracleDate(date, type, writeLength = true) {
857
887
  let fsec;
858
888
  let length = type._bufferSizeFactor;
889
+ if (type === types.DB_TYPE_TIMESTAMP_LTZ) {
890
+ if (this.caps?.dbTzRegion) {
891
+ errors.throwErr(errors.ERR_TIMESTAMP_LTZ_REGION_NOT_SUPPORTED,
892
+ this.caps.dbTzRegion);
893
+ }
894
+ const offset = this.caps?.dbTzOffset;
895
+ if (offset !== null && offset !== undefined) {
896
+ date = new Date(date.getTime() + offset * 60000);
897
+ }
898
+ }
859
899
  if (length > 7) {
860
900
  fsec = date.getUTCMilliseconds() * 1000 * 1000;
861
901
  if (fsec === 0 && length <= 11)
@@ -1123,6 +1163,29 @@ class BaseBuffer {
1123
1163
  }
1124
1164
  }
1125
1165
 
1166
+ //---------------------------------------------------------------------------
1167
+ // writeUB8BigInt()
1168
+ //
1169
+ // Writes an unsigned BigInt in variable length format, up to eight bytes.
1170
+ //---------------------------------------------------------------------------
1171
+ writeUB8BigInt(value) {
1172
+ if (value === 0n) {
1173
+ this.writeUInt8(0);
1174
+ } else if (value <= 0xffn) {
1175
+ this.writeUInt8(1);
1176
+ this.writeUInt8(Number(value));
1177
+ } else if (value <= 0xffffn) {
1178
+ this.writeUInt8(2);
1179
+ this.writeUInt16BE(Number(value));
1180
+ } else if (value <= 0xffffffffn) {
1181
+ this.writeUInt8(4);
1182
+ this.writeUInt32BE(Number(value));
1183
+ } else {
1184
+ this.writeUInt8(8);
1185
+ this.writeBigUInt64BE(value);
1186
+ }
1187
+ }
1188
+
1126
1189
  //---------------------------------------------------------------------------
1127
1190
  // writeUInt8()
1128
1191
  //
@@ -1175,6 +1238,16 @@ class BaseBuffer {
1175
1238
  this.buf.writeUInt32BE(n, pos + 4);
1176
1239
  }
1177
1240
 
1241
+ //---------------------------------------------------------------------------
1242
+ // writeBigUInt64BE()
1243
+ //
1244
+ // Writes an unsigned BigInt value up to 64 bits in big endian order.
1245
+ //---------------------------------------------------------------------------
1246
+ writeBigUInt64BE(n) {
1247
+ const pos = this.reserveBytes(8);
1248
+ this.buf.writeBigUInt64BE(n, pos);
1249
+ }
1250
+
1178
1251
  //---------------------------------------------------------------------------
1179
1252
  // writeUInt16LE()
1180
1253
  //
@@ -1194,11 +1267,11 @@ class GrowableBuffer extends BaseBuffer {
1194
1267
  //
1195
1268
  // Initializes the buffer with an initial fixed chunk size.
1196
1269
  //---------------------------------------------------------------------------
1197
- constructor(initializer) {
1270
+ constructor(initializer, caps) {
1198
1271
  if (initializer) {
1199
- super(initializer);
1272
+ super(initializer, caps);
1200
1273
  } else {
1201
- super(constants.BUFFER_CHUNK_SIZE);
1274
+ super(constants.BUFFER_CHUNK_SIZE, caps);
1202
1275
  this.size = this.maxSize;
1203
1276
  }
1204
1277
  }
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2023, 2025, Oracle and/or its affiliates.
1
+ // Copyright (c) 2023, 2026, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -754,7 +754,8 @@ class OsonEncoder extends GrowableBuffer {
754
754
  this.maxFieldNameSize = maxFieldNameSize;
755
755
 
756
756
  // determine the flags to use
757
- let flags = constants.TNS_JSON_FLAG_INLINE_LEAF;
757
+ let flags = constants.TNS_JSON_FLAG_INLINE_LEAF |
758
+ constants.TNS_JSON_FLAG_LEN_IN_PCODE;
758
759
  if (Array.isArray(value) || (value && Array.isArray(value.fields))) {
759
760
  // examine all values recursively to determine the unique set of field
760
761
  // names and whether they need to be added to the long field names
@@ -81,8 +81,8 @@ const CONNECT_OVERRIDES = [
81
81
 
82
82
  // SECURITY parameters
83
83
  { opt: 'walletLocation', section: ['DESCRIPTION', 'SECURITY', 'MY_WALLET_DIRECTORY'] },
84
- { opt: 'sslServerCertDn', section: ['DESCRIPTION', 'SECURITY', 'SSL_SERVER_CERT_DN'] },
85
- { opt: 'sslServerDnMatch', section: ['DESCRIPTION', 'SECURITY', 'SSL_SERVER_DN_MATCH'] },
84
+ { opt: 'sslServerCertDN', section: ['DESCRIPTION', 'SECURITY', 'SSL_SERVER_CERT_DN'] },
85
+ { opt: 'sslServerDNMatch', section: ['DESCRIPTION', 'SECURITY', 'SSL_SERVER_DN_MATCH'] },
86
86
 
87
87
  // ADDRESS parameters
88
88
  { opt: 'httpsProxy', section: ['DESCRIPTION', 'ADDRESS', 'HTTPS_PROXY'], perAddress: true },
@@ -297,6 +297,10 @@ async function applyConnectStringOverrides(options) {
297
297
  if (raw === undefined) {
298
298
  continue;
299
299
  }
300
+ // Treat walletLocation=SYSTEM as "use system certs" -> do not inject into descriptor
301
+ if (def.opt === 'walletLocation' && typeof raw === 'string' && raw.trim().toUpperCase() === 'SYSTEM') {
302
+ continue;
303
+ }
300
304
  const formatter = def.fmt || (v => v);
301
305
  const value = formatter(raw);
302
306
  configured.push({ def, value });
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2025, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2026, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -200,6 +200,17 @@ class ResultSetImpl extends BaseImpl {
200
200
  return this._parentObj;
201
201
  }
202
202
 
203
+ //---------------------------------------------------------------------------
204
+ // _getDbObjectType()
205
+ //
206
+ // Return the object identifying the object type. These are cached by fully
207
+ // qualified name and by OID (thin mode only).
208
+ //---------------------------------------------------------------------------
209
+ _getDbObjectType(schema, name, packageName, oid) {
210
+ return this._getConnImpl()._getDbObjectType(schema, name, packageName,
211
+ oid);
212
+ }
213
+
203
214
  //---------------------------------------------------------------------------
204
215
  // _setup()
205
216
  //
@@ -210,7 +221,7 @@ class ResultSetImpl extends BaseImpl {
210
221
  //---------------------------------------------------------------------------
211
222
  _setup(options, metaData) {
212
223
  this._parentObj = options.connection._impl;
213
- this.metaData = metaData;
224
+ this.metaData = [];
214
225
  this.lobIndices = [];
215
226
  this.dbObjectIndices = [];
216
227
  this.nestedCursorIndices = [];
@@ -227,13 +238,23 @@ class ResultSetImpl extends BaseImpl {
227
238
  }
228
239
  }
229
240
  for (let i = 0; i < metaData.length; i++) {
230
- const info = metaData[i];
231
- if (info.dbTypeClass) {
232
- const cls = options.connection._getDbObjectClass(info.dbTypeClass);
233
- info.dbTypeClass = cls;
241
+ const fetchInfo = metaData[i];
242
+ if (fetchInfo.dbTypeClass) {
243
+ const cls = options.connection._getDbObjectClass(fetchInfo.dbTypeClass);
244
+ fetchInfo.dbTypeClass = cls;
234
245
  }
235
- nodbUtil.addTypeProperties(info, "dbType");
246
+ nodbUtil.addTypeProperties(fetchInfo, "dbType");
247
+
248
+ // Use a per-resultset metadata copy so any fetchTypeHandler or
249
+ // resultset-specific metadata mutations (for example renaming columns)
250
+ // do not leak back into the underlying statement metadata.
251
+ // This is also applied in thick mode for consistency, even though the
252
+ // extra copy is only needed to protect the thin-mode cached metadata.
253
+ const info = {...fetchInfo};
254
+ this.metaData.push(info);
236
255
  this._determineFetchType(info, options, metaData);
256
+ fetchInfo.fetchType = info.fetchType;
257
+ fetchInfo.converter = info.converter;
237
258
  if (info.fetchType === types.DB_TYPE_CURSOR) {
238
259
  this.nestedCursorIndices.push(i);
239
260
  } else if (info.fetchType === types.DB_TYPE_CLOB ||
@@ -281,7 +302,9 @@ class ResultSetImpl extends BaseImpl {
281
302
  //---------------------------------------------------------------------------
282
303
  // _getAllRows() [INTERNAL]
283
304
  //
284
- // Fetches all the rows from the database to use internally.
305
+ // Fetches all the rows from the database to use internally. getRows()
306
+ // already materializes and consumes each batch, so this method only
307
+ // accumulates the returned rows.
285
308
  //---------------------------------------------------------------------------
286
309
  async _getAllRows() {
287
310
  const fetchArraySize = 100;
@@ -290,10 +313,8 @@ class ResultSetImpl extends BaseImpl {
290
313
  while (true) {
291
314
  // constant default value for fetchArraySize
292
315
  const rows = await this.getRows(fetchArraySize, {});
293
- if (rows) {
294
- await this._processRows(rows, false);
316
+ if (rows)
295
317
  rowsFetched = rowsFetched.concat(rows);
296
- }
297
318
  if (rows.length < fetchArraySize) {
298
319
  break;
299
320
  }