bitlvl
RU

Форматтер SQL

Вставьте запрос, миграцию или целый дамп инструкций. Ключевые слова приводятся к выбранному регистру, предложения выносятся на отдельные строки, подзапросы, CTE, выражения CASE и условия JOIN получают отступы, а строки, идентификаторы и комментарии остаются ровно такими, какими были. Работает с синтаксисом PostgreSQL, MySQL/MariaDB, SQLite и SQL Server.

Результаты и сообщения этого инструмента выводятся на английском языке.

Что делает форматтер

  • Предложения (SELECT, FROM, WHERE, GROUP BY, ORDER BY, SET, VALUES, RETURNING…) каждое начинают строку; их содержимое идёт с отступом ниже, для списков — по одному элементу на строку.
  • Соединения (JOIN) начинают строку на уровне предложений; условие ON остаётся при join, а дальнейшие члены AND/OR получают отступ под ним.
  • Подзапросы и CTE открывают блок в скобках, содержимое которого сдвинуто на один уровень; короткие списки в скобках (IN ('a', 'b'), аргументы функций, кортежи) остаются на одной строке.
  • Выражения CASE выносят каждый WHEN и ELSE на отдельную строку и выравнивают END по CASE.
  • Оконные функции держат OVER (PARTITION BY … ORDER BY …) на одной строке, если помещается.
  • CREATE TABLE пишет по одному определению столбца на строку; INSERT … VALUES — по одному кортежу на строку.
  • Инструкции разделяются пустой строкой после каждой точки с запятой.

Что он никогда не трогает

Строковые литералы ('it''s', E'\n', $$ … $$), идентификаторы в кавычках ("Name", `name`, [name]), комментарии (--, #, /* */) и параметры (?, $1, :name, @var) копируются байт в байт. Меняются только пробелы и регистр ключевых слов, поэтому отформатированный запрос — тот же самый запрос. Смена регистра применяется к ключевым словам SQL и стандартным функциям (COUNT, COALESCE, NOW…), но не к вашим идентификаторам: my_table остаётся my_table даже в режиме верхнего регистра.

Запятые в конце или в начале

Запятые в конце (a, в конце строки) — то, что выдают большинство руководств по стилю и ORM. Запятые в начале (, b в начале строки) позволяют закомментировать любую строку списка select, кроме первой, не сломав запрос, поэтому они популярны в аналитическом SQL. Выберите то, что ваша команда читает быстрее; форматтер преобразует одно в другое.

Минификация

Минификация сворачивает всё в одну строку с одиночными пробелами, превращая строчные комментарии в блочные, чтобы они сохранились. Используйте её для строк логов, параметров URL или вставки запроса в чат, где переводы строк были бы съедены.

Диалекты

Токенизатор понимает PostgreSQL (приведения ::, параметры $1, dollar quoting, JSON-операторы ->>, FILTER, RETURNING, ON CONFLICT), MySQL/MariaDB (идентификаторы в обратных кавычках, комментарии #, STRAIGHT_JOIN, ON DUPLICATE KEY UPDATE, LIMIT x OFFSET y), SQLite и SQL Server (идентификаторы в [квадратных скобках], @переменные, TOP, CROSS APPLY). Он не проверяет SQL на корректность; запрос с синтаксической ошибкой форматируется по мере возможности, чтобы его всё же можно было прочитать.

Форматирование SQL в других местах

# PostgreSQL: pg_format (pgFormatter, Perl)
pg_format -s 2 -u 1 query.sql

# любой диалект: sqlfluff (Python), также делает lint
sqlfluff fix --dialect postgres query.sql

# JavaScript: sql-formatter
npx sql-formatter -l postgresql query.sql

Вопросы

Меняет ли он то, что делает запрос?

Нет. Меняются только пробелы и регистр ключевых слов; литералы, идентификаторы, комментарии и параметры копируются без изменений. Смена регистра применяется к ключевым словам и именам стандартных функций, которые нечувствительны к регистру во всех диалектах SQL.

Почему короткий подзапрос разбит на несколько строк?

Любая группа в скобках, содержащая ключевое слово предложения (SELECT, FROM, WHERE…), записывается как блок, потому что именно это делает вложенные запросы читаемыми. Аргументы функций, списки IN и кортежи VALUES остаются в одной строке, если они короткие.

Может ли он форматировать функции PL/pgSQL или хранимые процедуры?

Тело функции в $$ … $$ для форматтера — строковый литерал, и оно остаётся как есть. Инструкция CREATE FUNCTION вокруг него форматируется. Полное форматирование процедурного языка выходит за рамки инструмента.

Мой SQL отправляется на сервер?

Нет. Страница полностью работает в вашем браузере, что важно для запросов, содержащих имена продакшн-таблиц или литералы.

А как насчёт вывода EXPLAIN?

Это другой инструмент: вставьте план в визуализатор EXPLAIN, который рисует дерево и отмечает ошибки оценок.