Formatador de SQL para PostgreSQL

Cole uma consulta Postgres e receba SQL limpo e com indentação consistente. Marcadores numerados $1 de prepared statements são detectados para você preenchê-los, e a sintaxe específica do Postgres — operadores JSONB, casts e corpos de função entre sinais de dólar — é preservada.

Uma consulta PostgreSQL, antes e depois

A consulta sem formatação abaixo é o exemplo carregado no editor acima, e a saída é exatamente o que este formatador devolve para ela com as opções padrão. Nada foi ajustado à mão.

Colado
WITH recent AS (SELECT user_id, count(*) AS n, max(created_at) AS last_seen FROM events WHERE created_at >= $1 AND payload->>'type' = $2 GROUP BY user_id) SELECT u.id, u.email, r.n, row_number() OVER (ORDER BY r.n DESC) AS rank FROM users u JOIN recent r ON r.user_id = u.id WHERE u.status = 'active' AND u.created_at::date BETWEEN $3 AND $4 ORDER BY r.n DESC LIMIT 50
Saída formatada
WITH
  recent AS (
    SELECT
      user_id,
      count(*) AS n,
      max(created_at) AS last_seen
    FROM
      events
    WHERE
      created_at >= $1
      AND payload ->> 'type' = $2
    GROUP BY
      user_id
  )
SELECT
  u.id,
  u.email,
  r.n,
  row_number() OVER (
    ORDER BY
      r.n DESC
  ) AS rank
FROM
  users u
  JOIN recent r ON r.user_id = u.id
WHERE
  u.status = 'active'
  AND u.created_at::date BETWEEN $3 AND $4
ORDER BY
  r.n DESC
LIMIT
  50

Sintaxe do PostgreSQL que ele trata

Um formatador genérico destrói a sintaxe específica do dialeto ou simplesmente a recusa. Estas são as construções do PostgreSQL contra as quais este formatador é testado.

$1, $2

Marcadores numerados de prepared statements são detectados e podem ser preenchidos para produzir uma consulta executável.

payload->>'key'

Operadores JSON e JSONB são mantidos exatamente como escritos.

value::type

A sintaxe de cast nunca é confundida com um parâmetro :name.

$$ ... $$

Corpos de função entre sinais de dólar são tratados como literais, então palavras-chave dentro deles não são reformatadas.

WITH ... AS

A cláusula WHERE de cada CTE é listada separadamente e pode ser editada por conta própria.

OVER (PARTITION BY ...)

Funções de janela e seus frames são formatados sem quebrar a cláusula.

Perguntas frequentes do formatador de PostgreSQL

Ele lida com marcadores $1 de prepared statements?

Sim. Os marcadores numerados do Postgres são detectados e listados no painel de Parâmetros. Preencha cada um e troque a saída para SQL com valores para obter uma consulta que pode colar direto no psql.

Ele vai quebrar meus ::casts ou operadores JSONB?

Não. Casts são distinguidos de parâmetros :name, e operadores JSON/JSONB como -> e ->> passam sem alteração.

Ele formata uma consulta com várias CTEs — e edita só uma delas?

Sim. Cada cláusula WHERE é listada pela CTE à qual pertence, então uma consulta feita de uma sequência de blocos WITH dá uma entrada por bloco. Você escolhe um, edita como árvore AND/OR ou como grafo de nós, e a alteração é inserida exatamente naquela cláusula enquanto o resto da consulta fica intacto byte a byte.

Ele formata uma consulta incompleta ou só uma cláusula WHERE?

Sim. Nada aqui depende de uma análise completa e válida, então você pode colar um trecho tirado de um log ou do dump de depuração de um ORM — até um WHERE created_at >= $1 AND status = $2 sozinho — e ele ainda será formatado e editável visualmente.

Ele mantém corpos PL/pgSQL entre cifrões intactos?

Sim. Um corpo entre cifrões é tratado como um literal único, de modo que as palavras-chave lá dentro não são reindentadas como se fizessem parte do comando externo, e uma tag de abertura só é casada com a própria tag de fechamento, não com o próximo cifrão encontrado.

Dá para minificar uma consulta Postgres de volta para uma linha?

Sim — embelezar e minificar estão disponíveis. A minificação leva em conta os espaços de verdade em vez de aplicar uma expressão regular genérica, então o espaçamento dentro de literais de texto é preservado e a consulta minificada continua retornando exatamente as mesmas linhas.