めもちょー

メモ帳代わりに使っています。

DataformとBigQueryでコメントアウトの記法が異なる罠を踏んだ

結論

BigQueryのSQLとDataformのsqlxはコメントの適用が異なることが分かりました。

これらはBigQueryでもDataformでもコメントとして認識されます。

-- SELECT 1

/*
SELECT 1
*/

#によるコメントは、BigQueryでは(標準SQL導入前のコメント記法で)コメントとして認識され実行できませんが、Dataformではクエリとして認識されるようです。

# SELECT 1

ブロックコメントの打ち消しは、BigQueryではクエリとして認識され実行できますが、Dataformではコメントとして認識されSQLにコンパイルできないようです。

# /*
SELECT 1
# */

実験

Dataform CLIで初期化を行い、下記のようなファイル構成を用意します。

   ~/src/tmp/dataform-exp2/sample-project   main ≡   23:00:33   0ms⠀
🦄  ls
 compile.json  📂 definitions  📂 includes   workflow_settings.yaml
   ~/src/tmp/dataform-exp2/sample-project   main ≡   23:00:35   11ms⠀
🦄  tree definitions/
definitions/
├── sample_view_00.sqlx
├── sample_view_01.sqlx
├── sample_view_02.sqlx
├── sample_view_03.sqlx
└── sample_view_04.sqlx

0 directories, 5 files
   ~/src/tmp/dataform-exp2/sample-project   main ≡   23:00:38   10ms⠀
🦄  bat definitions/*
───────┬───────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_00.sqlx
───────┼───────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45   │ SELECT 1
───────┴───────────────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_01.sqlx
───────┼───────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45   │ /*
   6   │ SELECT ${ref("sample_view_00")}
   7   │ */
───────┴───────────────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_02.sqlx
───────┼───────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45# /*
   6   │ SELECT ${ref("sample_view_00")}
   7# */
───────┴───────────────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_03.sqlx
───────┼───────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45# SELECT ${ref("sample_view_00")}
───────┴───────────────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_04.sqlx
───────┼───────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45-- SELECT ${ref("sample_view_00")}
───────┴───────────────────────────────────────────────────────────────────────────
   ~/src/tmp/dataform-exp2/sample-project   main ≡   23:00:41   23ms⠀
🦄

dataformコンソールでのエディタ表示

sample_view_00.sqlx (BQでもDataformでも実行可)
sample_view_01.sqlx (BQでもDataformでもコメントとして認識される)
sample_view_02.sqlx (BQでは実行可、Dataformではコメントとして認識される)
sample_view_03.sqlx (BQではコメントとして認識される、DataformではSQLにコンパイル可)
sample_view_04.sqlx (BQでもDataformでもコメントとして認識される)

compile結果

sqlx記法であるref関数が変換されているか否かを確認します。
sample_view_03.sqlxのみがsqlxとして認識され、SQLへコンパイルされていることが分かります。
その他はコメントとして認識され、コメントとしてコンパイルされています。

   ~/src/tmp/dataform-exp2/sample-project   main ≡   23:00:22   0ms⠀
🦄  dataform compile --json > compile.json
   ~/src/tmp/dataform-exp2/sample-project   main ≡   23:00:56   1.263s⠀
🦄  jq '.tables[] | {name: .target.name, query: .query}' compile.json
{
  "name": "sample_view_00",
  "query": "\n\nSELECT 1\n"
}
{
  "name": "sample_view_01",
  "query": "\n\n/*\nSELECT ${ref(\"sample_view_00\")}\n*/\n"
}
{
  "name": "sample_view_02",
  "query": "\n\n# /*\nSELECT ${ref(\"sample_view_00\")}\n# */\n"
}
{
  "name": "sample_view_03",
  "query": "\n\n# SELECT `dataform-sandbox.sample_dataset.sample_view_00`\n"
}
{
  "name": "sample_view_04",
  "query": "\n\n-- SELECT ${ref(\"sample_view_00\")}\n"
}
   ~/src/tmp/dataform-exp2/sample-project   main ≡   23:01:01   36ms⠀
🦄

dataformコンソールでのリネージ表示

リネージ

さらにヤバさがわかるように

今度は、さらにコトの重大さがわかるように、「意図していないクエリとして認識される」例を実験してみます。
BQでは、sample_view_02のSQLだけUNIONが有効となります。

🦄  bat definitions/*
───────┬────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_00.sqlx
───────┼────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45   │ SELECT 1
───────┴────────────────────────────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_01.sqlx
───────┼────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45 + │ SELECT ${ref("sample_view_00")}
   6   │ /*
   7 + │ UNION ALL
   8   │ SELECT ${ref("sample_view_00")}
   9   │ */
───────┴────────────────────────────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_02.sqlx
───────┼────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45 + │ SELECT ${ref("sample_view_00")}
   6# /*
   7 + │ UNION ALL
   8   │ SELECT ${ref("sample_view_00")}
   9# */
───────┴────────────────────────────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_03.sqlx
───────┼────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45 + │ SELECT ${ref("sample_view_00")}
   6 + │ # UNION ALL
   7# SELECT ${ref("sample_view_00")}
───────┴────────────────────────────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: definitions/sample_view_04.sqlx
───────┼────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ config {
   2   │     type: 'view'
   3}
   45 + │ SELECT ${ref("sample_view_00")}
   6 + │ -- UNION ALL
   7-- SELECT ${ref("sample_view_00")}
───────┴───────────────────────────────────────────────────────────────────────────────────────────────

これをdataform compileしてみると...

{
  "name": "sample_view_00",
  "query": "

SELECT 1
"
}
{
  "name": "sample_view_01",
  "query": "

SELECT `dataform-sandbox.sample_dataset.sample_view_00`
/*
UNION ALL
SELECT ${ref(\"sample_view_00\")}
*/
"
}
{
  "name": "sample_view_02",
  "query": "

SELECT `dataform-sandbox.sample_dataset.sample_view_00`
# /*
UNION ALL
SELECT ${ref(\"sample_view_00\")}
# */
"
}
{
  "name": "sample_view_03",
  "query": "

SELECT `dataform-sandbox.sample_dataset.sample_view_00`
# UNION ALL
# SELECT `dataform-sandbox.sample_dataset.sample_view_00`
"
}
{
  "name": "sample_view_04",
  "query": "

SELECT `dataform-sandbox.sample_dataset.sample_view_00`
-- UNION ALL
-- SELECT ${ref(\"sample_view_00\")}
"
}

おわかりいただけたであろうか
sample_view_02のUNIONはうまくコンパイルできず、逆にsample_view_03はUNION以降がコンパイルできます。
つまり、BQからDataformへ移植しようと思っていたクエリが別のクエリになってしまうのです。
以上の罠を気にしないと、BQとDataform間でのクエリ変換に躓くことになります。

さらに罠が...

上記はsqlxからSQLへの変換ですが、そのSQLが正しく動く保証はありません。
sample_view_02では、UNION以降が正しくコンパイルされなかったため実際にSQLを実行すると「refが不正です。」というエラーになります。
sample_view_03では、UNION以降で正しくコンパイルはできましたが、SQLを実行するとコメントのため実行はされません。