oracle / node-oracledb

Oracle Database driver for Node.js maintained by Oracle Corp.
http://oracle.github.io/node-oracledb/
Other
2.24k stars 1.07k forks source link

fetchAsString raw type not supported in thin mode #1586

Closed hellower closed 10 months ago

hellower commented 1 year ago

$ npm list|grep oracle ├── oracledb@6.0.2

$ uname -a Linux tnt-factory-ubuntu 5.15.0-76-generic #83-Ubuntu SMP Thu Jun 15 19:16:32 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

................ node.js ........................ oracledb.fetchAsString = [oracledb.DB_TYPE_RAW];

,.. select saddr from v$session where rownum <= 1; .. ..............

  1. thick mode 00000000690F5028 <--- fetch as string / good

  2. thin mode {"data": [0,0,0,0,105,15,80,40], "type": "Buffer"} -- not good


----oracle node  impl/resultset.js source ...
103     // in thin mode, Oracle NUMBER values are internally fetched as string in
104     // order to preserve precision so must be converted to JavaScript Number
105     // when needed; other numeric and date types are fetched natively as
106     // JavaScript Number and Date values and are converted to string using
107     // toString() when desired
108     if (settings.thin) {
109       let converter;
110       const userConverter = metadata.converter;
111       if (metadata.dbType === types.DB_TYPE_NUMBER &&
112           metadata.fetchType === types.DB_TYPE_NUMBER) {
113         converter = (v) => (v === null) ? null : parseFloat(v);
114       } else if (metadata.fetchType === types.DB_TYPE_VARCHAR &&    <---------- DB_TYPE_RAW NOT exists???
115           (metadata.dbType === types.DB_TYPE_BINARY_DOUBLE ||
116            metadata.dbType === types.DB_TYPE_BINARY_FLOAT ||
117            metadata.dbType === types.DB_TYPE_DATE ||
118            metadata.dbType === types.DB_TYPE_TIMESTAMP ||
119            metadata.dbType === types.DB_TYPE_TIMESTAMP_LTZ ||
120            metadata.dbType === types.DB_TYPE_TIMESTAMP_TZ)) {
121         converter = (v) => (v === null) ? null : v.toString();
122       }
123       if (userConverter && converter) {
124         const internalConverter = converter;
125         converter = (v) => userConverter(internalConverter(v));
126       }
127       if (converter) {
128         metadata.converter = converter;
129       }
130     }
131 
cjbj commented 1 year ago

Thanks for the report.

sharadraju commented 10 months ago
diff --git a/lib/impl/resultset.js b/lib/impl/resultset.js
index 3815e8e8..7d96a1f2 100644
--- a/lib/impl/resultset.js
+++ b/lib/impl/resultset.js
@@ -111,14 +111,17 @@ class ResultSetImpl {
       if (metadata.dbType === types.DB_TYPE_NUMBER &&
           metadata.fetchType === types.DB_TYPE_NUMBER) {
         converter = (v) => (v === null) ? null : parseFloat(v);
-      } else if (metadata.fetchType === types.DB_TYPE_VARCHAR &&
-          (metadata.dbType === types.DB_TYPE_BINARY_DOUBLE ||
+      } else if (metadata.fetchType === types.DB_TYPE_VARCHAR) {
+        if (metadata.dbType === types.DB_TYPE_BINARY_DOUBLE ||
            metadata.dbType === types.DB_TYPE_BINARY_FLOAT ||
            metadata.dbType === types.DB_TYPE_DATE ||
            metadata.dbType === types.DB_TYPE_TIMESTAMP ||
            metadata.dbType === types.DB_TYPE_TIMESTAMP_LTZ ||
-           metadata.dbType === types.DB_TYPE_TIMESTAMP_TZ)) {
-        converter = (v) => (v === null) ? null : v.toString();
+           metadata.dbType === types.DB_TYPE_TIMESTAMP_TZ) {
+          converter = (v) => (v === null) ? null : v.toString();
+        } else if (metadata.dbType === types.DB_TYPE_RAW) {
+          converter = (v) => (v === null) ? null : v.toString('hex').toUpperCase();
+        }
       }
       if (userConverter && converter) {
         const internalConverter = converter;

The patch file for this issue has been uploaded in GitHub. This fix will be available as part of the 6.1 release

sharadraju commented 10 months ago

This is now fixed in the 6.1 release.