您的位置:首页 > 数据库

PostgreSQL在何处处理 sql查询之四十二

2013-06-03 10:29 543 查看
接前面,再次上溯。可以知道:

ExecProcNode: 会根据情况不同,将PlanNode转为各种类型Node再参与运算:

TupleTableSlot *
ExecProcNode(PlanState *node)
{

//ExecProcNode
fprintf(stderr,"ExecProcNode:node->ss_currentScanDesc->rs_startblock is: %d by process %d\n",
((SeqScanState *) node)->ss_currentScanDesc->rs_startblock,getpid());

TupleTableSlot *result;

CHECK_FOR_INTERRUPTS();

if (node->chgParam != NULL) /* something changed */
ExecReScan(node);        /* let ReScan handle this */

if (node->instrument)
InstrStartNode(node->instrument);

switch (nodeTag(node))
{
/*
* control nodes
*/
case T_ResultState:
result = ExecResult((ResultState *) node);
break;

...

/*
* scan nodes
*/
case T_SeqScanState:
result = ExecSeqScan((SeqScanState *) node);
break;

case T_IndexScanState:
result = ExecIndexScan((IndexScanState *) node);
break;

...

default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
result = NULL;
break;
}

if (node->instrument)
InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);

return result;
}


各种 Node,有点像 Java里的 类和基类,这是如何实现的呢?

看下面就清楚了:

/* ----------------
*        PlanState node
*
* We never actually instantiate any PlanState nodes; this is just the common
* abstract superclass for all PlanState-type nodes.
* ----------------
*/
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 */

Instrumentation *instrument;    /* Optional runtime stats for this node */

/*
* 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).
*/
List       *targetlist;        /* target list to be computed at this node */
List       *qual;            /* implicitly-ANDed qual conditions */
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 */
bool        ps_TupFromTlist;/* state flag for processing set-valued
* functions in targetlist */
} PlanState;


再看:

/* ----------------
*     ResultState information
* ----------------
*/
typedef struct ResultState
{
PlanState    ps;                /* its first field is NodeTag */
ExprState  *resconstantqual;
bool        rs_done;        /* are we done? */
bool        rs_checkqual;    /* do we need to check the qual? */
} ResultState;


再看:

/* ----------------
*     ScanState information
*
*        ScanState extends PlanState for node types that represent
*        scans of an underlying relation.  It can also be used for nodes
*        that scan the output of an underlying plan node --- in that case,
*        only ScanTupleSlot is actually useful, and it refers to the tuple
*        retrieved from the subplan.
*
*        currentRelation    relation being scanned (NULL if none)
*        currentScanDesc    current scan descriptor for scan (NULL if none)
*        ScanTupleSlot       pointer to slot in tuple table holding scan tuple
* ----------------
*/
typedef struct ScanState
{
PlanState    ps;                /* its first field is NodeTag */
Relation    ss_currentRelation;
HeapScanDesc ss_currentScanDesc;
TupleTableSlot *ss_ScanTupleSlot;
} ScanState;


甚至还有这个:

/* ----------------
*     IndexScanState information
*
*        indexqualorig       execution state for indexqualorig expressions
*        ScanKeys           Skey structures for index quals
*        NumScanKeys           number of ScanKeys
*        OrderByKeys           Skey structures for index ordering operators
*        NumOrderByKeys       number of OrderByKeys
*        RuntimeKeys           info about Skeys that must be evaluated at runtime
*        NumRuntimeKeys       number of RuntimeKeys
*        RuntimeKeysReady   true if runtime Skeys have been computed
*        RuntimeContext       expr context for evaling runtime Skeys
*        RelationDesc       index relation descriptor
*        ScanDesc           index scan descriptor
* ----------------
*/
typedef struct IndexScanState
{
ScanState    ss;                /* its first field is NodeTag */
List       *indexqualorig;
ScanKey        iss_ScanKeys;
int            iss_NumScanKeys;
ScanKey        iss_OrderByKeys;
int            iss_NumOrderByKeys;
IndexRuntimeKeyInfo *iss_RuntimeKeys;
int            iss_NumRuntimeKeys;
bool        iss_RuntimeKeysReady;
ExprContext *iss_RuntimeContext;
Relation    iss_RelationDesc;
IndexScanDesc iss_ScanDesc;
} IndexScanState;


那就相当于 子类的子类了。

我的感觉,与其说C语言是面向过程语言,不如说它是数据结构为中心的语言。

熟练掌握各类数据结构以及指针的用法,那就无往而不利了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: