oracledb 6.3.0 → 6.5.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 (71) hide show
  1. package/LICENSE.txt +1 -1
  2. package/NOTICE.txt +1 -1
  3. package/README.md +3 -3
  4. package/build/Release/oracledb-6.5.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.5.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.5.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.5.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.5.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.5.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.5.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.5.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.5.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/README.md +3 -0
  14. package/lib/aqQueue.js +8 -8
  15. package/lib/connection.js +65 -22
  16. package/lib/constants.js +7 -1
  17. package/lib/dbObject.js +72 -1
  18. package/lib/errors.js +51 -10
  19. package/lib/impl/connection.js +2 -1
  20. package/lib/{thin/protocol → impl/datahandlers}/buffer.js +36 -32
  21. package/lib/impl/datahandlers/constants.js +106 -0
  22. package/lib/{thin/protocol → impl/datahandlers}/oson.js +320 -151
  23. package/lib/impl/datahandlers/vector.js +137 -0
  24. package/lib/impl/pool.js +9 -0
  25. package/lib/impl/resultset.js +34 -17
  26. package/lib/lob.js +22 -6
  27. package/lib/oracledb.js +35 -1
  28. package/lib/pool.js +17 -2
  29. package/lib/poolStatistics.js +3 -1
  30. package/lib/settings.js +31 -6
  31. package/lib/sodaDocCursor.js +14 -1
  32. package/lib/thin/connection.js +120 -193
  33. package/lib/thin/dbObject.js +4 -2
  34. package/lib/thin/lob.js +6 -6
  35. package/lib/thin/pool.js +84 -10
  36. package/lib/thin/protocol/capabilities.js +20 -6
  37. package/lib/thin/protocol/constants.js +34 -54
  38. package/lib/thin/protocol/messages/auth.js +2 -2
  39. package/lib/thin/protocol/messages/base.js +28 -27
  40. package/lib/thin/protocol/messages/dataType.js +4 -2
  41. package/lib/thin/protocol/messages/execute.js +5 -1
  42. package/lib/thin/protocol/messages/{connectionCookie.js → fastAuth.js} +18 -16
  43. package/lib/thin/protocol/messages/fetch.js +4 -0
  44. package/lib/thin/protocol/messages/index.js +2 -2
  45. package/lib/thin/protocol/messages/protocol.js +9 -1
  46. package/lib/thin/protocol/messages/withData.js +40 -11
  47. package/lib/thin/protocol/packet.js +93 -8
  48. package/lib/thin/protocol/protocol.js +10 -5
  49. package/lib/thin/protocol/utils.js +11 -18
  50. package/lib/thin/sqlnet/constants.js +5 -2
  51. package/lib/thin/sqlnet/ezConnectResolver.js +9 -5
  52. package/lib/thin/sqlnet/navNodes.js +4 -3
  53. package/lib/thin/sqlnet/networkSession.js +27 -4
  54. package/lib/thin/sqlnet/packet.js +2 -5
  55. package/lib/thin/statement.js +43 -7
  56. package/lib/thin/statementCache.js +190 -0
  57. package/lib/thin/util.js +2 -2
  58. package/lib/transformer.js +21 -6
  59. package/lib/types.js +21 -3
  60. package/lib/util.js +30 -1
  61. package/lib/version.js +2 -2
  62. package/package.json +1 -1
  63. package/build/Release/oracledb-6.3.0-darwin-x64.node +0 -0
  64. package/build/Release/oracledb-6.3.0-darwin-x64.node-buildinfo.txt +0 -1
  65. package/build/Release/oracledb-6.3.0-js-buildinfo.txt +0 -1
  66. package/build/Release/oracledb-6.3.0-linux-arm64.node +0 -0
  67. package/build/Release/oracledb-6.3.0-linux-arm64.node-buildinfo.txt +0 -1
  68. package/build/Release/oracledb-6.3.0-linux-x64.node +0 -0
  69. package/build/Release/oracledb-6.3.0-linux-x64.node-buildinfo.txt +0 -1
  70. package/build/Release/oracledb-6.3.0-win32-x64.node +0 -0
  71. package/build/Release/oracledb-6.3.0-win32-x64.node-buildinfo.txt +0 -1
package/lib/thin/pool.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -53,6 +53,7 @@ class ThinPoolImpl extends PoolImpl {
53
53
  this._poolIncrement = params.poolIncrement;
54
54
  this._poolTimeout = params.poolTimeout;
55
55
  this._poolPingInterval = params.poolPingInterval;
56
+ this._poolPingTimeout = params.poolPingTimeout;
56
57
  this._stmtCacheSize = params.stmtCacheSize;
57
58
 
58
59
  // The user Config filterd from common layer is cached except
@@ -104,6 +105,7 @@ class ThinPoolImpl extends PoolImpl {
104
105
  this._accessTokenFn = params.accessTokenFn;
105
106
  this._accessTokenConfig = params.accessTokenConfig;
106
107
  this._isDRCPEnabled = false;
108
+ this._implicitPool = null;
107
109
  this.eventEmitter = new EventEmitter();
108
110
  // listener to remove dead or idle connections
109
111
  this.eventEmitter.on('_removePoolConnection', async (connImpl) => {
@@ -318,6 +320,13 @@ class ThinPoolImpl extends PoolImpl {
318
320
  return this._poolPingInterval;
319
321
  }
320
322
 
323
+ //---------------------------------------------------------------------------
324
+ // returns the pool ping Timeout (milliseconds)
325
+ //---------------------------------------------------------------------------
326
+ getPoolPingTimeout() {
327
+ return this._poolPingTimeout;
328
+ }
329
+
321
330
  //---------------------------------------------------------------------------
322
331
  // returns the pool timeout
323
332
  //---------------------------------------------------------------------------
@@ -363,13 +372,13 @@ class ThinPoolImpl extends PoolImpl {
363
372
  _scanIdleConnection() {
364
373
  while ((this._usedConnectionList.size + this._freeConnectionList.length) >
365
374
  this._poolMin && this._freeConnectionList.length > 0) {
366
- const conn = this._freeConnectionList[this._freeConnectionList.length - 1];
375
+ const conn = this._freeConnectionList[0];
367
376
  if (Date.now() - conn._lastTimeUsed < this._poolTimeout * 1000) {
368
377
  break;
369
378
  }
370
379
 
371
380
  this.eventEmitter.emit('_removePoolConnection', conn);
372
- this._freeConnectionList.pop();
381
+ this._freeConnectionList.shift();
373
382
  }
374
383
 
375
384
  this._schedulerJob = null;
@@ -377,11 +386,11 @@ class ThinPoolImpl extends PoolImpl {
377
386
  }
378
387
 
379
388
  //---------------------------------------------------------------------------
380
- // _getNumConns()
389
+ // _getNumConnsToCreate()
381
390
  //
382
391
  // get number of connections need to be created
383
392
  //---------------------------------------------------------------------------
384
- _getNumConns() {
393
+ _getNumConnsToCreate() {
385
394
  const usedConns = this._freeConnectionList.length + this._usedConnectionList.size;
386
395
  // less connections in the pool than poolMin? restore to poolMin
387
396
  if (usedConns < this._poolMin) {
@@ -407,11 +416,19 @@ class ThinPoolImpl extends PoolImpl {
407
416
 
408
417
  // continue until a close request is received
409
418
  while (!this._poolCloseWaiter) {
410
- // get count for connections to be created
411
- const numConns = this._getNumConns();
419
+ // eliminate connections that exceed the poolMax (this should only happen
420
+ // after a reconfiguration has taken place where the maximum number of
421
+ // connections is reduced)
422
+ let numToDestroy = this._poolMax - this.getConnectionsOpen();
423
+ while (numToDestroy > 0 && this._freeConnectionList.length > 0) {
424
+ const connToBeRemoved = this._freeConnectionList.shift();
425
+ this.eventEmitter.emit('_removePoolConnection', connToBeRemoved);
426
+ numToDestroy--;
427
+ }
412
428
 
429
+ const numToCreate = this._getNumConnsToCreate();
413
430
  // connection creation is going on serially and not concurrently
414
- for (let i = 0; i < numConns; i++) {
431
+ for (let i = 0; i < numToCreate; i++) {
415
432
  try {
416
433
  // get deobfuscated value
417
434
  const config = await this._getConnAttrs();
@@ -495,11 +512,21 @@ class ThinPoolImpl extends PoolImpl {
495
512
  requiresPing = true;
496
513
  }
497
514
  if (requiresPing) {
515
+ let pingTimer;
498
516
  try {
517
+ if (this._poolPingTimeout) {
518
+ pingTimer = setTimeout(() => {
519
+ // force disconnect causes ping task to unblock
520
+ // and return.
521
+ conn.nscon.forceDisconnect();
522
+ }, this._poolPingTimeout);
523
+ }
499
524
  await conn.ping();
500
525
  } catch {
501
- this.eventEmitter.emit('_removePoolConnection', conn);
526
+ conn.nscon.forceDisconnect();
502
527
  continue;
528
+ } finally {
529
+ clearTimeout(pingTimer);
503
530
  }
504
531
  }
505
532
 
@@ -546,8 +573,14 @@ class ThinPoolImpl extends PoolImpl {
546
573
  if (conn.nscon.connected) {
547
574
  conn._lastTimeUsed = Date.now();
548
575
  conn._newSession = false;
549
- this._freeConnectionList.push(conn);
576
+ if ((this._freeConnectionList.length + this._usedConnectionList.size)
577
+ < this._poolMax) {
578
+ this._freeConnectionList.push(conn);
579
+ } else {
580
+ this.eventEmitter.emit('_removePoolConnection', conn);
581
+ }
550
582
  }
583
+
551
584
  this._setScheduler();
552
585
  }
553
586
 
@@ -560,6 +593,47 @@ class ThinPoolImpl extends PoolImpl {
560
593
  this._userConfig.connectionClass = crypto.randomBytes(16).toString('base64');
561
594
  this._userConfig.connectionClass = "NJS:" + this._userConfig.connectionClass;
562
595
  }
596
+
597
+ //---------------------------------------------------------------------------
598
+ // reconfigure()
599
+ //
600
+ // Reconfigures the pool with new parameters
601
+ //---------------------------------------------------------------------------
602
+ reconfigure(params) {
603
+ if (params.poolIncrement !== undefined) {
604
+ this._poolIncrement = params.poolIncrement;
605
+ }
606
+
607
+ if (params.poolTimeout !== undefined &&
608
+ this._poolTimeout !== params.poolTimeout) {
609
+ this._poolTimeout = params.poolTimeout;
610
+ // clear scheduled job
611
+ if (this._schedulerJob) {
612
+ clearTimeout(this._schedulerJob);
613
+ this._schedulerJob = null;
614
+ }
615
+ }
616
+
617
+ if (params.poolPingInterval !== undefined) {
618
+ this._poolPingInterval = params.poolPingInterval;
619
+ }
620
+
621
+ if (params.stmtCacheSize !== undefined) {
622
+ this._stmtCacheSize = params.stmtCacheSize;
623
+ }
624
+
625
+ if (params.poolMax !== undefined) {
626
+ this._poolMax = params.poolMax;
627
+ }
628
+
629
+ if (params.poolMin !== undefined) {
630
+ this._poolMin = params.poolMin;
631
+ }
632
+
633
+ if (this.bgWaiter) {
634
+ this.bgWaiter();
635
+ }
636
+ }
563
637
  }
564
638
 
565
639
  module.exports = ThinPoolImpl;
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -36,25 +36,32 @@ const errors = require('../../errors');
36
36
  */
37
37
  class Capabilities {
38
38
 
39
- constructor(protocolVersion) {
40
- this.protocolVersion = protocolVersion;
39
+ constructor(nscon) {
40
+ this.protocolVersion = nscon.sAtts.version;
41
41
  this.ttcFieldVersion = constants.TNS_CCAP_FIELD_VERSION_MAX;
42
42
  this.supports12cLogon = true;
43
43
  this.supportsOob = false;
44
44
  this.nCharsetId = constants.TNS_CHARSET_UTF16;
45
45
  this.compileCaps = Buffer.alloc(constants.TNS_CCAP_MAX);
46
46
  this.runtimeCaps = Buffer.alloc(constants.TNS_RCAP_MAX);
47
- this.initCompileCaps();
47
+ this.initCompileCaps(nscon);
48
48
  this.initRuntimeCaps();
49
49
  this.maxStringSize = 0;
50
50
  }
51
51
 
52
- adjustForServerCompileCaps(serverCaps) {
52
+ adjustForServerCompileCaps(serverCaps, nscon) {
53
53
  if (serverCaps[constants.TNS_CCAP_FIELD_VERSION] < this.ttcFieldVersion) {
54
54
  this.ttcFieldVersion = serverCaps[constants.TNS_CCAP_FIELD_VERSION];
55
55
  this.compileCaps[constants.TNS_CCAP_FIELD_VERSION] =
56
56
  this.ttcFieldVersion;
57
57
  }
58
+ if ((this.ttcFieldVersion < constants.TNS_CCAP_FIELD_VERSION_23_4
59
+ && nscon.endOfRequestSupport)) {
60
+ // endOfRequestSupport used only from 23.4 onwards and not for 23.3
61
+ this.compileCaps[constants.TNS_CCAP_TTC4]
62
+ ^= constants.TNS_CCAP_END_OF_REQUEST;
63
+ nscon.endOfRequestSupport = false;
64
+ }
58
65
  }
59
66
 
60
67
  adjustForServerRuntimeCaps(serverCaps) {
@@ -65,7 +72,7 @@ class Capabilities {
65
72
  }
66
73
  }
67
74
 
68
- initCompileCaps() {
75
+ initCompileCaps(nscon) {
69
76
  this.compileCaps[constants.TNS_CCAP_SQL_VERSION] =
70
77
  constants.TNS_CCAP_SQL_VERSION_MAX;
71
78
  this.compileCaps[constants.TNS_CCAP_LOGON_TYPES] =
@@ -104,6 +111,13 @@ class Capabilities {
104
111
  constants.TNS_CCAP_CLIENT_FN_MAX;
105
112
  this.compileCaps[constants.TNS_CCAP_TTC4] =
106
113
  constants.TNS_CCAP_INBAND_NOTIFICATION;
114
+ if (nscon.endOfRequestSupport) {
115
+ this.compileCaps[constants.TNS_CCAP_TTC4] |= constants.TNS_CCAP_END_OF_REQUEST;
116
+ }
117
+ this.compileCaps[constants.TNS_CCAP_CTB_FEATURE_BACKPORT] =
118
+ constants.TNS_CCAP_CTB_IMPLICIT_POOL;
119
+ this.compileCaps[constants.TNS_CCAP_TTC5] =
120
+ constants.TNS_CCAP_VECTOR_SUPPORT;
107
121
  }
108
122
 
109
123
  initRuntimeCaps() {
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -28,6 +28,7 @@
28
28
 
29
29
  const { Buffer } = require('buffer');
30
30
  const constants = require('../../constants.js');
31
+ const dataHandlerConstants = require('../../impl/datahandlers/constants.js');
31
32
 
32
33
  module.exports = {
33
34
 
@@ -198,6 +199,7 @@ module.exports = {
198
199
  TNS_DATA_TYPE_UD12: 124 + 256,
199
200
  TNS_DATA_TYPE_AL8: 125 + 256,
200
201
  TNS_DATA_TYPE_LFOP: 126 + 256,
202
+ TNS_DATA_TYPE_VECTOR: 127,
201
203
  TNS_DATA_TYPE_FCRT: 127 + 256,
202
204
  TNS_DATA_TYPE_DNY: 128 + 256,
203
205
  TNS_DATA_TYPE_OPR: 129 + 256,
@@ -431,7 +433,8 @@ module.exports = {
431
433
  TNS_MSG_TYPE_ONEWAY_FN: 26,
432
434
  TNS_MSG_TYPE_IMPLICIT_RESULTSET: 27,
433
435
  TNS_MSG_TYPE_RENEGOTIATE: 28,
434
- TNS_MSG_TYPE_COOKIE: 30,
436
+ TNS_MSG_TYPE_END_OF_REQUEST: 29,
437
+ TNS_MSG_TYPE_FAST_AUTH: 34,
435
438
 
436
439
  // parameter keyword numbers,
437
440
  TNS_KEYWORD_NUM_CURRENT_SCHEMA: 168,
@@ -462,6 +465,7 @@ module.exports = {
462
465
  TNS_EXEC_OPTION_DESCRIBE: 0x20000,
463
466
  TNS_EXEC_OPTION_NO_COMPRESSED_FETCH: 0x40000,
464
467
  TNS_EXEC_OPTION_BATCH_ERRORS: 0x80000,
468
+ TNS_EXEC_OPTION_NO_IMPL_REL: 0x200000,
465
469
 
466
470
  // server side piggyback op codes
467
471
  TNS_SERVER_PIGGYBACK_QUERY_CACHE_INVALIDATION: 1,
@@ -513,42 +517,6 @@ module.exports = {
513
517
 
514
518
  // base JSON constants
515
519
  TNS_JSON_MAX_LENGTH: 32 * 1024 * 1024,
516
- TNS_JSON_MAGIC_BYTE_1: 0xff,
517
- TNS_JSON_MAGIC_BYTE_2: 0x4a, // 'J'
518
- TNS_JSON_MAGIC_BYTE_3: 0x5a, // 'Z'
519
- TNS_JSON_VERSION: 1,
520
- TNS_JSON_FLAG_HASH_ID_UINT8: 0x0100,
521
- TNS_JSON_FLAG_HASH_ID_UINT16: 0x0200,
522
- TNS_JSON_FLAG_NUM_FNAMES_UINT16: 0x0400,
523
- TNS_JSON_FLAG_FNAMES_SEG_UINT32: 0x0800,
524
- TNS_JSON_FLAG_TINY_NODES_STAT: 0x2000,
525
- TNS_JSON_FLAG_TREE_SEG_UINT32: 0x1000,
526
- TNS_JSON_FLAG_REL_OFFSET_MODE: 0x01,
527
- TNS_JSON_FLAG_INLINE_LEAF: 0x02,
528
- TNS_JSON_FLAG_LEN_IN_PCODE: 0x04,
529
- TNS_JSON_FLAG_NUM_FNAMES_UINT32: 0x08,
530
- TNS_JSON_FLAG_IS_SCALAR: 0x10,
531
-
532
- // JSON data types
533
- TNS_JSON_TYPE_NULL: 0x30,
534
- TNS_JSON_TYPE_TRUE: 0x31,
535
- TNS_JSON_TYPE_FALSE: 0x32,
536
- TNS_JSON_TYPE_STRING_LENGTH_UINT8: 0x33,
537
- TNS_JSON_TYPE_NUMBER_LENGTH_UINT8: 0x34,
538
- TNS_JSON_TYPE_BINARY_DOUBLE: 0x36,
539
- TNS_JSON_TYPE_STRING_LENGTH_UINT16: 0x37,
540
- TNS_JSON_TYPE_STRING_LENGTH_UINT32: 0x38,
541
- TNS_JSON_TYPE_TIMESTAMP: 0x39,
542
- TNS_JSON_TYPE_BINARY_LENGTH_UINT16: 0x3a,
543
- TNS_JSON_TYPE_BINARY_LENGTH_UINT32: 0x3b,
544
- TNS_JSON_TYPE_DATE: 0x3c,
545
- TNS_JSON_TYPE_INTERVAL_YM: 0x3d,
546
- TNS_JSON_TYPE_INTERVAL_DS: 0x3e,
547
- TNS_JSON_TYPE_TIMESTAMP_TZ: 0x7c,
548
- TNS_JSON_TYPE_TIMESTAMP7: 0x7d,
549
- TNS_JSON_TYPE_BINARY_FLOAT: 0x7f,
550
- TNS_JSON_TYPE_OBJECT: 0x84,
551
- TNS_JSON_TYPE_ARRAY: 0xc0,
552
520
 
553
521
  // end-to-end metrics
554
522
  TNS_END_TO_END_ACTION: 0x0010,
@@ -592,6 +560,7 @@ module.exports = {
592
560
  // compile time capability indices
593
561
  TNS_CCAP_SQL_VERSION: 0,
594
562
  TNS_CCAP_LOGON_TYPES: 4,
563
+ TNS_CCAP_CTB_FEATURE_BACKPORT: 5,
595
564
  TNS_CCAP_FIELD_VERSION: 7,
596
565
  TNS_CCAP_SERVER_DEFINE_CONV: 8,
597
566
  TNS_CCAP_TTC1: 15,
@@ -608,7 +577,8 @@ module.exports = {
608
577
  TNS_CCAP_TTC3: 37,
609
578
  TNS_CCAP_TTC4: 40,
610
579
  TNS_CCAP_LOB2: 42,
611
- TNS_CCAP_MAX: 45,
580
+ TNS_CCAP_TTC5: 44,
581
+ TNS_CCAP_MAX: 51,
612
582
 
613
583
  // compile time capability values
614
584
  TNS_CCAP_SQL_VERSION_MAX: 6,
@@ -630,7 +600,8 @@ module.exports = {
630
600
  TNS_CCAP_FIELD_VERSION_23_1_EXT_4: 21,
631
601
  TNS_CCAP_FIELD_VERSION_23_1_EXT_5: 22,
632
602
  TNS_CCAP_FIELD_VERSION_23_1_EXT_6: 23,
633
- TNS_CCAP_FIELD_VERSION_MAX: 23,
603
+ TNS_CCAP_FIELD_VERSION_23_4: 24,
604
+ TNS_CCAP_FIELD_VERSION_MAX: 24,
634
605
  TNS_CCAP_O5LOGON: 8,
635
606
  TNS_CCAP_O5LOGON_NP: 2,
636
607
  TNS_CCAP_O7LOGON: 32,
@@ -657,9 +628,12 @@ module.exports = {
657
628
  TNS_CCAP_DRCP: 0x10,
658
629
  TNS_CCAP_ZLNP: 0x04,
659
630
  TNS_CCAP_INBAND_NOTIFICATION: 0x04,
631
+ TNS_CCAP_END_OF_REQUEST: 0x20,
660
632
  TNS_CCAP_CLIENT_FN_MAX: 12,
661
633
  TNS_CCAP_LOB2_QUASI: 0x01,
662
634
  TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
635
+ TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
636
+ TNS_CCAP_VECTOR_SUPPORT: 0x08,
663
637
 
664
638
  // runtime capability indices
665
639
  TNS_RCAP_COMPAT: 0,
@@ -680,28 +654,24 @@ module.exports = {
680
654
 
681
655
  // UDS flags
682
656
  TNS_UDS_FLAGS_IS_JSON: 0x00000100,
657
+ TNS_UDS_FLAGS_IS_OSON: 0x00000800,
658
+
659
+ // end of call status flags
660
+ TNS_EOCS_FLAGS_TXN_IN_PROGRESS: 0x00000002,
661
+ TNS_EOCS_FLAGS_SESS_RELEASE: 0x00008000,
683
662
 
684
663
  // other constants
685
- TNS_MAX_SHORT_LENGTH: 252,
686
664
  TNS_ESCAPE_CHAR: 253,
687
- TNS_LONG_LENGTH_INDICATOR: 254,
688
- TNS_NULL_LENGTH_INDICATOR: 255,
665
+ TNS_LONG_LENGTH_INDICATOR: dataHandlerConstants.TNS_LONG_LENGTH_INDICATOR,
666
+ TNS_NULL_LENGTH_INDICATOR: dataHandlerConstants.TNS_NULL_LENGTH_INDICATOR,
689
667
  TNS_MAX_ROWID_LENGTH: 18,
690
- TNS_DURATION_MID: 0x80000000,
691
- TNS_DURATION_OFFSET: 60,
692
668
  TNS_DURATION_SESSION: 10,
693
669
  TNS_MAX_LONG_LENGTH: 0x7fffffff,
694
670
  TNS_SDU: 8192,
695
671
  TNS_TDU: 65535,
696
- TNS_TXN_IN_PROGRESS: 0x00000002,
697
672
  TNS_MAX_CONNECT_DATA: 230,
698
- TNS_CHUNK_SIZE: 32767,
699
673
  TNS_MAX_UROWID_LENGTH: 3950,
700
- TNS_HAS_REGION_ID: 0x80,
701
-
702
- // timezone offsets
703
- TZ_HOUR_OFFSET: 20,
704
- TZ_MINUTE_OFFSET: 60,
674
+ TNS_SERVER_CONVERTS_CHARS: 0x01, // server does charset conversion
705
675
 
706
676
  // drcp release mode
707
677
  DRCP_DEAUTHENTICATE: 0x00000002,
@@ -742,6 +712,10 @@ module.exports = {
742
712
  TNS_OBJ_TDS_TYPE_BLOB: 30,
743
713
  TNS_OBJ_TDS_TYPE_TIMESTAMP_LTZ: 33,
744
714
  TNS_OBJ_TDS_TYPE_BINARY_FLOAT: 37,
715
+ TNS_OBJ_TDS_TYPE_START_EMBED_ADT: 39,
716
+ TNS_OBJ_TDS_TYPE_END_EMBED_ADT: 40,
717
+ TNS_OBJ_TDS_TYPE_SUBTYPE_MARKER: 43,
718
+ TNS_OBJ_TDS_TYPE_EMBED_ADT_INFO: 44,
745
719
  TNS_OBJ_TDS_TYPE_BINARY_DOUBLE: 45,
746
720
 
747
721
  // xml type constants
@@ -760,13 +734,19 @@ module.exports = {
760
734
  // warnings
761
735
  TNS_WARN_COMPILATION_CREATE: 0x20,
762
736
 
737
+ // vector constants
738
+ TNS_VECTOR_MAX_LENGTH: 1048576,
739
+ VECTOR_FORMAT_FLEX: 0,
740
+ VECTOR_META_FLAG_FLEXIBLE_DIM: 1,
741
+
763
742
  // other constants
764
743
  PACKET_HEADER_SIZE: 8,
765
744
  NUMBER_AS_TEXT_CHARS: 172,
766
- NUMBER_MAX_DIGITS: 40,
767
- BUFFER_CHUNK_SIZE: 65536,
768
745
  CHUNKED_BYTES_CHUNK_SIZE: 65536,
769
746
 
747
+ // Network Header flags for Data packet
748
+ TNS_DATA_FLAGS_END_OF_REQUEST: 0x2000,
749
+
770
750
  TNS_BASE64_ALPHABET_ARRAY: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),
771
751
  TNS_EXTENT_OID: Buffer.from('00000000000000000000000000010001', 'hex')
772
752
  };
@@ -181,7 +181,7 @@ class AuthMessage extends Message {
181
181
  if (this.userByteLen > 0) {
182
182
  buf.writeBytesWithLength(Buffer.from(this.username));
183
183
  }
184
- buf.writeKeyValue("AUTH_TERMINAL", "unknown");
184
+ buf.writeKeyValue("AUTH_TERMINAL", cInfo.terminal);
185
185
  buf.writeKeyValue("AUTH_PROGRAM_NM", cInfo.program);
186
186
  buf.writeKeyValue("AUTH_MACHINE", cInfo.hostName);
187
187
  buf.writeKeyValue("AUTH_PID", cInfo.pid);
@@ -322,7 +322,7 @@ class AuthMessage extends Message {
322
322
 
323
323
  this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'];
324
324
  this.conn.dbName = this.sessionData['AUTH_SC_DBUNIQUE_NAME'];
325
- this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS']);
325
+ this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
326
326
  this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
327
327
  this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
328
328
  const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -42,10 +42,9 @@ class Message {
42
42
  this.functionCode = 0;
43
43
  this.callStatus = 0;
44
44
  this.flushOutBinds = false;
45
+ this.endOfResponse = false;
45
46
  this.endToEndSeqNum = 0;
46
47
  this.errorOccurred = false;
47
- this.flushOutBinds = false;
48
- this.processedError = false;
49
48
  this.warning = undefined;
50
49
  }
51
50
 
@@ -90,11 +89,11 @@ class Message {
90
89
  buf.skipBytesChunked();
91
90
  }
92
91
  // batch error codes
93
- let numEntries = buf.readUB2(); // batch error codes array
94
- if (numEntries > 0) {
92
+ const numErrors = buf.readUB2(); // batch error codes array
93
+ if (numErrors > 0) {
95
94
  this.errorInfo.batchErrors = [];
96
95
  const firstByte = buf.readUInt8();
97
- for (let i = 0; i < numEntries; i++) {
96
+ for (let i = 0; i < numErrors; i++) {
98
97
  if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
99
98
  buf.skipUB4(); // chunk length ignored
100
99
  }
@@ -107,14 +106,21 @@ class Message {
107
106
  }
108
107
 
109
108
  // batch error offset
110
- numEntries = buf.readUB2(); // batch error row offset array
111
- if (numEntries > 0) {
109
+ const numOffsets = buf.readUB4(); // batch error row offset array
110
+ if (numOffsets > 0) {
111
+ if (numOffsets > 65535) {
112
+ errors.throwErr(errors.ERR_TOO_MANY_BATCH_ERRORS);
113
+ }
112
114
  const firstByte = buf.readUInt8();
113
- for (let i = 0; i < numEntries; i++) {
115
+ let offset;
116
+ for (let i = 0; i < numOffsets; i++) {
114
117
  if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
115
118
  buf.skipUB4(); // chunk length ignored
116
119
  }
117
- this.errorInfo.batchErrors[i].offset = buf.readUB4();
120
+ offset = buf.readUB4();
121
+ if (i < numErrors) {
122
+ this.errorInfo.batchErrors[i].offset = offset;
123
+ }
118
124
  }
119
125
  if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
120
126
  buf.skipBytes(1); // ignore end marker
@@ -122,10 +128,10 @@ class Message {
122
128
  }
123
129
 
124
130
  // batch error messages
125
- numEntries = buf.readUB2(); // batch error messages array
126
- if (numEntries > 0) {
131
+ const errMsgArr = buf.readUB2(); // batch error messages array
132
+ if (errMsgArr > 0) {
127
133
  buf.skipBytes(1); // ignore packed size
128
- for (let i = 0; i < numEntries; i++) {
134
+ for (let i = 0; i < errMsgArr; i++) {
129
135
  buf.skipUB2(); // skip chunk length
130
136
 
131
137
  this.errorInfo.batchErrors[i].message = buf.readStr(constants.CSFRM_IMPLICIT);
@@ -154,7 +160,7 @@ class Message {
154
160
  */
155
161
  this.errorInfo.message = this.errorInfo.message.trim();
156
162
  }
157
- this.processedError = true;
163
+ this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
158
164
  }
159
165
 
160
166
  processReturnParameter() { }
@@ -171,22 +177,18 @@ class Message {
171
177
  }
172
178
  }
173
179
 
174
- hasMoreData(buf) {
175
- return buf.numBytesLeft() > 0 && !this.flushOutBinds;
176
- }
177
-
178
180
  decode(buf) {
179
181
  this.process(buf);
180
182
  }
181
183
 
182
184
  process(buf) {
185
+ this.endOfResponse = false;
183
186
  this.flushOutBinds = false;
184
- this.processedError = false;
185
187
  do {
186
188
  this.savePoint(buf);
187
189
  const messageType = buf.readUInt8();
188
190
  this.processMessage(buf, messageType);
189
- } while (this.hasMoreData(buf));
191
+ } while (!this.endOfResponse);
190
192
  }
191
193
 
192
194
  savePoint(buf) {
@@ -201,10 +203,13 @@ class Message {
201
203
  } else if (messageType === constants.TNS_MSG_TYPE_STATUS) {
202
204
  this.callStatus = buf.readUB4();
203
205
  this.endToEndSeqNum = buf.readUB2();
206
+ this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
204
207
  } else if (messageType === constants.TNS_MSG_TYPE_PARAMETER) {
205
208
  this.processReturnParameter(buf);
206
209
  } else if (messageType === constants.TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK) {
207
210
  this.processServerSidePiggyBack(buf);
211
+ } else if (messageType === constants.TNS_MSG_TYPE_END_OF_REQUEST) {
212
+ this.endOfResponse = true;
208
213
  } else {
209
214
  errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType, buf.pos, buf.packetNum);
210
215
  }
@@ -275,7 +280,7 @@ class Message {
275
280
  const flags = buf.readUB4(); // session flags
276
281
  if (flags & constants.TNS_SESSGET_SESSION_CHANGED) {
277
282
  if (this.connection._drcpEstablishSession) {
278
- this.connection.resetStatementCache();
283
+ this.connection.statementCache.clearCursors();
279
284
  }
280
285
  }
281
286
  this.connection._drcpEstablishSession = false;
@@ -290,7 +295,7 @@ class Message {
290
295
  if (this.connection._currentSchemaModified) {
291
296
  this._writeCurrentSchemaPiggyback(buf);
292
297
  }
293
- if (this.connection._cursorsToClose.size > 0 && !this.connection._drcpEstablishSession) {
298
+ if (this.connection.statementCache._cursorsToClose.size > 0 && !this.connection._drcpEstablishSession) {
294
299
  this.writeCloseCursorsPiggyBack(buf);
295
300
  }
296
301
  if (
@@ -319,11 +324,7 @@ class Message {
319
324
  writeCloseCursorsPiggyBack(buf) {
320
325
  this.writePiggybackHeader(buf, constants.TNS_FUNC_CLOSE_CURSORS);
321
326
  buf.writeUInt8(1);
322
- buf.writeUB4(this.connection._cursorsToClose.size);
323
- for (const cursorNum of this.connection._cursorsToClose.keys()) {
324
- buf.writeUB4(cursorNum);
325
- }
326
- this.connection._cursorsToClose.clear();
327
+ this.connection.statementCache.writeCursorsToClose(buf);
327
328
  }
328
329
 
329
330
  writeCloseTempLobsPiggyback(buf) {
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -48,6 +48,7 @@ class DataTypeMessage extends Message {
48
48
  if (convDataType !== 0)
49
49
  buf.skipBytes(4);
50
50
  }
51
+ this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
51
52
  } else {
52
53
  super.processMessage(buf, messageType);
53
54
  }
@@ -392,7 +393,8 @@ const dataTypes = [
392
393
  [constants.TNS_DATA_TYPE_UDS, constants.TNS_DATA_TYPE_UDS, constants.TNS_TYPE_REP_UNIVERSAL],
393
394
  [constants.TNS_DATA_TYPE_TNP, constants.TNS_DATA_TYPE_TNP, constants.TNS_TYPE_REP_UNIVERSAL],
394
395
  [constants.TNS_DATA_TYPE_OER, constants.TNS_DATA_TYPE_OER, constants.TNS_TYPE_REP_UNIVERSAL],
395
- [constants.TNS_DATA_TYPE_OAC, constants.TNS_DATA_TYPE_OAC, constants.TNS_TYPE_REP_UNIVERSAL]
396
+ [constants.TNS_DATA_TYPE_OAC, constants.TNS_DATA_TYPE_OAC, constants.TNS_TYPE_REP_UNIVERSAL],
397
+ [constants.TNS_DATA_TYPE_VECTOR, constants.TNS_DATA_TYPE_VECTOR, constants.TNS_TYPE_REP_UNIVERSAL]
396
398
  ];
397
399
 
398
400
  module.exports = DataTypeMessage;
@@ -68,13 +68,17 @@ class ExecuteMessage extends MessageWithData {
68
68
  const stmt = this.statement;
69
69
  const params = stmt.bindInfoList;
70
70
 
71
+ if (this.noImplicitRelease) {
72
+ dmlOptions |= constants.TNS_EXEC_OPTION_NO_IMPL_REL;
73
+ }
74
+
71
75
  if (!stmt.requiresDefine && !this.parseOnly && params) {
72
76
  numParams = params.length;
73
77
  }
74
78
  if (stmt.requiresDefine) {
75
79
  options |= constants.TNS_EXEC_OPTION_DEFINE;
76
80
  } else if (!this.parseOnly && stmt.sql) {
77
- dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
81
+ dmlOptions |= constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
78
82
  options |= constants.TNS_EXEC_OPTION_EXECUTE;
79
83
  }
80
84
  if (stmt.cursorId === 0 || stmt.isDdl) {