• PostgreSQL在何处处理 sql查询之七


    前面已经说过,exec_simple_query要运行 PortalStart和 PortalRun。

    可以说,PortalRun是重头戏,sql的真正执行,就在这里完成。

    /*
     * PortalRun
     *        Run a portal's query or queries.
     *
     * 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".  Note that count is ignored in multi-query
     * situations, where we always run the portal to completion.
     *
     * isTopLevel: true if query is being executed at backend "top level"
     * (that is, directly from a client command message)
     *
     * dest: where to send output of primary (canSetTag) query
     *
     * altdest: where to send output of non-primary queries
     *
     * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
     *        in which to store a command completion status string.
     *        May be NULL if caller doesn't want a status string.
     *
     * Returns TRUE if the portal's execution is complete, FALSE if it was
     * suspended due to exhaustion of the count parameter.
     */
    bool
    PortalRun(Portal portal, long count, bool isTopLevel,
              DestReceiver *dest, DestReceiver *altdest,
              char *completionTag)
    {
      ...
        PG_TRY();
        {
            ActivePortal = portal;
            CurrentResourceOwner = portal->resowner;
            PortalContext = PortalGetHeapMemory(portal);
    
            MemoryContextSwitchTo(PortalContext);
    
            switch (portal->strategy)
            {
                case PORTAL_ONE_SELECT:
                case PORTAL_ONE_RETURNING:
                case PORTAL_ONE_MOD_WITH:
                case PORTAL_UTIL_SELECT:
    
                    /*
                     * If we have not yet run the command, do so, storing its
                     * results in the portal's tuplestore.  But we don't do that
                     * for the PORTAL_ONE_SELECT case.
                     */
                    if (portal->strategy != PORTAL_ONE_SELECT && !portal->holdStore)
                        FillPortalStore(portal, isTopLevel);
    
                    /*
                     * Now fetch desired portion of results.
                     */
                    nprocessed = PortalRunSelect(portal, true, count, dest);
    
                    /*
                     * If the portal result contains a command tag and the caller
                     * gave us a pointer to store it, copy it. Patch the "SELECT"
                     * tag to also provide the rowcount.
                     */
                    if (completionTag && portal->commandTag)
                    {
                        if (strcmp(portal->commandTag, "SELECT") == 0)
                            snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
                                     "SELECT %u", nprocessed);
                        else
                            strcpy(completionTag, portal->commandTag);
                    }
    
                    /* Mark portal not active */
                    portal->status = PORTAL_READY;
    
                    /*
                     * Since it's a forward fetch, say DONE iff atEnd is now true.
                     */
                    result = portal->atEnd;
                    break;
    
                case PORTAL_MULTI_QUERY:
                    PortalRunMulti(portal, isTopLevel,
                                   dest, altdest, completionTag);
    
                    /* Prevent portal's commands from being re-executed */
                    MarkPortalDone(portal);
    
                    /* Always complete at end of RunMulti */
                    result = true;
                    break;
    
                default:
                    elog(ERROR, "unrecognized portal strategy: %d",
                         (int) portal->strategy);
                    result = false; /* keep compiler quiet */
                    break;
            }
        }
        PG_CATCH();
        {
         ...
            PG_RE_THROW();
        }
        PG_END_TRY();
        ...
        return result;
    }

    这里面,这一段是核心:

                    /*
                     * Now fetch desired portion of results.
                     */
                    nprocessed = PortalRunSelect(portal, true, count, dest);
  • 相关阅读:
    排序算法(二)插入排序---直接插入排序
    Shazam 是如何听音辨曲的?
    Android 读取<meta-data>元素的数据
    Android <uses-featureandroid:name="string">详解
    Android AsyncTask的用法
    Android ViewPager使用详解
    Git 使用教程(4)—— Git 常用命令集合
    Git 使用教程(3)
    Git 使用教程(2)
    Git 使用教程
  • 原文地址:https://www.cnblogs.com/gaojian/p/3092705.html
Copyright © 2020-2023  润新知