LCOV - code coverage report
Current view: top level - src/backend/tcop - dest.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 86.4 % 66 57
Test Date: 2026-03-09 05:14:47 Functions: 100.0 % 9 9
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-2026, 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/explain_dr.h"
      37              : #include "commands/matview.h"
      38              : #include "executor/functions.h"
      39              : #include "executor/tqueue.h"
      40              : #include "executor/tstoreReceiver.h"
      41              : #include "libpq/libpq.h"
      42              : #include "libpq/pqformat.h"
      43              : 
      44              : 
      45              : /* ----------------
      46              :  *      dummy DestReceiver functions
      47              :  * ----------------
      48              :  */
      49              : static bool
      50       660032 : donothingReceive(TupleTableSlot *slot, DestReceiver *self)
      51              : {
      52       660032 :     return true;
      53              : }
      54              : 
      55              : static void
      56         1797 : donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
      57              : {
      58         1797 : }
      59              : 
      60              : static void
      61       100488 : donothingCleanup(DestReceiver *self)
      62              : {
      63              :     /* this is used for both shutdown and destroy methods */
      64       100488 : }
      65              : 
      66              : /* ----------------
      67              :  *      static DestReceiver structs for dest types needing no local state
      68              :  * ----------------
      69              :  */
      70              : static const DestReceiver donothingDR = {
      71              :     donothingReceive, donothingStartup, donothingCleanup, donothingCleanup,
      72              :     DestNone
      73              : };
      74              : 
      75              : static const DestReceiver debugtupDR = {
      76              :     debugtup, debugStartup, donothingCleanup, donothingCleanup,
      77              :     DestDebug
      78              : };
      79              : 
      80              : static const DestReceiver printsimpleDR = {
      81              :     printsimple, printsimple_startup, donothingCleanup, donothingCleanup,
      82              :     DestRemoteSimple
      83              : };
      84              : 
      85              : static const DestReceiver spi_printtupDR = {
      86              :     spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup,
      87              :     DestSPI
      88              : };
      89              : 
      90              : /*
      91              :  * Globally available receiver for DestNone.
      92              :  *
      93              :  * It's ok to cast the constness away as any modification of the none receiver
      94              :  * would be a bug (which gets easier to catch this way).
      95              :  */
      96              : DestReceiver *None_Receiver = (DestReceiver *) &donothingDR;
      97              : 
      98              : /* ----------------
      99              :  *      BeginCommand - initialize the destination at start of command
     100              :  * ----------------
     101              :  */
     102              : void
     103       386900 : BeginCommand(CommandTag commandTag, CommandDest dest)
     104              : {
     105              :     /* Nothing to do at present */
     106       386900 : }
     107              : 
     108              : /* ----------------
     109              :  *      CreateDestReceiver - return appropriate receiver function set for dest
     110              :  * ----------------
     111              :  */
     112              : DestReceiver *
     113       536760 : CreateDestReceiver(CommandDest dest)
     114              : {
     115              :     /*
     116              :      * It's ok to cast the constness away as any modification of the none
     117              :      * receiver would be a bug (which gets easier to catch this way).
     118              :      */
     119              : 
     120       536760 :     switch (dest)
     121              :     {
     122       344803 :         case DestRemote:
     123              :         case DestRemoteExecute:
     124       344803 :             return printtup_create_DR(dest);
     125              : 
     126         2427 :         case DestRemoteSimple:
     127         2427 :             return unconstify(DestReceiver *, &printsimpleDR);
     128              : 
     129          576 :         case DestNone:
     130          576 :             return unconstify(DestReceiver *, &donothingDR);
     131              : 
     132        34948 :         case DestDebug:
     133        34948 :             return unconstify(DestReceiver *, &debugtupDR);
     134              : 
     135        79196 :         case DestSPI:
     136        79196 :             return unconstify(DestReceiver *, &spi_printtupDR);
     137              : 
     138        27185 :         case DestTuplestore:
     139        27185 :             return CreateTuplestoreDestReceiver();
     140              : 
     141            0 :         case DestIntoRel:
     142            0 :             return CreateIntoRelDestReceiver(NULL);
     143              : 
     144          231 :         case DestCopyOut:
     145          231 :             return CreateCopyDestReceiver();
     146              : 
     147        47394 :         case DestSQLFunction:
     148        47394 :             return CreateSQLFunctionDestReceiver();
     149              : 
     150            0 :         case DestTransientRel:
     151            0 :             return CreateTransientRelDestReceiver(InvalidOid);
     152              : 
     153            0 :         case DestTupleQueue:
     154            0 :             return CreateTupleQueueDestReceiver(NULL);
     155              : 
     156            0 :         case DestExplainSerialize:
     157            0 :             return CreateExplainSerializeDestReceiver(NULL);
     158              :     }
     159              : 
     160              :     /* should never get here */
     161            0 :     pg_unreachable();
     162              : }
     163              : 
     164              : /* ----------------
     165              :  *      EndCommand - clean up the destination at end of command
     166              :  * ----------------
     167              :  */
     168              : void
     169       365011 : EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output)
     170              : {
     171              :     char        completionTag[COMPLETION_TAG_BUFSIZE];
     172              :     Size        len;
     173              : 
     174       365011 :     switch (dest)
     175              :     {
     176       330063 :         case DestRemote:
     177              :         case DestRemoteExecute:
     178              :         case DestRemoteSimple:
     179              : 
     180       330063 :             len = BuildQueryCompletionString(completionTag, qc,
     181              :                                              force_undecorated_output);
     182       330063 :             pq_putmessage(PqMsg_CommandComplete, completionTag, len + 1);
     183       330063 :             break;
     184              : 
     185        34948 :         case DestNone:
     186              :         case DestDebug:
     187              :         case DestSPI:
     188              :         case DestTuplestore:
     189              :         case DestIntoRel:
     190              :         case DestCopyOut:
     191              :         case DestSQLFunction:
     192              :         case DestTransientRel:
     193              :         case DestTupleQueue:
     194              :         case DestExplainSerialize:
     195        34948 :             break;
     196              :     }
     197       365011 : }
     198              : 
     199              : /* ----------------
     200              :  *      EndReplicationCommand - stripped down version of EndCommand
     201              :  *
     202              :  *      For use by replication commands.
     203              :  * ----------------
     204              :  */
     205              : void
     206         2891 : EndReplicationCommand(const char *commandTag)
     207              : {
     208         2891 :     pq_putmessage(PqMsg_CommandComplete, commandTag, strlen(commandTag) + 1);
     209         2891 : }
     210              : 
     211              : /* ----------------
     212              :  *      NullCommand - tell dest that an empty query string was recognized
     213              :  *
     214              :  *      This ensures that there will be a recognizable end to the response
     215              :  *      to an Execute message in the extended query protocol.
     216              :  * ----------------
     217              :  */
     218              : void
     219          931 : NullCommand(CommandDest dest)
     220              : {
     221          931 :     switch (dest)
     222              :     {
     223          930 :         case DestRemote:
     224              :         case DestRemoteExecute:
     225              :         case DestRemoteSimple:
     226              : 
     227              :             /* Tell the FE that we saw an empty query string */
     228          930 :             pq_putemptymessage(PqMsg_EmptyQueryResponse);
     229          930 :             break;
     230              : 
     231            1 :         case DestNone:
     232              :         case DestDebug:
     233              :         case DestSPI:
     234              :         case DestTuplestore:
     235              :         case DestIntoRel:
     236              :         case DestCopyOut:
     237              :         case DestSQLFunction:
     238              :         case DestTransientRel:
     239              :         case DestTupleQueue:
     240              :         case DestExplainSerialize:
     241            1 :             break;
     242              :     }
     243          931 : }
     244              : 
     245              : /* ----------------
     246              :  *      ReadyForQuery - tell dest that we are ready for a new query
     247              :  *
     248              :  *      The ReadyForQuery message is sent so that the FE can tell when
     249              :  *      we are done processing a query string.
     250              :  *      In versions 3.0 and up, it also carries a transaction state indicator.
     251              :  *
     252              :  *      Note that by flushing the stdio buffer here, we can avoid doing it
     253              :  *      most other places and thus reduce the number of separate packets sent.
     254              :  * ----------------
     255              :  */
     256              : void
     257       383781 : ReadyForQuery(CommandDest dest)
     258              : {
     259       383781 :     switch (dest)
     260              :     {
     261       352880 :         case DestRemote:
     262              :         case DestRemoteExecute:
     263              :         case DestRemoteSimple:
     264              :             {
     265              :                 StringInfoData buf;
     266              : 
     267       352880 :                 pq_beginmessage(&buf, PqMsg_ReadyForQuery);
     268       352880 :                 pq_sendbyte(&buf, TransactionBlockStatusCode());
     269       352880 :                 pq_endmessage(&buf);
     270              :             }
     271              :             /* Flush output at end of cycle in any case. */
     272       352880 :             pq_flush();
     273       352880 :             break;
     274              : 
     275        30901 :         case DestNone:
     276              :         case DestDebug:
     277              :         case DestSPI:
     278              :         case DestTuplestore:
     279              :         case DestIntoRel:
     280              :         case DestCopyOut:
     281              :         case DestSQLFunction:
     282              :         case DestTransientRel:
     283              :         case DestTupleQueue:
     284              :         case DestExplainSerialize:
     285        30901 :             break;
     286              :     }
     287       383781 : }
        

Generated by: LCOV version 2.0-1