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

feat: add support for bigints (backport of #14485) #15413

Merged
merged 10 commits into from
Dec 12, 2022
2 changes: 1 addition & 1 deletion src/data-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class NUMBER extends ABSTRACT {
return true;
}
_stringify(number) {
if (typeof number === 'number' || typeof number === 'boolean' || number === null || number === undefined) {
if (typeof number === 'number' || typeof number === 'bigint' || typeof number === 'boolean' || number === null || number === undefined) {
return number;
}
if (typeof number.toString === 'function') {
Expand Down
2 changes: 1 addition & 1 deletion src/dialects/abstract/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2792,7 +2792,7 @@ class QueryGenerator {
type: options.type
});
}
if (typeof smth === 'number') {
if (typeof smth === 'number' || typeof smth === 'bigint') {
let primaryKeys = factory ? Object.keys(factory.primaryKeys) : [];

if (primaryKeys.length > 0) {
Expand Down
24 changes: 15 additions & 9 deletions src/dialects/db2/query.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const util = require('node:util');

const AbstractQuery = require('../abstract/query');
const sequelizeErrors = require('../../errors');
const parserStore = require('../parserStore')('db2');
Expand All @@ -14,15 +16,19 @@ class Query extends AbstractQuery {
}

getSQLTypeFromJsType(value) {
const param = { ParamType: 'INPUT', Data: value };
if (Buffer.isBuffer(value)) {
param.DataType = 'BLOB';
return param;
return { ParamType: 'INPUT', DataType: 'BLOB', Data: value };
}

if (typeof value === 'bigint') {
// The ibm_db module does not handle bigint, send as a string instead:
return value.toString();
}

return value;
}

async _run(connection, sql, parameters) {
async _run(connection, sql, parameters) {
this.sql = sql;
const benchmark = this.sequelize.options.benchmark || this.options.benchmark;
let queryBegin;
Expand Down Expand Up @@ -98,10 +104,10 @@ class Query extends AbstractQuery {
}

stmt.execute(params, (err, result, outparams) => {
debug(`executed(${this.connection.uuid || 'default'}):${newSql} ${parameters ? JSON.stringify(parameters) : ''}`);
debug(`executed(${this.connection.uuid || 'default'}):${newSql} ${parameters ? util.inspect(parameters, { compact: true, breakLength: Infinity }) : ''}`);

if (benchmark) {
this.sequelize.log(`Executed (${ this.connection.uuid || 'default' }): ${ newSql} ${parameters ? JSON.stringify(parameters) : ''}`, Date.now() - queryBegin, this.options);
this.sequelize.log(`Executed (${this.connection.uuid || 'default'}): ${newSql} ${parameters ? util.inspect(parameters, { compact: true, breakLength: Infinity }) : ''}`, Date.now() - queryBegin, this.options);
}

if (err && err.message) {
Expand Down Expand Up @@ -454,7 +460,7 @@ class Query extends AbstractQuery {
result = result || this.sql.startsWith('SELECT NAME AS "name", TBNAME AS "tableName", UNIQUERULE AS "keyType", COLNAMES, INDEXTYPE AS "type" FROM SYSIBM.SYSINDEXES');
return result;
}

handleShowIndexesQuery(data) {
let currItem;
const result = [];
Expand All @@ -468,7 +474,7 @@ class Query extends AbstractQuery {
unique: item.keyType === 'U',
type: item.type
};

_.forEach(item.COLNAMES.replace(/\+|-/g, x => { return ` ${ x}`; }).split(' '), column => {
let columnName = column.trim();
if ( columnName ) {
Expand All @@ -484,7 +490,7 @@ class Query extends AbstractQuery {
result.push(currItem);
}
});
return result;
return result;
}

handleInsertQuery(results, metaData) {
Expand Down
3 changes: 3 additions & 0 deletions src/dialects/mssql/connection-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ class ConnectionManager extends AbstractConnectionManager {
if (error.message.includes('connect EADDRNOTAVAIL')) {
throw new sequelizeErrors.HostNotReachableError(error);
}
if (error.message.includes('connect EAFNOSUPPORT')) {
throw new sequelizeErrors.HostNotReachableError(error);
}
if (error.message.includes('getaddrinfo ENOTFOUND')) {
throw new sequelizeErrors.HostNotFoundError(error);
}
Expand Down
13 changes: 11 additions & 2 deletions src/dialects/mssql/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const { logger } = require('../../utils/logger');

const debug = logger.debugContext('sql:mssql');

const minSafeIntegerAsBigInt = BigInt(Number.MIN_SAFE_INTEGER);
const maxSafeIntegerAsBigInt = BigInt(Number.MAX_SAFE_INTEGER);

function getScale(aNum) {
if (!Number.isFinite(aNum)) return 0;
let e = 1;
Expand All @@ -21,8 +24,7 @@ class Query extends AbstractQuery {
}

getSQLTypeFromJsType(value, TYPES) {
const paramType = { type: TYPES.VarChar, typeOptions: {} };
paramType.type = TYPES.NVarChar;
const paramType = { type: TYPES.NVarChar, typeOptions: {}, value };
if (typeof value === 'number') {
if (Number.isInteger(value)) {
if (value >= -2147483648 && value <= 2147483647) {
Expand All @@ -35,6 +37,13 @@ class Query extends AbstractQuery {
//Default to a reasonable numeric precision/scale pending more sophisticated logic
paramType.typeOptions = { precision: 30, scale: getScale(value) };
}
} else if (typeof value === 'bigint') {
if (value < minSafeIntegerAsBigInt || value > maxSafeIntegerAsBigInt) {
paramType.type = TYPES.VarChar;
paramType.value = value.toString();
} else {
return this.getSQLTypeFromJsType(Number(value), TYPES);
}
} else if (typeof value === 'boolean') {
paramType.type = TYPES.Bit;
}
Expand Down
30 changes: 19 additions & 11 deletions src/dialects/oracle/data-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ module.exports = BaseTypes => {
// sending it over the wire as a string,
// We pass it through escape function to remove un-necessary quotes
// this.format in insert/bulkinsert query calls stringify hence we need to convert binary buffer
// to hex string. Since this block is used by both bind (insert/bulkinsert) and
// non-bind (select query where clause) hence we need to
// to hex string. Since this block is used by both bind (insert/bulkinsert) and
// non-bind (select query where clause) hence we need to
// have an operation that supports both
return options.escape(value.toString('hex'));
}
}
return options.escape(value);
}

_getBindDef(oracledb) {
if (this._binary) {
return { type: oracledb.DB_TYPE_RAW, maxSize: this._length };
}
}
return { type: oracledb.DB_TYPE_VARCHAR, maxSize: this._length };
}

Expand Down Expand Up @@ -93,7 +93,7 @@ module.exports = BaseTypes => {

_sanitize(value) {
if (typeof value === 'string') {
// If value is a string we return true if among '1' and 'true'
// If value is a string we return true if among '1' and 'true'
// We return false if among '0' and 'false'
// Else return the value as is and let the DB raise error for invalid values
return value === '1' || value === 'true' ? true : value === '0' || value === 'false' ? false : value;
Expand Down Expand Up @@ -212,7 +212,7 @@ module.exports = BaseTypes => {
*/
_bindParam(value, options) {
return options.bindParam(value);
}
}
}

DATE.prototype.escape = false;
Expand Down Expand Up @@ -302,6 +302,14 @@ module.exports = BaseTypes => {
_getBindDef(oracledb) {
marra85 marked this conversation as resolved.
Show resolved Hide resolved
return { type: oracledb.DB_TYPE_NUMBER };
}

_sanitize(value) {
if (typeof value === 'bigint' || typeof value === 'number') {
return value.toString();
}
return value;
}

}

class NUMBER extends BaseTypes.NUMBER {
Expand Down Expand Up @@ -335,7 +343,7 @@ module.exports = BaseTypes => {
_stringify(value) {
if (value === Number.POSITIVE_INFINITY) {
return 'inf';
}
}
if (value === Number.NEGATIVE_INFINITY) {
return '-inf';
}
Expand All @@ -348,11 +356,11 @@ module.exports = BaseTypes => {
}

class BLOB extends BaseTypes.BLOB {
// Generic hexify returns X'${hex}' but Oracle expects '${hex}' for BLOB datatype
// Generic hexify returns X'${hex}' but Oracle expects '${hex}' for BLOB datatype
_hexify(hex) {
return `'${hex}'`;
}

toSql() {
return 'BLOB';
}
Expand Down Expand Up @@ -438,9 +446,9 @@ module.exports = BaseTypes => {
_bindParam(value, options) {
if (typeof value === 'string') {
return options.bindParam(new Date(value));
}
}
return options.bindParam(value);

}
}

Expand Down