フューチャー技術ブログ

Engineer Camp2020でSQLフォーマッタを開発しました

はじめに

はじめまして。フューチャーのインターン”Engineer Camp”に参加した中村と申します。

フューチャーのインターンについてはこちらの記事をご覧ください!

この記事では、今回のインターンで私が取り組んだ内容を紹介します。

SQLフォーマッタとは

今回のインターンで私は、SQLフォーマッタの作成に取り組みました。
SQLフォーマッタとは以下のようにSQLのインデントなど整形するツールのことです。

SQLフォーマッタを用いることで、SQLの見た目を整える手間を削減したり、チームで統一感があるコーディングを実現できます。

取り組んだ課題

もともとフューチャーではuroboroSQL formatterというSQLフォーマッタが開発されていました。(このフォーマッタについてはこちらの記事をご覧ください!)

しかし、このフォーマッタはPythonベースで書かれていたため、(現在広く使われているエディタである)VSCodeの拡張機能として動かすことが困難でした。

そこで、uroboroSQL formatterの後継として、新しいフォーマッタを作成しようと今回のプロジェクトが始まりました。

新しいフォーマッタが満たすべき条件として、次の3つがあります:

  • VSCode上で動く
  • 2-Way SQL 1のフォーマットに対応している(≒式中にコメントが入ってもフォーマットが崩れない)
  • カラムやAS句等の縦ぞろえに対応している

これらの条件を満たすフォーマッタを作成することが、今回のインターンでの課題でした。

使用したOSS

今回の開発では、すべてのコードを一から書くことはせず、利用できるツールは使っていく方針を取りました。具体的には、以下に示す2つのOSSを使いました。

Prettier

PrettierとはVSCodeなど様々なエディタで動作する、OSSのコードフォーマッタです。Prettier単体でもHTMLやCSSといった言語をフォーマットできるのですが、プラグインを作成することで、フォーマット可能な言語をさらに増やすことができます。

今回のSQLフォーマッタは、このPrettierプラグインとして開発を行いました。このようにすることで、VSCodeからフォーマット対象のコードを取得する処理や、フォーマットしたコードをVSCode上に反映する処理などをPrettierが代わりに行ってくれるため、フォーマット処理に集中して開発を行うことができます。また、Prettierが動作する他のエディタに対しても、今回作成したフォーマッタが使えるというメリットもあります。

ANTLR

ANTLRはパーサ(構文解析器)を生成するためのOSSです。パーサとは、コードの処理構造を解析し、結果をASTという表現で出力するプログラムです。(ANTLRやパーサに関する詳しい説明はこちらの記事をご覧ください)
今回のフォーマッタではパーサとプリンタという二つのプログラムを使用するのですが、そのうちの一つをANTLRで自動生成してしまおう!という作戦です。

フォーマッタの構成

今回作成したフォーマッタによる、フォーマット処理の流れを下図に示します。

フォーマット処理は2つのステップからなり、パーサとプリンタという2つのプログラムを用います。

第1ステップでは、パーサがフォーマット対象のSQLコードを受け取り、コードをASTという表現に変換します。

第2ステップでは、プリンタがASTを受け取り、ASTの情報をもとにフォーマットされたコードを出力します。

この2ステップを組み合わせることで、SQLを入力として受け取り、成形したものを出力するという、フォーマッタの動作が実現できます!

行った作業

プリンタの開発

今回のインターンで、私は主にプリンタ(受け取ったASTをもとに、コードを成型して出力するプログラム)の開発を行いました。
PrettierプラグインとしてSQLフォーマッタの開発を行ったので、基本的な部分は他のプラグインを参考にすることができたのですが、縦ぞろえや式中コメントへの対応といった独自の機能については、一から実装を行いました。

ANTLRの高速化

開発をしていく中で、SQLのパース処理にかかる時間がありえないほど長いという問題が発生しました。
メンターの方と調査を行った結果、ANTLR内部の実装にミスがあることが判明し、ANTLRのリポジトリにissueが立つという一幕がありました。

現在は修正されているのですが、この修正で今まで90分かけても終わらなかった処理が20秒で終わるようになり、特定の条件下において、約270倍(!)の高速化を行うことができました。

フォーマット結果

今回作成したフォーマッタでのフォーマット結果を以下に示します。

フォーマット前のSQLコードです。とても見にくい…。

フォーマット後のSQLコードです。見やすい!

各カラムや条件式が整えられ、見やすくなっています。また、最後のWHERE句のような、式中にコメントがある場合もうまくフォーマットが行われています。

さいごに

今回作成したSQLフォーマッタは基本的な構文にしか対応しておらず、実際の業務で使えるレベルにはまだ達していません。
それでも、実際にVSCode上で動作するフォーマッタを開発できたことはとても嬉しく、今後の糧になるような経験でした。
今回は私が行ったタスクの話が中心になってしまいましたが、Engineer Campでは業務以外にも次のような沢山のイベントがありました:

  • 社内競技プログラミング部主催のバーチャルコンテスト
  • コミュ会・ランチ会(インターン生同士が集まり、ざっくばらんに話す会)
  • 社内ベテランエンジニアの方々による講義
  • インターン生主催のzoom飲み会

こういったイベントがあったため、リモートであっても実際にフューチャー社でインターンをしているんだという実感が持てました。

また、業務においても、ペアプログラミングや夕会(一日の終わりに集まり、今日の進捗や明日やることを共有する場)をしていただけたため、たくさんの知見を得ることができたと感じています。

総じて本当に楽しいインターンで、一か月があっという間でした。

受け入れ先プロジェクトの方々やフューチャーHRの皆さん、本当にありがとうございました!

参考リンク

https://prettier.io/
https://www.antlr.org/


  1. 1.2-Way SQLの詳細についてはこちらのドキュメントをご参照ください。