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-03-15 21:15:10 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         2391 : printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
      33              : {
      34              :     StringInfoData buf;
      35              :     int         i;
      36              : 
      37         2391 :     pq_beginmessage(&buf, PqMsg_RowDescription);
      38         2391 :     pq_sendint16(&buf, tupdesc->natts);
      39              : 
      40         9288 :     for (i = 0; i < tupdesc->natts; ++i)
      41              :     {
      42         6897 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
      43              : 
      44         6897 :         pq_sendstring(&buf, NameStr(attr->attname));
      45         6897 :         pq_sendint32(&buf, 0);  /* table oid */
      46         6897 :         pq_sendint16(&buf, 0);  /* attnum */
      47         6897 :         pq_sendint32(&buf, (int) attr->atttypid);
      48         6897 :         pq_sendint16(&buf, attr->attlen);
      49         6897 :         pq_sendint32(&buf, attr->atttypmod);
      50         6897 :         pq_sendint16(&buf, 0);  /* format code */
      51              :     }
      52              : 
      53         2391 :     pq_endmessage(&buf);
      54         2391 : }
      55              : 
      56              : /*
      57              :  * For each tuple, send a DataRow message.
      58              :  */
      59              : bool
      60         3232 : printsimple(TupleTableSlot *slot, DestReceiver *self)
      61              : {
      62         3232 :     TupleDesc   tupdesc = slot->tts_tupleDescriptor;
      63              :     StringInfoData buf;
      64              :     int         i;
      65              : 
      66              :     /* Make sure the tuple is fully deconstructed */
      67         3232 :     slot_getallattrs(slot);
      68              : 
      69              :     /* Prepare and send message */
      70         3232 :     pq_beginmessage(&buf, PqMsg_DataRow);
      71         3232 :     pq_sendint16(&buf, tupdesc->natts);
      72              : 
      73        12665 :     for (i = 0; i < tupdesc->natts; ++i)
      74              :     {
      75         9433 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
      76              :         Datum       value;
      77              : 
      78         9433 :         if (slot->tts_isnull[i])
      79              :         {
      80         1474 :             pq_sendint32(&buf, -1);
      81         1474 :             continue;
      82              :         }
      83              : 
      84         7959 :         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         7959 :         switch (attr->atttypid)
      92              :         {
      93         6606 :             case TEXTOID:
      94              :                 {
      95         6606 :                     text       *t = DatumGetTextPP(value);
      96              : 
      97         6606 :                     pq_sendcountedtext(&buf,
      98         6606 :                                        VARDATA_ANY(t),
      99         6606 :                                        VARSIZE_ANY_EXHDR(t));
     100              :                 }
     101         6606 :                 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         1316 :             case INT8OID:
     115              :                 {
     116         1316 :                     int64       num = DatumGetInt64(value);
     117              :                     char        str[MAXINT8LEN + 1];
     118              :                     int         len;
     119              : 
     120         1316 :                     len = pg_lltoa(num, str);
     121         1316 :                     pq_sendcountedtext(&buf, str, len);
     122              :                 }
     123         1316 :                 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         3232 :     pq_endmessage(&buf);
     142              : 
     143         3232 :     return true;
     144              : }
        

Generated by: LCOV version 2.0-1