メインコンテンツまでスキップ
メインコンテンツまでスキップ

ユーザー定義関数 (UDF)

実行可能なユーザー定義関数

Private preview in ClickHouse Cloud
注記

この機能は、ClickHouse Cloudのプライベートプレビューでサポートされています。アクセスにはClickHouse Supportにご連絡ください。

ClickHouseは、データを処理するために外部の実行可能なプログラムまたはスクリプトを呼び出すことができます。

実行可能なユーザー定義関数の設定は、一つまたは複数のxmlファイルに保存されます。設定ファイルへのパスは user_defined_executable_functions_configパラメータで指定します。

関数の設定には以下の設定項目が含まれます:

  • name - 関数名。
  • command - 実行するスクリプト名、またはexecute_directがfalseの場合のコマンド。
  • argument - 引数の説明(typeとオプションのname)を含む引数。この引数はそれぞれ別の設定で説明されます。引数名がNativeJSONEachRowのようなユーザー定義関数形式のシリアル化の一部である場合には、名前を指定する必要があります。デフォルトの引数名はc + argument_numberです。
  • format - コマンドに渡される引数のフォーマット
  • return_type - 戻り値の型。
  • return_name - 戻り値の名前。戻り値の名前がNativeJSONEachRowのようなユーザー定義関数形式のシリアル化の一部である場合には、戻り値名を指定する必要があります。オプション。デフォルト値はresultです。
  • type - 実行可能なタイプ。typeexecutableに設定されている場合、単一のコマンドが開始されます。executable_poolに設定されている場合は、コマンドのプールが作成されます。
  • max_command_execution_time - データブロックを処理するための最大実行時間(秒単位)。この設定はexecutable_poolコマンドにのみ有効です。オプション。デフォルト値は10です。
  • command_termination_timeout - コマンドがそのパイプが閉じられたあとに完了するべき時間(秒単位)。その時間が過ぎると、SIGTERMが実行中のコマンドに送信されます。オプション。デフォルト値は10です。
  • command_read_timeout - コマンドのstdoutからデータを読み取るためのタイムアウト(ミリ秒単位)。デフォルト値は10000。オプションのパラメータです。
  • command_write_timeout - コマンドのstdinにデータを書くためのタイムアウト(ミリ秒単位)。デフォルト値は10000。オプションのパラメータです。
  • pool_size - コマンドプールのサイズ。オプション。デフォルト値は16です。
  • send_chunk_header - チャンクのデータを処理する前に行数を送信するかどうかを制御します。オプション。デフォルト値はfalseです。
  • execute_direct - execute_direct = 1の場合、command user_scripts_pathで指定されたuser_scriptsフォルダ内で検索されます。追加のスクリプト引数は、空白で区切って指定できます。例:script_name arg1 arg2execute_direct = 0の場合、commandbin/sh -cの引数として渡されます。デフォルト値は1です。オプションのパラメータです。
  • lifetime - 関数の再読み込み間隔(秒単位)。0に設定されている場合、関数は再読み込みされません。デフォルト値は0です。オプションのパラメータです。

コマンドは引数をSTDINから読み取り、結果をSTDOUTに出力しなければなりません。コマンドは引数を反復的に処理する必要があります。すなわち、引数のチャンクを処理した後は、次のチャンクを待たなければなりません。

インラインスクリプト

execute_direct0に指定してtest_function_sumを手動で作成します。 ファイルtest_function.xml (/etc/clickhouse-server/test_function.xmlのデフォルトパス設定)。

クエリ:

結果:

Pythonスクリプト

STDINから値を読み取り、それを文字列として返します:

XML設定を使用してtest_functionを作成します。 ファイルtest_function.xml (/etc/clickhouse-server/test_function.xmlのデフォルトパス設定)。

user_scriptsフォルダ内のスクリプトファイルtest_function.py (/var/lib/clickhouse/user_scripts/test_function.pyのデフォルトパス設定)。

クエリ:

結果:

STDINから2つの値を読み取り、JSONオブジェクトとしてその合計を返します:

XML設定を使用して名前付き引数とフォーマットJSONEachRowtest_function_sum_jsonを作成します。 ファイルtest_function.xml (/etc/clickhouse-server/test_function.xmlのデフォルトパス設定)。

user_scriptsフォルダ内のスクリプトファイルtest_function_sum_json.py (/var/lib/clickhouse/user_scripts/test_function_sum_json.pyのデフォルトパス設定)。

クエリ:

結果:

command設定のパラメータを使用:

実行可能なユーザー定義関数は、command設定で構成された定数パラメータを取ることができます(これはexecutableタイプのユーザー定義関数に対してのみ機能します)。また、execute_directオプションも必要です(シェル引数の展開脆弱性を回避するため)。 ファイルtest_function_parameter_python.xml (/etc/clickhouse-server/test_function_parameter_python.xmlのデフォルトパス設定)。

user_scriptsフォルダ内のスクリプトファイルtest_function_parameter_python.py (/var/lib/clickhouse/user_scripts/test_function_parameter_python.pyのデフォルトパス設定)。

クエリ:

結果:

シェルスクリプト

各値を2倍にするシェルスクリプト:

実行可能なユーザー定義関数はシェルスクリプトでも使用できます。 ファイルtest_function_shell.xml (/etc/clickhouse-server/test_function_shell.xmlのデフォルトパス設定)。

user_scriptsフォルダ内のスクリプトファイルtest_shell.sh (/var/lib/clickhouse/user_scripts/test_shell.shのデフォルトパス設定)。

クエリ:

結果:

エラーハンドリング

データが無効な場合、一部の関数は例外をスローすることがあります。この場合、クエリはキャンセルされ、エラーテキストがクライアントに返されます。分散処理の場合、サーバーのいずれかで例外が発生すると、他のサーバーもクエリの中止を試みます。

引数式の評価

ほぼすべてのプログラミング言語において、特定の演算子に対しては引数の一つが評価されない場合があります。これは通常、演算子&&||、および?:が関与します。 しかし、ClickHouseでは、関数(演算子)の引数は常に評価されます。これは、カラムの全体の部分が一度に評価され、各行を別々に計算するのではないためです。

分散クエリ処理のための関数の実行

分散クエリ処理では、できるだけ多くのクエリ処理ステージがリモートサーバーで行われ、残りのステージ(中間結果のマージとその後のすべて)はリクエスタサーバーで実行されます。

これは、関数が異なるサーバーで実行される可能性があることを意味します。 例えば、クエリSELECT f(sum(g(x))) FROM distributed_table GROUP BY h(y),のように、

  • distributed_tableが少なくとも2つのシャードを持っている場合、関数'g'と'h'はリモートサーバーで実行され、関数'f'はリクエスタサーバーで実行されます。
  • distributed_tableが1つのシャードのみを持っている場合、すべての'f'、'g'、'h'関数はこのシャードのサーバーで実行されます。

関数の結果は通常、どのサーバーで実行されるかに依存しません。しかし、時にはこれが重要です。 例えば、辞書と連携する関数は、そのサーバーで実行される辞書を使用します。 もう一つの例は、hostName関数で、この関数はSELECTクエリでサーバーごとにGROUP BYを行うために実行されるサーバーの名前を返します。

クエリ内の関数がリクエスタサーバーで実行される場合でも、リモートサーバーで実行する必要がある場合は、それを'any'集約関数にラップするか、GROUP BYのキーに追加することができます。

SQLユーザー定義関数

ラムダ式からカスタム関数を作成するには、CREATE FUNCTIONステートメントを使用します。これらの関数を削除するには、DROP FUNCTIONステートメントを使用します。

ClickHouse Cloudのユーザー定義関数