##JOINをしているのにテーブル名を書いていない場所を見つける
テーブル名の宣言無しに列名が使われるとわかりづらいため、
「joinを行ったらテーブル名を書かなくてはならない」というコーディング規約が現場にある。
しかし、この規約違反を目でチェックするのが面倒なので自動化する。
つまり、
SELECT
book.title
FROM
book
INNER JOIN shelf ON boo.id_shelf = shelf.id
WHERE
shelf.name = 'mine'
というのを、
SELECT
title
FROM
book
INNER JOIN shelf ON boo.id_shelf = shelf.id
WHERE
shelf.name = 'mine'
のように書いている場所を発見したい。(下のSELECT句にはbookが抜けている)
##道具の用意
静的にTransact-SQLを解析するのは自分の力ではできそうになかったので、ライブラリを使用した。
使用したのは、Microsoftが提供しているTransact-SQLのパーサー兼ジェネレータ
TransactSql.ScriptDom
使い方はT-SQL の パーサーとジェネレーター(ScriptDom)の紹介が参考になる。
これはVisitorを使用していて、動きに合わせて全ての部分に行けるのでパース結果から静的な解析が楽にできる。
が、ドキュメントが皆無なので、どんな時に何のメソッドが呼ばれるのかは実験する必要がある。
##解析する
目的は「joinを行ったのにテーブル名を書いていない場所を見つける」こと
テーブルの列名が宣言されるべき場所はSELECT, WHERE, ORDERなど色々あるが、パースした結果では共通してExplicitVisit(ColumnReferenceExpression)が呼ばれている。
そのため、
- SELECT,INSERT,UPDATE,DELETE文内でExplicitVisit(..)が呼ばれている
- 宣言されている列名にテーブル名がついていない
- JOINが呼ばれている
以上を満たせば「joinがあるのにテーブル名が宣言されていない」ということがわかる。
これを利用して、T-SQL文字列から規約違反を発見することが出来る。
実際に使用しているプログラムはGithubにおいている。
SQLChecker内が実際にT-SQLをチェックしている部分