UDF の呼び出し

他の関数を呼び出すのと同じ方法で、ユーザー定義関数(UDF)またはユーザー定義テーブル関数(UDTF)を呼び出すことができます。

UDF の呼び出し

一般に、他の関数を呼び出すのと同じ方法で UDF を呼び出します。

UDF に引数がある場合は、それらの引数を名前または位置で指定できます。

たとえば、次の UDF は、3つの引数を受け付けます。

CREATE OR REPLACE FUNCTION udf_concatenate_strings(
    first VARCHAR,
    second VARCHAR,
    third VARCHAR)
  RETURNS VARCHAR
  LANGUAGE SQL
  AS
  $$
    RETURN first || second || third;
  $$;
Copy

UDF の呼び出し時に、引数を名前で指定できます。

SELECT udf_concatenate_strings(
  first => 'one',
  second => 'two',
  third => 'three');
Copy

引数を名前で指定する場合は、引数を特定の順序で指定する必要はありません。

SELECT udf_concatenate_strings(
  third => 'three',
  first => 'one',
  second => 'two');
Copy

また、引数を位置で指定することもできます。

SELECT udf_concatenate_strings(
  'one',
  'two',
  'three');
Copy

次の点に注意してください。

  • すべての引数を名前または位置のいずれかで指定する必要があります。一部の引数を名前で、他の引数を位置で指定することはできません。

    引数を名前で指定する場合は、引数名を二重引用符で囲むことはできません。

  • 2つの関数または2つのプロシージャが同じ名前で引数の型が異なり、引数名が異なる場合は、引数名を使ってどの関数またはプロシージャを実行するかを指定することができます。 プロシージャおよび関数のオーバーロード をご参照ください。

オプションの引数を持つ UDF の呼び出し

UDF に オプションの引数 がある場合は、呼び出しの際にオプションの引数を省略できます。オプションの引数それぞれには、引数が省略された場合に使用されるデフォルト値があります。

たとえば、次の UDF には、必須引数が1つ、オプションの引数が2つあります。オプションの引数それぞれには、デフォルト値があります。

CREATE OR REPLACE FUNCTION build_string_udf(
    word VARCHAR,
    prefix VARCHAR DEFAULT 'pre-',
    suffix VARCHAR DEFAULT '-post'
  )
  RETURNS VARCHAR
  AS
  $$
    SELECT prefix || word || suffix
  $$
  ;
Copy

オプションの引数は省略可能です。引数を省略すると、その引数のデフォルト値が使用されます。

SELECT build_string_udf('hello');
Copy
+---------------------------+
| BUILD_STRING_UDF('HELLO') |
|---------------------------|
| pre-hello-post            |
+---------------------------+
SELECT build_string_udf('hello', 'before-');
Copy
+--------------------------------------+
| BUILD_STRING_UDF('HELLO', 'BEFORE-') |
|--------------------------------------|
| before-hello-post                    |
+--------------------------------------+

オプションの引数を省略し、署名で省略された引数の後に表示される別のオプションの引数を指定する必要がある場合は、位置引数ではなく名前付き引数を使用します。

たとえば、 prefix 引数を省略し、 suffix 引数を指定するとします。 suffix 引数は署名の prefix の後に表示されるため、引数は名前で指定する必要があります。

SELECT build_string_udf(word => 'hello', suffix => '-after');
Copy
+-------------------------------------------------------+
| BUILD_STRING_UDF(WORD => 'HELLO', SUFFIX => '-AFTER') |
|-------------------------------------------------------|
| pre-hello-after                                       |
+-------------------------------------------------------+

UDTF の呼び出し

テーブル関数を呼び出すのと同じ方法で UDTF を呼び出すことができます。クエリの FROM 句で UDTF を呼び出す場合は、 組み込まれたテーブル関数の呼び出し 時のように、 TABLE キーワードに続く括弧内に UDTF の名前と引数を指定します。

つまり、 UDTF を呼び出すときは、 TABLE キーワードに次のような形式を使用します。

SELECT ...
  FROM TABLE ( udtf_name (udtf_arguments) )
Copy

次の例のコードは、引数 '2021-01-16'::DATE に DATE リテラルを指定して、 my_java_udtf テーブル関数を呼び出します。

SELECT ...
  FROM TABLE(my_java_udtf('2021-01-16'::DATE));
Copy

テーブル関数の引数は、リテラルだけでなく、式にすることもできます。たとえば、テーブル関数は、テーブルの列を使用して呼び出すことができます。 例のセクション を含め、いくつかの例を以下に示します。

UDFs を呼び出す場合と同様に、引数は名前または位置で指定できます。

一般的なテーブル関数の詳細については、 テーブル関数 をご参照ください。

注釈

CREATE TABLE ステートメントの DEFAULT 句内で UDF を呼び出すことはできません。

UDTF への入力としてのテーブルまたは UDTF の使用

テーブル関数への入力は、 テーブル関数への入力としてテーブルを使用 に記載されているように、テーブルまたは別の UDTF から取得できます。

以下の例は、テーブルを使用して、 UDTF split_file_into_words に入力を提供する方法を示しています。

create table file_names (file_name varchar);
insert into file_names (file_name) values ('sample.txt'),
                                          ('sample_2.txt');

select f.file_name, w.word
   from file_names as f, table(split_file_into_words(f.file_name)) as w;
Copy

出力は、次に類似したものになります。

+-------------------+------------+
| FILE_NAME         | WORD       |
+-------------------+------------+
| sample_data.txt   | some       |
| sample_data.txt   | words      |
| sample_data_2.txt | additional |
| sample_data_2.txt | words      |
+-------------------+------------+
Copy

UDTF の IMPORTS 句は、 UDTF に渡される ファイルの名前とパスを指定する必要があります。例:

create function split_file_into_words(inputFileName string)
    ...
    imports = ('@inline_jars/sample.txt', '@inline_jars/sample_2.txt')
    ...
Copy

UDTF がファイルを読み取る前に、各ファイルは、すでにステージ(この場合は @inline_jars という名前のステージ)にコピーされている必要があります。

別の UDTF への入力として UDTF を使用する例については、 JavaScript UDTF ドキュメントの 入力としてテーブル値とその他の UDTFs を使用した拡張例 をご参照ください。

テーブル関数とパーティション

行がテーブル関数に渡される前に、行を パーティション にグループ化できます。パーティション分割には2つの主な利点があります。

  • パーティション分割は、Snowflakeがワークロードを分割して並列化を改善し、パフォーマンスを向上させられるようにします。

  • パーティション分割により、Snowflakeは共通の特性を持つすべての行をグループとして処理できます。個々の行だけでなく、グループ内のすべての行に基づく結果を返すことができます。

たとえば、株価データを株式ごとに1つのグループに分割できます。個々の会社の株価すべてを同時に分析しながら、各会社の株価を他の会社とは分離して分析することができます。

データは、明示的または暗黙的に分割できます。

明示的なパーティション分割

複数のグループへの明示的なパーティション分割

次のステートメントは、個々のパーティションで my_udtf という名前の UDTF を呼び出します。各パーティションには、 PARTITION BY 式が同じ値(例: 同じ会社または銘柄記号)と評価されるすべての行が含まれます。

SELECT *
    FROM stocks_table AS st,
         TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol))
Copy

単一グループへの明示的なパーティション分割

次のステートメントは、1つのパーティションで my_udtf という名前の UDTF を呼び出します。 PARTITION BY <定数> 句(この場合は PARTITION BY 1)は、すべての行を同じパーティションに配置します。

SELECT *
    FROM stocks_table AS st,
         TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY 1))
Copy

より包括的で現実的な例については、 クエリでJava UDTFs を呼び出す例、特に 単一のパーティション というタイトルのサブセクションをご参照ください。

パーティションの行の並べ替え

指定した順序で各パーティションの行を処理するには、 ORDER BY 句を含めます。これは、行を指定された順序で行ごとのハンドラーメソッドに渡すよう、Snowflakeに指示します。

たとえば、株価の移動平均を経時的に計算する場合は、タイムスタンプの順に株価を並べます(また、銘柄記号ごとにパーティションします)。次の例は、これを実行する方法を示しています。

SELECT *
     FROM stocks_table AS st,
          TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
Copy

OVER 句には、 PARTITION BY 句がない場合でも ORDER BY 句を含めることができます。

OVER 句内に ORDER BY 句を含めることは、クエリの最も外側のレベルに ORDER BY 句を配置することと同じではないことに注意してください。クエリ結果全体を並べ替える場合は、個別の ORDER BY 句が必要です。例:

SELECT *
    FROM stocks_table AS st,
         TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
    ORDER BY st.symbol, st.transaction_date, st.transaction_time;
Copy

明示的なパーティション分割の使用上の注意

PARTITION BY 句で UDTF を使用する場合は、 PARTITION BY 句に一般式ではなく、列参照またはリテラルを使用する必要があります。たとえば、次のコマンドは許可されて いません

SELECT * FROM udtf_table, TABLE(my_func(col1) OVER (PARTITION BY udtf_table.col2 * 2));   -- NO!
Copy

暗黙的なパーティション分割

テーブル関数が PARTITION BY 句を使用して行を明示的にパーティションしない場合、Snowflakeは通常、並列処理を使用するために行を暗黙的に分割して、パフォーマンスを向上させます。

パーティションの数は通常、関数を処理するウェアハウスのサイズや入力関係のカーディナリティなどの要因に基づいています。行は通常、行の物理的な場所(例: マイクロパーティションによる)などの要因に基づいて特定のパーティションに割り当てられるため、パーティションのグループ化には意味がありません。