SQL differences

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.

CREATE TABLE t (x INTEGER); CREATE INDEX IF NOT EXISTS t_x ON t (x); SELECT COUNT(*) FROM t, run on four engines: 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 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.