这段代码用于迭代节点结构,但是箭头操作符在这里做什么,为什么它返回下一个元素?
static inline TupleTableSlot *
ExecProcNode(PlanState *node)
{
if (node->chgParam != NULL) /* something changed? */
ExecReScan(node); /* let ReScan handle this */
return node->ExecProcNode(node);
}下面是PLanState结构:
typedef struct PlanState
{
NodeTag type;
Plan *plan; /* associated Plan node */
EState *state; /* at execution time, states of individual
* nodes point to one EState for the whole
* top-level plan */
ExecProcNodeMtd ExecProcNode; /* function to return next tuple */
ExecProcNodeMtd ExecProcNodeReal; /* actual function, if above is a
* wrapper */
Instrumentation *instrument; /* Optional runtime stats for this node */
WorkerInstrumentation *worker_instrument; /* per-worker instrumentation */
/* Per-worker JIT instrumentation */
struct SharedJitInstrumentation *worker_jit_instrument;
/*
* Common structural data for all Plan types. These links to subsidiary
* state trees parallel links in the associated plan tree (except for the
* subPlan list, which does not exist in the plan tree).
*/
ExprState *qual; /* boolean qual condition */
struct PlanState *lefttree; /* input plan tree(s) */
struct PlanState *righttree;
List *initPlan; /* Init SubPlanState nodes (un-correlated expr
* subselects) */
List *subPlan; /* SubPlanState nodes in my expressions */
/*
* State for management of parameter-change-driven rescanning
*/
Bitmapset *chgParam; /* set of IDs of changed Params */
/*
* Other run-time state needed by most if not all node types.
*/
TupleTableSlot *ps_ResultTupleSlot; /* slot for my result tuples */
ExprContext *ps_ExprContext; /* node's expression-evaluation context */
ProjectionInfo *ps_ProjInfo; /* info for doing tuple projection */
/*
* Scanslot's descriptor if known. This is a bit of a hack, but otherwise
* it's hard for expression compilation to optimize based on the
* descriptor, without encoding knowledge about all executor nodes.
*/
TupleDesc scandesc;
} PlanState;这里是node-object的结构。我不认为这有什么帮助,但如果你看到一些我没有看到的东西,请详细说明。
我不明白这段代码是如何在链表中“递增”箭头的,特别是通过使用c-/iterates运算符。
发布于 2021-06-09 21:45:16
PostgreSQL执行器“按需”生成结果元组(存储在TupleTableSlot中)。如果需要执行计划节点的下一个结果行,可以调用它的ExecProcNode函数,该函数将返回所需的结果。这将根据需要在其他较低的计划节点上调用ExecProcNode。
结构成员ExecProcNode的类型为ExecProcNodeMtd,其定义如下
typedef TupleTableSlot *(*ExecProcNodeMtd) (struct PlanState *pstate);所以这是一个指向函数的指针。当创建一个节点时,该节点类型的实际执行器函数存储在ExecProcNode中,代码可以读取为“调用为该节点定义的任何执行器函数”。
例如,ExecInitSeqScan按如下方式初始化扫描状态:
scanstate = makeNode(SeqScanState);
scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecSeqScan;因此,在顺序扫描的情况下,实际调用的函数是ExecSeqScan。
如果您愿意,这种编码技术可以用C语言以面向对象的方式实现抽象。
https://stackoverflow.com/questions/67904424
复制相似问题