LCOV - code coverage report
Current view: top level - src/backend/access/common - printsimple.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 86.3 % 51 44
Test Date: 2026-04-07 14:16:30 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * printsimple.c
       4              :  *    Routines to print out tuples containing only a limited range of
       5              :  *    builtin types without catalog access.  This is intended for
       6              :  *    backends that don't have catalog access because they are not bound
       7              :  *    to a specific database, such as some walsender processes.  It
       8              :  *    doesn't handle standalone backends or protocol versions other than
       9              :  *    3.0, because we don't need such handling for current applications.
      10              :  *
      11              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      12              :  * Portions Copyright (c) 1994, Regents of the University of California
      13              :  *
      14              :  * IDENTIFICATION
      15              :  *    src/backend/access/common/printsimple.c
      16              :  *
      17              :  *-------------------------------------------------------------------------
      18              :  */
      19              : #include "postgres.h"
      20              : 
      21              : #include "access/printsimple.h"
      22              : #include "catalog/pg_type.h"
      23              : #include "libpq/pqformat.h"
      24              : #include "libpq/protocol.h"
      25              : #include "utils/builtins.h"
      26              : #include "varatt.h"
      27              : 
      28              : /*
      29              :  * At startup time, send a RowDescription message.
      30              :  */
      31              : void
      32         2447 : printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
      33              : {
      34              :     StringInfoData buf;
      35              :     int         i;
      36              : 
      37         2447 :     pq_beginmessage(&buf, PqMsg_RowDescription);
      38         2447 :     pq_sendint16(&buf, tupdesc->natts);
      39              : 
      40         9530 :     for (i = 0; i < tupdesc->natts; ++i)
      41              :     {
      42         7083 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
      43              : 
      44         7083 :         pq_sendstring(&buf, NameStr(attr->attname));
      45         7083 :         pq_sendint32(&buf, 0);  /* table oid */
      46         7083 :         pq_sendint16(&buf, 0);  /* attnum */
      47         7083 :         pq_sendint32(&buf, (int) attr->atttypid);
      48         7083 :         pq_sendint16(&buf, attr->attlen);
      49         7083 :         pq_sendint32(&buf, attr->atttypmod);
      50         7083 :         pq_sendint16(&buf, 0);  /* format code */
      51              :     }
      52              : 
      53         2447 :     pq_endmessage(&buf);
      54         2447 : }
      55              : 
      56              : /*
      57              :  * For each tuple, send a DataRow message.
      58              :  */
      59              : bool
      60         3305 : printsimple(TupleTableSlot *slot, DestReceiver *self)
      61              : {
      62         3305 :     TupleDesc   tupdesc = slot->tts_tupleDescriptor;
      63              :     StringInfoData buf;
      64              :     int         i;
      65              : 
      66              :     /* Make sure the tuple is fully deconstructed */
      67         3305 :     slot_getallattrs(slot);
      68              : 
      69              :     /* Prepare and send message */
      70         3305 :     pq_beginmessage(&buf, PqMsg_DataRow);
      71         3305 :     pq_sendint16(&buf, tupdesc->natts);
      72              : 
      73        12976 :     for (i = 0; i < tupdesc->natts; ++i)
      74              :     {
      75         9671 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
      76              :         Datum       value;
      77              : 
      78         9671 :         if (slot->tts_isnull[i])
      79              :         {
      80         1501 :             pq_sendint32(&buf, -1);
      81         1501 :             continue;
      82              :         }
      83              : 
      84         8170 :         value = slot->tts_values[i];
      85              : 
      86              :         /*
      87              :          * We can't call the regular type output functions here because we
      88              :          * might not have catalog access.  Instead, we must hard-wire
      89              :          * knowledge of the required types.
      90              :          */
      91         8170 :         switch (attr->atttypid)
      92              :         {
      93         6777 :             case TEXTOID:
      94              :                 {
      95         6777 :                     text       *t = DatumGetTextPP(value);
      96              : 
      97         6777 :                     pq_sendcountedtext(&buf,
      98         6777 :                                        VARDATA_ANY(t),
      99         6777 :                                        VARSIZE_ANY_EXHDR(t));
     100              :                 }
     101         6777 :                 break;
     102              : 
     103            0 :             case INT4OID:
     104              :                 {
     105            0 :                     int32       num = DatumGetInt32(value);
     106              :                     char        str[12];    /* sign, 10 digits and '\0' */
     107              :                     int         len;
     108              : 
     109            0 :                     len = pg_ltoa(num, str);
     110            0 :                     pq_sendcountedtext(&buf, str, len);
     111              :                 }
     112            0 :                 break;
     113              : 
     114         1356 :             case INT8OID:
     115              :                 {
     116         1356 :                     int64       num = DatumGetInt64(value);
     117              :                     char        str[MAXINT8LEN + 1];
     118              :                     int         len;
     119              : 
     120         1356 :                     len = pg_lltoa(num, str);
     121         1356 :                     pq_sendcountedtext(&buf, str, len);
     122              :                 }
     123         1356 :                 break;
     124              : 
     125           37 :             case OIDOID:
     126              :                 {
     127           37 :                     Oid         num = DatumGetObjectId(value);
     128              :                     char        str[10];    /* 10 digits */
     129              :                     int         len;
     130              : 
     131           37 :                     len = pg_ultoa_n(num, str);
     132           37 :                     pq_sendcountedtext(&buf, str, len);
     133              :                 }
     134           37 :                 break;
     135              : 
     136            0 :             default:
     137            0 :                 elog(ERROR, "unsupported type OID: %u", attr->atttypid);
     138              :         }
     139              :     }
     140              : 
     141         3305 :     pq_endmessage(&buf);
     142              : 
     143         3305 :     return true;
     144              : }
        

Generated by: LCOV version 2.0-1