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

接前面,再次上溯。可以知道:

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语言是面向过程语言,不如说它是数据结构为中心的语言。

熟练掌握各类数据结构以及指针的用法,那就无往而不利了。

你可能感兴趣的:(PostgreSQL)