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

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

  • 相关阅读:
    JMeter学习(二十三)关联
    最常用的DOS命令
    不同类型的操作系统
    分级存储管理的四大优点
    软件工程中数据库设计
    PPP(点对点协议(Point to Point Protocol)
    关键路径法
    什么是鲁棒性测试
    何为蠕虫病毒
    临界区
  • 原文地址:https://www.cnblogs.com/gaojian/p/3114824.html
Copyright © 2020-2023  润新知