LCOV - code coverage report
Current view: top level - src/backend/tcop - dest.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 39 47 83.0 %
Date: 2017-09-29 13:40:31 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * dest.c
       4             :  *    support for communication destinations
       5             :  *
       6             :  *
       7             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/tcop/dest.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : /*
      16             :  *   INTERFACE ROUTINES
      17             :  *      BeginCommand - initialize the destination at start of command
      18             :  *      CreateDestReceiver - create tuple receiver object for destination
      19             :  *      EndCommand - clean up the destination at end of command
      20             :  *      NullCommand - tell dest that an empty query string was recognized
      21             :  *      ReadyForQuery - tell dest that we are ready for a new query
      22             :  *
      23             :  *   NOTES
      24             :  *      These routines do the appropriate work before and after
      25             :  *      tuples are returned by a query to keep the backend and the
      26             :  *      "destination" portals synchronized.
      27             :  */
      28             : 
      29             : #include "postgres.h"
      30             : 
      31             : #include "access/printsimple.h"
      32             : #include "access/printtup.h"
      33             : #include "access/xact.h"
      34             : #include "commands/copy.h"
      35             : #include "commands/createas.h"
      36             : #include "commands/matview.h"
      37             : #include "executor/functions.h"
      38             : #include "executor/tqueue.h"
      39             : #include "executor/tstoreReceiver.h"
      40             : #include "libpq/libpq.h"
      41             : #include "libpq/pqformat.h"
      42             : #include "utils/portal.h"
      43             : 
      44             : 
      45             : /* ----------------
      46             :  *      dummy DestReceiver functions
      47             :  * ----------------
      48             :  */
      49             : static bool
      50       31051 : donothingReceive(TupleTableSlot *slot, DestReceiver *self)
      51             : {
      52       31051 :     return true;
      53             : }
      54             : 
      55             : static void
      56          30 : donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
      57             : {
      58          30 : }
      59             : 
      60             : static void
      61        5113 : donothingCleanup(DestReceiver *self)
      62             : {
      63             :     /* this is used for both shutdown and destroy methods */
      64        5113 : }
      65             : 
      66             : /* ----------------
      67             :  *      static DestReceiver structs for dest types needing no local state
      68             :  * ----------------
      69             :  */
      70             : static DestReceiver donothingDR = {
      71             :     donothingReceive, donothingStartup, donothingCleanup, donothingCleanup,
      72             :     DestNone
      73             : };
      74             : 
      75             : static DestReceiver debugtupDR = {
      76             :     debugtup, debugStartup, donothingCleanup, donothingCleanup,
      77             :     DestDebug
      78             : };
      79             : 
      80             : static DestReceiver printsimpleDR = {
      81             :     printsimple, printsimple_startup, donothingCleanup, donothingCleanup,
      82             :     DestRemoteSimple
      83             : };
      84             : 
      85             : static DestReceiver spi_printtupDR = {
      86             :     spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup,
      87             :     DestSPI
      88             : };
      89             : 
      90             : /* Globally available receiver for DestNone */
      91             : DestReceiver *None_Receiver = &donothingDR;
      92             : 
      93             : 
      94             : /* ----------------
      95             :  *      BeginCommand - initialize the destination at start of command
      96             :  * ----------------
      97             :  */
      98             : void
      99       27374 : BeginCommand(const char *commandTag, CommandDest dest)
     100             : {
     101             :     /* Nothing to do at present */
     102       27374 : }
     103             : 
     104             : /* ----------------
     105             :  *      CreateDestReceiver - return appropriate receiver function set for dest
     106             :  * ----------------
     107             :  */
     108             : DestReceiver *
     109       38890 : CreateDestReceiver(CommandDest dest)
     110             : {
     111       38890 :     switch (dest)
     112             :     {
     113             :         case DestRemote:
     114             :         case DestRemoteExecute:
     115       25269 :             return printtup_create_DR(dest);
     116             : 
     117             :         case DestRemoteSimple:
     118           0 :             return &printsimpleDR;
     119             : 
     120             :         case DestNone:
     121           1 :             return &donothingDR;
     122             : 
     123             :         case DestDebug:
     124        1023 :             return &debugtupDR;
     125             : 
     126             :         case DestSPI:
     127        5697 :             return &spi_printtupDR;
     128             : 
     129             :         case DestTuplestore:
     130        1668 :             return CreateTuplestoreDestReceiver();
     131             : 
     132             :         case DestIntoRel:
     133           0 :             return CreateIntoRelDestReceiver(NULL);
     134             : 
     135             :         case DestCopyOut:
     136          33 :             return CreateCopyDestReceiver();
     137             : 
     138             :         case DestSQLFunction:
     139        5199 :             return CreateSQLFunctionDestReceiver();
     140             : 
     141             :         case DestTransientRel:
     142           0 :             return CreateTransientRelDestReceiver(InvalidOid);
     143             : 
     144             :         case DestTupleQueue:
     145           0 :             return CreateTupleQueueDestReceiver(NULL);
     146             :     }
     147             : 
     148             :     /* should never get here */
     149           0 :     return &donothingDR;
     150             : }
     151             : 
     152             : /* ----------------
     153             :  *      EndCommand - clean up the destination at end of command
     154             :  * ----------------
     155             :  */
     156             : void
     157       24284 : EndCommand(const char *commandTag, CommandDest dest)
     158             : {
     159       24284 :     switch (dest)
     160             :     {
     161             :         case DestRemote:
     162             :         case DestRemoteExecute:
     163             :         case DestRemoteSimple:
     164             : 
     165             :             /*
     166             :              * We assume the commandTag is plain ASCII and therefore requires
     167             :              * no encoding conversion.
     168             :              */
     169       23261 :             pq_putmessage('C', commandTag, strlen(commandTag) + 1);
     170       23261 :             break;
     171             : 
     172             :         case DestNone:
     173             :         case DestDebug:
     174             :         case DestSPI:
     175             :         case DestTuplestore:
     176             :         case DestIntoRel:
     177             :         case DestCopyOut:
     178             :         case DestSQLFunction:
     179             :         case DestTransientRel:
     180             :         case DestTupleQueue:
     181        1023 :             break;
     182             :     }
     183       24284 : }
     184             : 
     185             : /* ----------------
     186             :  *      NullCommand - tell dest that an empty query string was recognized
     187             :  *
     188             :  *      In FE/BE protocol version 1.0, this hack is necessary to support
     189             :  *      libpq's crufty way of determining whether a multiple-command
     190             :  *      query string is done.  In protocol 2.0 it's probably not really
     191             :  *      necessary to distinguish empty queries anymore, but we still do it
     192             :  *      for backwards compatibility with 1.0.  In protocol 3.0 it has some
     193             :  *      use again, since it ensures that there will be a recognizable end
     194             :  *      to the response to an Execute message.
     195             :  * ----------------
     196             :  */
     197             : void
     198           5 : NullCommand(CommandDest dest)
     199             : {
     200           5 :     switch (dest)
     201             :     {
     202             :         case DestRemote:
     203             :         case DestRemoteExecute:
     204             :         case DestRemoteSimple:
     205             : 
     206             :             /*
     207             :              * tell the fe that we saw an empty query string.  In protocols
     208             :              * before 3.0 this has a useless empty-string message body.
     209             :              */
     210           5 :             if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
     211           5 :                 pq_putemptymessage('I');
     212             :             else
     213           0 :                 pq_putmessage('I', "", 1);
     214           5 :             break;
     215             : 
     216             :         case DestNone:
     217             :         case DestDebug:
     218             :         case DestSPI:
     219             :         case DestTuplestore:
     220             :         case DestIntoRel:
     221             :         case DestCopyOut:
     222             :         case DestSQLFunction:
     223             :         case DestTransientRel:
     224             :         case DestTupleQueue:
     225           0 :             break;
     226             :     }
     227           5 : }
     228             : 
     229             : /* ----------------
     230             :  *      ReadyForQuery - tell dest that we are ready for a new query
     231             :  *
     232             :  *      The ReadyForQuery message is sent so that the FE can tell when
     233             :  *      we are done processing a query string.
     234             :  *      In versions 3.0 and up, it also carries a transaction state indicator.
     235             :  *
     236             :  *      Note that by flushing the stdio buffer here, we can avoid doing it
     237             :  *      most other places and thus reduce the number of separate packets sent.
     238             :  * ----------------
     239             :  */
     240             : void
     241       27471 : ReadyForQuery(CommandDest dest)
     242             : {
     243       27471 :     switch (dest)
     244             :     {
     245             :         case DestRemote:
     246             :         case DestRemoteExecute:
     247             :         case DestRemoteSimple:
     248       26947 :             if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
     249             :             {
     250             :                 StringInfoData buf;
     251             : 
     252       26947 :                 pq_beginmessage(&buf, 'Z');
     253       26947 :                 pq_sendbyte(&buf, TransactionBlockStatusCode());
     254       26947 :                 pq_endmessage(&buf);
     255             :             }
     256             :             else
     257           0 :                 pq_putemptymessage('Z');
     258             :             /* Flush output at end of cycle in any case. */
     259       26947 :             pq_flush();
     260       26947 :             break;
     261             : 
     262             :         case DestNone:
     263             :         case DestDebug:
     264             :         case DestSPI:
     265             :         case DestTuplestore:
     266             :         case DestIntoRel:
     267             :         case DestCopyOut:
     268             :         case DestSQLFunction:
     269             :         case DestTransientRel:
     270             :         case DestTupleQueue:
     271         524 :             break;
     272             :     }
     273       27471 : }

Generated by: LCOV version 1.11