zoukankan      html  css  js  c++  java
  • PostgreSQL在何处处理 sql查询之九

    调用关系:PortalRun -> PortalRunSelect -> ExecutorRun

    ExecutorRun,实际上会去运行 standard_ExecutorRun ->ExecutePlan:

    /* ----------------------------------------------------------------
     *        ExecutorRun
     *
     *        This is the main routine of the executor module. It accepts
     *        the query descriptor from the traffic cop and executes the
     *        query plan.
     *
     *        ExecutorStart must have been called already.
     *
     *        If direction is NoMovementScanDirection then nothing is done
     *        except to start up/shut down the destination.  Otherwise,
     *        we retrieve up to 'count' tuples in the specified direction.
     *
     *        Note: count = 0 is interpreted as no portal limit, i.e., run to
     *        completion.
     *
     *        There is no return value, but output tuples (if any) are sent to
     *        the destination receiver specified in the QueryDesc; and the number
     *        of tuples processed at the top level can be found in
     *        estate->es_processed.
     *
     *        We provide a function hook variable that lets loadable plugins
     *        get control when ExecutorRun is called.  Such a plugin would
     *        normally call standard_ExecutorRun().
     *
     * ----------------------------------------------------------------
     */
    void
    ExecutorRun(QueryDesc *queryDesc,
                ScanDirection direction, long count)
    {
        if (ExecutorRun_hook)
            (*ExecutorRun_hook) (queryDesc, direction, count);
        else
            standard_ExecutorRun(queryDesc, direction, count);
    }
    
    void
    standard_ExecutorRun(QueryDesc *queryDesc,
                         ScanDirection direction, long count)
    {
        EState       *estate;
        CmdType        operation;
        DestReceiver *dest;
        bool        sendTuples;
        MemoryContext oldcontext;
    
        /* sanity checks */
        Assert(queryDesc != NULL);
    
        estate = queryDesc->estate;
    
        Assert(estate != NULL);
        Assert(!(estate->es_top_eflags & EXEC_FLAG_EXPLAIN_ONLY));
    
        /*
         * Switch into per-query memory context
         */
        oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
    
        /* Allow instrumentation of Executor overall runtime */
        if (queryDesc->totaltime)
            InstrStartNode(queryDesc->totaltime);
    
        /*
         * extract information from the query descriptor and the query feature.
         */
        operation = queryDesc->operation;
        dest = queryDesc->dest;
    
        /*
         * startup tuple receiver, if we will be emitting tuples
         */
        estate->es_processed = 0;
        estate->es_lastoid = InvalidOid;
    
        sendTuples = (operation == CMD_SELECT ||
                      queryDesc->plannedstmt->hasReturning);
    
        if (sendTuples)
            (*dest->rStartup) (dest, operation, queryDesc->tupDesc);
    
        /*
         * run plan
         */
        if (!ScanDirectionIsNoMovement(direction))
            ExecutePlan(estate,
                        queryDesc->planstate,
                        operation,
                        sendTuples,
                        count,
                        direction,
                        dest);
    
        /*
         * shutdown tuple receiver, if we started it
         */
        if (sendTuples)
            (*dest->rShutdown) (dest);
    
        if (queryDesc->totaltime)
            InstrStopNode(queryDesc->totaltime, estate->es_processed);
    
        MemoryContextSwitchTo(oldcontext);
    }
  • 相关阅读:
    fopen和open的区别
    vc代码缩进
    防止u盘中autorun的一个小方法
    判断单链表是否有环
    四色原理
    Log4j的使用
    Ant学习笔记
    关于Oracle Exp00003问题的解决方法
    装机小记
    用iframe做编辑器
  • 原文地址:https://www.cnblogs.com/gaojian/p/3092816.html
Copyright © 2011-2022 走看看