]> granicus.if.org Git - postgresql/blob - src/backend/access/common/printtup.c
Clean up a few of the #include files
[postgresql] / src / backend / access / common / printtup.c
1 /*-------------------------------------------------------------------------
2  *
3  * printtup.c--
4  *    Routines to print out tuples to the destination (binary or non-binary
5  *    portals, frontend/interactive backend, etc.).
6  *
7  * Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *    $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.10 1996/11/05 05:26:32 scrappy Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "postgres.h"
17
18 #include "fmgr.h" 
19 #include "access/heaptuple.h" 
20 #include "catalog/pg_type.h"
21 #include "libpq/libpq.h"
22 #include "utils/syscache.h"
23
24 /* ----------------------------------------------------------------
25  *      printtup / debugtup support
26  * ----------------------------------------------------------------
27  */
28
29 /* ----------------
30  *      typtoout - used by printtup and debugtup
31  * ----------------
32  */
33 Oid
34 typtoout(Oid type)
35 {
36     HeapTuple   typeTuple;
37     
38     typeTuple = SearchSysCacheTuple(TYPOID,
39                                     ObjectIdGetDatum(type),
40                                     0, 0, 0);
41     
42     if (HeapTupleIsValid(typeTuple))
43         return((Oid)
44                ((TypeTupleForm) GETSTRUCT(typeTuple))->typoutput);
45     
46     elog(WARN, "typtoout: Cache lookup of type %d failed", type);
47     return(InvalidOid);
48 }
49
50 Oid
51 gettypelem(Oid type)
52 {
53     HeapTuple   typeTuple;
54     
55     typeTuple = SearchSysCacheTuple(TYPOID,
56                                     ObjectIdGetDatum(type),
57                                     0,0,0);
58     
59     if (HeapTupleIsValid(typeTuple))
60         return((Oid)
61                ((TypeTupleForm) GETSTRUCT(typeTuple))->typelem);
62     
63     elog(WARN, "typtoout: Cache lookup of type %d failed", type);
64     return(InvalidOid);
65 }
66
67 /* ----------------
68  *      printtup
69  * ----------------
70  */
71 void
72 printtup(HeapTuple tuple, TupleDesc typeinfo)
73 {
74     int         i, j, k;
75     char        *outputstr, *attr;
76     bool        isnull;
77     Oid typoutput;
78     
79     /* ----------------
80      *  tell the frontend to expect new tuple data
81      * ----------------
82      */
83     pq_putnchar("D", 1);
84     
85     /* ----------------
86      *  send a bitmap of which attributes are null
87      * ----------------
88      */
89     j = 0;
90     k = 1 << 7;
91     for (i = 0; i < tuple->t_natts; ) {
92         attr = heap_getattr(tuple, InvalidBuffer, ++i, typeinfo, &isnull);
93         if (!isnull)
94             j |= k;
95         k >>= 1;
96         if (!(i & 7)) {
97             pq_putint(j, 1);
98             j = 0;
99             k = 1 << 7;
100         }
101     }
102     if (i & 7)
103         pq_putint(j, 1);
104     
105     /* ----------------
106      *  send the attributes of this tuple
107      * ----------------
108      */
109     for (i = 0; i < tuple->t_natts; ++i) {
110         attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
111         typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
112         
113         if (!isnull && OidIsValid(typoutput)) {
114             outputstr = fmgr(typoutput, attr, 
115                              gettypelem(typeinfo->attrs[i]->atttypid));
116             pq_putint(strlen(outputstr)+4, 4);
117             pq_putnchar(outputstr, strlen(outputstr));
118             pfree(outputstr);
119         }
120     }
121 }
122
123 /* ----------------
124  *      printatt
125  * ----------------
126  */
127 static void
128 printatt(unsigned attributeId,
129          AttributeTupleForm attributeP,
130          char *value)
131 {
132     printf("\t%2d: %.*s%s%s%s\t(typeid = %u, len = %d, byval = %c)\n",
133            attributeId,
134            NAMEDATALEN,         /* attname is a char16 */
135            attributeP->attname.data,
136            value != NULL ? " = \"" : "",
137            value != NULL ? value : "",
138            value != NULL ? "\"" : "",
139            (unsigned int) (attributeP->atttypid),
140            attributeP->attlen,
141            attributeP->attbyval ? 't' : 'f');
142 }
143
144 /* ----------------
145  *      showatts
146  * ----------------
147  */
148 void
149 showatts(char *name, TupleDesc tupleDesc)
150 {
151     int i;
152     int natts = tupleDesc->natts;
153     AttributeTupleForm *attinfo = tupleDesc->attrs;
154
155     puts(name);
156     for (i = 0; i < natts; ++i)
157         printatt((unsigned) i+1, attinfo[i], (char *) NULL);
158     printf("\t----\n");
159 }
160
161 /* ----------------
162  *      debugtup
163  * ----------------
164  */
165 void
166 debugtup(HeapTuple tuple, TupleDesc typeinfo)
167 {
168     register int        i;
169     char                *attr, *value;
170     bool                isnull;
171     Oid         typoutput;
172     
173     for (i = 0; i < tuple->t_natts; ++i) {
174         attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
175         typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
176         
177         if (!isnull && OidIsValid(typoutput)) {
178             value = fmgr(typoutput, attr, 
179                          gettypelem(typeinfo->attrs[i]->atttypid));
180             printatt((unsigned) i+1, typeinfo->attrs[i], value);
181             pfree(value);
182         }
183     }
184     printf("\t----\n");
185 }
186
187 /* ----------------
188  *      printtup_internal
189  *      Protocol expects either T, D, C, E, or N.
190  *      We use a different data prefix, e.g. 'B' instead of 'D' to
191  *      indicate a tuple in internal (binary) form.
192  *
193  *      This is same as printtup, except we don't use the typout func.
194  * ----------------
195  */
196 void
197 printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
198 {
199     int         i, j, k;
200     char        *attr;
201     bool        isnull;
202     
203     /* ----------------
204      *  tell the frontend to expect new tuple data
205      * ----------------
206      */
207     pq_putnchar("B", 1);
208     
209     /* ----------------
210      *  send a bitmap of which attributes are null
211      * ----------------
212      */
213     j = 0;
214     k = 1 << 7;
215     for (i = 0; i < tuple->t_natts; ) {
216         attr = heap_getattr(tuple, InvalidBuffer, ++i, typeinfo, &isnull);
217         if (!isnull)
218             j |= k;
219         k >>= 1;
220         if (!(i & 7)) {
221             pq_putint(j, 1);
222             j = 0;
223             k = 1 << 7;
224         }
225     }
226     if (i & 7)
227         pq_putint(j, 1);
228     
229     /* ----------------
230      *  send the attributes of this tuple
231      * ----------------
232      */
233 #ifdef IPORTAL_DEBUG
234     fprintf(stderr, "sending tuple with %d atts\n", tuple->t_natts);
235 #endif
236     for (i = 0; i < tuple->t_natts; ++i) {
237         int32 len = typeinfo->attrs[i]->attlen;
238         
239         attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
240         if (!isnull) {
241             /* # of bytes, and opaque data */
242             if (len == -1) {
243                 /* variable length, assume a varlena structure */
244                 len = VARSIZE(attr) - VARHDRSZ;
245                 
246                 pq_putint(len, sizeof(int32));
247                 pq_putnchar(VARDATA(attr), len);
248 #ifdef IPORTAL_DEBUG
249                 {
250                     char *d = VARDATA(attr);
251                     
252                     fprintf(stderr, "length %d data %x%x%x%x\n",
253                             len, *d, *(d+1), *(d+2), *(d+3));
254                 }
255 #endif
256             } else {
257                 /* fixed size */
258                 if (typeinfo->attrs[i]->attbyval) {
259                     int8 i8;
260                     int16 i16;
261                     int32 i32;
262                     
263                     pq_putint(len, sizeof(int32));
264                     switch (len) {
265                     case sizeof(int8):
266                         i8 = DatumGetChar(attr);
267                         pq_putnchar((char *) &i8, len);
268                         break;
269                     case sizeof(int16):
270                         i16 = DatumGetInt16(attr);
271                         pq_putnchar((char *) &i16, len);
272                         break;
273                     case sizeof(int32):
274                         i32 = DatumGetInt32(attr);
275                         pq_putnchar((char *) &i32, len);
276                         break;
277                     }
278 #ifdef IPORTAL_DEBUG
279                     fprintf(stderr, "byval length %d data %d\n", len, attr);
280 #endif
281                 } else {
282                     pq_putint(len, sizeof(int32));
283                     pq_putnchar(attr, len);
284 #ifdef IPORTAL_DEBUG
285                     fprintf(stderr, "byref length %d data %x\n", len, attr);
286 #endif
287                 }
288             }
289         }
290     }
291 }