エクゼキュータ。PlanStateとExprState

クエリの実行では、プランツリーがそのまま使われるわけではなく、プランツリー(Plan)から変換されたプランステート(PlanState)が使われる。変換を行うのはExecInitNode()。ExecInitNodeのシグネチャは次のとおり。

PlanState *
ExecInitNode(Plan *node, EState *estate, int eflags)

PlanStateの継承関係はPlanの継承関係にほととんどそのまま対応する。すべてexecnodes.hに定義されている。継承関係は次のとおり。

PlanState
 +--ResultState
 +--AppendState
 +--BitmapAndState
 +--BitmapOrState
 +--ScanState
     +--SeqScanState
     +--IndexScanState
     +--BitmapIndexScanState
     +--BitmapHeapScanState
     +--TidScanStateState
     +--SubqueryScanState
     +--FunctionScanState
     +--ValuesScanState
     +--MaterialState                ※ Planの継承関係と一致していない
     +--SortState                    ※ Planの継承関係と一致していない
     +--GroupState                   ※ Planの継承関係と一致していない
     +--AggState                     ※ Planの継承関係と一致していない
 +--JoinState
     +--NestLoopState
     +--MergeJoinState
     +--HashJoinState
 +--UniqueState
 +--HashState
 +--SetOpState
 +--LimitState

なぜか、MaterialState、SortState、GroupState、AggStateがPlanのときと継承関係が一致していない。


ExecInitNode()すると、プランツリーにぶらさがるExprはExprStateに変換されPlanStateにぶらさがる。これらもexecnodes.hで定義されている。ExprStateを親とした継承関係がある。

ExprState
 +--GenericExprState
 +--AppendState
 +--AggrefExprState
 +--ArrayRefExprState
 +--FuncExprState
     +--ScalarArrayOpExprState
 +--BoolExprState
 +--SubPlanState
 +--FieldSelectState
 +--FieldStoreState
 +--CoerceViaIOState
 +--ArrayCoerceExprState
 +--ConvertRowtypeExprState
 +--CaseExprState
 +--CaseWhenState
 +--ArrayExprState
 +--RowExprState
 +--RowCompareExprState
 +--CoalesceExprState
 +--MinMaxExprState
 +--XmlExprState
 +--NullTestState
 +--CoerceToDomainState

ExprStateは元の式に応じて関数ポインタがセットされるようになっている。評価されるときに呼び出されるのだと思う。名前だけ何をやるのか想像がつくものもあればよくわからないのもある。


クエリの実行でPlanStateのノードを処理しているのはExecProcNode()。ExecProcNodeのシグネチャは次のとおり。

TupleTableSlot *
ExecProcNode(PlanState *node)

ここから下の処理を読むと実行計画がどのように処理されていくかわかるはず。


追記
PlanStateのノードをpprintでデバッグ出力したかったのだけどできなかった。対応していないみたい。