Skip to main content
サーバー設定ファイルを編集せずに、SQL で定義したカスタム HTTP ハンドラーを作成します。SQL で定義したハンドラーは、設定ベースのHTTP インターフェイスハンドラーの代替手段です。

構文

指定したnameのハンドラーを作成します。この名前は、SQLクエリによるハンドラーの管理、診断メッセージ、およびハンドラーの順序付けに使用されます。

  • PROTOCOL — 任意。プロトコル名を指定した場合、ハンドラーは指定された合成可能プロトコルでのみ有効になります。指定しない場合、ハンドラーは組み込みの http/https ポートと、すべての HTTP 型合成可能プロトコルリスナーを含む、すべての HTTP エンドポイントで有効になります。PROTOCOL ANY は後者のデフォルト動作を明示的に選択します。ALTER HANDLER では、以前に設定したプロトコル制限を解除します。文字どおり any という名前のプロトコルは、バッククォートで参照できます: PROTOCOL `any`
  • URL — 必須。完全一致 URL、URL PREFIX、または URL REGEXP の形式を指定できます。完全一致 URL とプレフィックスでは、作成時または変更時に曖昧性が検査され、曖昧性がある場合は例外がスローされます。正規表現では、曖昧性を検査できません。URL は、? クエリ文字列および # フラグメント識別子を除いて照合されます。URL PREFIX は、パスセグメントの境界においてベースパスとして照合されます。これは設定で定義されたハンドラーurl_prefix ルールと同じセマンティクスです。URL PREFIX '/api/v1'/api/v1/api/v1//api/v1/write に一致しますが、/api/v1beta には一致しません。プレフィックス末尾の / は無視されるため、'/api/v1/''/api/v1' は同じように動作します。
  • METHODS — 任意。許可する HTTP メソッドのリストです。デフォルトは GET のみです。サポートされるメソッドは GETPOSTPUTDELETE です。データ変更メソッドである POSTPUTDELETE では、データを変更するクエリを実行できます。一方、GETHEAD などの安全なメソッドは常に readonly モードで実行されます。したがって、データを変更するクエリ (たとえば INSERT や DDL) を実行するハンドラーでは、少なくとも 1 つのデータ変更メソッドを許可する必要があります。読み取り専用メソッドのみ (たとえばデフォルトの GET) を指定してこのようなハンドラーを作成すると、例外がスローされます。readonly モードでも副作用が残るクエリは特殊なケースです。BACKUPRESTORE には永続的な副作用があり、セッションを変更するステートメント SETSET ROLEUSEBEGIN TRANSACTIONCOMMITROLLBACKSET TRANSACTION SNAPSHOT は、session_id の使用時にリクエスト間で維持されるセッションまたはトランザクションの状態を変更します。また、CREATE TEMPORARY TABLE / CREATE TEMPORARY VIEW はセッション内に存在するオブジェクトを作成します。しかし、安全なメソッドの readonly モードでは、これらはいずれもブロックされません。既存の一時テーブルに対する変更も readonly モードではブロックされないため、そのようなテーブルをターゲットにする可能性があるクエリも同様に扱われます。具体的には、データベースで修飾されていないターゲットテーブルを持つ INSERT (修飾されていない名前はセッション一時テーブルに解決される可能性があります) 、DROP TEMPORARY TABLE、データベースで修飾されていないテーブルに対する DROP TABLE / TRUNCATE TABLE、およびデータベースで修飾されていないテーブルに対する ALTER (ALTER TEMPORARY TABLE は同じステートメントです) が該当します。データベースで修飾されたターゲットが一時テーブルになることはないため、そのようなクエリにはこのルールは適用されません。HTTP では、安全なメソッドに副作用がないことが求められます (GET 用に宣言されたハンドラーは HEAD にも応答し、その場合レスポンス本文は抑制されるため、副作用は見えません) 。したがって、このようなクエリを実行するハンドラーには、データ変更メソッドのみを列挙する必要があります。安全なメソッドを含めて作成または変更すると、例外がスローされます。複合ステートメントは内部のステートメントまで検査されます。statement1 PARALLEL WITH statement2 ... および EXECUTE AS <user> <statement> では、実際に実行されるラップされたステートメントに上記のルールが適用されます (各ステートメントは、readonly モードを維持するハンドラーのコンテキストのコピーで実行されます) 。単独の EXECUTE AS <user> はセッション全体を別のユーザーとして実行するため、それ自体がセッション変更として扱われます。さらに、単独の場合でもステートメントをラップする場合でも、すべての EXECUTE AS ハンドラーでは少なくとも 1 つのデータ変更メソッドを許可する必要があります。権限借用には IMPERSONATE 権限が必要であり、安全なメソッドの readonly モードではこれが拒否されるためです。
  • TYPE — 任意。現時点でサポートされる唯一の型は query です。
  • AS — このハンドラーで実行されるSQLクエリです。クエリはパラメーター化できます。クエリはハンドラーの作成または変更時に構文の正しさが解析されますが、意味解析は行われません。たとえば、ハンドラーの作成時点では、クエリが参照するテーブルが存在しない場合があります。FORMAT 句や類似の句は、CREATE/ALTER ステートメント全体ではなくクエリに属します。曖昧さを解消するため、クエリを括弧で囲むことができます。INSERT クエリには、VALUES または FORMAT 句の後にインラインデータを含めてはなりません。このようなハンドラーを作成または変更すると、例外がスローされます。インラインペイロードをハンドラー定義に保持できないためです。データはHTTPボディで提供する必要があります (または INSERT ... SELECT で生成されます) 。ボディを読み取るクエリを持つハンドラーへのリクエスト、つまりボディからデータを取得する INSERT、または _request_body パラメーターを使用するクエリでは、長さを宣言する必要があります。Content-Length ヘッダーのない非チャンク化リクエストには 411 Length Required が返されます。そうしないと、ボディがストリーム終端まで読み取られ、接続が切断されても完全なリクエストとして受け入れられてしまうためです。このようなハンドラーのすべてのメソッドも、ボディを伴うメソッド (POSTPUT、または DELETE) である必要があります。METHODS 句で安全なメソッド (たとえばデフォルトの GET) を指定して作成すると、例外がスローされます。安全なメソッドではリクエストボディが提供されないため、クエリが空のボディを暗黙的に読み取ってしまうからです。宣言された GETHEAD に対しても提供されるため、安全なメソッドとボディを伴うメソッドを混在させると、それらの呼び出しが到達可能なままになります。INSERT ... SELECT はボディを読み取りません (データは SELECT から取得されます) 。したがって、SELECT がリクエストボディから供給される input テーブル関数を読み取る場合を除き、これらの要件は適用されません。ボディを読み取る INSERT は、ハンドラー自身のクエリである必要があります。EXECUTE AS および PARALLEL WITH は、それらがラップするステートメントをリクエストボディなしで実行するため、これらでラップした場合は、すべてのアップロードが暗黙的に破棄されるのではなく、作成時に拒否されます。ボディを読み取るクエリでは、_request_body パラメーターも使用してはなりません。リクエストボディは1つしかなく、_request_body をバインドするとクエリが入力データを読み取る前にそのボディが消費されるためです。そのため、このようなハンドラーは、すべてのアップロードが暗黙的に失われるのではなく、作成時に拒否されます。クエリ自身のボディ入力か _request_body のいずれか一方のみを使用し、両方を使用しないでください。ボディを読み取らないハンドラーには、このような要件はありません。そのようなハンドラーへのリクエストのボディは無視され、ハンドラーのクエリに追加されることはありません。保存されたクエリテキストは、ハンドラーが再ロードまたは呼び出されるたびに、無制限のパーサー深度とバックトラック数でサーバーにより再解析されます。そのため、max_parser_depth / max_parser_backtracks を引き上げたセッションで作成されたハンドラーは、通常のセッション制限下でもロードおよび呼び出し可能です。

優先順位

server configuration で定義されたハンドラーは、SQL で定義されたハンドラーよりも優先されます。SQL で定義されたハンドラーは、名前の辞書式順序に従って照合されます。

パラメータ

パラメータ化クエリのクエリパラメータは、構成で定義されたハンドラーと同様に、次の方法で指定します。
  • クエリ文字列内の HTTP URL パラメータ。param_<name> 形式を使用します (例: ?param_id=42{id:Type} にバインドされます) 。
  • URL REGEXP 内の名前付きキャプチャグループ (例: URL REGEXP '/users/(?P<id>\d+)'{id:Type} にバインドされます) 。
  • クエリでパラメータを宣言しているハンドラーでは、リクエストボディのフォームフィールド。application/x-www-form-urlencoded ボディ (例: curl -d 'param_id=42') および multipart/form-data ボディのフィールドは、ボディを含む POSTPUTDELETE メソッドで、URL パラメータと同様に {name:Type} パラメータにバインドされます。パラメータが URL とボディの両方に存在する場合は、URL の値が使用されます。フォームとしてパースされたボディはハンドラーレイヤーで消費され、INSERT データとしてクエリに渡されません。ボディを _request_body にのみ使用するハンドラーは、フォームとしてパースされず、生のボディを受け取ります。ほかのパラメータとともに _request_body を宣言するハンドラーは、両方を受け取ります。ボディがフォームとしてパースされる前に、生の未パースボディのコピーが _request_body に保持されます (http_max_request_param_data_size の制限対象) 。
ハンドラーの呼び出し時には、標準の ClickHouse HTTP ヘッダー (X-ClickHouse-DatabaseX-ClickHouse-UserX-ClickHouse-Key など) が通常どおり使用されます。 関数 currentHandler および currentRequestURL を使用すると、呼び出されたハンドラーとリクエスト URL に応じてクエリの動作をカスタマイズできます。

アクセス制御

CREATE HANDLERDROP HANDLERALTER HANDLER を実行するには、それぞれ CREATE HANDLERDROP HANDLERALTER HANDLER 権限が必要です。 system.handlers テーブルを読み取るには、SHOW HANDLERS 権限が必要です。ハンドラーのクエリに埋め込まれている可能性のあるシークレットは、ユーザーにシークレットの閲覧も許可されていない限り、このテーブルではマスクされます (system.handlers を参照) 。 ハンドラーの呼び出しに個別の権限は必要ありませんが、クエリの呼び出し時には通常どおり権限が確認され、認証も通常どおり行われます。特定のクエリへのアクセスをカプセル化するには、SQL SECURITY DEFINER を指定した VIEW を作成し、そのビューから選択するハンドラーを定義します。

ストレージ

ハンドラーは、名前付きコレクションと同様に、設定ファイルのquery_rules_storageセクションで設定されるローカルストレージまたはKeeperストレージに保存されます。
Keeper ストレージでは、ハンドラーはすべてのレプリカ間で自動的に同期されるため、明示的な ON CLUSTER 句は不要です。指定すると、すべてのレプリカが同じハンドラーを作成しようとします。ignore_on_cluster_for_replicated_handler_queries 設定を有効にすると、ストレージがレプリケートされている場合、CREATEALTERDROP HANDLERON CLUSTER を無視します。これは ignore_on_cluster_for_replicated_named_collections_queries と同様の動作です。

ALTER HANDLER

ハンドラーを新しいものに置き換えます。ALTER クエリには一部の句のみを含めることができ、たとえば URL またはクエリだけを変更できます。指定しない句は以前の値を保持します。PROTOCOL ANY を指定すると既存のプロトコル制限が解除され、ハンドラーは再びすべての HTTP エンドポイントで有効になります。

DROP HANDLER

指定した名前のハンドラーを削除します。

イントロスペクション

system.handlers テーブルには、SQL で定義されたすべてのハンドラーが一覧表示されます。system.query_log テーブルには、各クエリのハンドラー名と HTTP リクエストのパス (クエリ文字列を除く) が、http_handler_name および http_request_url カラムに記録されます。

正規表現 URL を使用するパラメーター化ハンドラー:
CREATE HANDLERCREATE ステートメントファミリーに属し、ALTER および DROP と関連しています。
最終更新日 2026年8月27日