クエリのパース処理。クエリツリーの構造体

昨日のクエリツリーのデバッグ出力を見ながらデバッグ用の名前と構造体をとりあえず結び付けてみた。ほとんどがそのままだけど、RTEがRangeTblEntryに対応するのは調べるまでわからなかった。

  • QUERY
    • Query
  • RTE
    • RangeTblEntry
    • 結合していると結合の結果を表すRangeTblEntryが追加される。メンバのjoinaliasvarsに結合の結果を表すVarのリストが格納される。
    • relidはリレーションのoid。SQLでは「select oid, * from pg_class」で確認できる。relfilenodeというカラムがoidを表しているように見えるけど、oidとrelfilenodeは一致しないこともあるとどこかで読んだ気がする。
  • ALIAS
    • Alias
  • VAR
    • Var
    • vartypeはpg_typeのOID。SQLで確認するには「select oid, * from pg_type」。vartypeが23はint4、1042はbpcharのこと。vartypmodとvarlevelsupは何だろう?
  • FROMEXPR
    • FromExpr
  • JOINEXPR
    • JoinExpr
    • rtindexは結合の結果を表すRangeTblEntryに対応しているよう。
  • RANGETBLREF
    • RangeTblRef
    • rtindexは対応するRangeTblEntryのインデックス。
  • OPEXPR
    • OpExpr
    • opnoは演算子のoid。SQLでは「select oid, * from pg_operator」で確認できる。opnoの96はint4同士の「=」。
    • opfuncidは演算子の振る舞いを実行する関数のoid。SQLでは「select oid, * from pg_proc」で確認できる。opfuncidの65はint4eqという名前の関数を表す。
  • CONST
    • Const
  • TARGETENTRY
    • TargetEntry
    • SELECTではSELECT句に並ぶカラムのことのよう。

思ったこと

  • 結合の結果を表すRangeTblEntryが追加されているのが気になった。
  • システムカタログであってもOIDを知るには隠しカラム?のoidをSELECT句に指定する必要がある。
  • pg_operatorに演算子の定義がたくさんあって驚いた。演算の対象となる値の型が違えば見た目は同じ演算しでも異なる関数で扱わなければいけないからか。あとは、GiSTやGINのインデックス用専用の演算子も定義されているからそのぶん数が多いのかも。