Fixed bug which throws NJS-112 error during fetching of JSON and Vector columns as string after table recreation with statement caching

This commit is contained in:
Sharad Chandran R 2024-06-20 12:23:31 +05:30
parent f6c8f6c7e7
commit 94ad326d9c
5 changed files with 161 additions and 1 deletions

View File

@ -7,6 +7,16 @@ node-oracledb Release Notes
For deprecated and desupported features, see :ref:`Deprecations and desupported features <deprecations>`.
node-oracledb `v6.6.0 <https://github.com/oracle/node-oracledb/compare/v6.5.1...v6.6.0>`__ (TBD)
---------------------------------------------------------------------------------------------------------
Thin Mode Changes
+++++++++++++++++
#) Fixed bug which throws an `NJS-112` error during fetching of JSON and
vector columns after table recreation. This is similar to the
fix provided for GitHub issue #1565.
node-oracledb `v6.5.1 <https://github.com/oracle/node-oracledb/compare/v6.5.0...v6.5.1>`__ (23 May 2024)
---------------------------------------------------------------------------------------------------------

View File

@ -140,7 +140,11 @@ class MessageWithData extends Message {
if ((cVar.fetchInfo.dbType._oraTypeNum === constants.TNS_DATA_TYPE_CLOB
&& pVar.fetchInfo.fetchType._oraTypeNum === constants.TNS_DATA_TYPE_LONG)
|| (cVar.fetchInfo.dbType._oraTypeNum === constants.TNS_DATA_TYPE_BLOB
&& pVar.fetchInfo.fetchType._oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW)) {
&& pVar.fetchInfo.fetchType._oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW)
|| (cVar.fetchInfo.dbType._oraTypeNum === constants.TNS_DATA_TYPE_JSON
&& pVar.fetchInfo.fetchType._oraTypeNum === constants.TNS_DATA_TYPE_VARCHAR)
|| (cVar.fetchInfo.dbType._oraTypeNum === constants.TNS_DATA_TYPE_VECTOR
&& pVar.fetchInfo.fetchType._oraTypeNum === constants.TNS_DATA_TYPE_LONG)) {
cVar.type = pVar.fetchInfo.fetchType;
cVar.maxSize = pVar.maxSize;
}

View File

@ -1026,4 +1026,98 @@ describe('244.dataTypeJson.js', function() {
}); // 244.12
describe('244.13 Read JSON data on meta data change', function() {
const tableNameJSON = 'nodb_myjson_recreate';
let sequence = 1;
const sqlCreate = " CREATE TABLE " + tableNameJSON + " ( \n" +
" id NUMBER, \n" +
" content JSON \n" +
" )";
before('create table, insert data', async function() {
if (!isRunnable) {
this.skip();
}
await testsUtil.createTable(connection, tableNameJSON, sqlCreate);
}); // before()
after(async function() {
if (!isRunnable) {
this.skip();
}
oracledb.stmtCacheSize = default_stmtCacheSize;
oracledb.fetchAsString = [];
await testsUtil.dropTable(connection, tableNameJSON);
}); // after()
async function recreateTable() {
await testsUtil.dropTable(connection, tableNameJSON);
await testsUtil.createTable(connection, tableNameJSON, sqlCreate);
}
const testInsertAndFetch = async function(seq, jsonVal, resultStr, selectOpts) {
let sql = "insert into " + tableNameJSON + " ( id, content ) values (:i, :c)";
const binds = [
{ val: seq, type: oracledb.NUMBER, dir: oracledb.BIND_IN },
{ val: jsonVal, type: oracledb.DB_TYPE_JSON, dir: oracledb.BIND_IN }
];
await connection.execute(sql, binds);
sql = "select content as C from " + tableNameJSON + " where id = " + seq;
const result = await connection.execute(sql, [], selectOpts);
assert.strictEqual(result.rows[0][0], resultStr);
};
it('244.13.1 table recreate - with oracledb.fetchAsString', async function() {
oracledb.fetchAsString = [ oracledb.DB_TYPE_JSON ];
const jsonVals = [{ "key5": "2018/11/01 18:30:00" }];
const resultStr = ["{\"key5\":\"2018/11/01 18:30:00\"}"];
// Add the JSON Field with Long Field Name to the JSON Values Array
// for Oracle DB 23.4 (and Oracle Client 23.4)
if (isOracle_23_4) {
const longFieldName = 'A'.repeat(1000);
const jsonVal = {};
jsonVal[longFieldName] = "2018/11/01 18:30:00";
jsonVals.push(jsonVal);
resultStr.push(`{"${longFieldName}":"2018/11/01 18:30:00"}`);
}
for (let i = 0; i < jsonVals.length; i++) {
await testInsertAndFetch(sequence, jsonVals[i], resultStr[i], {});
sequence++;
}
await recreateTable();
sequence = 1;
for (let i = 0; i < jsonVals.length; i++) {
await testInsertAndFetch(sequence, jsonVals[i], resultStr[i], {});
sequence++;
}
}); // 244.13.1
it('244.13.2 table recreate - with fetchInfo oracledb.STRING', async function() {
oracledb.fetchAsString = [];
const jsonVal = { "key5": "2018/11/01 18:30:00" };
const resultStr = "{\"key5\":\"2018/11/01 18:30:00\"}";
const options = {
fetchInfo: { C: { type: oracledb.STRING } }
};
// Test Insert and Fetch of JSON Data
await testInsertAndFetch(sequence, jsonVal, resultStr, options);
// Recreate the same table
await recreateTable();
// Test Insert and Fetch of JSON Data again
await testInsertAndFetch(sequence, jsonVal, resultStr, options);
sequence++;
}); // 244.13.2
}); // 244.13
});

View File

@ -1897,4 +1897,52 @@ describe('294. dataTypeVector1.js', function() {
);
}
}); // 294.72
it('294.73 fetch VECTOR column as string with table recreate', async function() {
oracledb.fetchTypeHandler = function() {
return {type: oracledb.STRING};
};
const table = 'nodb_vectorDbTable1';
const sqlCreate = `CREATE TABLE IF NOT EXISTS ${table} (
IntCol NUMBER,
Vector64Col vector(10, float64)
)`;
let plsqlCreate = testsUtil.sqlCreateTable(table, sqlCreate);
await connection.execute(plsqlCreate);
// Create a Float64Array
const float64Array = new Float64Array(
[-999999.12345, 987654.321, -12345.6789, 56789.0123,
-314159.2654, 291828.1828, -99999.9999, 43210.9876, -87654.321, 65432.1098]);
const sqlInsert = `INSERT INTO ${table} (IntCol, Vector64Col) VALUES(:id, :vec64)`;
const bindOpts = {
id: 2,
vec64: float64Array
};
await connection.execute(sqlInsert, bindOpts);
let result = await connection.execute(`SELECT Vector64Col FROM ${table}`);
// Convert the vector data returned as a string back to Float64Array
const resultFloat64Array1 = new Float64Array(JSON.parse(result.rows[0][0]));
assert.deepStrictEqual(resultFloat64Array1, float64Array);
await connection.execute(testsUtil.sqlDropTable(table));
// Recreate the table with same data and redo the fetch
plsqlCreate = testsUtil.sqlCreateTable(table, sqlCreate);
await connection.execute(plsqlCreate);
await connection.execute(sqlInsert, bindOpts);
result = await connection.execute(`SELECT Vector64Col FROM ${table}`);
// Convert the vector data returned as a string back to Float64Array
const resultFloat64Array2 = new Float64Array(JSON.parse(result.rows[0][0]));
assert.deepStrictEqual(resultFloat64Array2, float64Array);
await connection.execute(testsUtil.sqlDropTable(table));
}); // 294.73
});

View File

@ -4940,6 +4940,9 @@ oracledb.OUT_FORMAT_OBJECT and resultSet = true
244.11.3 fetch JSON with relative offsets and shared fields, not values
244.12 Verify auto-generated SODA document key
244.12.1 Verify Json Id on select
244.13 Read JSON data on meta data change
244.13.1 table recreate - with oracledb.fetchAsString
244.13.2 table recreate - with fetchInfo oracledb.STRING
245. fetchLobAsStrBuf.js
245.1 CLOB,BLOB Insert
@ -5775,6 +5778,7 @@ oracledb.OUT_FORMAT_OBJECT and resultSet = true
294.70 typed arrays with undefined value
294.71 typed arrays with null values
294.72 inserting empty vector in Fixed and Flex vector columns
294.73 fetch VECTOR column as string with table recreate
295. dataTypeVector2.js
295.1 verify fetch information for older clients