MySQLにおけるSELECT文のAST

最近DBにハマってるのですが、MySQLにおけるクエリのASTってどうなってるのかなと思い調べてみました。今回はSELECT文を調べてみました。

結論としては、全く自信が無いですがおそらく見つけたかなと思います。(間違ってる可能性もかなりありそうです。)

きっかけ

もともと詳解MySQLを読んでいて、「パーサとオプティマイザ」の章があり、その中に解析ツリーに関することが少し触れられました。 そこで以前SQL Parserを書いたのでMySQLのASTはどうなってるのかなと興味を持ったのがきっかけとなります。

今MySQLはバージョン8ですが、詳解MySQLはバージョン4~5の内容になっています。ですので半分くらい内容は当てにならないのですが、記載内容からどこらへんのclassかなというのはあたりを付けることができました。

SELECT文のAST

バージョン4~5自体の解析ツリーは sql/sql_lex.hst_select_lex_node クラスだったそうですが、最新のバージョン8ではそのクラスは存在しません。

なんとかコードを読んでいったところ sql/sql_lex.h にあるQuery_block というクラスが、SELECT文を表してそうだったので調べてみることにしました。

Query_block はテーブル、フィールド、GROUP BYかどうか、ORDER BYかどうかなどの情報を持ってるのでそう判断しました。

https://github.com/mysql/mysql-server/blob/8.0/sql/sql_lex.h#L1119L1124

/**
This class represents a query block, aka a query specification, which is
a query consisting of a SELECT keyword, followed by a table list,
optionally followed by a WHERE clause, a GROUP BY, etc.
*/
class Query_block {

ビルドとデバッグ

次にビルドして変数の中身を確認してみようと思います。

上記の通りにビルドしてVS Codeで中身を見てみました。ビルドに関しては成功しませんでしたが、 mysqldmysql など必要なバイナリは生成されてたので、上記のリンクの通りにデバッグしてみました。

Query_block が生成されるポイントは見つけていたので、そこにブレイクポイントを貼ってみました。

見てみたところ、ポインタを指していて中身が見れないものが多く、また双方向リストでどこに向いてるかわからないものなど変数の中身が釈然としませんでした。

結論

SELECT文のASTはコメントと変数から、おそらく sql/sql_lex.hQuery_block クラスであろうと思います。

ただかなり自信が無いので、もっと調査が必要そうです。

またデバッガが動かせるので、引き続き処理の流れなど追って理解を深めてみようかなと思います。

関連リンク

--

--