• 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);
    }
  • 相关阅读:
    Linux_文件系统、磁盘分区_RHEL7
    Linux_LVM、RAID_RHEL7
    Linux_LVM、RAID_RHEL7
    Linux_系统时间管理
    简单聊聊HDFS RBF第二阶段工作近期的一些进展
    LinkedBlockingQueue和ArrayBlockingQueue之间的比较
    LinkedBlockingQueue和ArrayBlockingQueue之间的比较
    公司如何使用开源软件
    公司如何使用开源软件
    ListenableFuture和CompletableFuture简单小结
  • 原文地址:https://www.cnblogs.com/gaojian/p/3092816.html
Copyright © 2020-2023  润新知