mysqljs / sqlstring

Simple SQL escape and format for MySQL
MIT License
403 stars 78 forks source link

How to use "?" placeholders with bigint values? #46

Closed cakoose closed 5 years ago

cakoose commented 5 years ago

Some of our columns are bigints and we're currently using BigNumber.js to work with those values.

My first attempt:

const n = new BigNumber('26000000000000000')
connection.query(`SELECT ?;`, [n], ...)
// SELECT `s` = 1, `e` = 16, `c` = 260, `_isBigNumber` = true

DoingBigNumber.toString() fixes that:

connection.query(`SELECT ?;`, [n.toString()], ...)
// SELECT '26000000000000000'

But the problem is that quoting numbers causes MySQL to treat the value differently, and lose precision when doing arithmetic (bug):

SELECT 26000000000012345;            // 26000000000012345
SELECT '26000000000012345';          // 26000000000012345
SELECT 12345 + 26000000000000000;    // 26000000000012345
SELECT 12345 + '26000000000000000';  // 2.6000000000012344e16

Is there a way to use a "?" placeholder to produce an unquoted bigint value?

dougwilson commented 5 years ago

Something like the following:

console.log(SqlString.format('SELECT ?', [SqlString.raw(n.toString())]))
cakoose commented 5 years ago

Ah, thanks! That does work, but one concern is that we'd lose some protection against SQL injection.

Does the "mysql" package allow replacing "sqlstring" with a different quoting function? I could write a custom function that handles all the standard types and also handles BigNumber.js.

dougwilson commented 5 years ago

https://github.com/mysqljs/mysql/blob/master/Readme.md#custom-format

cakoose commented 5 years ago

Thanks, again!

dougwilson commented 5 years ago

No problem at all! Node.js updated the JavaScript and supports native BigInts now. I don't think this lib works with them, but I should be able to add support, which would mean if you're able to use the native BitInts, then you can use this without modification. It would be like console.log(SqlString.format('SELECT ?', [26000000000000000n]))

cakoose commented 5 years ago

Yeah, BigInts currently come through quoted as well. Would be nice to fix that.

(It'll take us a while to migrate from BigNumber.js to native BigInt, so we'll need to use one of the other workarounds for now...)