Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/commands/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Execute extends Command {
this._rows = [];
this._fields = [];
this._result = [];
this._warningCounts = [];
this._fieldCount = 0;
this._rowParser = null;
this._executeOptions = options;
Expand Down
14 changes: 11 additions & 3 deletions lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Query extends Command {
this._fieldCount = 0;
this._rowParser = null;
this._fields = [];
// Warning counts for SELECT queries only, does not included warning counts for DML queries.
this._warningCounts = [];
this._rows = [];
this._receivedFieldsCount = 0;
this._resultIndex = 0;
Expand Down Expand Up @@ -73,21 +75,23 @@ class Query extends Command {
this.queryTimeout = null;
}
if (this.onResult) {
let rows, fields;
let rows, fields, warningCounts;
if (this._resultIndex === 0) {
rows = this._rows[0];
fields = this._fields[0];
warningCounts = this._warningCounts[0];
} else {
rows = this._rows;
fields = this._fields;
warningCounts = this._warningCounts
}
if (fields) {
process.nextTick(() => {
this.onResult(null, rows, fields);
this.onResult(null, rows, fields, warningCounts);
});
} else {
process.nextTick(() => {
this.onResult(null, rows);
this.onResult(null, rows, fields, warningCounts);
});
}
}
Expand All @@ -105,6 +109,7 @@ class Query extends Command {
}
this._rows.push(rs);
this._fields.push(void 0);
this._warningCounts.push(void 0);
this.emit('fields', void 0);
this.emit('result', rs);
if (rs.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
Expand Down Expand Up @@ -132,6 +137,7 @@ class Query extends Command {
this._receivedFieldsCount = 0;
this._rows.push([]);
this._fields.push([]);
this._warningCounts.push(0);
return this.readField;
}

Expand Down Expand Up @@ -230,6 +236,8 @@ class Query extends Command {
row(packet, _connection) {
if (packet.isEOF()) {
const status = packet.eofStatusFlags();
this._warningCounts[this._resultIndex] = packet.eofWarningCount();

const moreResults = status & ServerStatus.SERVER_MORE_RESULTS_EXISTS;
if (moreResults) {
this._resultIndex++;
Expand Down
25 changes: 9 additions & 16 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const Packets = require('./packets/index.js');
const Commands = require('./commands/index.js');
const ConnectionConfig = require('./connection_config.js');
const CharsetToEncoding = require('./constants/charset_encodings.js');
const ErrorCodeToName = require('./constants/errors.js');

let _connectionId = 0;

Expand Down Expand Up @@ -362,25 +363,17 @@ class Connection extends EventEmitter {
const secureSocket = Tls.connect({
rejectUnauthorized,
requestCert: rejectUnauthorized,
checkServerIdentity: verifyIdentity
? Tls.checkServerIdentity
: function() { return undefined; },
secureContext,
isServer: false,
socket: this.stream,
servername
}, () => {
secureEstablished = true;
if (rejectUnauthorized) {
if (typeof servername === 'string' && verifyIdentity) {
const cert = secureSocket.getPeerCertificate(true);
const serverIdentityCheckError = Tls.checkServerIdentity(servername, cert);
if (serverIdentityCheckError) {
onSecure(serverIdentityCheckError);
return;
}
servername,
checkServerIdentity: (servername, cert) => {
if (rejectUnauthorized && typeof servername === 'string' && verifyIdentity) {
return Tls.checkServerIdentity(servername, cert);
}
}
}, () => {
secureEstablished = true;
onSecure();
});
// error handler for secure socket
Expand Down Expand Up @@ -411,7 +404,7 @@ class Connection extends EventEmitter {
err.code = code || 'PROTOCOL_ERROR';
this.emit('error', err);
}

get fatalError() {
return this._fatalError;
}
Expand Down Expand Up @@ -448,7 +441,7 @@ class Connection extends EventEmitter {
// If it's an Err Packet, we should use it.
if (marker === 0xff) {
const error = Packets.Error.fromPacket(packet);
this.protocolError(error.message, error.code);
this.protocolError(error.message, ErrorCodeToName[error.code]);
} else {
// Otherwise, it means it's some other unexpected packet.
this.protocolError(
Expand Down
24 changes: 10 additions & 14 deletions lib/packets/packet.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,9 @@ class Packet {
return word1 * 0x100000000 + word0;
}
res = new Long(word0, word1, !signed); // Long need unsigned
const resNumber = res.toNumber();
const resString = res.toString();
res = resNumber.toString() === resString ? resNumber : resString;
return bigNumberStrings ? resString : res;
const safeResNumberPreferred = res.greaterThan(Number.MAX_SAFE_INTEGER) || res.lessThan(Number.MIN_SAFE_INTEGER) ? resString : res.toNumber();
return bigNumberStrings ? resString : safeResNumberPreferred;
}
// eslint-disable-next-line no-console
console.trace();
Expand Down Expand Up @@ -425,7 +424,7 @@ class Packet {
return StringParser.decode(
this.buffer,
encoding,
this.offset - len,
this.offset - len,
this.offset
);
}
Expand All @@ -450,21 +449,18 @@ class Packet {
this.offset++;
sign = -1;
}
// max precise int is 9007199254740992
// max precise int is Number.MAX_SAFE_INTEGER 9007199254740991
let str;
const numDigits = end - this.offset;
if (supportBigNumbers) {
if (numDigits >= 15) {
str = this.readString(end - this.offset, 'binary');
result = parseInt(str, 10);
if (result.toString() === str) {
return sign * result;
}
return sign === -1 ? `-${str}` : str;
}
if (numDigits > 16) {
str = this.readString(end - this.offset);
return sign === -1 ? `-${str}` : str;
str = sign === -1 ? `-${str}` : str;
result = Long.fromString(str, false, 10);
if (result.greaterThan(Number.MAX_SAFE_INTEGER) || result.lessThan(Number.MIN_SAFE_INTEGER)) {
return result.toString();
}
return result.toNumber();
}
}
if (this.buffer[this.offset] === plus) {
Expand Down
3 changes: 2 additions & 1 deletion lib/packets/resultset_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ class ResultSetHeader {
if (stateChanges) {
this.stateChanges = stateChanges;
}
const m = this.info.match(/\schanged:\s*(\d+)/i);
// Use the same regex as mysqljs at https://github.com/mysqljs/mysql/blob/dc9c152a87ec51a1f647447268917243d2eab1fd/lib/protocol/packets/OkPacket.js#L3C29-L3C91
const m = this.info.match(/^[^:0-9]+: [0-9]+[^:0-9]+: ([0-9]+)[^:0-9]+: [0-9]+[^:0-9]*$/);
if (m !== null) {
this.changedRows = parseInt(m[1], 10);
} else {
Expand Down
16 changes: 8 additions & 8 deletions test/integration/connection/test-insert-bigint.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ connection.query("INSERT INTO bigs SET title='test1'", (err, result) => {
connection.query("INSERT INTO bigs SET title='test2'", (err, result) => {
assert.strictEqual(result.insertId, 123456790);
// big int
connection.query("INSERT INTO bigs SET title='test', id=9007199254740992");
connection.query("INSERT INTO bigs SET title='test', id=9007199254740991");
connection.query("INSERT INTO bigs SET title='test3'", (err, result) => {
assert.strictEqual(
Long.fromString('9007199254740993').compare(result.insertId),
Long.fromString('9007199254740992').compare(result.insertId),
0,
);
connection.query(
"INSERT INTO bigs SET title='test', id=90071992547409924",
"INSERT INTO bigs SET title='test', id=90071992547409923",
);
connection.query("INSERT INTO bigs SET title='test4'", (err, result) => {
assert.strictEqual(
Long.fromString('90071992547409925').compare(result.insertId),
Long.fromString('90071992547409924').compare(result.insertId),
0,
);
connection.query(
Expand All @@ -51,10 +51,10 @@ connection.query("INSERT INTO bigs SET title='test1'", (err, result) => {
assert.strictEqual(result[1].id, 124);
assert.strictEqual(result[2].id, 123456789);
assert.strictEqual(result[3].id, 123456790);
assert.strictEqual(result[4].id, 9007199254740992);
assert.strictEqual(result[5].id, '9007199254740993');
assert.strictEqual(result[6].id, '90071992547409924');
assert.strictEqual(result[7].id, '90071992547409925');
assert.strictEqual(result[4].id, 9007199254740991);
assert.strictEqual(result[5].id, '9007199254740992');
assert.strictEqual(result[6].id, '90071992547409923');
assert.strictEqual(result[7].id, '90071992547409924');
connection.end();
},
);
Expand Down
2 changes: 1 addition & 1 deletion test/integration/test-server-close.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ process.on('exit', () => {
error.message,
'The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.',
);
assert.equal(error.code, errors.ER_CLIENT_INTERACTION_TIMEOUT);
assert.equal(error.code, 'ER_CLIENT_INTERACTION_TIMEOUT');
});