Update execProcnode.cpp

This commit is contained in:
bjyb 2023-09-26 19:37:29 +08:00
parent 74fa63df6e
commit dfb3849780
1 changed files with 111 additions and 0 deletions

View File

@ -175,6 +175,23 @@
* initilaization work like open scanrel, instead allow NodeInit work to continue on its
* lefttree/righttree
*/
/*The function is called ` NeedStubExecution', and its input parameter is a pointer to type ` Plan'.
The main function of this function is to judge whether a plan node needs pile execution.
The following is a detailed explanation of each part of the function:
-` # ifndef enable _ multiple _ nodes`: This is a preprocessor instruction to check whether the
macro definition `enable _ multiple _ nodes` exists. If it does not exist, the function directly returns false.
-`if (exec _ in _ recursive _ mode (plan) )`: This judgment statement checks whether the plan node is
in recursive mode. If so, the function returns false.
-`if (NeedExecute(plan) )`: This judgment statement calls the `NeedExecute' function to judge
whether this plan step needs to be executed on the current data node. If necessary, the function returns false.
-`switch (nodeTag(plan) )`: This judgment statement is processed differently according to the type
of plan node. For most types of planning nodes, it returns ` false', but for certain node types
(such as T_ModifyTable, T_VecModifyTable, T_Scan, etc.), it returns ` true'. If `enable _ multiple _ nodes` is defined, it will also handle the T_TsStoreScan type.
Therefore, in a word, this function mainly judges whether a given plan node needs to be executed,
and it is influenced by many conditions, including whether some macros are defined,
the state of the plan node, and the type of the plan node.*/
bool NeedStubExecution(Plan* plan)
{
#ifndef ENABLE_MULTIPLE_NODES
@ -219,6 +236,21 @@ bool NeedStubExecution(Plan* plan)
/*
* not need execute active sql if the datanode don't run in multi-nodegroup.
*/
/*1. `Needexecutivesql (plan * plan)' function: judge whether the current plan node needs to be executed.
If the current node is neither a PGXC coordinator nor a single node and does not need to be executed, then return false; Otherwise return true.
2. `seqscannodestub (seqscanstate * seq _ scan) ` function: judge whether the sequential scanning node is a pile.
If the scan description is NULL, then it is a pile and returns true; Otherwise return false.
3. `idxscannodestub (indexscanstate * index _ scan) ` function: judge whether the index scanning node is a stub.
If the scan description is NULL, then it is a pile and returns true; Otherwise return false.
4. `idxonlyscannodestub (indexonlyscanstate * index _ only _ scan) ` function: judge whether the index-only
scanning node is a pile. If the scan description is NULL, then it is a pile and returns true; Otherwise return false.
5. `bmidxonlyscannodestub (bitmapindexscanstate * BM _ index _ scan) ` function: judge whether the
bitmap index scanning node is a pile. If the scan description is NULL, then it is a pile and returns true; Otherwise return false.
6. `bmheapscannodestub (bitmapheapstate * BM _ heap _ scan) ` function: judge whether the bitmap heap
scanning node is a pile. If the scan description is NULL, then it is a pile and returns true; Otherwise return false.
Each of these functions checks whether certain types of database operations (such as sequential scanning,
index scanning, etc.) need to be performed on the current data node. If not, then the operation is a "stub", that is, it is a placeholder and does not actually perform any work.*/
static bool NeedExecuteActiveSql(Plan* plan)
{
if ((!IS_PGXC_COORDINATOR) && (!IS_SINGLE_NODE) && false == NeedExecute(plan)) {
@ -252,7 +284,16 @@ static inline bool BmHeapScanNodeIsStub(BitmapHeapScanState* bm_heap_scan)
{
return bm_heap_scan->ss.ss_currentScanDesc == NULL;
}
/*The function is called ExecInitNodeByType, and it has three parameters: plan * node, estate * estate,
int eflags. This function calls the corresponding initialization function by judging the type of the incoming Plan node.
This code is a part of a database management system (such as PostgreSQL) to handle the execution of the query plan
. Each query will be parsed and transformed into a plan, and then the plan will guide the execution of the query.
In the code, each case corresponds to a plan node type, such as T_SeqScan corresponding to sequential scanning
and T_IndexScan corresponding to index scanning. Each case will pass the node, estate and eflags to the corresponding
initialization function, and return the initialized PlanState. This is a kind of polymorphism,
which enables us to call the corresponding function according to the node type.*/
PlanState* ExecInitNodeByType(Plan* node, EState* estate, int eflags)
{
switch (nodeTag(node)) {
@ -405,7 +446,24 @@ PlanState* ExecInitNodeByType(Plan* node, EState* estate, int eflags)
return NULL; /* keep compiler quiet */
}
}
/*
The function ExecInitNodeSubPlan accepts three parameters: a Plan node, an execution state and a result PlanState.
Its main purpose is to initialize sub-plans and execute them if certain conditions are met.
The following is a detailed explanation of the code:
A sub_ps variable is defined, which is a list used to store the initialized sub-plan status.
Traverse each element in the node->initPlan list. Node->initPlan is a list containing subplans.
In each iteration, take the current sub-plan out of the list and check whether it is empty. If empty, the current iteration is skipped.
Make sure that the sub-plan taken out is indeed of SubPlan type.
This part of the code performs different processing according to whether the macro ENABLE_MULTIPLE_NODES is defined.
If this macro is defined, then if the current node is PGXC coordinator, or estate->es_subplan_ids is empty, or the ID of the
current node is equal to the ID of the subplan, the subplan will be executed. If the macro is not defined, the sub-plan
will be executed if the current node is the top consumer of the stream, or if the estate->es_subplan_ids is empty,
or if the ID of the current node is equal to the ID of the sub-plan.
If the above conditions are met, the ExecInitSubPlan function is called to initialize the subplan,
and the returned subplan status is stored in the sub_ps list.
Finally, assign the sub_ps list to the result->initPlan, that is, the status of the result plan.
Generally speaking, the main task of this function is to initialize and execute the subplans in the query plan.*/
void ExecInitNodeSubPlan(Plan* node, EState* estate, PlanState* result)
{
List* sub_ps = NIL;
@ -1002,6 +1060,27 @@ ExecProcFuncType g_execProcFuncTable[] = {
* Execute the given node to return a(nother) tuple.
* ----------------------------------------------------------------
*/
/*The function ExecProcNode accepts a pointer node of type PlanState and returns a pointer of type TupleTableSlot'.
The following is a detailed explanation of the code:
1. A pointer' result' to the type' TupleTableSlot' is defined and initialized to NULL. This pointer will be used to store the return value of the function.
2. `CHECK_FOR_INTERRUPTS () ` is a macro used to check whether there is an interrupt signal. If so, it will stop the current operation and handle the interrupt.
3. `MemoryContext old_context; Defines a variable' old_context' of type' MemoryContext', which will be used to save the current memory context.
4.' # ifdef ENABLE_MULTIPLE_NODES' is a preprocessor instruction.
If' enable _ multiple _ nodes' is defined, the next code will be compiled and executed.
This code checks whether there is an early stop signal, and if there is, the function returns NULL.
5. `MemoryContextSwitchTo(node->nodeContext); Switch the memory context to the memory context of the node.
6. If the parameters of the node have changed, call ExecReScan(node)' for rescan.
7. If the node has an instrument (for performance analysis), call `instr start node (node-> instrument)' to start the timing of the instrument.
8. In the case of multi-nodes, if the nodes need stubs, call ExecProcNodeStub(node)' to execute stub nodes.
Otherwise, the node is processed by looking up the ` g _ execprocfunctional` function table and executing the corresponding function.
9. If the node has instruments, call ExecProcNodeInstr(node, result)' to record the implementation of the node.
10. Switch back to the old memory context.
11. Increment the row counter of the node.
12. Return the result pointer.
The purpose of this code is to perform the corresponding operation according to the type of node and return the result. It is one of the core parts of database query execution.*/
TupleTableSlot* ExecProcNode(PlanState* node)
{
TupleTableSlot* result = NULL;
@ -1062,6 +1141,38 @@ TupleTableSlot* ExecProcNode(PlanState* node)
* function must provide its own instrumentation support.
* ----------------------------------------------------------------
*/
/*This code is a part of a database management system (such as PostgreSQL) and is used to handle the execution of the query plan.
Each query will be parsed and transformed into a plan, and then the plan will guide the execution of the query.
The function MultiExecProcNode accepts a pointer `node` of type
PlanState and returns a pointer to type `node`.
The following is a detailed explanation of the code:
1. A pointer result to the type Node is defined and initialized to NULL.
This pointer will be used to store the return value of the function.
2. `MemoryContext old_context; Defines a variable' old_context' of type' MemoryContext',
which will be used to save the current memory context.
3. `CHECK_FOR_INTERRUPTS(); ` is a macro used to check whether there is an interrupt signal.
If so, it will stop the current operation and handle the interrupt.
4. `MemoryContextSwitchTo(node->nodeContext);
Switch the memory context to the memory context of the node.
5. If the parameters of the node have changed, call ExecReScan(node)' for rescan.
6. The `switch (node tag (node)) ` statement performs
corresponding operations according to the type of node:
-If the node type is `t _ hashstate`, call `multiexecshash ((hashstate *) node) `.
-If the node type is `t _ bitmapindexscanState', call `multiexecbitmapindexscan ((bitmapindexscanState *) node) `.
-If the node type is `t _ bitmapandstate`, call `multiexecbitmapand ((bitmapandstate *) node) `.
-If the node type is `t _ bitmaporstate`, call `multiexecbitmapor ((bitmaporstate *) node) `.
-If the node type is not any of the above, an error is reported with the error code `errcode _ unrecognized _ node _ type`
and ERRCODE_UNRECOGNIZED_NODE_TYPE is displayed.
7. If the node has an instrument (used for performance analysis),
set the memory information of the node as the memory information of the instrument.
8. Switch back to the old memory context.
9. Return the result pointer.
The purpose of this code is to perform the corresponding operation according to the type of node and return the result.
It is one of the core parts of database query execution.*/
Node* MultiExecProcNode(PlanState* node)
{
Node* result = NULL;