細々と SQL の Parser を作っているのだけど、よく考えたらそもそも各エンジン、SQLのパースどうやってるんだっけ、と思って調べたメモ。多少独自拡張はあるものの基本的には yacc ベースなようだ。だったら最初からこっちをベースにすればよかったのでは感なくはない(ということもない。実際には文法の外部に別の要件があって、そう簡単でもない。例えばバージョンによって文法が異なるなど)。
Sqlite3
Sqlite3 は LEMON という YACC を独自拡張した LRLA(1) パーサーを使っているようだ。様々な最適化が行われているようではあるけど文法そのものにあまり違いはないように見える。
PostgreSQL
- postgres/src/backend/parser/gram.y at master · postgres/postgres · GitHub
- postgres/src/pl/plpgsql/src/pl_gram.y at master · postgres/postgres · GitHub
Postgresql は Gnu 版 YACC である Bison を使っている。PL/pgSQL は別文法なのでわかれている。
- mysql-server/sql/sql_yacc.yy at trunk · mysql/mysql-server · GitHub
- mysql-server/sql/sql_hints.yy at trunk · mysql/mysql-server · GitHub
こちらも同様に Bison を使っている。hint 句が別に分かれている。
BigQuery/Spanner
- zetasql/zetasql/parser/bison_parser.y at master · google/zetasql · GitHub
BigQuery や Spanner は Google Standard SQL という文法を使っていて ZetaSQL というライブラリとしてパーサーが公開されている。こちらも Bison が使われている模様。
SQLって変な文法だから独自でパーサー書いてるのが多いのかな、と思ってたけど意外にそうでもないようで。