以前に以下の記事で特定の要素が配列の中に含まれているかどうかを判定するUDFを紹介しました。
しかし、このUDFにはINT64という型情報があからさまに含まれているため、他の型に対応した関数を作りたくなった場合には、ARRAY_STRING_INCLUDEやARRAY_FLOAT_INCLUDEのような関数を作成する必要があります。
1つの関数だけで複数の型に対応させるにはどうすればよいでしょうか?
そのためには、 ANY TYPE
という特殊な型を使います。
この型を使うことで任意の型を受け取ることができます。
CREATE TEMPORARY FUNCTION ARRAY_INCLUDE(arr ANY TYPE, val ANY TYPE)
RETURNS BOOL AS ((
SELECT LOGICAL_OR(elem = val) FROM UNNEST(arr) as elem
));
一見すると、動的型付けのような動作をするような見た目ですが、C++のtemplateのように静的情報のみで型チェックが行われます。
そのため、以下のような型チェック違反になるようなコードは、クエリの実行前のdry runのタイミングでエラーが検知されます。
SELECT ARRAY_INCLUDE([1, 2, 3], "hoge")
-- Invalid function ARRAY_INCLUDE No matching signature for operator = for argument types: INT64, STRING. Supported signature: ANY = ANY Analysis of function Templated_SQL_Function:ARRAY_INCLUDE failed at [6:8]
配列などのいわゆるコンテナ型を使ったUDFを書く時には積極的に活用していきたい機能です。