Formateador de SQL para ClickHouse
Pega una consulta de ClickHouse y obténla formateada al instante. Este formateador usa una gramática real de ClickHouse en lugar de aproximarla con MySQL, así que la sintaxis exclusiva de ClickHouse sobrevive intacta, y además lee los parámetros de consulta {name:Type} para que puedas rellenarlos y recuperar una consulta ejecutable.
Una consulta ClickHouse, antes y después
La consulta sin formato de abajo es el ejemplo cargado en el editor de arriba, y la salida es exactamente lo que devuelve este formateador con las opciones por defecto. No se ha retocado nada a mano.
WITH matched AS (SELECT fingerprint FROM traces_resource WHERE simpleJSONExtractString(labels, 'service.name') = {service:String}), ranked AS (SELECT resource_string_service$$name AS svc, toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts, attributes_string['http.method'] AS method, quantile(0.95)(duration_nano) AS p95 FROM signoz_index_v3 PREWHERE timestamp >= {start_ts:UInt64} AND timestamp <= {end_ts:UInt64} WHERE resource_fingerprint GLOBAL IN (SELECT fingerprint FROM matched) GROUP BY svc, ts, method) SELECT * FROM ranked WHERE p95 > {threshold:UInt64} ORDER BY ts DESC SETTINGS max_threads = 8 WITH
matched AS (
SELECT
fingerprint
FROM
traces_resource
WHERE
simpleJSONExtractString(labels, 'service.name') = {service:String}
),
ranked AS (
SELECT
resource_string_service$$name AS svc,
toStartOfInterval(timestamp, INTERVAL 60 SECOND) AS ts,
attributes_string['http.method'] AS method,
quantile(0.95)(duration_nano) AS p95
FROM
signoz_index_v3
PREWHERE
timestamp >= {start_ts:UInt64}
AND timestamp <= {end_ts:UInt64}
WHERE
resource_fingerprint GLOBAL IN (
SELECT
fingerprint
FROM
matched
)
GROUP BY
svc,
ts,
method
)
SELECT
*
FROM
ranked
WHERE
p95 > {threshold:UInt64}
ORDER BY
ts DESC
SETTINGS
max_threads = 8 Sintaxis de ClickHouse que soporta
Un formateador genérico destroza la sintaxis propia del dialecto o la rechaza directamente. Estas son las construcciones de ClickHouse contra las que se prueba este formateador.
{name:Type} Los parámetros de consulta de ClickHouse se detectan como parámetros reales, nombrados por el parámetro y no por su tipo. Rellena start_ts una vez y todos sus usos se actualizan; los tipos DateTime64, Array y Nullable se asignan al campo adecuado.
PREWHERE Se descubre como cláusula de filtro editable propia junto a WHERE, para que puedas ajustar la cláusula que realmente dirige la lectura en ClickHouse.
ARRAY JOIN Se mantiene como una sola cláusula en lugar de partirse en un JOIN fantasma.
attributes['key'] Los subíndices de mapas y arrays se conservan exactamente, incluidas las claves con puntos como attributes_string['http.method'].
quantile(0.95)(x) Las funciones de agregación paramétricas mantienen sus dos listas de argumentos pegadas.
column$$name Las columnas materializadas que contienen $$ se tratan como identificadores, no como una cadena entre signos de dólar sin cerrar.
GLOBAL IN Los operadores de consulta distribuida se dejan literales, y la subconsulta que contienen sigue siendo editable.
SETTINGS / FORMAT Las cláusulas finales se reconocen como límites de cláusula, así que editar un WHERE nunca se las traga.
Preguntas frecuentes del formateador de ClickHouse
¿Entiende los parámetros de consulta de ClickHouse?
Sí. Los parámetros {name:Type} de ClickHouse se detectan, se agrupan por nombre y se tipan según su tipo declarado. Dos parámetros que comparten tipo —por ejemplo {start_ts:UInt64} y {end_ts:UInt64}— siguen separados, y rellenar uno no sobrescribe el otro. Cambia la salida a SQL con valores y obtendrás una consulta que puedes ejecutar directamente.
¿Puede formatear una consulta construida con varias CTE?
Sí, y además puede editarlas. Todas las cláusulas WHERE y PREWHERE de la consulta aparecen listadas por la CTE a la que pertenecen, así que puedes elegir una y editarla como árbol AND/OR o como grafo de nodos. Las ediciones se insertan exactamente en esa cláusula y nada más de la consulta se mueve.
¿Se envía mi consulta de ClickHouse a un servidor?
No. El formateo se ejecuta enteramente en tu navegador, así que las consultas de producción, los nombres de tabla y los valores incrustados nunca salen de tu máquina.
¿Por qué editar un WHERE no se traga el SETTINGS del final?
Porque SETTINGS y FORMAT se reconocen por la sintaxis de sus argumentos, no por la palabra clave suelta. Esa distinción importa en ambos sentidos: una consulta que filtra por una columna llamada literalmente settings se sigue analizando bien, y un SETTINGS max_threads = 8 final se reconoce como límite de cláusula en lugar de acabar dentro de la condición que estás editando.
¿Se manejan ARRAY JOIN y las columnas de tipo mapa?
Sí. ARRAY JOIN se mantiene como una sola cláusula en vez de partirse en un JOIN inexistente, y los subíndices de mapa conservan su texto exacto —incluidas las claves con puntos como attributes_string['http.method'], que otros formateadores rompen al meter espacios alrededor del punto.
¿Soporta nombres de columnas materializadas con doble signo de dólar?
Sí. Un nombre como resource_string_service$$name se trata como identificador, no como la apertura de una cadena entre dólares al estilo Postgres. Equivocarse ahí deja en blanco el resto de la consulta, así que todos los parámetros y cláusulas WHERE posteriores desaparecen sin aviso: exactamente el fallo que aparece al pegar esquemas de SigNoz o de observabilidad en un formateador genérico.