LCOV - code coverage report
Current view: top level - src/backend/tcop - dest.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 86.2 % 65 56
Test Date: 2026-02-17 17:20:33 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       106298 : donothingCleanup(DestReceiver *self)
      62              : {
      63              :     /* this is used for both shutdown and destroy methods */
      64       106298 : }
      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       383315 : BeginCommand(CommandTag commandTag, CommandDest dest)
     104              : {
     105              :     /* Nothing to do at present */
     106       383315 : }
     107              : 
     108              : /* ----------------
     109              :  *      CreateDestReceiver - return appropriate receiver function set for dest
     110              :  * ----------------
     111              :  */
     112              : DestReceiver *
     113       528336 : 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       528336 :     switch (dest)
     121              :     {
     122       335240 :         case DestRemote:
     123              :         case DestRemoteExecute:
     124       335240 :             return printtup_create_DR(dest);
     125              : 
     126         2362 :         case DestRemoteSimple:
     127         2362 :             return unconstify(DestReceiver *, &printsimpleDR);
     128              : 
     129          568 :         case DestNone:
     130          568 :             return unconstify(DestReceiver *, &donothingDR);
     131              : 
     132        40926 :         case DestDebug:
     133        40926 :             return unconstify(DestReceiver *, &debugtupDR);
     134              : 
     135        79137 :         case DestSPI:
     136        79137 :             return unconstify(DestReceiver *, &spi_printtupDR);
     137              : 
     138        27072 :         case DestTuplestore:
     139        27072 :             return CreateTuplestoreDestReceiver();
     140              : 
     141            0 :         case DestIntoRel:
     142            0 :             return CreateIntoRelDestReceiver(NULL);
     143              : 
     144          231 :         case DestCopyOut:
     145          231 :             return CreateCopyDestReceiver();
     146              : 
     147        42800 :         case DestSQLFunction:
     148        42800 :             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       361489 : EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output)
     170              : {
     171              :     char        completionTag[COMPLETION_TAG_BUFSIZE];
     172              :     Size        len;
     173              : 
     174       361489 :     switch (dest)
     175              :     {
     176       320563 :         case DestRemote:
     177              :         case DestRemoteExecute:
     178              :         case DestRemoteSimple:
     179              : 
     180       320563 :             len = BuildQueryCompletionString(completionTag, qc,
     181              :                                              force_undecorated_output);
     182       320563 :             pq_putmessage(PqMsg_CommandComplete, completionTag, len + 1);
     183              : 
     184       361489 :         case DestNone:
     185              :         case DestDebug:
     186              :         case DestSPI:
     187              :         case DestTuplestore:
     188              :         case DestIntoRel:
     189              :         case DestCopyOut:
     190              :         case DestSQLFunction:
     191              :         case DestTransientRel:
     192              :         case DestTupleQueue:
     193              :         case DestExplainSerialize:
     194       361489 :             break;
     195              :     }
     196       361489 : }
     197              : 
     198              : /* ----------------
     199              :  *      EndReplicationCommand - stripped down version of EndCommand
     200              :  *
     201              :  *      For use by replication commands.
     202              :  * ----------------
     203              :  */
     204              : void
     205         2806 : EndReplicationCommand(const char *commandTag)
     206              : {
     207         2806 :     pq_putmessage(PqMsg_CommandComplete, commandTag, strlen(commandTag) + 1);
     208         2806 : }
     209              : 
     210              : /* ----------------
     211              :  *      NullCommand - tell dest that an empty query string was recognized
     212              :  *
     213              :  *      This ensures that there will be a recognizable end to the response
     214              :  *      to an Execute message in the extended query protocol.
     215              :  * ----------------
     216              :  */
     217              : void
     218          922 : NullCommand(CommandDest dest)
     219              : {
     220          922 :     switch (dest)
     221              :     {
     222          921 :         case DestRemote:
     223              :         case DestRemoteExecute:
     224              :         case DestRemoteSimple:
     225              : 
     226              :             /* Tell the FE that we saw an empty query string */
     227          921 :             pq_putemptymessage(PqMsg_EmptyQueryResponse);
     228          921 :             break;
     229              : 
     230            1 :         case DestNone:
     231              :         case DestDebug:
     232              :         case DestSPI:
     233              :         case DestTuplestore:
     234              :         case DestIntoRel:
     235              :         case DestCopyOut:
     236              :         case DestSQLFunction:
     237              :         case DestTransientRel:
     238              :         case DestTupleQueue:
     239              :         case DestExplainSerialize:
     240            1 :             break;
     241              :     }
     242          922 : }
     243              : 
     244              : /* ----------------
     245              :  *      ReadyForQuery - tell dest that we are ready for a new query
     246              :  *
     247              :  *      The ReadyForQuery message is sent so that the FE can tell when
     248              :  *      we are done processing a query string.
     249              :  *      In versions 3.0 and up, it also carries a transaction state indicator.
     250              :  *
     251              :  *      Note that by flushing the stdio buffer here, we can avoid doing it
     252              :  *      most other places and thus reduce the number of separate packets sent.
     253              :  * ----------------
     254              :  */
     255              : void
     256       379245 : ReadyForQuery(CommandDest dest)
     257              : {
     258       379245 :     switch (dest)
     259              :     {
     260       343052 :         case DestRemote:
     261              :         case DestRemoteExecute:
     262              :         case DestRemoteSimple:
     263              :             {
     264              :                 StringInfoData buf;
     265              : 
     266       343052 :                 pq_beginmessage(&buf, PqMsg_ReadyForQuery);
     267       343052 :                 pq_sendbyte(&buf, TransactionBlockStatusCode());
     268       343052 :                 pq_endmessage(&buf);
     269              :             }
     270              :             /* Flush output at end of cycle in any case. */
     271       343052 :             pq_flush();
     272       343052 :             break;
     273              : 
     274        36193 :         case DestNone:
     275              :         case DestDebug:
     276              :         case DestSPI:
     277              :         case DestTuplestore:
     278              :         case DestIntoRel:
     279              :         case DestCopyOut:
     280              :         case DestSQLFunction:
     281              :         case DestTransientRel:
     282              :         case DestTupleQueue:
     283              :         case DestExplainSerialize:
     284        36193 :             break;
     285              :     }
     286       379245 : }
        

Generated by: LCOV version 2.0-1