PostgreSQL在何处处理 sql查询之六

前面说过 PortalStart明确执行策略后,要执行 ExecutorStart。

那么ExecutorStart 到底作了什么呢。以下是缩略:

/* ----------------------------------------------------------------
 *        ExecutorStart
 *
 *        This routine must be called at the beginning of any execution of any
 *        query plan
 *
 * Takes a QueryDesc previously created by CreateQueryDesc (which is separate
 * only because some places use QueryDescs for utility commands).  The tupDesc
 * field of the QueryDesc is filled in to describe the tuples that will be
 * returned, and the internal fields (estate and planstate) are set up.
 *
 * eflags contains flag bits as described in executor.h.
 *
 * NB: the CurrentMemoryContext when this is called will become the parent
 * of the per-query context used for this Executor invocation.
 *
 * We provide a function hook variable that lets loadable plugins
 * get control when ExecutorStart is called.  Such a plugin would
 * normally call standard_ExecutorStart().
 *
 * ----------------------------------------------------------------
 */
void
ExecutorStart(QueryDesc *queryDesc, int eflags)
{

    if (ExecutorStart_hook)
        (*ExecutorStart_hook) (queryDesc, eflags);
    else
        standard_ExecutorStart(queryDesc, eflags);
}

void
standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
{
    ...

    /*
     * If non-read-only query, set the command ID to mark output tuples with
     */
    switch (queryDesc->operation)
    {
    ...
    }

    /*
     * Copy other important information into the EState
     */
    estate->es_snapshot = RegisterSnapshot(queryDesc->snapshot);
    estate->es_crosscheck_snapshot = RegisterSnapshot(queryDesc->crosscheck_snapshot);
    estate->es_top_eflags = eflags;
    estate->es_instrument = queryDesc->instrument_options;

    /*
     * Initialize the plan state tree
     */
    InitPlan(queryDesc, eflags);

    /*
     * Set up an AFTER-trigger statement context, unless told not to, or
     * unless it's EXPLAIN-only mode (when ExecutorFinish won't be called).
     */
    if (!(eflags & (EXEC_FLAG_SKIP_TRIGGERS | EXEC_FLAG_EXPLAIN_ONLY)))
        AfterTriggerBeginQuery();

    MemoryContextSwitchTo(oldcontext);
}

核心一条就是,对  QueryDesc 型指针所指向的结构,进行了设置,以备后面的使用(ExecutorRun)。

上述代码的注释中已经说明:使用了CreateQueryDesc时产生的 QueryDesc,设置其tupDesc。

原文地址:https://www.cnblogs.com/gaojian/p/3092629.html