Understanding SQL compatibility modes in MySQL and MariaDB
MySQL and MariaDB have an SQL mode setting which changes how MySQL behaves.
The SQL mode value is comprised of multiple flags like
"STRICT_TRANS_TABLES, NO_ZERO_IN_DATE". Each flag activates or disables a particular behavior.
The default SQL mode varies widly between versions of MySQL and MySQL. In general, more recent versions of MySQL and MariaDB have stricter settings than older versions, and MySQL has stricter settings than the more liberal MariaDB.
If your app explodes after changing SQL servers, you might be able to fix it by setting the SQL mode to the value in your previous server version.
Important SQL mode flags
These SQL modes will probably give you the most headaches:
Introduced in MySQL 5.7, these enable Strict SQL mode. In SQL Strict mode MySQL is likely to throw an error if an
UPDATE has invalid or missing values. Without strict mode, MySQL will try more to not throw an error.
For instance, if a
STRING exceeds the length of a field, MySQL will throw an error in strict mode. Without strict mode it would truncate the string to the maximum column size.
With this enabled (default in MySQL 5.7), you can no longer
SELECT values from a group without an aggregate function.
E.g. you will probably find queries like these in old apps:
SELECT name, address, MAX(age) FROM users GROUP BY name;
ONLY_FULL_GROUP_BY this now explodes with:
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydb.t.address' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
You need to make sure that any selected value is either (1) the value you group by or (2) passed to an aggregate function like
MAX. If you don't care about the aggregate function, you can use
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
This is a shortcut that activates multiple SQL mode flags.
Which SQL mode flags it activates varies between MySQL, MariaDB and their individual versions (see below).
TRADITIONAL does not necessarily make the SQL server behave more liberally in what it accepts. In particular, it enables strict mode, but disables
ONLY_FULL_GROUP_BY in all versions we've seen.
Because of this you might want to list individual flags instead of using
Default SQL mode settings
In general, more recent versions of MySQL and MariaDB have stricter settings than older versions, and MySQL has stricter settings than the more liberal MariaDB.
|Maria DB 10 Traditional||MariaDB 10.0 default||MariaDB 10.2 default||MySQL 5.7 Traditional||MySQL 5.7 Default||MySQL 5.6 Default||MySQL 5.6 Traditional|
Changing the SQL mode
To change the SQL for your entire database server, edit
/etc/mysql/my.cnf and add this to the
Now restart MySQL:
sudo service mysql restart
For a single Rails project
If you only want to change the SQL mode for one project, you can add this to your
development: adapter: mysql2 database: myproject ... variables: sql_mode: "NO_AUTO_CREATE_USER, STRICT_TRANS_TABLES"
If you make any changes to your
database.yml, remember to also change it here:
- all colleagues that have a local
database.yml(which is in
- staging servers
- production servers