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。

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

你可能感兴趣的:(PostgreSQL)