ClickHouse SQL フォーマッター
ClickHouse のクエリを貼り付ければ、即座に整形されます。このフォーマッターは MySQL で近似するのではなく本物の ClickHouse 文法を使うため、ClickHouse 固有の構文がそのまま保たれます。さらに {name:Type} クエリパラメーターを読み取るので、値を入力してそのまま実行できるクエリを得られます。
ClickHouse のクエリ、整形前と整形後
下の未整形のクエリは、上のエディタに読み込まれているサンプルそのものです。出力はデフォルト設定でこのフォーマッターが返す内容そのままで、手作業で整えた箇所はありません。
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 の構文
汎用のフォーマッターは方言固有の構文を壊すか、そもそも受け付けません。ここに挙げるのは、このフォーマッターがテストで確認している ClickHouse の構文です。
{name:Type} ClickHouse のクエリパラメーターは、型ではなくパラメーター名で命名された本物のパラメーターとして検出されます。start_ts を一度入力すればすべての使用箇所が更新され、DateTime64、Array、Nullable の各型は適切な入力欄に対応づけられます。
PREWHERE WHERE と並ぶ独立した編集可能なフィルター句として検出されるため、ClickHouse の読み取り経路を実際に左右する句を調整できます。
ARRAY JOIN 架空の JOIN に分割されることなく、単一の句として保たれます。
attributes['key'] マップと配列の添字は、attributes_string['http.method'] のようなドットを含むキーも含めて、そのまま正確に保持されます。
quantile(0.95)(x) パラメトリック集約関数は 2 つの引数リストを密着させたまま保ちます。
column$$name $$ を含むマテリアライズド列は、閉じられていないドル引用符文字列ではなく識別子として扱われます。
GLOBAL IN 分散クエリ用の演算子はそのまま残され、その内部のサブクエリも編集可能なままです。
SETTINGS / FORMAT 末尾の句は句の境界として認識されるため、WHERE を編集してもそれらを飲み込むことはありません。
ClickHouse フォーマッターのよくある質問
ClickHouse のクエリパラメーターを理解しますか?
はい。ClickHouse の {name:Type} パラメーターは検出され、名前でグループ化され、宣言された型から型付けされます。型が同じ 2 つのパラメーター(たとえば {start_ts:UInt64} と {end_ts:UInt64})は別々のまま扱われ、一方を入力しても他方は上書きされません。出力を値入り SQL に切り替えれば、そのまま実行できるクエリが得られます。
複数の CTE から構成されるクエリを整形できますか?
はい、編集もできます。クエリ内のすべての WHERE 句と PREWHERE 句が、それが属する CTE ごとに一覧されるので、1 つを選んで AND/OR ツリーやノードグラフとして編集できます。編集内容はまさにその句に差し戻され、クエリの他の部分は動きません。
ClickHouse のクエリはサーバーに送信されますか?
いいえ。整形は完全にブラウザ内で行われるため、本番のクエリ、テーブル名、埋め込まれた値があなたのマシンから出ることはありません。
WHERE 句を編集しても末尾の SETTINGS が巻き込まれないのはなぜですか?
SETTINGS と FORMAT を、キーワード単体ではなく引数の構文で判定しているためです。この違いは両方向に効きます。settings という名前の列で絞り込むクエリも正しく解析されますし、末尾の SETTINGS max_threads = 8 は句の境界として認識され、編集中の条件に取り込まれることはありません。
ARRAY JOIN やマップ型の列にも対応していますか?
はい。ARRAY JOIN は実体のない JOIN に分割されず 1 つの句のまま保たれ、マップの添字も文字どおり維持されます。attributes_string['http.method'] のようにドットを含むキーも同様で、単純なフォーマッタはここでドットの前後に空白を入れて壊してしまいます。
ドル記号 2 つを含むマテリアライズド列名も扱えますか?
はい。resource_string_service$$name のような名前は識別子として扱われ、Postgres 形式のドル引用文字列の開始とは見なされません。ここを誤るとクエリの残り全体が空白化し、それ以降のパラメータや WHERE 句が黙って消えます。SigNoz や可観測性まわりのスキーマを汎用フォーマッタに貼ったときに起きるのが、まさにこの不具合です。