結論
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 │ } 4 │ 5 │ SELECT 1 ───────┴─────────────────────────────────────────────────────────────────────────── ───────┬─────────────────────────────────────────────────────────────────────────── │ File: definitions/sample_view_01.sqlx ───────┼─────────────────────────────────────────────────────────────────────────── 1 │ config { 2 │ type: 'view' 3 │ } 4 │ 5 │ /* 6 │ SELECT ${ref("sample_view_00")} 7 │ */ ───────┴─────────────────────────────────────────────────────────────────────────── ───────┬─────────────────────────────────────────────────────────────────────────── │ File: definitions/sample_view_02.sqlx ───────┼─────────────────────────────────────────────────────────────────────────── 1 │ config { 2 │ type: 'view' 3 │ } 4 │ 5 │ # /* 6 │ SELECT ${ref("sample_view_00")} 7 │ # */ ───────┴─────────────────────────────────────────────────────────────────────────── ───────┬─────────────────────────────────────────────────────────────────────────── │ File: definitions/sample_view_03.sqlx ───────┼─────────────────────────────────────────────────────────────────────────── 1 │ config { 2 │ type: 'view' 3 │ } 4 │ 5 │ # SELECT ${ref("sample_view_00")} ───────┴─────────────────────────────────────────────────────────────────────────── ───────┬─────────────────────────────────────────────────────────────────────────── │ File: definitions/sample_view_04.sqlx ───────┼─────────────────────────────────────────────────────────────────────────── 1 │ config { 2 │ type: 'view' 3 │ } 4 │ 5 │ -- SELECT ${ref("sample_view_00")} ───────┴─────────────────────────────────────────────────────────────────────────── ~/src/tmp/dataform-exp2/sample-project main ≡ 23:00:41 23ms⠀ 🦄
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 │ } 4 │ 5 │ SELECT 1 ───────┴──────────────────────────────────────────────────────────────────────────────────────────────── ───────┬──────────────────────────────────────────────────────────────────────────────────────────────── │ File: definitions/sample_view_01.sqlx ───────┼──────────────────────────────────────────────────────────────────────────────────────────────── 1 │ config { 2 │ type: 'view' 3 │ } 4 │ 5 + │ 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 │ } 4 │ 5 + │ 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 │ } 4 │ 5 + │ 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 │ } 4 │ 5 + │ 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を実行するとコメントのため実行はされません。