UDFsの概要

このトピックでは、 UDFs (ユーザー定義関数)に適用される概念と使用法の詳細について説明します。

このトピックの内容:

スカラーと表形式 UDFs

スカラー UDF* は、入力行ごとに1つの出力行を返します。返される行は、単一の列/値で構成されます。

表形式UDF は、入力行ごとに0、1、または複数の行を返します。返される各行には、1つ以上の列を含めることができます。返された行には、クエリの FROM 句でアクセスできます。表形式の UDF は、 TABLE キーワードを含み、テーブルの結果にある列の名前と型を指定する戻り句を指定することにより定義されます。

表形式の UDFs は、しばしば UDTFs (ユーザー定義のテーブル関数)または テーブル UDFs と呼ばれます。

例を含む、 UDTFs の作成および使用の詳細については、 表形式 SQL UDFs (UDTFs) および 表形式 JavaScript UDFs (UDTFs) をご参照ください。Snowflakeで提供されるシステム定義のテーブル関数の一般的な情報については、 テーブル関数 をご参照ください。

UDFs 作成のためにサポートされているプログラミング言語

Snowflakeは次のプログラミング言語をサポートしています。

SQL

SQL UDF は、任意の SQL 式を評価し、式の結果を返します。

関数定義は、スカラー(つまり、単一)値、またはテーブル関数として定義されている場合は行のセットを返す SQL 式です。

式はクエリ式にできますが、非表形式関数の場合、クエリ式は1列を含む最大1行を返すことが保証されている必要があります。

UDF を定義する式は、関数の入力引数、およびテーブル、ビュー、シーケンスなどのデータベースオブジェクトを参照できます。UDF 所有者には、 UDF がアクセスするデータベースオブジェクトに対する適切な権限が必要です。SQL UDF の定義式は他のユーザー定義関数を参照できますが、直接または別の関数を呼び出してそれ自体を再帰的に参照することはできません。

JavaScript

JavaScript UDFs は、 JavaScript プログラミング言語とランタイム環境を使用してデータを操作できます。JavaScript UDFs は、SQL UDFsと同じ方法で作成されますが、 LANGUAGE パラメーターを JAVASCRIPT に設定します。

SQL UDFs と同様に、 JavaScript UDFs は UDF の定義方法に応じて、スカラーまたは表形式の結果を返すことができます。

JavaScript UDF の定義式はそれ自体を再帰的に参照できますが、他のユーザー定義関数を参照することはできません。

注釈

JavaScript UDFs には、 SQL UDFs で適用されない要件、使用方法の詳細、制限があります。例などの詳細については、 JavaScript UDFs をご参照ください。

Java

Java UDFs により、Javaプログラミング言語とランタイム環境を使用してデータを操作できます。

Java UDFs はスカラー結果を返します。Java UDTFs は現在サポートされていません。

Java UDFs は、次に挙げる2つの方法のいずれかで作成できます。

  • インライン: CREATE FUNCTION コマンドの一部としてJavaコードを入力します。

  • JAR file: CREATE FUNCTION コマンドの一部として、コンパイル済みの JAR ファイルの場所を指定します。

これらのそれぞれについては、後で詳しく説明します。

注釈

Java UDFs には、 SQL UDFs で適用されない要件、使用方法の詳細、制限があります。詳細については、以下をご参照ください。

プログラミング言語の選択

UDF の記述に使用するプログラミング言語の選択には、多くの要因が影響を及ぼす可能性があります。要因には次のものが含まれます。

  • 特定の言語のコードがすでにあるかどうか。たとえば、必要な作業を実行するメソッドを含む.jarファイルがすでにある場合は、プログラミング言語としてJavaを使用することをお勧めします。

  • 言語の機能。

  • 言語に、必要な処理を実行するために役立つライブラリがあるかどうか。

次のテーブルは、各 UDF プログラミング言語の主な機能をまとめたものです。以下のリストは、テーブルの列を説明しています。

  • 表形式: Snowflakeが(スカラー関数に加えて)テーブル関数の記述をサポートするかどうかを示します。

  • ループと分岐: プログラミング言語がループと分岐をサポートしているかどうかを示します。

  • プリコンパイル済み: UDF のコードをプリコンパイル済みファイルとして(例: .JAR ファイルとして)提供できるかどうかを示します。

  • インライン: CREATE FUNCTION ステートメントでコードをテキストとして提供できるかどうかを示します。

  • 共有可能: この言語で記述された UDFs が、Snowflake Secure Data Sharing 機能で使用できるかどうかを示します。

言語

表形式

ループと分岐

プリコンパイル済み

インライン

共有可能

SQL

不可

不可

JavaScript

不可

Java

不可

不可 1

1

Java UDFs の共有に関する制限の詳細については、 Java UDFs の制限 をご参照ください。

UDFs の命名規則

UDFs はデータベースオブジェクトであり、指定されたデータベースとスキーマで作成されます。そのため、 データベース.スキーマ.関数名 の形式で、名前空間で定義された完全修飾名を持っています。例:

SELECT temporary_db_qualified_names_test.temporary_schema_1.udf_pi();

完全修飾名なしで呼び出された場合、 UDFs はセッションで使用されているデータベースとスキーマに従って解決されます。

これは、Snowflakeが提供する組み込みのシステム定義関数とは対照的です。Snowflakeは名前空間を持たないため、どこからでも呼び出すことができます。

システム定義関数との競合

関数を呼び出すときの競合を避けるために、Snowflakeでは、システム定義の関数と同じ名前の UDFs を作成できません。

UDF名のオーバーロード

Snowflakeは、SQL UDF名のオーバーロードをサポートしています。同じスキーマ内の複数のSQL UDFsは、引数の署名が引数の数または引数の種類によって異なる限り、同じ名前を持つことができます。オーバーロードされたUDFが呼び出されると、Snowflakeは引数をチェックし、正しい関数を呼び出します。

add5 という名前の2つのSQL UDFsを作成する次の例を検討してください。

CREATE OR REPLACE FUNCTION add5 (n number)
  RETURNS number
  AS 'n + 5';

CREATE OR REPLACE FUNCTION add5 (s string)
  RETURNS string
  AS 's || ''5''';

重要

2番目のADD5関数では、文字列リテラル '5' をエスケープするために一重引用符が使用されます。UDF定義で使用される一重引用符は、 必ず 一重引用符でエスケープする必要があります。

add5 が数値引数で呼び出された場合、最初の実装が選択され、文字列型の引数は2番目の実装を使用します。引数が数値でも文字列でもない場合、実装はSnowflakeの暗黙的な型変換規則に依存します。例えば、日付型の引数は文字列に変換され、 DATE から NUMBER への変換はサポートされていないため、文字列実装が選択されます。

例:

select add5(1);

+---------+
| ADD5(1) |
|---------|
|       6 |
+---------+

select add5('1');

+-----------+
| ADD5('1') |
|-----------|
| 15        |
+-----------+

select add5('hello');

+---------------+
| ADD5('HELLO') |
|---------------|
| hello5        |
+---------------+

select add5(to_date('2014-01-01'));

+-----------------------------+
| ADD5(TO_DATE('2014-01-01')) |
|-----------------------------|
| 2014-01-015                 |
+-----------------------------+

オーバーロードを使用する場合は注意してください。自動型変換とオーバーロードの組み合わせにより、軽微なユーザーエラーが予期しない結果を引き起こしやすくなります。例については、 関数名のオーバーロード をご参照ください。

ご用心

SQL 以外の言語で記述された UDFs の場合は、ルールが異なる可能性があります。

関数名のオーバーロード

このトピック内の UDF名のオーバーロード で説明されているように、関数名をオーバーロードできます。

次のオーバーロードの例は、オーバーロードと自動型変換を組み合わせて、予期しない結果を簡単に得る方法を示しています。

FLOAT パラメーターを受け取る関数を作成します。

CREATE FUNCTION add_pi(PARAM_1 FLOAT)
    RETURNS FLOAT
    LANGUAGE SQL
    AS $$
        PARAM_1 + 3.1415926::FLOAT
    $$;

関数を2回呼び出します。1回目は、 FLOATを渡します。2回目は、 VARCHARを渡します。 VARCHAR は FLOATに変換され、各呼び出しからの出力は同じです。

SELECT add_pi(1.0), add_pi('1.0');
+-------------+---------------+
| ADD_PI(1.0) | ADD_PI('1.0') |
|-------------+---------------|
|   4.1415926 |     4.1415926 |
+-------------+---------------+

次に、 VARCHAR パラメーターを受け取るオーバーロード関数を作成します。

CREATE FUNCTION add_pi(PARAM_1 VARCHAR)
    RETURNS VARCHAR
    LANGUAGE SQL
    AS $$
        PARAM_1 || ' + 3.1415926'
    $$;

前とまったく同じ CALLs を使用します。これら2つの CALLs と前の2つの CALLsの出力の違いに注意してください。

SELECT add_pi(1.0), add_pi('1.0');
+-------------+-----------------+
| ADD_PI(1.0) | ADD_PI('1.0')   |
|-------------+-----------------|
|   4.1415926 | 1.0 + 3.1415926 |
+-------------+-----------------+