Loading
BLOG 開発者ブログ

2025年2月3日

SQL Fluff カスタムルールの覚書(crawl_behaviour編)

こんにちは。クラウドソリューショングループのkaneko.kです。
本記事ではこちらの記事「SQL Fluff カスタムルールの覚書(導入編)」の続きになります。
実際に導入してみたカスタムルールの細かいところを解説しつつ、チートシートを参考にあなたの開発に役立てればと思います。

0. 対象者

本記事では既にVSCodeにSQL Fluffの導入が完了しており、カスタムルールを追加したいという方に向けた記事です。
SQL Fluffの初期導入や基礎的な設定項目については他の方にお任せすることとします。
カスタムルールの導入方法についてはこちら:SQL Fluff カスタムルールの覚書(導入編)
また、バージョンについては下記を利用していますので、最新の書き方について公式を確認するようお願いします。
Python:3.13.0
SQL Fluff:3.2.5
VSCode:1.96.4

1.チートシート

項番 クラス名 用途
2.1. RootOnlyCrawler クエリ全体を構文チェックしたい場合
2.2. SegmentSeekerCrawler 特定の句に絞り込んで構文チェックしたい場合
2.3. ParentOfSegmentCrawler 特定の句を含むクエリのみに絞り込んで構文チェックしたい場合

 

項番 type名 用途
2.2.1. select_clause SELECT句
2.2.2. from_clause FROM句
2.2.3. where_clause WHERE句
2.2.4. orderby_clause ORDER BY句
2.2.5. groupby_clause GROUP BY句
2.2.6. limit_clause LIMIT句
2.2.7. having_clause HAVING句
2.2.8. subquery サブクエリ

2. crawl_behaviourについて

リンティングする際にクローラークラスがどのセグメントに対して働くのかの振る舞いを設定することができます。
こちらは項目は主に3種類の振る舞いから選択することができます。

2.0. 基底クラス BaseCrawler

(基底クラスを直接呼び出すことはあまりないかとは思いますが)
引数works_on_unparsableの有効/無効設定を設定できます。
こちらは対象のセグメントが解析不可能な場合に機能するかどうかを決められます。
ので、○○という条件下で解析エラーになった場合にXXというリンティング結果を返してほしいという場合はこちらをTrue(有効)にするといいでしょう。

デフォルトはfalse(無効)です。

2.1. RootOnlyCrawler

クローリングはせず、対象のファイルの最上位セグメントであるルートレベルからコンテキストを生成します。
特定のセグメントに依存しないようなSQLの構文チェックをしたい場合にこちらを使用するといいと思います。
特定のセグメント(例えばWhere句の構文のみチェックしたい場合等)に作用させたい場合は次のSegmentSeekerCrawlerを使って効率よく解析できます。

2.2. SegmentSeekerCrawler

特定のセグメントタイプを効率的に検索するためのクローラーです。
インスタンス生成時にどの句を対象にLintをかけるのかを設定することができます。
下記のように  <Lintしたい対象_clause>  の形式で指定してください。
また、サブクエリを直接指定したい場合は<subquery>で指定できるようです。
※ この辺は公式サイトに纏まっていなかったので、適宜試しながら探っていく必要性がありそうです
– select_clause:SELECT句
– from_clause:FROM句
– where_clause:WHERE句
– orderby_clause:ORDER BY句
– groupby_clause:GROUP BY句
– limit_clause: LIMIT句
– having_clause:HAVING句
– subquery:サブクエリ

✔️ ワンポイント

複数の対象を同時にとることことで、対象をより絞り込むことができます。
例えばサブクエリ内のSELECT句内のみ対象としたい場合は
SegmentSeekerCrawler({“select_clause”, “subquery”})
とすることでサブクエリ内のSELECT句に絞ってLINTをかけることができます。

2.3. ParentOfSegmentCrawler

特定の句の親を効率的に検索するためのクローラーです。
SegmentSeekerCrawlerを継承していますので、対象とする句の設定方法についてはSegmentSeekerCrawlerと同様です。
例えば下記のようなSQL文があった場合
SELECT *
FROM (
    SELECT column1
    FROM my_table
    WHERE column1 IS NOT NULL
) subquery;
ParentOfSegmentCrawler({“where_clause”})とした場合、WHERE句のあるサブクエリである
SELECT column1
    FROM my_table
    WHERE column1 IS NOT NULL
がLint対象になります。
ちなみに、
SELECT *
FROM (
    SELECT column1
    FROM my_table_1
    WHERE column1 IS NOT NULL
) subquery
INNER JOIN my_table_2
ON subquery.id = my_table_2.id
WHRER my_table_2.column2 > 0;
のようにWHERE句が複数ある場合は、サブクエリだけでなく、その親であるクエリ全体も対象となります。

3. 次回

今回触れられなかったカスタムルールの「groups」について簡単な解説をしつつ、
チートシートを用意して開発の補助になる記事を書いていきます。

 

kaneko.kのブログ