oracle / node-oracledb

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

Writing unicode characters to CLOB stream gives unexpected string growth #1069

Closed wallride closed 5 years ago

wallride commented 5 years ago

Hi again! :) I've got another problem while trying to play with LOBs. It's a problem with unicode characters (tat take more then 1 byte to store). When I write such a character to a CLOB an additional space character (or may be just 0x00 byte) appears after the written chunk. The more special symbols, the more spaces I see... Google and experiments with specifying 'utf8' encoding gave nothing...

Here's a code example to reproduce the problem:

const oracle = require('oracledb');

// PL/SQL Procedure
// CREATE PROCEDURE mock_lob(P_CLOB IN OUT CLOB) AS BEGIN NULL; END;

const originString = 'dddЩЩЩ';

oracle.getConnection({connectString:'odb_app', user: 'system', password: 'oracle'}, (err, connection) => {
    connection.createLob(oracle.CLOB, (err, clob) => {
        if (err) {
            console.error(err);
            return;
        }

        console.log('CLOB created');

        // Write originString to clob many times

        let sentData = '';

        for (let i = 0; i < 1000; i++) {
            clob.write(originString);
            sentData += originString;
        }
        clob.end();

        clob.on('finish', async () => {
            console.log('Write to CLOB complete');
            let outClob;

            // Now execute: pass the populated clob to procedure and receive another clob that is expected to equal origin one

            try {
                const result = await connection.execute(
                    'begin mock_lob(P_CLOB => :clob); end;',
                    {clob: {type: oracle.CLOB, dir: oracle.BIND_INOUT, val: clob}},
                    {outFormat: oracle.OBJECT}
                );
                outClob = result.outBinds['clob'];
            } catch(e) {
                console.error(e);
                return;
            }
            finally {
                clob.close();
            }

            // Read the received clob object an check data consistency

            let receivedData = '';
            outClob.on('data', chunk => {
                const slice = sentData.slice(receivedData.length, receivedData.length + chunk.length);

                if (slice !== chunk)
                    throw new Error(`Unequal part ${receivedData.length}-${receivedData.length + chunk.length}\n${slice}\n${chunk}`);

                receivedData += chunk;
            })
        });
    });
});

Can anyone explain what am I missing?

anthony-tuininga commented 5 years ago

I have replicated the issue and have a patch that corrects it available. @cjbj will push it out to the dev-4.0 branch once it has been tested further internally.

cjbj commented 5 years ago

@wallride I pushed the proposed patch to the dev-4.0 branch. Tests are still pending, but please let us know what you find. See https://github.com/oracle/node-oracledb/issues/1053#issuecomment-472233930 for info about installing this development branch.

wallride commented 5 years ago

@cjbj I switched to dev-4.0 and got another error (not related with this particular issue). Probably you are aware of it.

Statement:

begin "TEST".createItem(
    P_CODE =>     :code,
    P_CREATED =>  :created,
    P_BIN =>      :bin,
    P_ID =>       :id
); end;

Bind parameters:

 { code: { type: 2001, dir: 3002, val: 'code-0' },
  created: { type: 2014, dir: 3001, val: new Date() },
  bin: { type: 2006, dir: 3001, val: <Buffer 30> },
  id: { type: 2010, dir: 3003 } } { outFormat: 4002, fetchInfo: {} }

Got an error: Error: NJS-012: encountered invalid bind data type in parameter 2.

So, I cannot test the patch. :)

anthony-tuininga commented 5 years ago

Can you provide the full code that you are using? Without that it is very hard to know why you might be getting that error.

cjbj commented 5 years ago

@wallride our regressions are passing, so we don't know about it. Please tell us more, as @anthony-tuininga recommended.

cjbj commented 5 years ago

@wallride I couldn't reproduce any problem with issue1069.js

cjbj commented 5 years ago

@wallride ping?

cjbj commented 5 years ago

@wallride Node-oracledb 4.0 has been released with a fix for the original problem. We couldn't reproduce your later report. The release announcement is at https://blogs.oracle.com/opal/oracle-db-named-objects-and-advanced-queuing-support-new-in-node-oracledb-40