diff --git a/lib/db/mysql.js b/lib/db/mysql.js index 3f2cd2f3..68662975 100644 --- a/lib/db/mysql.js +++ b/lib/db/mysql.js @@ -15,6 +15,11 @@ const dbUtil = require('./util') const REQUIRED_CHARSET = 'UTF8MB4_BIN' const DATABASE_NAME = require('../constants').DATABASE_NAME +const REQUIRED_SQL_MODES = [ + 'STRICT_ALL_TABLES', + 'NO_ENGINE_SUBSTITUTION', +] + // http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html const ER_TOO_MANY_CONNECTIONS = 1040 const ER_DUP_ENTRY = 1062 @@ -67,6 +72,18 @@ module.exports = function (log, error) { options.master.charset = options.charset options.slave.charset = options.charset + var mode = REQUIRED_SQL_MODES.join(',') + if (options.sql_mode && options.sql_mode !== mode) { + log.error('createPoolCluster.invalidSqlMode', { sql_mode: options.sql_mode }) + throw new Error(`You cannot use any sql mode other than ${mode}`) + } else { + options.sql_mode = REQUIRED_SQL_MODES.join(',') + } + + options.master.sql_mode = options.sql_mode + options.slave.sql_mode = options.sql_mode + + // Use separate pools for master and slave connections. this.poolCluster.add('MASTER', options.master) this.poolCluster.add('SLAVE', options.slave) @@ -1138,14 +1155,20 @@ module.exports = function (log, error) { return resolve(connection) } - connection.query('SET NAMES utf8mb4 COLLATE utf8mb4_bin;', (err) => { + var mode = REQUIRED_SQL_MODES.join(',') + connection.query(`SET SESSION sql_mode = '${mode}';`, (err) => { if (err) { return reject(err) } - connection._fxa_initialized = true + connection.query('SET NAMES utf8mb4 COLLATE utf8mb4_bin;', (err) => { + if (err) { + return reject(err) + } - resolve(connection) + connection._fxa_initialized = true + resolve(connection) + }) }) }) @@ -1247,7 +1270,8 @@ module.exports = function (log, error) { 'collation_server', 'max_connections', 'version', - 'wait_timeout' + 'wait_timeout', + 'sql_mode' ] return this.getConnection(poolName) diff --git a/test/local/mysql_tests.js b/test/local/mysql_tests.js index 89d9b41d..9c5ea38e 100644 --- a/test/local/mysql_tests.js +++ b/test/local/mysql_tests.js @@ -41,6 +41,26 @@ describe('MySQL', () => { } ) + it( + 'forces REQUIRED_SQL_MODES for connections', + () => { + const configSqlMode = Object.assign({}, config) + const REQUIRED_SQL_MODES = [ + 'STRICT_ALL_TABLES', + 'NO_ENGINE_SUBSTITUTION', + ] + var mode = REQUIRED_SQL_MODES.join(',') + configSqlMode.sql_mode = 'xyz' + return DB.connect(configSqlMode) + .then( + assert.fail, + err => { + assert.equal(err.message, `You cannot use any sql mode other than ${mode}`) + } + ) + } + ) + it( 'a select on an unknown table should result in an error', () => {