MySQL Refuses CREATE INDEX IF NOT EXISTS
Migrations that may run twice often say CREATE INDEX IF NOT EXISTS, and SQLite, PostgreSQL and MariaDB accept it. MySQL stops the migration with a syntax error.
MySQL accepts IF NOT EXISTS for tables and databases, and not for indexes.

What Each Engine Answered
The example
CREATE TABLE t (x INTEGER);
CREATE INDEX IF NOT EXISTS t_x ON t (x);
SELECT COUNT(*) FROM t;
gave these answers:
| Engine | Answer |
|---|---|
| SQLite 3.45.1 | 0 |
| PostgreSQL 16.15 | 0 |
| MySQL 8.0.46 | error: You have an error in your SQL syntax ... near 'IF NOT EXISTS t_x ON t (x)' at line 1 |
| MariaDB 10.11.14 | 0 |
What to Write Instead
This form answers the same on every engine:
CREATE TABLE t (x INTEGER);
CREATE INDEX t_x ON t (x);
SELECT COUNT(*) FROM t;
| Engine | Answer |
|---|---|
| SQLite 3.45.1 | 0 |
| PostgreSQL 16.15 | 0 |
| MySQL 8.0.46 | 0 |
| MariaDB 10.11.14 | 0 |
Create each index once, in a migration that runs once, without IF NOT EXISTS.
What BareSQL Portable Reports
Saved as example.sql, the example gets this from baresql lint --all:
$ baresql lint --all example.sql
example.sql:2:1: error: MySQL refuses IF NOT EXISTS in CREATE INDEX; SQLite, PostgreSQL and MariaDB accept it. [index-if-not-exists]
CREATE INDEX IF NOT EXISTS
Create each index once, in a migration that runs once, without IF NOT EXISTS.
1 problem: 1 error.
baresql rules index-if-not-exists prints the same answers in the terminal, and the BareSQL Portable page lists every difference BareSQL knows.