Fixed bug that throws the NJS-111 internal error, on the second SELECT call issued after the first SELECT call on an empty table with LOBs
This commit is contained in:
parent
8abee4c661
commit
bae7dd19bd
|
@ -11,6 +11,10 @@ node-oracledb `v6.0.3 <https://github.com/oracle/node-oracledb/compare/v6.0.2...
|
||||||
Thin Mode Changes
|
Thin Mode Changes
|
||||||
+++++++++++++++++
|
+++++++++++++++++
|
||||||
|
|
||||||
|
#) Fixed bug that throws the NJS-111 internal error, on the second
|
||||||
|
select SQL issued after first select SQL is done on an empty
|
||||||
|
table involving LOB types.
|
||||||
|
|
||||||
#) Avoid throwing errors when calls to ``os.userInfo()`` fail.
|
#) Avoid throwing errors when calls to ``os.userInfo()`` fail.
|
||||||
`Issue #1564 <https://github.com/oracle/node-oracledb/issues/1564>`__.
|
`Issue #1564 <https://github.com/oracle/node-oracledb/issues/1564>`__.
|
||||||
|
|
||||||
|
|
|
@ -77,21 +77,21 @@ class ExecuteMessage extends MessageWithData {
|
||||||
dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
|
dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
|
||||||
options |= constants.TNS_EXEC_OPTION_EXECUTE;
|
options |= constants.TNS_EXEC_OPTION_EXECUTE;
|
||||||
}
|
}
|
||||||
if (stmt.cursorId == 0 || stmt.isDdl) {
|
if (stmt.cursorId === 0 || stmt.isDdl) {
|
||||||
options |= constants.TNS_EXEC_OPTION_PARSE;
|
options |= constants.TNS_EXEC_OPTION_PARSE;
|
||||||
}
|
}
|
||||||
if (stmt.isQuery) {
|
if (stmt.isQuery) {
|
||||||
if (this.parseOnly) {
|
if (this.parseOnly) {
|
||||||
options |= constants.TNS_EXEC_OPTION_DESCRIBE;
|
options |= constants.TNS_EXEC_OPTION_DESCRIBE;
|
||||||
} else {
|
} else {
|
||||||
if (this.options.prefetchRows > 0) {
|
|
||||||
options |= constants.TNS_EXEC_OPTION_FETCH;
|
|
||||||
}
|
|
||||||
if (stmt.cursorId === 0 || stmt.requiresDefine) {
|
if (stmt.cursorId === 0 || stmt.requiresDefine) {
|
||||||
numIters = this.options.prefetchRows;
|
numIters = this.options.prefetchRows;
|
||||||
} else {
|
} else {
|
||||||
numIters = this.options.fetchArraySize;
|
numIters = this.options.fetchArraySize;
|
||||||
}
|
}
|
||||||
|
if (numIters > 0 && !stmt.noPrefetch) {
|
||||||
|
options |= constants.TNS_EXEC_OPTION_FETCH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!stmt.isPlSql && !this.parseOnly) {
|
if (!stmt.isPlSql && !this.parseOnly) {
|
||||||
|
@ -276,7 +276,7 @@ class ExecuteMessage extends MessageWithData {
|
||||||
if (this.currentRow === 0) {
|
if (this.currentRow === 0) {
|
||||||
let stmt = this.statement;
|
let stmt = this.statement;
|
||||||
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.isDdl && !this.batchErrors) {
|
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.isDdl && !this.batchErrors) {
|
||||||
if (stmt.isQuery && !stmt.requiresDefine && this.options.prefetchRows > 0) {
|
if (stmt.isQuery && !stmt.requiresDefine && !stmt.noPrefetch && this.options.prefetchRows > 0) {
|
||||||
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
|
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
|
||||||
} else {
|
} else {
|
||||||
this.functionCode = constants.TNS_FUNC_REEXECUTE;
|
this.functionCode = constants.TNS_FUNC_REEXECUTE;
|
||||||
|
|
|
@ -547,6 +547,7 @@ class MessageWithData extends Message {
|
||||||
variable.maxSize = constants.TNS_MAX_LONG_LENGTH;
|
variable.maxSize = constants.TNS_MAX_LONG_LENGTH;
|
||||||
}
|
}
|
||||||
resultSet.statement.requiresDefine = true;
|
resultSet.statement.requiresDefine = true;
|
||||||
|
resultSet.statement.noPrefetch = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ class Statement {
|
||||||
this.queryVars = [];
|
this.queryVars = [];
|
||||||
this.bindInfoDict = new Map();
|
this.bindInfoDict = new Map();
|
||||||
this.requiresFullExecute = false;
|
this.requiresFullExecute = false;
|
||||||
|
this.noPrefetch = false;
|
||||||
this.returnToCache = false;
|
this.returnToCache = false;
|
||||||
this.numColumns = 0;
|
this.numColumns = 0;
|
||||||
this.lastRowIndex;
|
this.lastRowIndex;
|
||||||
|
|
|
@ -42,6 +42,7 @@ const fs = require('fs');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const dbConfig = require('./dbconfig.js');
|
const dbConfig = require('./dbconfig.js');
|
||||||
const assist = require('./dataTypeAssist.js');
|
const assist = require('./dataTypeAssist.js');
|
||||||
|
const testsUtil = require('./testsUtil.js');
|
||||||
|
|
||||||
let inFileName = 'test/clobexample.txt'; // the file with text to be inserted into the database
|
let inFileName = 'test/clobexample.txt'; // the file with text to be inserted into the database
|
||||||
let outFileName = 'test/clobstreamout.txt'; // output file with the stream out data
|
let outFileName = 'test/clobstreamout.txt'; // output file with the stream out data
|
||||||
|
@ -170,4 +171,43 @@ describe('40. dataTypeClob.js', function() {
|
||||||
await assist.verifyNullValues(connection, tableName);
|
await assist.verifyNullValues(connection, tableName);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('40.3 Read CLOB data on meta data change', function() {
|
||||||
|
let connection = null;
|
||||||
|
const tableNameCLOB = 'nodb_myclobs_re_create';
|
||||||
|
const sqlCreateQuery = `
|
||||||
|
CREATE TABLE ${tableNameCLOB} (
|
||||||
|
num NUMBER,
|
||||||
|
content CLOB
|
||||||
|
)`;
|
||||||
|
const sqlDrop = testsUtil.sqlDropTable(tableNameCLOB);
|
||||||
|
const sqlCreate = testsUtil.sqlCreateTable(tableNameCLOB, sqlCreateQuery);
|
||||||
|
const insertSql = `INSERT INTO ${tableNameCLOB} (num, content) ` +
|
||||||
|
`VALUES (:n, 'CLOB')`;
|
||||||
|
const selectSql = `SELECT content FROM ${tableNameCLOB} WHERE num = 1`;
|
||||||
|
|
||||||
|
before(async function() {
|
||||||
|
oracledb.fetchAsString = [oracledb.CLOB];
|
||||||
|
connection = await oracledb.getConnection(dbConfig);
|
||||||
|
await connection.execute(sqlCreate);
|
||||||
|
await connection.execute(insertSql, { n: 1 }, { autoCommit: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async function() {
|
||||||
|
oracledb.fetchAsString = [];
|
||||||
|
await connection.execute(sqlDrop);
|
||||||
|
await connection.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('40.3.1 Recreate table after CLOB column is read and statement is in statement cache',
|
||||||
|
async function() {
|
||||||
|
await connection.execute(selectSql, {}, { keepInStmtCache: true });
|
||||||
|
await connection.execute(sqlDrop);
|
||||||
|
await connection.execute(sqlCreate);
|
||||||
|
await connection.execute(insertSql, { n: 1 }, { autoCommit: false });
|
||||||
|
await connection.execute(selectSql);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,6 +36,7 @@ const fs = require('fs');
|
||||||
const fsPromises = require('fs/promises');
|
const fsPromises = require('fs/promises');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const dbConfig = require('./dbconfig.js');
|
const dbConfig = require('./dbconfig.js');
|
||||||
|
const testsUtil = require('./testsUtil.js');
|
||||||
|
|
||||||
describe("72. lobBind2.js", function() {
|
describe("72. lobBind2.js", function() {
|
||||||
|
|
||||||
|
@ -539,4 +540,38 @@ describe("72. lobBind2.js", function() {
|
||||||
|
|
||||||
}); // 72.3
|
}); // 72.3
|
||||||
|
|
||||||
|
describe('72.4 Create Table with CLOB and Number columns and do select with empty rows and select after rows insertion', function() {
|
||||||
|
let connection = null;
|
||||||
|
const tableNameCLOB = 'nodb_myclobs_num_table';
|
||||||
|
const sqlCreateQuery = `
|
||||||
|
CREATE TABLE ${tableNameCLOB} (
|
||||||
|
F1 NUMBER,
|
||||||
|
F2 CLOB,
|
||||||
|
F3 CLOB
|
||||||
|
)`;
|
||||||
|
const sqlDrop = testsUtil.sqlDropTable(tableNameCLOB);
|
||||||
|
const sqlCreate = testsUtil.sqlCreateTable(tableNameCLOB, sqlCreateQuery);
|
||||||
|
const insertSql = `INSERT INTO ${tableNameCLOB} (F1, F2, F3) ` +
|
||||||
|
`VALUES (:1, :2, :3)`;
|
||||||
|
const selectSql = `SELECT * FROM ${tableNameCLOB} `;
|
||||||
|
|
||||||
|
before(async function() {
|
||||||
|
oracledb.fetchAsString = [oracledb.CLOB];
|
||||||
|
connection = await oracledb.getConnection(dbConfig);
|
||||||
|
await connection.execute(sqlCreate);
|
||||||
|
await connection.execute(selectSql, {}, {keepInStmtCache: true});
|
||||||
|
await connection.execute(insertSql, [1, 'CLOB1', 'CLOB2']);
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async function() {
|
||||||
|
oracledb.fetchAsString = [];
|
||||||
|
await connection.execute(sqlDrop);
|
||||||
|
await connection.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('72.4.1 Read both CLOB and Number with statement being in statement cache', async function() {
|
||||||
|
await connection.execute(selectSql, {}, {keepInStmtCache: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue