458 文字
2 分

Q. BigQueryでクエリを実行するとNo matching signature for function IFNULLエラーが出る

2024-12-05

エラーが発生する状況#

リクエストに応じてクエリを生成して BigQuery にリクエストを投げるサービスで、次のようなクエリが生成される。

MERGE INTO `dataset_id.table_id` AS T
USING (
SELECT id, name, updated_at
FROM UNNEST([STRUCT("123" AS id, NULL AS name, NULL AS updated_at)]) AS source_data
) AS S
ON T.id = S.id
WHEN MATCHED THEN UPDATE SET
T.name = IFNULL(S.name, T.name),
T.updated_at = IFNULL(S.updated_at, T.updated_at ),
WHEN NOT MATCHED THEN INSERT (id, name, updated_at)
VALUES (S.id, S.name, S.updated_at)

ここで STRING 型や INTEGER 型でない TIMESTAMP 型や RECORD 型のカラムにデータを渡そうとすると、BigQuery 側で次のようなエラーが発生する。

No matching signature for function IFNULL
Argument types: INT64, TIMESTAMP
Signature: IFNULL(T1, T1)
Unable to find common supertype for templated argument <T1>
Input types for <T1>: {INT64, TIMESTAMP} at [0:0], invalidQuery

IFNULL の仕様#

BigQuery の IFNULL の仕様は次のようになっている。

  • 1 つ目の引数が NULL である場合、2 つ目の引数を返す。
  • 2 つの引数は同じデータ型に強制変換可能である必要がある。

強制変換可能かはConversion rules | BigQueryで確認できる。

問題の原因#

BigQuery では型を識別する方法がない場合、デフォルトの INT64 型が適用される。

つまり生成されるクエリでは NULL に対しての型の指定がなく INT64 型が適用されるため、INT64 と強制変換可能でないデータ型を操作しようとすると IFNULL でエラーが発生する。

解決策#

次のように NULL を本来のデータ型に明示的にキャストすることで回避できる。

CAST(NULL AS TIMESTAMP) AS updated_at

全体のクエリは次のようになる。

MERGE INTO `dataset_id.table_id` AS T
USING (
SELECT id, name, updated_at
FROM UNNEST([STRUCT("123" AS id, CAST(NULL AS STRING) AS name, CAST(NULL AS TIMESTAMP) AS updated_at)]) AS source_data
) AS S
ON T.id = S.id
WHEN MATCHED THEN UPDATE SET
T.name = IFNULL(S.name, T.name),
T.updated_at = IFNULL(S.updated_at, T.updated_at ),
WHEN NOT MATCHED THEN INSERT (id, name, updated_at)
VALUES (S.id, S.name, S.updated_at)
Q. BigQueryでクエリを実行するとNo matching signature for function IFNULLエラーが出る
https://blog.ohirunewani.com/posts/q-bigquery-no-matching-signature-for-function-ifnull/
作者
hrdtbs
公開日
2024-12-05
ライセンス
CC BY-NC-SA 4.0