LCOV - code coverage report
Current view: top level - src/backend/tcop - dest.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 87.3 % 71 62
Test Date: 2026-07-03 19:57:34 Functions: 100.0 % 10 10
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 66.7 % 24 16

             Branch data     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                 :      881148 : donothingReceive(TupleTableSlot *slot, DestReceiver *self)
      51                 :             : {
      52                 :      881148 :     return true;
      53                 :             : }
      54                 :             : 
      55                 :             : static void
      56                 :        2403 : donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
      57                 :             : {
      58                 :        2403 : }
      59                 :             : 
      60                 :             : static void
      61                 :      120347 : donothingCleanup(DestReceiver *self)
      62                 :             : {
      63                 :             :     /* this is used for both shutdown and destroy methods */
      64                 :      120347 : }
      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                 :      460536 : BeginCommand(CommandTag commandTag, CommandDest dest)
     104                 :             : {
     105                 :             :     /* Nothing to do at present */
     106                 :      460536 : }
     107                 :             : 
     108                 :             : /* ----------------
     109                 :             :  *      CreateDestReceiver - return appropriate receiver function set for dest
     110                 :             :  * ----------------
     111                 :             :  */
     112                 :             : DestReceiver *
     113                 :      630816 : 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   [ +  +  +  +  :      630816 :     switch (dest)
          +  +  -  +  +  
             -  -  -  - ]
     121                 :             :     {
     122                 :      409518 :         case DestRemote:
     123                 :             :         case DestRemoteExecute:
     124                 :      409518 :             return printtup_create_DR(dest);
     125                 :             : 
     126                 :        2512 :         case DestRemoteSimple:
     127                 :        2512 :             return unconstify(DestReceiver *, &printsimpleDR);
     128                 :             : 
     129                 :         616 :         case DestNone:
     130                 :         616 :             return unconstify(DestReceiver *, &donothingDR);
     131                 :             : 
     132                 :       41151 :         case DestDebug:
     133                 :       41151 :             return unconstify(DestReceiver *, &debugtupDR);
     134                 :             : 
     135                 :       94907 :         case DestSPI:
     136                 :       94907 :             return unconstify(DestReceiver *, &spi_printtupDR);
     137                 :             : 
     138                 :       33200 :         case DestTuplestore:
     139                 :       33200 :             return CreateTuplestoreDestReceiver();
     140                 :             : 
     141                 :           0 :         case DestIntoRel:
     142                 :           0 :             return CreateIntoRelDestReceiver(NULL);
     143                 :             : 
     144                 :         322 :         case DestCopyOut:
     145                 :         322 :             return CreateCopyDestReceiver();
     146                 :             : 
     147                 :       48590 :         case DestSQLFunction:
     148                 :       48590 :             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                 :             : 
     169                 :             : void
     170                 :      430263 : EndCommandExtended(const QueryCompletion *qc, CommandDest dest,
     171                 :             :                    bool force_undecorated_output, bool noblock)
     172                 :             : {
     173                 :             :     char        completionTag[COMPLETION_TAG_BUFSIZE];
     174                 :             :     Size        len;
     175                 :             : 
     176      [ +  +  - ]:      430263 :     switch (dest)
     177                 :             :     {
     178                 :      389112 :         case DestRemote:
     179                 :             :         case DestRemoteExecute:
     180                 :             :         case DestRemoteSimple:
     181                 :             : 
     182                 :      389112 :             len = BuildQueryCompletionString(completionTag, qc,
     183                 :             :                                              force_undecorated_output);
     184         [ +  + ]:      389112 :             if (noblock)
     185                 :          48 :                 pq_putmessage_noblock(PqMsg_CommandComplete, completionTag, len + 1);
     186                 :             :             else
     187                 :      389064 :                 pq_putmessage(PqMsg_CommandComplete, completionTag, len + 1);
     188                 :      389112 :             break;
     189                 :             : 
     190                 :       41151 :         case DestNone:
     191                 :             :         case DestDebug:
     192                 :             :         case DestSPI:
     193                 :             :         case DestTuplestore:
     194                 :             :         case DestIntoRel:
     195                 :             :         case DestCopyOut:
     196                 :             :         case DestSQLFunction:
     197                 :             :         case DestTransientRel:
     198                 :             :         case DestTupleQueue:
     199                 :             :         case DestExplainSerialize:
     200                 :       41151 :             break;
     201                 :             :     }
     202                 :      430263 : }
     203                 :             : 
     204                 :             : void
     205                 :      430215 : EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_output)
     206                 :             : {
     207                 :      430215 :     EndCommandExtended(qc, dest, force_undecorated_output, false);
     208                 :      430215 : }
     209                 :             : 
     210                 :             : /* ----------------
     211                 :             :  *      EndReplicationCommand - stripped down version of EndCommand
     212                 :             :  *
     213                 :             :  *      For use by replication commands.
     214                 :             :  * ----------------
     215                 :             :  */
     216                 :             : void
     217                 :        2984 : EndReplicationCommand(const char *commandTag)
     218                 :             : {
     219                 :        2984 :     pq_putmessage(PqMsg_CommandComplete, commandTag, strlen(commandTag) + 1);
     220                 :        2984 : }
     221                 :             : 
     222                 :             : /* ----------------
     223                 :             :  *      NullCommand - tell dest that an empty query string was recognized
     224                 :             :  *
     225                 :             :  *      This ensures that there will be a recognizable end to the response
     226                 :             :  *      to an Execute message in the extended query protocol.
     227                 :             :  * ----------------
     228                 :             :  */
     229                 :             : void
     230                 :        1019 : NullCommand(CommandDest dest)
     231                 :             : {
     232      [ +  +  - ]:        1019 :     switch (dest)
     233                 :             :     {
     234                 :        1018 :         case DestRemote:
     235                 :             :         case DestRemoteExecute:
     236                 :             :         case DestRemoteSimple:
     237                 :             : 
     238                 :             :             /* Tell the FE that we saw an empty query string */
     239                 :        1018 :             pq_putemptymessage(PqMsg_EmptyQueryResponse);
     240                 :        1018 :             break;
     241                 :             : 
     242                 :           1 :         case DestNone:
     243                 :             :         case DestDebug:
     244                 :             :         case DestSPI:
     245                 :             :         case DestTuplestore:
     246                 :             :         case DestIntoRel:
     247                 :             :         case DestCopyOut:
     248                 :             :         case DestSQLFunction:
     249                 :             :         case DestTransientRel:
     250                 :             :         case DestTupleQueue:
     251                 :             :         case DestExplainSerialize:
     252                 :           1 :             break;
     253                 :             :     }
     254                 :        1019 : }
     255                 :             : 
     256                 :             : /* ----------------
     257                 :             :  *      ReadyForQuery - tell dest that we are ready for a new query
     258                 :             :  *
     259                 :             :  *      The ReadyForQuery message is sent so that the FE can tell when
     260                 :             :  *      we are done processing a query string.
     261                 :             :  *      In versions 3.0 and up, it also carries a transaction state indicator.
     262                 :             :  *
     263                 :             :  *      Note that by flushing the stdio buffer here, we can avoid doing it
     264                 :             :  *      most other places and thus reduce the number of separate packets sent.
     265                 :             :  * ----------------
     266                 :             :  */
     267                 :             : void
     268                 :      457197 : ReadyForQuery(CommandDest dest)
     269                 :             : {
     270      [ +  +  - ]:      457197 :     switch (dest)
     271                 :             :     {
     272                 :      420646 :         case DestRemote:
     273                 :             :         case DestRemoteExecute:
     274                 :             :         case DestRemoteSimple:
     275                 :             :             {
     276                 :             :                 StringInfoData buf;
     277                 :             : 
     278                 :      420646 :                 pq_beginmessage(&buf, PqMsg_ReadyForQuery);
     279                 :      420646 :                 pq_sendbyte(&buf, TransactionBlockStatusCode());
     280                 :      420646 :                 pq_endmessage(&buf);
     281                 :             :             }
     282                 :             :             /* Flush output at end of cycle in any case. */
     283                 :      420646 :             pq_flush();
     284                 :      420646 :             break;
     285                 :             : 
     286                 :       36551 :         case DestNone:
     287                 :             :         case DestDebug:
     288                 :             :         case DestSPI:
     289                 :             :         case DestTuplestore:
     290                 :             :         case DestIntoRel:
     291                 :             :         case DestCopyOut:
     292                 :             :         case DestSQLFunction:
     293                 :             :         case DestTransientRel:
     294                 :             :         case DestTupleQueue:
     295                 :             :         case DestExplainSerialize:
     296                 :       36551 :             break;
     297                 :             :     }
     298                 :      457197 : }
        

Generated by: LCOV version 2.0-1