SQL Formatter & Dialect Converter

Format SQL and translate it between MySQL, PostgreSQL and SQLite. Every change is listed, and anything that cannot be translated safely is flagged instead of guessed — all in your browser.

Also available as a desktop app for Windows.

About this tool

SQL looks portable and mostly is — until it is not. The same statement can mean different things in MySQL and PostgreSQL, and the differences are exactly the ones that do not raise an error. PostgreSQL reads "name" as an identifier, MySQL reads it as a string. In MySQL || is logical OR; in PostgreSQL it concatenates. A query moved without fixing those still runs, still returns rows, and returns the wrong ones.

This tool does two things. It reformats SQL so clauses, lists and boolean conditions each get their own line, and it translates between MySQL, PostgreSQL and SQLite. Every rewrite it makes is listed with its before and after text, so you can check the work rather than trust it.

Anything that cannot be translated without guessing is left alone and flagged instead — the :: cast, UPSERT variants, ILIKE, AUTO_INCREMENT, storage engine options. Guessing there would produce SQL that is syntactically valid and semantically different, which is worse than an error. Everything runs in your browser; no query you paste is sent anywhere.

Frequently asked questions

Does formatting change what my SQL does?
No. The formatter only moves whitespace and upper-cases reserved words — it never adds, removes or reorders a token. That is enforced by a test that re-tokenizes the formatted output and demands the same token sequence as the input, so a missing space can never slip through.
Why does it warn instead of translating some things?
Because some differences need to know what you meant. MySQL || is logical OR; in PostgreSQL the same symbols concatenate. MySQL "abc" is a string, in PostgreSQL it is a column name. There is no rewrite that is correct for both readings, so the tool refuses to pick one and tells you instead.
Is MySQL LIMIT 50, 25 the same as LIMIT 25 OFFSET 50?
Yes. MySQL accepts LIMIT offset, row_count as a shorthand; PostgreSQL and SQLite only accept LIMIT row_count OFFSET offset. The tool rewrites the shorthand into the standard form when you convert away from MySQL.
What about ON DUPLICATE KEY UPDATE and ON CONFLICT?
They are not equivalent, so they are flagged rather than converted. ON CONFLICT takes a conflict target — the columns or constraint that trigger the merge — and that cannot be derived from an ON DUPLICATE KEY statement, which relies on whatever unique indexes happen to exist. You have to name the target yourself.
Can it convert stored procedures or full schema dumps?
Not reliably. Procedures, triggers and vendor-specific DDL carry far more dialect detail than a formatter can track, and a wrong rewrite there is expensive. Use it on queries and simple DDL, and treat everything it lists under “needs your hand” as genuinely requiring your judgement.
Does it send my queries anywhere?
No. The whole thing is plain JavaScript running in the page — no server, no request, no logging. It also works offline once loaded, which is a reasonable way to check that claim yourself.

Related tools