Skip to content

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

@jameschenjav

Description

@jameschenjav
  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/[email protected]/node_modules/oracledb/lib/thin/protocol/messages/withData.js:617:33)
    at ExecuteMessage.processBindParams (./node_modules/.pnpm/[email protected]/node_modules/oracledb/lib/thin/protocol/messages/withData.js:611:10)
    at ExecuteMessage.writeExecuteMessage (./node_modules/.pnpm/[email protected]/node_modules/oracledb/lib/thin/protocol/messages/execute.js:216:19)
    at ExecuteMessage.encode (./node_modules/.pnpm/[email protected]/node_modules/oracledb/lib/thin/protocol/messages/execute.js:287:32)
    at Protocol._encodeMessage (./node_modules/.pnpm/[email protected]/node_modules/oracledb/lib/thin/protocol/protocol.js:108:20)
    at Protocol._processMessage (./node_modules/.pnpm/[email protected]/node_modules/oracledb/lib/thin/protocol/protocol.js:151:18)
    at ThinConnectionImpl._execute (./node_modules/.pnpm/[email protected]/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/[email protected]/node_modules/oracledb/lib/thin/connection.js:927:14)
    at async Connection.execute (./node_modules/.pnpm/[email protected]/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
  }
]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions