PostgreSQL在何处处理 sql查询之八

在PortalRun里要调用 PortalRunSelect,具体的过程缩略如下:

/*

 * PortalRunSelect

 *        Execute a portal's query in PORTAL_ONE_SELECT mode, and also

 *        when fetching from a completed holdStore in PORTAL_ONE_RETURNING,

 *        PORTAL_ONE_MOD_WITH, and PORTAL_UTIL_SELECT cases.

 *

 * This handles simple N-rows-forward-or-backward cases.  For more complex

 * nonsequential access to a portal, see PortalRunFetch.

 *

 * count <= 0 is interpreted as a no-op: the destination gets started up

 * and shut down, but nothing else happens.  Also, count == FETCH_ALL is

 * interpreted as "all rows".

 *

 * Caller must already have validated the Portal and done appropriate

 * setup (cf. PortalRun).

 *

 * Returns number of rows processed (suitable for use in result tag)

 */

static long

PortalRunSelect(Portal portal,

                bool forward,

                long count,

                DestReceiver *dest)

{

    ...

/*

     * Determine which direction to go in, and check to see if we're already

     * at the end of the available tuples in that direction.  If so, set the

     * direction to NoMovement to avoid trying to fetch any tuples.  (This

     * check exists because not all plan node types are robust about being

     * called again if they've already returned NULL once.)  Then call the

     * executor (we must not skip this, because the destination needs to see a

     * setup and shutdown even if no tuples are available).  Finally, update

     * the portal position state depending on the number of tuples that were

     * retrieved.

     */

    if (forward)

    {



        if (portal->atEnd || count <= 0)

            direction = NoMovementScanDirection;

        else

            direction = ForwardScanDirection;



        /* In the executor, zero count processes all rows */

        if (count == FETCH_ALL)

            count = 0;



        if (portal->holdStore)

            nprocessed = RunFromStore(portal, direction, count, dest);

        else

        {

            PushActiveSnapshot(queryDesc->snapshot);

            ExecutorRun(queryDesc, direction, count);

            nprocessed = queryDesc->estate->es_processed;

            PopActiveSnapshot();

        }



        if (!ScanDirectionIsNoMovement(direction))

        {

            ...

        }

    }

    else

    {

       ...

    }



    return nprocessed;

}

对于我们的 select * from tab01 查询,执行到  ExecutorRun(queryDesc, direction, count); 

你可能感兴趣的:(PostgreSQL)