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

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

posted @ 2013-06-03 10:29  健哥的数据花园  阅读(742)  评论(0编辑  收藏  举报