Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oracledb v6.2.0 parses multi-line comment into extra bind vars #1625

Closed
jameschenjav opened this issue Nov 20, 2023 · 5 comments
Closed

oracledb v6.2.0 parses multi-line comment into extra bind vars #1625

jameschenjav opened this issue Nov 20, 2023 · 5 comments

Comments

@jameschenjav
Copy link

  1. What versions are you using?

Oracle DB 21c XE

process.platform
'linux'
process.version
'v20.9.0'
process.arch
'x64'
require('oracledb').versionString
'6.2.0'
require('oracledb').oracleClientVersionString
undefined

  1. Is it an error or a hang or a crash?

An error. I have tried v6.1.0 and it works without a problem.

  1. What error(s) or behavior you are seeing?
Uncaught TypeError: Cannot read properties of null (reading 'type')
    at ExecuteMessage.writeColumnMetadata (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/protocol/messages/withData.js:617:33)
    at ExecuteMessage.processBindParams (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/protocol/messages/withData.js:611:10)
    at ExecuteMessage.writeExecuteMessage (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/protocol/messages/execute.js:216:19)
    at ExecuteMessage.encode (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/protocol/messages/execute.js:287:32)
    at Protocol._encodeMessage (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/protocol/protocol.js:108:20)
    at Protocol._processMessage (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/protocol/protocol.js:151:18)
    at ThinConnectionImpl._execute (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/connection.js:195:28)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ThinConnectionImpl.execute (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/thin/connection.js:927:14)
    at async Connection.execute (./node_modules/.pnpm/oracledb@6.2.0/node_modules/oracledb/lib/connection.js:861:16)
  processBindParams(buf, params) {
    const bindVars = [];
    const nonReturningParams = [];
    for (const bindInfo of params) {
      if (!bindInfo.isReturnBind) {
        nonReturningParams.push(bindInfo);
      }
      bindVars.push(bindInfo.bindVar);
    }
+    console.log(params, bindVars); // added on line 610, see the log below
    this.writeColumnMetadata(buf, bindVars);
    return nonReturningParams;
  }
  1. Include a runnable Node.js script that shows the problem.
const oracledb = require('oracledb');
const sql = `
/************************************************************************************************
 * Get COLUMN of tables
 *
 * Returns:
 *  - table_name: string
 *  - column_name: string
 *  - data_type: number
 *  - data_type: 'BLOB' | 'CHAR' | 'CLOB' | 'DATE' | 'FLOAT' | 'NUMBER' | 'TIMESTAMP(6)' | 'TIMESTAMP(6) WITH LOCAL TIME ZONE' | 'VARCHAR2'
 *  - data_length: number
 *  - data_precision: number | null
 *  - data_scale: number | null
 *  - nullable: 'Y' | 'N'
 *  - data_default: long | null
 *  - column_id: number
 ************************************************************************************************/
  SELECT  table_name
        , column_name
        , char_length
        , char_used
        , data_type
        , data_length
        , data_precision
        , data_scale
        , nullable
        , data_default
        , column_id
  FROM all_tab_cols
  WHERE owner = UPPER(:schema)
    AND hidden_column = 'NO'
    AND virtual_column = 'NO'
    AND user_generated = 'YES'
    AND table_name NOT IN (
      SELECT mview_name FROM all_mviews WHERE owner = UPPER(:schema)
      UNION SELECT view_name FROM all_views WHERE owner = UPPER(:schema)
      UNION SELECT log_table FROM all_mview_logs WHERE log_owner = UPPER(:schema)
    )
  ORDER BY table_name, column_id
`;

oracledb.getConnection({})
  .then((conn) => {
    return conn.execute(sql, { schema: 'foo' });
  });

It looks like it parsed the comment into bind vars (with regex?):

/************************************************************************************************
 * Get COLUMN of tables
 *
 * Returns:
 *  - table_name: string
 *  - column_name: string
 *  - data_type: number
 *  - data_type: 'BLOB' | 'CHAR' | 'CLOB' | 'DATE' | 'FLOAT' | 'NUMBER' | 'TIMESTAMP(6)' | 'TIMESTAMP(6) WITH LOCAL TIME ZONE' | 'VARCHAR2'
 *  - data_length: number
 *  - data_precision: number | null
 *  - data_scale: number | null
 *  - nullable: 'Y' | 'N'
 *  - data_default: long | null
 *  - column_id: number
 ************************************************************************************************/

// from `console.log`

[
  BindInfo { // table_name: string
    bindName: 'STRING',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo { // column_name: string
    bindName: 'STRING',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo { // data_type: number
    bindName: 'NUMBER',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo { // data_length: number
    bindName: 'NUMBER',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo { // data_precision: number
    bindName: 'NUMBER',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo { // data_scale: number
    bindName: 'NUMBER',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo { // data_default: long
    bindName: 'LONG',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo { // column_id: number
    bindName: 'NUMBER',
    isReturnBind: false,
    maxSize: 0,
    numElements: 0,
    maxArraySize: 0,
    type: null,
    isArray: false,
    dir: 3001,
    bindVar: null
  },
  BindInfo {
    bindName: 'SCHEMA',
    isReturnBind: false,
    maxSize: 6,
    numElements: 1,
    maxArraySize: undefined,
    type: [DbType DB_TYPE_VARCHAR],
    isArray: false,
    dir: 3001,
    bindVar: {
      name: 'schema',
      values: [Array],
      isArray: false,
      dir: 3001,
      type: [DbType DB_TYPE_VARCHAR],
      maxSize: 6
    }
  },
  BindInfo {
    bindName: 'SCHEMA',
    isReturnBind: false,
    maxSize: 6,
    numElements: 1,
    maxArraySize: undefined,
    type: [DbType DB_TYPE_VARCHAR],
    isArray: false,
    dir: 3001,
    bindVar: {
      name: 'schema',
      values: [Array],
      isArray: false,
      dir: 3001,
      type: [DbType DB_TYPE_VARCHAR],
      maxSize: 6
    }
  },
  BindInfo {
    bindName: 'SCHEMA',
    isReturnBind: false,
    maxSize: 6,
    numElements: 1,
    maxArraySize: undefined,
    type: [DbType DB_TYPE_VARCHAR],
    isArray: false,
    dir: 3001,
    bindVar: {
      name: 'schema',
      values: [Array],
      isArray: false,
      dir: 3001,
      type: [DbType DB_TYPE_VARCHAR],
      maxSize: 6
    }
  },
  BindInfo {
    bindName: 'SCHEMA',
    isReturnBind: false,
    maxSize: 6,
    numElements: 1,
    maxArraySize: undefined,
    type: [DbType DB_TYPE_VARCHAR],
    isArray: false,
    dir: 3001,
    bindVar: {
      name: 'schema',
      values: [Array],
      isArray: false,
      dir: 3001,
      type: [DbType DB_TYPE_VARCHAR],
      maxSize: 6
    }
  }
] [
  null,
  null,
  null,
  null,
  null,
  null,
  null,
  null,
  {
    name: 'schema',
    values: [ 'foo' ],
    isArray: false,
    dir: 3001,
    type: [DbType DB_TYPE_VARCHAR],
    maxSize: 6
  },
  {
    name: 'schema',
    values: [ 'foo' ],
    isArray: false,
    dir: 3001,
    type: [DbType DB_TYPE_VARCHAR],
    maxSize: 6
  },
  {
    name: 'schema',
    values: [ 'foo' ],
    isArray: false,
    dir: 3001,
    type: [DbType DB_TYPE_VARCHAR],
    maxSize: 6
  },
  {
    name: 'schema',
    values: [ 'foo' ],
    isArray: false,
    dir: 3001,
    type: [DbType DB_TYPE_VARCHAR],
    maxSize: 6
  }
]
@cjbj
Copy link
Member

cjbj commented Nov 21, 2023

Thanks for the report.

@sharadraju
Copy link
Member

We have identified the issue and working on a fix.

@sharadraju
Copy link
Member

@jameschenjav Please apply the following patch in lib/thin/statement.js and let us know:

diff --git a/lib/thin/statement.js b/lib/thin/statement.js
index 9740a85ae..96e09580d 100644
--- a/lib/thin/statement.js
+++ b/lib/thin/statement.js
@@ -142,7 +142,7 @@ class Parser {
           break;
         }
         inComment = true;
-      } else if (!exitingComment && ch === '*') {
+      } else if (ch === '*') {
         exitingComment = true;
       } else if (exitingComment) {
         if (ch === '/') {

@jameschenjav
Copy link
Author

@jameschenjav Please apply the following patch in lib/thin/statement.js and let us know:

diff --git a/lib/thin/statement.js b/lib/thin/statement.js
index 9740a85ae..96e09580d 100644
--- a/lib/thin/statement.js
+++ b/lib/thin/statement.js
@@ -142,7 +142,7 @@ class Parser {
           break;
         }
         inComment = true;
-      } else if (!exitingComment && ch === '*') {
+      } else if (ch === '*') {
         exitingComment = true;
       } else if (exitingComment) {
         if (ch === '/') {

thanks. it's working now

@sharadraju
Copy link
Member

This has been fixed as part of the 6.3 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants