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

    回到上一个层面,继续看 PortalStart的处理:

    void
    PortalStart(Portal portal, ParamListInfo params,
                int eflags, bool use_active_snapshot)
    {
        ...
        PG_TRY();
        {
            ...
    
            /*
             * Determine the portal execution strategy
             */
            portal->strategy = ChoosePortalStrategy(portal->stmts);
    
            /*
             * Fire her up according to the strategy
             */
            switch (portal->strategy)
            {
                case PORTAL_ONE_SELECT:
    
                    /* Must set snapshot before starting executor. */
                    if (use_active_snapshot)
                        PushActiveSnapshot(GetActiveSnapshot());
                    else
                        PushActiveSnapshot(GetTransactionSnapshot());
    
                    /*
                     * Create QueryDesc in portal's context; for the moment, set
                     * the destination to DestNone.
                     */
                   queryDesc = CreateQueryDesc((PlannedStmt *) linitial(portal->stmts,
                                                portal->sourceText,
                                                GetActiveSnapshot(),
                                                InvalidSnapshot,
                                                None_Receiver,
                                                params,
                                                0);
    
                    /*
                     * If it's a scrollable cursor, executor needs to support
                     * REWIND and backwards scan, as well as whatever the caller
                     * might've asked for.
                     */
                    if (portal->cursorOptions & CURSOR_OPT_SCROLL)
                        myeflags = eflags | EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD;
                    else
                        myeflags = eflags;
    
                    /*
                     * Call ExecutorStart to prepare the plan for execution
                     */
                    ExecutorStart(queryDesc, myeflags);
    
                    /*
                     * This tells PortalCleanup to shut down the executor
                     */
                    portal->queryDesc = queryDesc;
    
                    /*
                     * Remember tuple descriptor (computed by ExecutorStart)
                     */
                    portal->tupDesc = queryDesc->tupDesc;
    
                    /*
                     * Reset cursor position data to "start of query"
                     */
                    portal->atStart = true;
                    portal->atEnd = false;    /* allow fetches */
                    portal->portalPos = 0;
                    portal->posOverflow = false;
    
                    PopActiveSnapshot();
                    break;
    
                case PORTAL_ONE_RETURNING:
                case PORTAL_ONE_MOD_WITH:
    
                    ...
                    break;
    
                case PORTAL_UTIL_SELECT:
                    ...
                    break;
    
                case PORTAL_MULTI_QUERY:
                    /* Need do nothing now */
                    portal->tupDesc = NULL;
                    break;
            }
        }
        PG_CATCH();
        {
            ...
            PG_RE_THROW();
        }
        PG_END_TRY();
        ...
    }

    由之前的分析可以知道,满足  case PORTAL_ONE_SELECT 的条件,下面再看

    use_active_snapshot,回溯上层:

    static void
    exec_simple_query(const char *query_string)
    {
        ...
        foreach(parsetree_item, parsetree_list)
        {
            ...
            /*
             * Set up a snapshot if parse analysis/planning will need one.
             */
            if (analyze_requires_snapshot(parsetree))
            {
                PushActiveSnapshot(GetTransactionSnapshot());
                snapshot_set = true;
            }
            ...
            PortalStart(portal, NULL, 0, snapshot_set);
        }
        ...
    }

    可见,snapshot 还是要搞的。简言之,snapshot 是为了MVCC控制:

    typedef struct SnapshotData
    {
        SnapshotSatisfiesFunc satisfies;    /* tuple test function */
    
        /*
         * The remaining fields are used only for MVCC snapshots, and are normally
         * just zeroes in special snapshots.  (But xmin and xmax are used
         * specially by HeapTupleSatisfiesDirty.)
         *
         * An MVCC snapshot can never see the effects of XIDs >= xmax. It can see
         * the effects of all older XIDs except those listed in the snapshot. xmin
         * is stored as an optimization to avoid needing to search the XID arrays
         * for most tuples.
         */
        TransactionId xmin;            /* all XID < xmin are visible to me */
        TransactionId xmax;            /* all XID >= xmax are invisible to me */
        TransactionId *xip;            /* array of xact IDs in progress */
        uint32        xcnt;            /* # of xact ids in xip[] */
        /* note: all ids in xip[] satisfy xmin <= xip[i] < xmax */
        int32        subxcnt;        /* # of xact ids in subxip[] */
        TransactionId *subxip;        /* array of subxact IDs in progress */
        bool        suboverflowed;    /* has the subxip array overflowed? */
        bool        takenDuringRecovery;    /* recovery-shaped snapshot? */
        bool        copied;            /* false if it's a static snapshot */
    
        /*
         * note: all ids in subxip[] are >= xmin, but we don't bother filtering
         * out any that are >= xmax
         */
        CommandId    curcid;            /* in my xact, CID < curcid are visible */
        uint32        active_count;    /* refcount on ActiveSnapshot stack */
        uint32        regd_count;        /* refcount on RegisteredSnapshotList */
    } SnapshotData;
  • 相关阅读:
    初学Listener
    初学filter
    Servlet开发
    伪随机数生成
    枚举类
    LeetCode74——Search a 2D Matrix
    STL——lower_bound()
    LeetCode198——house robber(不懂dp)
    LeetCode171——Excel Sheet Column Number
    参数传递的三种方式
  • 原文地址:https://www.cnblogs.com/gaojian/p/3106221.html
Copyright © 2011-2022 走看看