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.
- package/README.md +16 -6
- package/build/Release/oracledb-26.0.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-26.0.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-26.0.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-linux-x64.node +0 -0
- package/build/Release/oracledb-26.0.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-win32-x64.node +0 -0
- package/build/Release/oracledb-26.0.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/aqDeqOptions.js +4 -4
- package/lib/aqEnqOptions.js +2 -2
- package/lib/aqQueue.js +11 -6
- package/lib/connection.js +73 -18
- package/lib/constants.js +4 -0
- package/lib/endUserSecurityContext.js +30 -25
- package/lib/errors.js +92 -5
- package/lib/impl/connection.js +36 -0
- package/lib/impl/datahandlers/buffer.js +91 -18
- package/lib/impl/datahandlers/oson.js +3 -2
- package/lib/impl/parserHelpers.js +6 -2
- package/lib/impl/resultset.js +32 -11
- package/lib/oracledb.js +34 -0
- package/lib/pool.js +6 -2
- package/lib/queryStream.js +13 -5
- package/lib/resultset.js +10 -3
- package/lib/securityContextProvider.js +206 -0
- package/lib/thin/aq.js +2 -3
- package/lib/thin/connection.js +380 -24
- package/lib/thin/dbObject.js +20 -11
- package/lib/thin/pool.js +4 -3
- package/lib/thin/protocol/capabilities.js +37 -4
- package/lib/thin/protocol/constants.js +49 -1
- package/lib/thin/protocol/messages/aqArray.js +2 -2
- package/lib/thin/protocol/messages/aqBase.js +2 -2
- package/lib/thin/protocol/messages/auth.js +17 -6
- package/lib/thin/protocol/messages/base.js +75 -17
- package/lib/thin/protocol/messages/dataType.js +46 -0
- package/lib/thin/protocol/messages/directPathLoadStream.js +3 -2
- package/lib/thin/protocol/messages/execute.js +10 -4
- package/lib/thin/protocol/messages/index.js +4 -0
- package/lib/thin/protocol/messages/notification.js +281 -0
- package/lib/thin/protocol/messages/subscribe.js +181 -0
- package/lib/thin/protocol/messages/withData.js +23 -10
- package/lib/thin/protocol/packet.js +2 -4
- package/lib/thin/protocol/protocol.js +7 -4
- package/lib/thin/resultSet.js +40 -20
- package/lib/thin/sqlnet/ezConnectResolver.js +9 -2
- package/lib/thin/sqlnet/navNodes.js +7 -5
- package/lib/thin/sqlnet/networkSession.js +17 -11
- package/lib/thin/sqlnet/ntTcp.js +24 -8
- package/lib/thin/sqlnet/packet.js +24 -4
- package/lib/thin/sqlnet/sessionAtts.js +2 -2
- package/lib/thin/statement.js +6 -1
- package/lib/thin/statementCache.js +34 -6
- package/lib/thin/subscr.js +363 -0
- package/lib/transformer.js +60 -17
- package/lib/util.js +46 -8
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/plugins/configProviders/gcpstorage/index.js +121 -0
- package/plugins/configProviders/ociobject/index.js +1 -1
- package/plugins/token/cache.js +154 -0
- package/plugins/token/endUserSecurityProvider/index.js +377 -0
- package/plugins/token/extensionAzure/index.js +160 -28
- package/plugins/token/extensionOci/index.js +221 -16
- package/plugins/vectorsdk/OracleVecDB.js +346 -0
- package/plugins/vectorsdk/index.js +49 -0
- package/plugins/vectorsdk/utils.js +370 -0
- package/plugins/vectorsdk/vectorEmbedding.js +223 -0
- package/plugins/vectorsdk/vectorIndex.js +177 -0
- package/plugins/vectorsdk/vectorRecords.js +406 -0
- package/plugins/vectorsdk/vectorSchema.js +408 -0
- package/plugins/vectorsdk/vectorSearch.js +538 -0
- package/build/Release/oracledb-7.0.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-linux-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-win32-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-win32-x64.node-buildinfo.txt +0 -1
- package/eslint.config.js +0 -39
|
@@ -45,10 +45,18 @@ class Capabilities {
|
|
|
45
45
|
this.charsetId = constants.TNS_CHARSET_UTF8;
|
|
46
46
|
this.compileCaps = Buffer.alloc(constants.TNS_CCAP_MAX);
|
|
47
47
|
this.runtimeCaps = Buffer.alloc(constants.TNS_RCAP_MAX);
|
|
48
|
+
this.dbTzOffset = null;
|
|
49
|
+
|
|
50
|
+
// Region-form DBTIMEZONE values are represented by an Oracle region ID in
|
|
51
|
+
// TTC. dbTzRegion holds the corresponding name obtained from DBTIMEZONE
|
|
52
|
+
// so LTZ operations can report that this unsupported configuration is used.
|
|
53
|
+
this.dbTzRegion = null;
|
|
48
54
|
this.initCompileCaps(nscon);
|
|
49
55
|
this.initRuntimeCaps();
|
|
50
56
|
this.maxStringSize = 0;
|
|
51
57
|
this.supportsEndUserSecurityContext = false;
|
|
58
|
+
this.supportsServerOtelTracing = false;
|
|
59
|
+
this.supportsTxnPriority = false;
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
adjustForServerCompileCaps(serverCaps, nscon) {
|
|
@@ -65,18 +73,34 @@ class Capabilities {
|
|
|
65
73
|
nscon.endOfRequestSupport = false;
|
|
66
74
|
}
|
|
67
75
|
const bpIndex = constants.TNS_CCAP_FEATURE_BACKPORT2;
|
|
68
|
-
if (bpIndex < serverCaps.length
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
if (bpIndex < serverCaps.length) {
|
|
77
|
+
if (serverCaps[bpIndex] & constants.TNS_CCAP_END_USER_SEC_CTX_PIGGYBACK) {
|
|
78
|
+
this.supportsEndUserSecurityContext = true;
|
|
79
|
+
}
|
|
80
|
+
if (serverCaps[bpIndex] &
|
|
81
|
+
constants.TNS_CCAP_TXN_PRIORITY_ALTSESS) {
|
|
82
|
+
this.supportsTxnPriority = true;
|
|
83
|
+
}
|
|
71
84
|
}
|
|
72
85
|
}
|
|
73
86
|
|
|
74
87
|
adjustForServerRuntimeCaps(serverCaps) {
|
|
88
|
+
// TZ_EX adds timezone fields to the TTIDTY request and response. Only
|
|
89
|
+
// advertise it when TTIPRO confirms that the server understands those
|
|
90
|
+
// fields; otherwise datatype negotiation would be decoded out of sync.
|
|
91
|
+
if (serverCaps.length <= constants.TNS_RCAP_TZ ||
|
|
92
|
+
!(serverCaps[constants.TNS_RCAP_TZ] & constants.TNS_RCAP_TZ_EX)) {
|
|
93
|
+
this.runtimeCaps[constants.TNS_RCAP_TZ] = 0;
|
|
94
|
+
}
|
|
75
95
|
if (serverCaps[constants.TNS_RCAP_TTC] & constants.TNS_RCAP_TTC_32K) {
|
|
76
96
|
this.maxStringSize = 32767;
|
|
77
97
|
} else {
|
|
78
98
|
this.maxStringSize = 4000;
|
|
79
99
|
}
|
|
100
|
+
this.supportsServerOtelTracing =
|
|
101
|
+
constants.TNS_RCAP_OTEL < serverCaps.length &&
|
|
102
|
+
(serverCaps[constants.TNS_RCAP_OTEL] &
|
|
103
|
+
constants.TNS_RCAP_OTEL_SUPPORTED) !== 0;
|
|
80
104
|
}
|
|
81
105
|
|
|
82
106
|
initCompileCaps(nscon) {
|
|
@@ -134,13 +158,16 @@ class Capabilities {
|
|
|
134
158
|
constants.TNS_CCAP_PIPELINING_SUPPORT |
|
|
135
159
|
constants.TNS_CCAP_PIPELINING_BREAK |
|
|
136
160
|
constants.TNS_CCAP_TTC5_SESSIONLESS_TXNS;
|
|
161
|
+
this.compileCaps[constants.TNS_CCAP_FEATURE_BACKPORT2] =
|
|
162
|
+
constants.TNS_CCAP_TXN_PRIORITY_ALTSESS |
|
|
163
|
+
constants.TNS_CCAP_END_USER_SEC_CTX_PIGGYBACK;
|
|
137
164
|
this.compileCaps[constants.TNS_CCAP_VECTOR_FEATURES] =
|
|
138
165
|
constants.TNS_CCAP_VECTOR_FEATURE_BINARY | constants.TNS_CCAP_VECTOR_FEATURE_SPARSE;
|
|
139
|
-
this.compileCaps[constants.TNS_CCAP_FEATURE_BACKPORT2] = constants.TNS_CCAP_END_USER_SEC_CTX_PIGGYBACK;
|
|
140
166
|
}
|
|
141
167
|
|
|
142
168
|
initRuntimeCaps() {
|
|
143
169
|
this.runtimeCaps[constants.TNS_RCAP_COMPAT] = constants.TNS_RCAP_COMPAT_81;
|
|
170
|
+
this.runtimeCaps[constants.TNS_RCAP_TZ] = constants.TNS_RCAP_TZ_EX;
|
|
144
171
|
this.runtimeCaps[constants.TNS_RCAP_TTC] =
|
|
145
172
|
constants.TNS_RCAP_TTC_ZERO_COPY | constants.TNS_RCAP_TTC_32K;
|
|
146
173
|
}
|
|
@@ -155,6 +182,12 @@ class Capabilities {
|
|
|
155
182
|
errors.throwErr(errors.ERR_CHAR_CS_NOT_SUPPORTED, this.charsetId);
|
|
156
183
|
}
|
|
157
184
|
|
|
185
|
+
assertTxnPrioritySupported() {
|
|
186
|
+
if (!this.supportsTxnPriority) {
|
|
187
|
+
errors.throwErr(errors.ERR_TXN_PRIORITY_NOT_SUPPORTED);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
158
191
|
}
|
|
159
192
|
|
|
160
193
|
module.exports = Capabilities;
|
|
@@ -411,6 +411,7 @@ module.exports = {
|
|
|
411
411
|
TNS_DATA_TYPE_PLBGN: 661,
|
|
412
412
|
TNS_DATA_TYPE_UDS: 663,
|
|
413
413
|
TNS_DATA_TYPE_PLOP: 665,
|
|
414
|
+
TNS_DATA_TYPE_ALTSESS: 668,
|
|
414
415
|
TNS_DATA_TYPE_KVE: 669,
|
|
415
416
|
TNS_DATA_TYPE_EUSC: 670,
|
|
416
417
|
|
|
@@ -429,6 +430,7 @@ module.exports = {
|
|
|
429
430
|
TNS_MSG_TYPE_PARAMETER: 8,
|
|
430
431
|
TNS_MSG_TYPE_STATUS: 9,
|
|
431
432
|
TNS_MSG_TYPE_IO_VECTOR: 11,
|
|
433
|
+
TNS_MSG_TYPE_OAC: 13,
|
|
432
434
|
TNS_MSG_TYPE_LOB_DATA: 14,
|
|
433
435
|
TNS_MSG_TYPE_WARNING: 15,
|
|
434
436
|
TNS_MSG_TYPE_DESCRIBE_INFO: 16,
|
|
@@ -449,6 +451,16 @@ module.exports = {
|
|
|
449
451
|
TNS_KEYWORD_NUM_TRANSACTION_ID: 201,
|
|
450
452
|
TNS_KEYWORD_PDBNAME: 197, // Container Name
|
|
451
453
|
TNS_KEYWORD_DBNAME: 179, // Global DB Name
|
|
454
|
+
TNS_KEYWORD_MODULE: 184,
|
|
455
|
+
TNS_KEYWORD_ACTION: 185,
|
|
456
|
+
TNS_KEYWORD_CLIENT_INFO: 186,
|
|
457
|
+
TNS_KEYWORD_CLIENT_ID: 198,
|
|
458
|
+
TNS_KEYWORD_NUM_TXN_PRIORITY: 204,
|
|
459
|
+
|
|
460
|
+
// key/value flags
|
|
461
|
+
// Empty txnPriority uses the same reset semantics as OCI
|
|
462
|
+
// KPD_TXNPROP_PRI_RESET.
|
|
463
|
+
TNS_KVAL_FLAG_TXN_PRIORITY_DEFAULT: 0x0001,
|
|
452
464
|
|
|
453
465
|
// bind flags
|
|
454
466
|
TNS_BIND_USE_INDICATORS: 0x0001,
|
|
@@ -538,9 +550,12 @@ module.exports = {
|
|
|
538
550
|
// end-to-end metrics
|
|
539
551
|
TNS_END_TO_END_ACTION: 0x0010,
|
|
540
552
|
TNS_END_TO_END_CLIENT_IDENTIFIER: 0x0001,
|
|
553
|
+
TNS_END_TO_END_ECID: 0x0020,
|
|
541
554
|
TNS_END_TO_END_CLIENT_INFO: 0x0100,
|
|
542
555
|
TNS_END_TO_END_DBOP: 0x0200,
|
|
543
556
|
TNS_END_TO_END_MODULE: 0x0008,
|
|
557
|
+
TNS_END_TO_END_OTEL_RESET: 0x0400,
|
|
558
|
+
TNS_END_TO_END_OTEL_TRACE: 0x80000000,
|
|
544
559
|
|
|
545
560
|
// versions
|
|
546
561
|
TNS_VERSION_MIN_ACCEPTED: 315,
|
|
@@ -560,6 +575,7 @@ module.exports = {
|
|
|
560
575
|
TNS_FUNC_FETCH: 5,
|
|
561
576
|
TNS_FUNC_LOB_OP: 96,
|
|
562
577
|
TNS_FUNC_LOGOFF: 9,
|
|
578
|
+
TNS_FUNC_NOTIFY: 187,
|
|
563
579
|
TNS_FUNC_PING: 147,
|
|
564
580
|
TNS_FUNC_PIPELINE_BEGIN: 199,
|
|
565
581
|
TNS_FUNC_PIPELINE_END: 200,
|
|
@@ -568,15 +584,17 @@ module.exports = {
|
|
|
568
584
|
TNS_FUNC_REEXECUTE: 4,
|
|
569
585
|
TNS_FUNC_REEXECUTE_AND_FETCH: 78,
|
|
570
586
|
TNS_FUNC_SET_SCHEMA: 152,
|
|
587
|
+
TNS_FUNC_SUBSCRIBE: 125,
|
|
571
588
|
TNS_FUNC_SESSION_GET: 162,
|
|
572
589
|
TNS_FUNC_SESSION_RELEASE: 163,
|
|
573
590
|
TNS_FUNC_SESSION_STATE: 176, // piggyback fn
|
|
574
|
-
|
|
591
|
+
TNS_FUNC_CANCEL_CURSORS: 120, // piggyback fn
|
|
575
592
|
TNS_FUNC_TPC_TXN_SWITCH: 103,
|
|
576
593
|
TNS_FUNC_TPC_TXN_CHANGE_STATE: 104,
|
|
577
594
|
TNS_FUNC_AQ_ENQ: 121,
|
|
578
595
|
TNS_FUNC_AQ_DEQ: 122,
|
|
579
596
|
TNS_FUNC_ARRAY_AQ: 145,
|
|
597
|
+
TNS_FUNC_ALTSESS: 204,
|
|
580
598
|
|
|
581
599
|
// character sets and encodings
|
|
582
600
|
TNS_CHARSET_UTF8: 873,
|
|
@@ -677,17 +695,22 @@ module.exports = {
|
|
|
677
695
|
TNS_CCAP_VECTOR_FEATURE_SPARSE: 0x02,
|
|
678
696
|
TNS_CCAP_TTC5_SESSIONLESS_TXNS: 0x20,
|
|
679
697
|
TNS_CCAP_OCI3_OCSSYNC: 0x20,
|
|
698
|
+
TNS_CCAP_TXN_PRIORITY_ALTSESS: 0x01,
|
|
680
699
|
TNS_CCAP_END_USER_SEC_CTX_PIGGYBACK: 0x02,
|
|
681
700
|
|
|
682
701
|
// runtime capability indices
|
|
683
702
|
TNS_RCAP_COMPAT: 0,
|
|
703
|
+
TNS_RCAP_TZ: 1,
|
|
684
704
|
TNS_RCAP_TTC: 6,
|
|
705
|
+
TNS_RCAP_OTEL: 12,
|
|
685
706
|
TNS_RCAP_MAX: 7,
|
|
686
707
|
|
|
687
708
|
// runtime capability values
|
|
688
709
|
TNS_RCAP_COMPAT_81: 2,
|
|
710
|
+
TNS_RCAP_TZ_EX: 0x01,
|
|
689
711
|
TNS_RCAP_TTC_ZERO_COPY: 0x01,
|
|
690
712
|
TNS_RCAP_TTC_32K: 0x04,
|
|
713
|
+
TNS_RCAP_OTEL_SUPPORTED: 0x01,
|
|
691
714
|
|
|
692
715
|
/** Verifier types. */
|
|
693
716
|
/** SHA1 (salted). */
|
|
@@ -788,6 +811,31 @@ module.exports = {
|
|
|
788
811
|
TNS_KPD_AQ_BUFMSG: 0x02,
|
|
789
812
|
TNS_KPD_AQ_EITHER: 0x10,
|
|
790
813
|
|
|
814
|
+
// subscription opcodes
|
|
815
|
+
TNS_SUBSCR_OP_REGISTER: 1,
|
|
816
|
+
TNS_SUBSCR_OP_UNREGISTER: 2,
|
|
817
|
+
|
|
818
|
+
// subscription modes/constants
|
|
819
|
+
TNS_INIT_KPNDRREQ: 1,
|
|
820
|
+
TNS_SUBSCR_MODE_CLIENT_INITIATED: 4,
|
|
821
|
+
TNS_SUBSCR_CLIENT_ID_LEN: 29,
|
|
822
|
+
TNS_SUBSCR_STOP_NOTIF: 0x04,
|
|
823
|
+
|
|
824
|
+
// subscription quality of service flags
|
|
825
|
+
TNS_SUBSCR_QOS_RELIABLE: 0x01,
|
|
826
|
+
TNS_SUBSCR_QOS_PAYLOAD: 0x02,
|
|
827
|
+
TNS_SUBSCR_QOS_REPLICATE: 0x04,
|
|
828
|
+
TNS_SUBSCR_QOS_SECURE: 0x08,
|
|
829
|
+
TNS_SUBSCR_QOS_PURGE_ON_NTFN: 0x10,
|
|
830
|
+
TNS_SUBSCR_QOS_MULTICBK: 0x20,
|
|
831
|
+
TNS_SUBSCR_QOS_ASYNC_DEQ: 0x200,
|
|
832
|
+
TNS_SUBSCR_QOS_AUTO_ACK: 0x400,
|
|
833
|
+
TNS_SUBSCR_QOS_TX_ACK: 0x800,
|
|
834
|
+
|
|
835
|
+
// subscription flags
|
|
836
|
+
TNS_SUBSCR_FLAGS_INCLUDE_ROWIDS: 0x10,
|
|
837
|
+
TNS_SUBSCR_FLAGS_QUERY: 0x20,
|
|
838
|
+
|
|
791
839
|
TNS_AQ_MESSAGE_ID_LENGTH: 16,
|
|
792
840
|
TNS_AQ_MESSAGE_VERSION: 1,
|
|
793
841
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2025, Oracle and/or its affiliates.
|
|
1
|
+
// Copyright (c) 2025, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -78,7 +78,7 @@ class AqArrayMessage extends AqBaseMessage {
|
|
|
78
78
|
}
|
|
79
79
|
temp16 = buf.readUB2(); // extensions len
|
|
80
80
|
if (temp16 > 0) {
|
|
81
|
-
errors.
|
|
81
|
+
errors.throwNotImplemented('AQ extensions');
|
|
82
82
|
}
|
|
83
83
|
buf.skipUB2(); // output ack
|
|
84
84
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2025, Oracle and/or its affiliates.
|
|
1
|
+
// Copyright (c) 2025, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -134,7 +134,7 @@ class AqBaseMessage extends BaseMessage {
|
|
|
134
134
|
this._processExtensions(buf, propsImpl);
|
|
135
135
|
const temp32 = buf.readUB4(); // user properties
|
|
136
136
|
if (temp32 > 0) {
|
|
137
|
-
errors.
|
|
137
|
+
errors.throwNotImplemented('AQ User Properties');
|
|
138
138
|
}
|
|
139
139
|
buf.skipUB4(); // csn
|
|
140
140
|
buf.skipUB4(); // dsn
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -117,6 +117,7 @@ class AuthMessage extends Message {
|
|
|
117
117
|
}
|
|
118
118
|
this.appContext = config.appContext;
|
|
119
119
|
this.setAuthMode(config);
|
|
120
|
+
this.txnPriority = config.txnPriority;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
setAuthMode(config) {
|
|
@@ -155,13 +156,13 @@ class AuthMessage extends Message {
|
|
|
155
156
|
}
|
|
156
157
|
}
|
|
157
158
|
|
|
158
|
-
|
|
159
|
-
let sign, tzRepr;
|
|
159
|
+
getAlterSessionStatement() {
|
|
160
|
+
let sign, stmt, tzRepr;
|
|
160
161
|
if (process.env.ORA_SDTZ) {
|
|
161
162
|
tzRepr = process.env.ORA_SDTZ;
|
|
162
163
|
// LOCAL and DBTIMEZONE are SQL keywords and must not be quoted.
|
|
163
164
|
if (["LOCAL", "DBTIMEZONE"].includes(tzRepr.toUpperCase())) {
|
|
164
|
-
|
|
165
|
+
stmt = `ALTER SESSION SET TIME_ZONE =${tzRepr}`;
|
|
165
166
|
}
|
|
166
167
|
} else {
|
|
167
168
|
const date = new Date();
|
|
@@ -177,7 +178,16 @@ class AuthMessage extends Message {
|
|
|
177
178
|
tzHour = tzHour.toLocaleString('en-US', {minimumIntegerDigits: 2});
|
|
178
179
|
tzRepr = `${sign}${tzHour}:${tzMinutes}`;
|
|
179
180
|
}
|
|
180
|
-
|
|
181
|
+
|
|
182
|
+
if (stmt === undefined) {
|
|
183
|
+
stmt = `ALTER SESSION SET TIME_ZONE =${parser.enquoteLiteral(tzRepr)}`;
|
|
184
|
+
}
|
|
185
|
+
if (this.txnPriority) {
|
|
186
|
+
this.conn._protocol.caps.assertTxnPrioritySupported();
|
|
187
|
+
stmt += ` TXN_PRIORITY = ${parser.enquoteLiteral(this.txnPriority)}`;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return `${stmt}\x00`;
|
|
181
191
|
}
|
|
182
192
|
|
|
183
193
|
encode(buf) {
|
|
@@ -290,7 +300,8 @@ class AuthMessage extends Message {
|
|
|
290
300
|
this.driverName ?? constants.DRIVER_NAME);
|
|
291
301
|
buf.writeKeyValue("SESSION_CLIENT_VERSION",
|
|
292
302
|
constants.CLIENT_VERSION.toString());
|
|
293
|
-
buf.writeKeyValue("AUTH_ALTER_SESSION",
|
|
303
|
+
buf.writeKeyValue("AUTH_ALTER_SESSION",
|
|
304
|
+
this.getAlterSessionStatement(), 1);
|
|
294
305
|
}
|
|
295
306
|
if (this.encodedPassword) {
|
|
296
307
|
buf.writeKeyValue("AUTH_PASSWORD", this.encodedPassword);
|
|
@@ -452,6 +452,16 @@ class Message {
|
|
|
452
452
|
this.connection.dbName = keyTextValue;
|
|
453
453
|
} else if (keywordNum === constants.TNS_KEYWORD_PDBNAME) {
|
|
454
454
|
this.connection.pdbName = keyTextValue;
|
|
455
|
+
} else if (keywordNum === constants.TNS_KEYWORD_ACTION) {
|
|
456
|
+
this.connection._action = keyTextValue;
|
|
457
|
+
} else if (keywordNum === constants.TNS_KEYWORD_CLIENT_INFO) {
|
|
458
|
+
this.connection._clientInfo = keyTextValue;
|
|
459
|
+
} else if (keywordNum === constants.TNS_KEYWORD_MODULE) {
|
|
460
|
+
this.connection._module = keyTextValue;
|
|
461
|
+
} else if (keywordNum === constants.TNS_KEYWORD_CLIENT_ID) {
|
|
462
|
+
this.connection._clientIdentifier = keyTextValue;
|
|
463
|
+
} else if (keywordNum === constants.TNS_KEYWORD_NUM_TXN_PRIORITY) {
|
|
464
|
+
this.connection._txnPriority = keyTextValue;
|
|
455
465
|
}
|
|
456
466
|
}
|
|
457
467
|
buf.skipUB4(); // skip overall flags
|
|
@@ -530,18 +540,27 @@ class Message {
|
|
|
530
540
|
this._writeCurrentSchemaPiggyback(buf);
|
|
531
541
|
}
|
|
532
542
|
this._writeApplicationContextPiggyback(buf);
|
|
533
|
-
if (
|
|
543
|
+
if (!this.connection._drcpEstablishSession) {
|
|
534
544
|
// skip closing cursors when '_drcpEstablishSession = true' Since we don't know whether the same session
|
|
535
545
|
// is in use. We can not send the information across until after the session information has been returned
|
|
536
546
|
// (on the first round trip).
|
|
537
|
-
this.
|
|
547
|
+
if (this.connection.statementCache._cursorsToClose.size > 0) {
|
|
548
|
+
this.writeCursorsPiggyBack(buf, constants.TNS_FUNC_CLOSE_CURSORS,
|
|
549
|
+
this.connection.statementCache._cursorsToClose);
|
|
550
|
+
}
|
|
551
|
+
if (this.connection.statementCache._cursorsToCancel.size > 0) {
|
|
552
|
+
this.writeCursorsPiggyBack(buf, constants.TNS_FUNC_CANCEL_CURSORS,
|
|
553
|
+
this.connection.statementCache._cursorsToCancel);
|
|
554
|
+
}
|
|
538
555
|
}
|
|
539
556
|
if (
|
|
540
557
|
this.connection._actionModified ||
|
|
541
558
|
this.connection._clientIdentifierModified ||
|
|
542
|
-
this.connection.
|
|
559
|
+
this.connection._ecidModified ||
|
|
560
|
+
this.connection._dbOpModified ||
|
|
543
561
|
this.connection._clientInfoModified ||
|
|
544
|
-
this.connection._moduleModified
|
|
562
|
+
this.connection._moduleModified ||
|
|
563
|
+
this.connection._otelModified
|
|
545
564
|
) {
|
|
546
565
|
this._writeEndToEndPiggybacks(buf);
|
|
547
566
|
}
|
|
@@ -553,6 +572,10 @@ class Message {
|
|
|
553
572
|
this.connection._sessionlessData.piggyback.encode(buf);
|
|
554
573
|
this.connection._sessionlessData.piggyback = null;
|
|
555
574
|
}
|
|
575
|
+
if (this.connection._txnPriorityModified) {
|
|
576
|
+
this.connection._protocol.caps.assertTxnPrioritySupported();
|
|
577
|
+
this._writeAltSessPiggyback(buf);
|
|
578
|
+
}
|
|
556
579
|
}
|
|
557
580
|
|
|
558
581
|
writePiggybackHeader(buf, functionCode) {
|
|
@@ -565,10 +588,10 @@ class Message {
|
|
|
565
588
|
}
|
|
566
589
|
}
|
|
567
590
|
|
|
568
|
-
|
|
569
|
-
this.writePiggybackHeader(buf,
|
|
591
|
+
writeCursorsPiggyBack(buf, functionCode, cursors) {
|
|
592
|
+
this.writePiggybackHeader(buf, functionCode);
|
|
570
593
|
buf.writeUInt8(1);
|
|
571
|
-
this.connection.statementCache.
|
|
594
|
+
this.connection.statementCache.writeCursors(buf, cursors);
|
|
572
595
|
}
|
|
573
596
|
|
|
574
597
|
writeCloseTempLobsPiggyback(buf) {
|
|
@@ -638,6 +661,9 @@ class Message {
|
|
|
638
661
|
if (this.connection._clientIdentifierModified) {
|
|
639
662
|
flags |= constants.TNS_END_TO_END_CLIENT_IDENTIFIER;
|
|
640
663
|
}
|
|
664
|
+
if (this.connection._ecidModified) {
|
|
665
|
+
flags |= constants.TNS_END_TO_END_ECID;
|
|
666
|
+
}
|
|
641
667
|
if (this.connection._clientInfoModified) {
|
|
642
668
|
flags |= constants.TNS_END_TO_END_CLIENT_INFO;
|
|
643
669
|
}
|
|
@@ -647,20 +673,25 @@ class Message {
|
|
|
647
673
|
if (this.connection._dbOpModified) {
|
|
648
674
|
flags |= constants.TNS_END_TO_END_DBOP;
|
|
649
675
|
}
|
|
676
|
+
if (this.connection._otelModified) {
|
|
677
|
+
flags |= constants.TNS_END_TO_END_OTEL_RESET;
|
|
678
|
+
flags |= this._getOtelFlags();
|
|
679
|
+
}
|
|
650
680
|
|
|
651
681
|
// write initial packet data
|
|
652
682
|
this.writePiggybackHeader(buf, constants.TNS_FUNC_SET_END_TO_END_ATTR);
|
|
653
683
|
buf.writeUInt8(0); // pointer (cidnam)
|
|
654
684
|
buf.writeUInt8(0); // pointer (cidser)
|
|
655
|
-
|
|
685
|
+
|
|
686
|
+
// Coerce to unsigned since JS bitwise operators produce signed 32-bit
|
|
687
|
+
// values, and OTEL trace uses the high bit.
|
|
688
|
+
buf.writeUB4(flags >>> 0);
|
|
656
689
|
|
|
657
690
|
const clientIdentifierBytes = this.writeEndEndTraceValue(buf, this.connection._clientIdentifier, this.connection._clientIdentifierModified);
|
|
658
691
|
const moduleBytes = this.writeEndEndTraceValue(buf, this.connection._module, this.connection._moduleModified);
|
|
659
692
|
const actionBytes = this.writeEndEndTraceValue(buf, this.connection._action, this.connection._actionModified);
|
|
660
|
-
|
|
693
|
+
const ecidBytes = this.writeEndEndTraceValue(buf, this.connection._ecid, this.connection._ecidModified);
|
|
661
694
|
// write unsupported bits
|
|
662
|
-
buf.writeUInt8(0); // pointer (cideci)
|
|
663
|
-
buf.writeUB4(0); // length (cideci)
|
|
664
695
|
buf.writeUInt8(0); // cidcct
|
|
665
696
|
buf.writeUB4(0); // cidecs
|
|
666
697
|
|
|
@@ -682,6 +713,9 @@ class Message {
|
|
|
682
713
|
if (this.connection._actionModified && this.connection._action) {
|
|
683
714
|
buf.writeBytesWithLength(actionBytes);
|
|
684
715
|
}
|
|
716
|
+
if (this.connection._ecidModified && this.connection._ecid) {
|
|
717
|
+
buf.writeBytesWithLength(ecidBytes);
|
|
718
|
+
}
|
|
685
719
|
if (this.connection._clientInfoModified && this.connection._clientInfo) {
|
|
686
720
|
buf.writeBytesWithLength(clientInfoBytes);
|
|
687
721
|
}
|
|
@@ -689,17 +723,24 @@ class Message {
|
|
|
689
723
|
buf.writeBytesWithLength(dbOpBytes);
|
|
690
724
|
}
|
|
691
725
|
|
|
692
|
-
//
|
|
726
|
+
// Safely retain the values and clear only their modified flags.
|
|
727
|
+
// This avoids resending stale values, while preserving ACTION
|
|
728
|
+
// because it is sent with MODULE updates.
|
|
693
729
|
this.connection._actionModified = false;
|
|
694
|
-
this.connection.
|
|
730
|
+
this.connection._ecidModified = false;
|
|
695
731
|
this.connection._clientIdentifierModified = false;
|
|
696
|
-
this.connection._clientIdentifier = "";
|
|
697
732
|
this.connection._clientInfoModified = false;
|
|
698
|
-
this.connection._clientInfo = "";
|
|
699
733
|
this.connection._dbOpModified = false;
|
|
700
|
-
this.connection._dbOp = "";
|
|
701
734
|
this.connection._moduleModified = false;
|
|
702
|
-
this.connection.
|
|
735
|
+
this.connection._otelModified = false;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
_getOtelFlags() {
|
|
739
|
+
let flags = 0;
|
|
740
|
+
if (this.connection.databaseOpenTelemetryTracing) {
|
|
741
|
+
flags |= constants.TNS_END_TO_END_OTEL_TRACE;
|
|
742
|
+
}
|
|
743
|
+
return flags >>> 0;
|
|
703
744
|
}
|
|
704
745
|
|
|
705
746
|
writeEndEndTraceValue(buf, value, modified) {
|
|
@@ -762,6 +803,23 @@ class Message {
|
|
|
762
803
|
}
|
|
763
804
|
}
|
|
764
805
|
|
|
806
|
+
_writeAltSessPiggyback(buf) {
|
|
807
|
+
const pendingTxnPriority = this.connection._pendingTxnPriority ?? "";
|
|
808
|
+
const flags = (pendingTxnPriority === "") ?
|
|
809
|
+
constants.TNS_KVAL_FLAG_TXN_PRIORITY_DEFAULT : 0;
|
|
810
|
+
|
|
811
|
+
this.writePiggybackHeader(buf, constants.TNS_FUNC_ALTSESS);
|
|
812
|
+
|
|
813
|
+
// OALTSESS uses DTYALTSESS, which wraps a KVAL array carrying the
|
|
814
|
+
// alter-session key/value pairs to apply on the server.
|
|
815
|
+
buf.writeUB4(0); // kpdAltSessFlg
|
|
816
|
+
buf.writeUInt8(1); // ptr to KVAL array
|
|
817
|
+
buf.writeUB4(1); // number of key/value pairs
|
|
818
|
+
buf.writeKeyValue("TXN_PRIORITY", pendingTxnPriority, flags);
|
|
819
|
+
this.connection._pendingTxnPriority = undefined;
|
|
820
|
+
this.connection._txnPriorityModified = false;
|
|
821
|
+
}
|
|
822
|
+
|
|
765
823
|
// Called when an error is encountered during decode of RPC
|
|
766
824
|
saveDeferredErr() {
|
|
767
825
|
if (!this.deferredErr) {
|
|
@@ -26,9 +26,23 @@
|
|
|
26
26
|
|
|
27
27
|
'use strict';
|
|
28
28
|
|
|
29
|
+
const { Buffer } = require('buffer');
|
|
29
30
|
const constants = require("../constants.js");
|
|
31
|
+
const dataHandlerConstants = require("../../../impl/datahandlers/constants.js");
|
|
30
32
|
const Message = require("./base.js");
|
|
31
33
|
|
|
34
|
+
// TTIDTY carries the client's time zone as an 11-byte INTERVAL DAY TO SECOND
|
|
35
|
+
// value. A zero day field is followed by the biased hour and minute offset;
|
|
36
|
+
// the remaining five bytes use the TTC time-zone trailer representation.
|
|
37
|
+
const TTIDTY_TIME_ZONE_TRAILER = Buffer.from([0x80, 0, 0, 0, 0]);
|
|
38
|
+
|
|
39
|
+
// In the server's 11-byte DBTIMEZONE interval, byte 4 holds either the biased
|
|
40
|
+
// hour offset or a region-ID marker. Oracle clients identify a region when
|
|
41
|
+
// this byte is greater than 120 (181 - the hour bias of 60 - 1). The region ID
|
|
42
|
+
// itself is encoded in bytes 2 and 3. node-oracledb currently obtains the
|
|
43
|
+
// region name with DBTIMEZONE, since it has no Oracle region-ID mapping table.
|
|
44
|
+
const TTIDTY_TIME_ZONE_REGION_ID_THRESHOLD = 120;
|
|
45
|
+
|
|
32
46
|
/**
|
|
33
47
|
* Does Datatype Negotiation
|
|
34
48
|
*
|
|
@@ -40,6 +54,19 @@ class DataTypeMessage extends Message {
|
|
|
40
54
|
|
|
41
55
|
processMessage(buf, messageType) {
|
|
42
56
|
if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
|
|
57
|
+
if (buf.caps.runtimeCaps[constants.TNS_RCAP_TZ] ===
|
|
58
|
+
constants.TNS_RCAP_TZ_EX) {
|
|
59
|
+
// TZ_EX adds the database time zone before the negotiated datatype
|
|
60
|
+
// list. It uses the same 11-byte INTERVAL DAY TO SECOND layout as the
|
|
61
|
+
// client value written below.
|
|
62
|
+
const dbTimeZone = buf.readBytes(11);
|
|
63
|
+
if (dbTimeZone[4] <= TTIDTY_TIME_ZONE_REGION_ID_THRESHOLD) {
|
|
64
|
+
// Fixed offsets encode hours and minutes with a bias of 60.
|
|
65
|
+
buf.caps.dbTzOffset = (dbTimeZone[4] -
|
|
66
|
+
dataHandlerConstants.TNS_DURATION_OFFSET) * 60 +
|
|
67
|
+
dbTimeZone[5] - dataHandlerConstants.TNS_DURATION_OFFSET;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
43
70
|
while (true) {
|
|
44
71
|
const dataType = buf.readUInt16BE();
|
|
45
72
|
if (dataType === 0)
|
|
@@ -62,6 +89,24 @@ class DataTypeMessage extends Message {
|
|
|
62
89
|
constants.TNS_ENCODING_CONV_LENGTH);
|
|
63
90
|
buf.writeBytesWithLength(buf.caps.compileCaps);
|
|
64
91
|
buf.writeBytesWithLength(buf.caps.runtimeCaps);
|
|
92
|
+
if (buf.caps.runtimeCaps[constants.TNS_RCAP_TZ] ===
|
|
93
|
+
constants.TNS_RCAP_TZ_EX) {
|
|
94
|
+
// Advertise the Node process's current fixed UTC offset. The server
|
|
95
|
+
// uses this client value while performing datatype negotiation and
|
|
96
|
+
// returns its DBTIMEZONE using the corresponding interval layout.
|
|
97
|
+
//
|
|
98
|
+
// Date#getTimezoneOffset() uses the opposite sign convention
|
|
99
|
+
// (UTC - local time), so negate it before encoding the offset for TTIDTY.
|
|
100
|
+
const timeZoneOffset = -new Date().getTimezoneOffset();
|
|
101
|
+
const timeZone = Buffer.alloc(11);
|
|
102
|
+
timeZone.writeUInt32BE(dataHandlerConstants.TNS_DURATION_MID, 0);
|
|
103
|
+
timeZone[4] = Math.trunc(timeZoneOffset / 60) +
|
|
104
|
+
dataHandlerConstants.TNS_DURATION_OFFSET;
|
|
105
|
+
timeZone[5] = timeZoneOffset % 60 +
|
|
106
|
+
dataHandlerConstants.TNS_DURATION_OFFSET;
|
|
107
|
+
TTIDTY_TIME_ZONE_TRAILER.copy(timeZone, 6);
|
|
108
|
+
buf.writeBytes(timeZone);
|
|
109
|
+
}
|
|
65
110
|
for (const val of dataTypes) {
|
|
66
111
|
buf.writeUInt16BE(val[0]);
|
|
67
112
|
buf.writeUInt16BE(val[1]);
|
|
@@ -399,6 +444,7 @@ const dataTypes = [
|
|
|
399
444
|
[constants.TNS_DATA_TYPE_PLEND, constants.TNS_DATA_TYPE_PLEND, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
400
445
|
[constants.TNS_DATA_TYPE_PLBGN, constants.TNS_DATA_TYPE_PLBGN, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
401
446
|
[constants.TNS_DATA_TYPE_PLOP, constants.TNS_DATA_TYPE_PLOP, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
447
|
+
[constants.TNS_DATA_TYPE_ALTSESS, constants.TNS_DATA_TYPE_ALTSESS, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
402
448
|
[constants.TNS_DATA_TYPE_KVE, constants.TNS_DATA_TYPE_KVE, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
403
449
|
[constants.TNS_DATA_TYPE_EUSC, constants.TNS_DATA_TYPE_EUSC, constants.TNS_TYPE_REP_UNIVERSAL]
|
|
404
450
|
];
|
|
@@ -93,13 +93,14 @@ class DirectPathPiece {
|
|
|
93
93
|
|
|
94
94
|
class PieceBuffer extends BaseBuffer {
|
|
95
95
|
constructor(connection) {
|
|
96
|
-
|
|
96
|
+
const caps = connection._protocol.caps;
|
|
97
|
+
super(Buffer.alloc(constants.TNS_DPLS_MAX_PIECE_SIZE), caps);
|
|
97
98
|
this.connection = connection;
|
|
98
99
|
this.currentPiece = null;
|
|
99
100
|
this.totalPieceLength = 0;
|
|
100
101
|
this.pieces = [];
|
|
101
102
|
this._encodingTempBuf = new BaseBuffer(
|
|
102
|
-
Buffer.alloc(constants.TNS_DPLS_MAX_BUFFER_SIZE_FACTOR)
|
|
103
|
+
Buffer.alloc(constants.TNS_DPLS_MAX_BUFFER_SIZE_FACTOR), caps
|
|
103
104
|
);
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -65,6 +65,8 @@ class ExecuteMessage extends MessageWithData {
|
|
|
65
65
|
let execFlags = 0;
|
|
66
66
|
let numParams = 0;
|
|
67
67
|
let numIters = 1;
|
|
68
|
+
let registrationIdMsb = 0;
|
|
69
|
+
let registrationIdLsb = 0;
|
|
68
70
|
// Configuring the options field thats send to the server
|
|
69
71
|
const stmt = this.statement;
|
|
70
72
|
const params = stmt.bindInfoList;
|
|
@@ -123,6 +125,10 @@ class ExecuteMessage extends MessageWithData {
|
|
|
123
125
|
this._handleSuspendSessionless();
|
|
124
126
|
}
|
|
125
127
|
|
|
128
|
+
registrationIdMsb = Number((this.statement._registrationId >> 32n) &
|
|
129
|
+
0xffffffffn);
|
|
130
|
+
registrationIdLsb = Number(this.statement._registrationId & 0xffffffffn);
|
|
131
|
+
|
|
126
132
|
this.writeFunctionHeader(buf);
|
|
127
133
|
buf.writeUB4(options); // execute options
|
|
128
134
|
buf.writeUB4(stmt.cursorId); // cursor id
|
|
@@ -159,14 +165,14 @@ class ExecuteMessage extends MessageWithData {
|
|
|
159
165
|
buf.writeUInt8(0);
|
|
160
166
|
buf.writeUB4(0);
|
|
161
167
|
}
|
|
162
|
-
buf.writeUB4(
|
|
168
|
+
buf.writeUB4(registrationIdLsb);
|
|
163
169
|
buf.writeUInt8(0); // pointer (al8objlist)
|
|
164
170
|
buf.writeUInt8(1); // pointer (al8objlen)
|
|
165
171
|
buf.writeUInt8(0); // pointer (al8blv)
|
|
166
172
|
buf.writeUB4(0); // al8blv
|
|
167
173
|
buf.writeUInt8(0); // pointer (al8dnam)
|
|
168
174
|
buf.writeUB4(0); // al8dnaml
|
|
169
|
-
buf.writeUB4(
|
|
175
|
+
buf.writeUB4(registrationIdMsb);
|
|
170
176
|
if (this.arrayDmlRowCounts) {
|
|
171
177
|
buf.writeUInt8(1); // pointer (al8pidmlrc)
|
|
172
178
|
buf.writeUB4(this.numExecs); // al8pidmlrcbl
|
|
@@ -323,7 +329,7 @@ class ExecuteMessage extends MessageWithData {
|
|
|
323
329
|
const stmt = this.statement;
|
|
324
330
|
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly
|
|
325
331
|
&& !stmt.requiresDefine && !stmt.noPrefetch && !stmt.isDdl
|
|
326
|
-
&& !this.batchErrors) {
|
|
332
|
+
&& !this.batchErrors && stmt._registrationId === 0n) {
|
|
327
333
|
if (stmt.isQuery && this.options.prefetchRows > 0) {
|
|
328
334
|
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
|
|
329
335
|
} else {
|
|
@@ -41,6 +41,8 @@ const PingMessage = require('./ping.js');
|
|
|
41
41
|
const ProtocolMessage = require('./protocol.js');
|
|
42
42
|
const RollbackMessage = require('./rollback.js');
|
|
43
43
|
const SessionReleaseMessage = require('./sessionRelease.js');
|
|
44
|
+
const SubscrMessage = require('./subscribe.js');
|
|
45
|
+
const NotifyMessage = require('./notification.js');
|
|
44
46
|
const FastAuthMessage = require('./fastAuth.js');
|
|
45
47
|
const TransactionChangeStateMessage = require('./transactionChangeState.js');
|
|
46
48
|
const TransactionSwitchMessage = require('./transactionSwitch.js');
|
|
@@ -62,6 +64,8 @@ module.exports = {
|
|
|
62
64
|
ProtocolMessage,
|
|
63
65
|
RollbackMessage,
|
|
64
66
|
SessionReleaseMessage,
|
|
67
|
+
SubscrMessage,
|
|
68
|
+
NotifyMessage,
|
|
65
69
|
TransactionChangeStateMessage,
|
|
66
70
|
TransactionSwitchMessage
|
|
67
71
|
};
|