1 /*-------------------------------------------------------------------------
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.
11 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
15 * src/backend/access/common/printsimple.c
17 *-------------------------------------------------------------------------
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"
28 * At startup time, send a RowDescription message.
31 printsimple_startup(DestReceiver
*self
, int operation
, TupleDesc tupdesc
)
36 pq_beginmessage(&buf
, PqMsg_RowDescription
);
37 pq_sendint16(&buf
, tupdesc
->natts
);
39 for (i
= 0; i
< tupdesc
->natts
; ++i
)
41 Form_pg_attribute attr
= TupleDescAttr(tupdesc
, i
);
43 pq_sendstring(&buf
, NameStr(attr
->attname
));
44 pq_sendint32(&buf
, 0); /* table oid */
45 pq_sendint16(&buf
, 0); /* attnum */
46 pq_sendint32(&buf
, (int) attr
->atttypid
);
47 pq_sendint16(&buf
, attr
->attlen
);
48 pq_sendint32(&buf
, attr
->atttypmod
);
49 pq_sendint16(&buf
, 0); /* format code */
56 * For each tuple, send a DataRow message.
59 printsimple(TupleTableSlot
*slot
, DestReceiver
*self
)
61 TupleDesc tupdesc
= slot
->tts_tupleDescriptor
;
65 /* Make sure the tuple is fully deconstructed */
66 slot_getallattrs(slot
);
68 /* Prepare and send message */
69 pq_beginmessage(&buf
, PqMsg_DataRow
);
70 pq_sendint16(&buf
, tupdesc
->natts
);
72 for (i
= 0; i
< tupdesc
->natts
; ++i
)
74 Form_pg_attribute attr
= TupleDescAttr(tupdesc
, i
);
77 if (slot
->tts_isnull
[i
])
79 pq_sendint32(&buf
, -1);
83 value
= slot
->tts_values
[i
];
86 * We can't call the regular type output functions here because we
87 * might not have catalog access. Instead, we must hard-wire
88 * knowledge of the required types.
90 switch (attr
->atttypid
)
94 text
*t
= DatumGetTextPP(value
);
96 pq_sendcountedtext(&buf
,
98 VARSIZE_ANY_EXHDR(t
));
104 int32 num
= DatumGetInt32(value
);
105 char str
[12]; /* sign, 10 digits and '\0' */
108 len
= pg_ltoa(num
, str
);
109 pq_sendcountedtext(&buf
, str
, len
);
115 int64 num
= DatumGetInt64(value
);
116 char str
[MAXINT8LEN
+ 1];
119 len
= pg_lltoa(num
, str
);
120 pq_sendcountedtext(&buf
, str
, len
);
126 Oid num
= ObjectIdGetDatum(value
);
127 char str
[10]; /* 10 digits */
130 len
= pg_ultoa_n(num
, str
);
131 pq_sendcountedtext(&buf
, str
, len
);
136 elog(ERROR
, "unsupported type OID: %u", attr
->atttypid
);