Coverage Report

Created: 2026-11-09 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/access/common/printsimple.c
Line
Count
Source
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
printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
33
0
{
34
0
  StringInfoData buf;
35
0
  int     i;
36
37
0
  pq_beginmessage(&buf, PqMsg_RowDescription);
38
0
  pq_sendint16(&buf, tupdesc->natts);
39
40
0
  for (i = 0; i < tupdesc->natts; ++i)
41
0
  {
42
0
    Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
43
44
0
    pq_sendstring(&buf, NameStr(attr->attname));
45
0
    pq_sendint32(&buf, 0);  /* table oid */
46
0
    pq_sendint16(&buf, 0);  /* attnum */
47
0
    pq_sendint32(&buf, (int) attr->atttypid);
48
0
    pq_sendint16(&buf, attr->attlen);
49
0
    pq_sendint32(&buf, attr->atttypmod);
50
0
    pq_sendint16(&buf, 0);  /* format code */
51
0
  }
52
53
0
  pq_endmessage(&buf);
54
0
}
55
56
/*
57
 * For each tuple, send a DataRow message.
58
 */
59
bool
60
printsimple(TupleTableSlot *slot, DestReceiver *self)
61
0
{
62
0
  TupleDesc tupdesc = slot->tts_tupleDescriptor;
63
0
  StringInfoData buf;
64
0
  int     i;
65
66
  /* Make sure the tuple is fully deconstructed */
67
0
  slot_getallattrs(slot);
68
69
  /* Prepare and send message */
70
0
  pq_beginmessage(&buf, PqMsg_DataRow);
71
0
  pq_sendint16(&buf, tupdesc->natts);
72
73
0
  for (i = 0; i < tupdesc->natts; ++i)
74
0
  {
75
0
    Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
76
0
    Datum   value;
77
78
0
    if (slot->tts_isnull[i])
79
0
    {
80
0
      pq_sendint32(&buf, -1);
81
0
      continue;
82
0
    }
83
84
0
    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
0
    switch (attr->atttypid)
92
0
    {
93
0
      case TEXTOID:
94
0
        {
95
0
          text     *t = DatumGetTextPP(value);
96
97
0
          pq_sendcountedtext(&buf,
98
0
                     VARDATA_ANY(t),
99
0
                     VARSIZE_ANY_EXHDR(t));
100
0
        }
101
0
        break;
102
103
0
      case INT4OID:
104
0
        {
105
0
          int32   num = DatumGetInt32(value);
106
0
          char    str[12];  /* sign, 10 digits and '\0' */
107
0
          int     len;
108
109
0
          len = pg_ltoa(num, str);
110
0
          pq_sendcountedtext(&buf, str, len);
111
0
        }
112
0
        break;
113
114
0
      case INT8OID:
115
0
        {
116
0
          int64   num = DatumGetInt64(value);
117
0
          char    str[MAXINT8LEN + 1];
118
0
          int     len;
119
120
0
          len = pg_lltoa(num, str);
121
0
          pq_sendcountedtext(&buf, str, len);
122
0
        }
123
0
        break;
124
125
0
      case OIDOID:
126
0
        {
127
0
          Oid     num = DatumGetObjectId(value);
128
0
          char    str[10];  /* 10 digits */
129
0
          int     len;
130
131
0
          len = pg_ultoa_n(num, str);
132
0
          pq_sendcountedtext(&buf, str, len);
133
0
        }
134
0
        break;
135
136
0
      default:
137
0
        elog(ERROR, "unsupported type OID: %u", attr->atttypid);
138
0
    }
139
0
  }
140
141
0
  pq_endmessage(&buf);
142
143
  return true;
144
0
}