ClickHouse SQL Formatter
Füge eine ClickHouse-Abfrage ein und erhalte sie sofort formatiert. Dieser Formatter nutzt eine echte ClickHouse-Grammatik statt einer Annäherung über MySQL, sodass ClickHouse-eigene Syntax intakt bleibt — und er liest {name:Type}-Abfrageparameter, sodass du sie ausfüllen und eine ausführbare Abfrage zurückbekommen kannst.
Eine ClickHouse-Abfrage, vorher und nachher
Die unformatierte Abfrage unten ist das Beispiel aus dem Editor weiter oben, und die Ausgabe ist genau das, was dieser Formatter mit den Standardoptionen dafür liefert. Nichts davon wurde von Hand nachgebessert.
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 ClickHouse-Syntax, die er beherrscht
Ein generischer Formatter verstümmelt dialektspezifische Syntax oder lehnt sie gleich ab. Das sind die ClickHouse-Konstrukte, gegen die dieser Formatter getestet wird.
{name:Type} ClickHouse-Abfrageparameter werden als echte Parameter erkannt, benannt nach dem Parameter und nicht nach seinem Typ. Fülle start_ts einmal aus und jede Verwendung aktualisiert sich; DateTime64-, Array- und Nullable-Typen werden auf das passende Eingabefeld abgebildet.
PREWHERE Wird als eigene bearbeitbare Filterklausel neben WHERE erkannt, sodass du genau die Klausel justieren kannst, die den Lesepfad von ClickHouse steuert.
ARRAY JOIN Bleibt eine einzige Klausel, statt in einen Phantom-JOIN zerlegt zu werden.
attributes['key'] Map- und Array-Indizes bleiben exakt erhalten, auch Schlüssel mit Punkten wie attributes_string['http.method'].
quantile(0.95)(x) Parametrische Aggregatfunktionen behalten beide Argumentlisten dicht beieinander.
column$$name Materialisierte Spalten mit $$ werden als Identifier behandelt, nicht als nicht abgeschlossene Dollar-quoted-String.
GLOBAL IN Operatoren für verteilte Abfragen bleiben wortgetreu, und die Unterabfrage darin bleibt bearbeitbar.
SETTINGS / FORMAT Abschließende Klauseln werden als Klauselgrenzen erkannt, sodass das Bearbeiten eines WHERE sie nie verschluckt.
FAQ zum ClickHouse-Formatter
Versteht es ClickHouse-Abfrageparameter?
Ja. ClickHouses {name:Type}-Parameter werden erkannt, nach Namen gruppiert und aus ihrem deklarierten Typ typisiert. Zwei Parameter mit gleichem Typ — etwa {start_ts:UInt64} und {end_ts:UInt64} — bleiben getrennt, und das Ausfüllen des einen überschreibt den anderen nicht. Schalte die Ausgabe auf ausgefülltes SQL und du erhältst eine Abfrage, die du direkt ausführen kannst.
Kann es eine Abfrage aus mehreren CTEs formatieren?
Ja, und es kann sie bearbeiten. Jede WHERE- und PREWHERE-Klausel der Abfrage wird nach dem CTE gelistet, zu dem sie gehört, sodass du eine auswählen und als AND/OR-Baum oder Knotengraph bearbeiten kannst. Änderungen werden genau in diese Klausel eingesetzt, und nichts anderes in der Abfrage verschiebt sich.
Wird meine ClickHouse-Abfrage an einen Server gesendet?
Nein. Die Formatierung läuft vollständig in deinem Browser, sodass Produktionsabfragen, Tabellennamen und eingebettete Werte deinen Rechner nie verlassen.
Warum verschluckt das Bearbeiten einer WHERE-Klausel nicht das SETTINGS am Ende?
Weil SETTINGS und FORMAT an der Syntax ihrer Argumente erkannt werden und nicht am blossen Schlüsselwort. Diese Unterscheidung wirkt in beide Richtungen: Eine Abfrage, die auf eine Spalte namens settings filtert, wird weiterhin korrekt zerlegt, und ein abschliessendes SETTINGS max_threads = 8 gilt als Klauselgrenze, statt in die gerade bearbeitete Bedingung gezogen zu werden.
Werden ARRAY JOIN und Map-Spalten unterstützt?
Ja. ARRAY JOIN bleibt eine einzelne Klausel, statt in einen nicht existierenden JOIN zerlegt zu werden, und Map-Indizes behalten ihren exakten Text — einschliesslich Schlüsseln mit Punkt wie attributes_string['http.method'], die einfachere Formatierer durch eingefügte Leerzeichen um den Punkt zerstören.
Kommt er mit materialisierten Spaltennamen mit doppeltem Dollarzeichen zurecht?
Ja. Ein Name wie resource_string_service$$name gilt als Bezeichner und nicht als Beginn eines dollar-quotierten Strings nach Postgres-Art. Wer das falsch macht, löscht den Rest der Abfrage: Alle Parameter und WHERE-Klauseln danach verschwinden stillschweigend — genau der Fehler, der beim Einfügen von SigNoz- oder Observability-Schemata in einen generischen Formatierer auftritt.