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

    在定义了Portal之后,需要运行:PortalStart,它主要的任务是明确执行策略,然后再执行 ExecutorStart:

    代码太长,进行缩略:

    void
    PortalStart(Portal portal, ParamListInfo params,
                int eflags, bool use_active_snapshot)
    {
        ...
        PG_TRY();
        {
            ActivePortal = portal;
            CurrentResourceOwner = portal->resowner;
            PortalContext = PortalGetHeapMemory(portal);
    
            oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
    
            /* Must remember portal param list, if any */
            portal->portalParams = params;
    
            /*
             * Determine the portal execution strategy
             */
            portal->strategy = ChoosePortalStrategy(portal->stmts);
    
            /*
             * Fire her up according to the strategy
             */
            switch (portal->strategy)
            {
                case PORTAL_ONE_SELECT:
    
              ...break;
    
                case PORTAL_ONE_RETURNING:
                case PORTAL_ONE_MOD_WITH:
    
              ...break;
    
                case PORTAL_UTIL_SELECT:
    
              ...break;
    
                case PORTAL_MULTI_QUERY:
              ...break;
            }
        }
        PG_CATCH();
        {
         ...
            PG_RE_THROW();
        }
        PG_END_TRY();
    
        MemoryContextSwitchTo(oldContext);
    
        ActivePortal = saveActivePortal;
        CurrentResourceOwner = saveResourceOwner;
        PortalContext = savePortalContext;
    
        portal->status = PORTAL_READY;
    }

    我们发送如 select * from tab01; 这样的查询时,得到的Strategy是: PORTAL_ONE_SELECT

    在得知Strategy 为  PORTAL_ONE_SELECT 之后,作了哪些事情呢:

     1 case PORTAL_ONE_SELECT:
     2                 /* Must set snapshot before starting executor. */
     3                 if (use_active_snapshot)
     4                     PushActiveSnapshot(GetActiveSnapshot());
     5                 else
     6                     PushActiveSnapshot(GetTransactionSnapshot());
     7 
     8                 /*
     9                  * Create QueryDesc in portal's context; for the moment, set
    10                  * the destination to DestNone.
    11                  */
    12                 queryDesc = CreateQueryDesc((PlannedStmt *) linitial(portal->stmts),
    13                                             portal->sourceText,
    14                                             GetActiveSnapshot(),
    15                                             InvalidSnapshot,
    16                                             None_Receiver,
    17                                             params,
    18                                             0);
    19 
    20                 /*
    21                  * If it's a scrollable cursor, executor needs to support
    22                  * REWIND and backwards scan, as well as whatever the caller
    23                  * might've asked for.
    24                  */
    25                 if (portal->cursorOptions & CURSOR_OPT_SCROLL)
    26                     myeflags = eflags | EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD;
    27                 else
    28                     myeflags = eflags;
    29 
    30                 /*
    31                  * Call ExecutorStart to prepare the plan for execution
    32                  */
    33                 ExecutorStart(queryDesc, myeflags);
    34 
    35                 /*
    36                  * This tells PortalCleanup to shut down the executor
    37                  */
    38                 portal->queryDesc = queryDesc;
    39 
    40                 /*
    41                  * Remember tuple descriptor (computed by ExecutorStart)
    42                  */
    43                 portal->tupDesc = queryDesc->tupDesc;
    44 
    45                 /*
    46                  * Reset cursor position data to "start of query"
    47                  */
    48                 portal->atStart = true;
    49                 portal->atEnd = false;    /* allow fetches */
    50                 portal->portalPos = 0;
    51                 portal->posOverflow = false;
    52 
    53                 PopActiveSnapshot();
    54                 break;

    对于 select * from tab01; 这样的查询, myeflags 为0。这里很重要的,就是执行了 ExecutorStart。

    这样,为执行做好了准备。

  • 相关阅读:
    软件杯学习:python爬虫爬取新浪新闻并保存为csv格式
    操作系统实验1:时间片轮转和存储管理动态分区分配及回收
    软件测试
    实验6-使用TensorFlow完成线性回归
    实验一
    pycharm中设置anaconda环境
    架构之美读书笔记一
    2.1学习总结:决策树分类器
    python自学日记一
    爱甩卖网站正式上线啦
  • 原文地址:https://www.cnblogs.com/gaojian/p/3092622.html
Copyright © 2011-2022 走看看