]> granicus.if.org Git - postgresql/blob - src/backend/libpq/pqformat.c
Update copyright for 2016
[postgresql] / src / backend / libpq / pqformat.c
1 /*-------------------------------------------------------------------------
2  *
3  * pqformat.c
4  *              Routines for formatting and parsing frontend/backend messages
5  *
6  * Outgoing messages are built up in a StringInfo buffer (which is expansible)
7  * and then sent in a single call to pq_putmessage.  This module provides data
8  * formatting/conversion routines that are needed to produce valid messages.
9  * Note in particular the distinction between "raw data" and "text"; raw data
10  * is message protocol characters and binary values that are not subject to
11  * character set conversion, while text is converted by character encoding
12  * rules.
13  *
14  * Incoming messages are similarly read into a StringInfo buffer, via
15  * pq_getmessage, and then parsed and converted from that using the routines
16  * in this module.
17  *
18  * These same routines support reading and writing of external binary formats
19  * (typsend/typreceive routines).  The conversion routines for individual
20  * data types are exactly the same, only initialization and completion
21  * are different.
22  *
23  *
24  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
25  * Portions Copyright (c) 1994, Regents of the University of California
26  *
27  *      src/backend/libpq/pqformat.c
28  *
29  *-------------------------------------------------------------------------
30  */
31 /*
32  * INTERFACE ROUTINES
33  * Message assembly and output:
34  *              pq_beginmessage - initialize StringInfo buffer
35  *              pq_sendbyte             - append a raw byte to a StringInfo buffer
36  *              pq_sendint              - append a binary integer to a StringInfo buffer
37  *              pq_sendint64    - append a binary 8-byte int to a StringInfo buffer
38  *              pq_sendfloat4   - append a float4 to a StringInfo buffer
39  *              pq_sendfloat8   - append a float8 to a StringInfo buffer
40  *              pq_sendbytes    - append raw data to a StringInfo buffer
41  *              pq_sendcountedtext - append a counted text string (with character set conversion)
42  *              pq_sendtext             - append a text string (with conversion)
43  *              pq_sendstring   - append a null-terminated text string (with conversion)
44  *              pq_send_ascii_string - append a null-terminated text string (without conversion)
45  *              pq_endmessage   - send the completed message to the frontend
46  * Note: it is also possible to append data to the StringInfo buffer using
47  * the regular StringInfo routines, but this is discouraged since required
48  * character set conversion may not occur.
49  *
50  * typsend support (construct a bytea value containing external binary data):
51  *              pq_begintypsend - initialize StringInfo buffer
52  *              pq_endtypsend   - return the completed string as a "bytea*"
53  *
54  * Special-case message output:
55  *              pq_puttextmessage - generate a character set-converted message in one step
56  *              pq_putemptymessage - convenience routine for message with empty body
57  *
58  * Message parsing after input:
59  *              pq_getmsgbyte   - get a raw byte from a message buffer
60  *              pq_getmsgint    - get a binary integer from a message buffer
61  *              pq_getmsgint64  - get a binary 8-byte int from a message buffer
62  *              pq_getmsgfloat4 - get a float4 from a message buffer
63  *              pq_getmsgfloat8 - get a float8 from a message buffer
64  *              pq_getmsgbytes  - get raw data from a message buffer
65  *              pq_copymsgbytes - copy raw data from a message buffer
66  *              pq_getmsgtext   - get a counted text string (with conversion)
67  *              pq_getmsgstring - get a null-terminated text string (with conversion)
68  *              pq_getmsgend    - verify message fully consumed
69  */
70
71 #include "postgres.h"
72
73 #include <sys/param.h>
74 #include <netinet/in.h>
75 #include <arpa/inet.h>
76
77 #include "libpq/libpq.h"
78 #include "libpq/pqformat.h"
79 #include "mb/pg_wchar.h"
80
81
82 /* --------------------------------
83  *              pq_beginmessage         - initialize for sending a message
84  * --------------------------------
85  */
86 void
87 pq_beginmessage(StringInfo buf, char msgtype)
88 {
89         initStringInfo(buf);
90
91         /*
92          * We stash the message type into the buffer's cursor field, expecting
93          * that the pq_sendXXX routines won't touch it.  We could alternatively
94          * make it the first byte of the buffer contents, but this seems easier.
95          */
96         buf->cursor = msgtype;
97 }
98
99 /* --------------------------------
100  *              pq_sendbyte             - append a raw byte to a StringInfo buffer
101  * --------------------------------
102  */
103 void
104 pq_sendbyte(StringInfo buf, int byt)
105 {
106         appendStringInfoCharMacro(buf, byt);
107 }
108
109 /* --------------------------------
110  *              pq_sendbytes    - append raw data to a StringInfo buffer
111  * --------------------------------
112  */
113 void
114 pq_sendbytes(StringInfo buf, const char *data, int datalen)
115 {
116         appendBinaryStringInfo(buf, data, datalen);
117 }
118
119 /* --------------------------------
120  *              pq_sendcountedtext - append a counted text string (with character set conversion)
121  *
122  * The data sent to the frontend by this routine is a 4-byte count field
123  * followed by the string.  The count includes itself or not, as per the
124  * countincludesself flag (pre-3.0 protocol requires it to include itself).
125  * The passed text string need not be null-terminated, and the data sent
126  * to the frontend isn't either.
127  * --------------------------------
128  */
129 void
130 pq_sendcountedtext(StringInfo buf, const char *str, int slen,
131                                    bool countincludesself)
132 {
133         int                     extra = countincludesself ? 4 : 0;
134         char       *p;
135
136         p = pg_server_to_client(str, slen);
137         if (p != str)                           /* actual conversion has been done? */
138         {
139                 slen = strlen(p);
140                 pq_sendint(buf, slen + extra, 4);
141                 appendBinaryStringInfo(buf, p, slen);
142                 pfree(p);
143         }
144         else
145         {
146                 pq_sendint(buf, slen + extra, 4);
147                 appendBinaryStringInfo(buf, str, slen);
148         }
149 }
150
151 /* --------------------------------
152  *              pq_sendtext             - append a text string (with conversion)
153  *
154  * The passed text string need not be null-terminated, and the data sent
155  * to the frontend isn't either.  Note that this is not actually useful
156  * for direct frontend transmissions, since there'd be no way for the
157  * frontend to determine the string length.  But it is useful for binary
158  * format conversions.
159  * --------------------------------
160  */
161 void
162 pq_sendtext(StringInfo buf, const char *str, int slen)
163 {
164         char       *p;
165
166         p = pg_server_to_client(str, slen);
167         if (p != str)                           /* actual conversion has been done? */
168         {
169                 slen = strlen(p);
170                 appendBinaryStringInfo(buf, p, slen);
171                 pfree(p);
172         }
173         else
174                 appendBinaryStringInfo(buf, str, slen);
175 }
176
177 /* --------------------------------
178  *              pq_sendstring   - append a null-terminated text string (with conversion)
179  *
180  * NB: passed text string must be null-terminated, and so is the data
181  * sent to the frontend.
182  * --------------------------------
183  */
184 void
185 pq_sendstring(StringInfo buf, const char *str)
186 {
187         int                     slen = strlen(str);
188         char       *p;
189
190         p = pg_server_to_client(str, slen);
191         if (p != str)                           /* actual conversion has been done? */
192         {
193                 slen = strlen(p);
194                 appendBinaryStringInfo(buf, p, slen + 1);
195                 pfree(p);
196         }
197         else
198                 appendBinaryStringInfo(buf, str, slen + 1);
199 }
200
201 /* --------------------------------
202  *              pq_send_ascii_string    - append a null-terminated text string (without conversion)
203  *
204  * This function intentionally bypasses encoding conversion, instead just
205  * silently replacing any non-7-bit-ASCII characters with question marks.
206  * It is used only when we are having trouble sending an error message to
207  * the client with normal localization and encoding conversion.  The caller
208  * should already have taken measures to ensure the string is just ASCII;
209  * the extra work here is just to make certain we don't send a badly encoded
210  * string to the client (which might or might not be robust about that).
211  *
212  * NB: passed text string must be null-terminated, and so is the data
213  * sent to the frontend.
214  * --------------------------------
215  */
216 void
217 pq_send_ascii_string(StringInfo buf, const char *str)
218 {
219         while (*str)
220         {
221                 char            ch = *str++;
222
223                 if (IS_HIGHBIT_SET(ch))
224                         ch = '?';
225                 appendStringInfoCharMacro(buf, ch);
226         }
227         appendStringInfoChar(buf, '\0');
228 }
229
230 /* --------------------------------
231  *              pq_sendint              - append a binary integer to a StringInfo buffer
232  * --------------------------------
233  */
234 void
235 pq_sendint(StringInfo buf, int i, int b)
236 {
237         unsigned char n8;
238         uint16          n16;
239         uint32          n32;
240
241         switch (b)
242         {
243                 case 1:
244                         n8 = (unsigned char) i;
245                         appendBinaryStringInfo(buf, (char *) &n8, 1);
246                         break;
247                 case 2:
248                         n16 = htons((uint16) i);
249                         appendBinaryStringInfo(buf, (char *) &n16, 2);
250                         break;
251                 case 4:
252                         n32 = htonl((uint32) i);
253                         appendBinaryStringInfo(buf, (char *) &n32, 4);
254                         break;
255                 default:
256                         elog(ERROR, "unsupported integer size %d", b);
257                         break;
258         }
259 }
260
261 /* --------------------------------
262  *              pq_sendint64    - append a binary 8-byte int to a StringInfo buffer
263  *
264  * It is tempting to merge this with pq_sendint, but we'd have to make the
265  * argument int64 for all data widths --- that could be a big performance
266  * hit on machines where int64 isn't efficient.
267  * --------------------------------
268  */
269 void
270 pq_sendint64(StringInfo buf, int64 i)
271 {
272         uint32          n32;
273
274         /* High order half first, since we're doing MSB-first */
275         n32 = (uint32) (i >> 32);
276         n32 = htonl(n32);
277         appendBinaryStringInfo(buf, (char *) &n32, 4);
278
279         /* Now the low order half */
280         n32 = (uint32) i;
281         n32 = htonl(n32);
282         appendBinaryStringInfo(buf, (char *) &n32, 4);
283 }
284
285 /* --------------------------------
286  *              pq_sendfloat4   - append a float4 to a StringInfo buffer
287  *
288  * The point of this routine is to localize knowledge of the external binary
289  * representation of float4, which is a component of several datatypes.
290  *
291  * We currently assume that float4 should be byte-swapped in the same way
292  * as int4.  This rule is not perfect but it gives us portability across
293  * most IEEE-float-using architectures.
294  * --------------------------------
295  */
296 void
297 pq_sendfloat4(StringInfo buf, float4 f)
298 {
299         union
300         {
301                 float4          f;
302                 uint32          i;
303         }                       swap;
304
305         swap.f = f;
306         swap.i = htonl(swap.i);
307
308         appendBinaryStringInfo(buf, (char *) &swap.i, 4);
309 }
310
311 /* --------------------------------
312  *              pq_sendfloat8   - append a float8 to a StringInfo buffer
313  *
314  * The point of this routine is to localize knowledge of the external binary
315  * representation of float8, which is a component of several datatypes.
316  *
317  * We currently assume that float8 should be byte-swapped in the same way
318  * as int8.  This rule is not perfect but it gives us portability across
319  * most IEEE-float-using architectures.
320  * --------------------------------
321  */
322 void
323 pq_sendfloat8(StringInfo buf, float8 f)
324 {
325         union
326         {
327                 float8          f;
328                 int64           i;
329         }                       swap;
330
331         swap.f = f;
332         pq_sendint64(buf, swap.i);
333 }
334
335 /* --------------------------------
336  *              pq_endmessage   - send the completed message to the frontend
337  *
338  * The data buffer is pfree()d, but if the StringInfo was allocated with
339  * makeStringInfo then the caller must still pfree it.
340  * --------------------------------
341  */
342 void
343 pq_endmessage(StringInfo buf)
344 {
345         /* msgtype was saved in cursor field */
346         (void) pq_putmessage(buf->cursor, buf->data, buf->len);
347         /* no need to complain about any failure, since pqcomm.c already did */
348         pfree(buf->data);
349         buf->data = NULL;
350 }
351
352
353 /* --------------------------------
354  *              pq_begintypsend         - initialize for constructing a bytea result
355  * --------------------------------
356  */
357 void
358 pq_begintypsend(StringInfo buf)
359 {
360         initStringInfo(buf);
361         /* Reserve four bytes for the bytea length word */
362         appendStringInfoCharMacro(buf, '\0');
363         appendStringInfoCharMacro(buf, '\0');
364         appendStringInfoCharMacro(buf, '\0');
365         appendStringInfoCharMacro(buf, '\0');
366 }
367
368 /* --------------------------------
369  *              pq_endtypsend   - finish constructing a bytea result
370  *
371  * The data buffer is returned as the palloc'd bytea value.  (We expect
372  * that it will be suitably aligned for this because it has been palloc'd.)
373  * We assume the StringInfoData is just a local variable in the caller and
374  * need not be pfree'd.
375  * --------------------------------
376  */
377 bytea *
378 pq_endtypsend(StringInfo buf)
379 {
380         bytea      *result = (bytea *) buf->data;
381
382         /* Insert correct length into bytea length word */
383         Assert(buf->len >= VARHDRSZ);
384         SET_VARSIZE(result, buf->len);
385
386         return result;
387 }
388
389
390 /* --------------------------------
391  *              pq_puttextmessage - generate a character set-converted message in one step
392  *
393  *              This is the same as the pqcomm.c routine pq_putmessage, except that
394  *              the message body is a null-terminated string to which encoding
395  *              conversion applies.
396  * --------------------------------
397  */
398 void
399 pq_puttextmessage(char msgtype, const char *str)
400 {
401         int                     slen = strlen(str);
402         char       *p;
403
404         p = pg_server_to_client(str, slen);
405         if (p != str)                           /* actual conversion has been done? */
406         {
407                 (void) pq_putmessage(msgtype, p, strlen(p) + 1);
408                 pfree(p);
409                 return;
410         }
411         (void) pq_putmessage(msgtype, str, slen + 1);
412 }
413
414
415 /* --------------------------------
416  *              pq_putemptymessage - convenience routine for message with empty body
417  * --------------------------------
418  */
419 void
420 pq_putemptymessage(char msgtype)
421 {
422         (void) pq_putmessage(msgtype, NULL, 0);
423 }
424
425
426 /* --------------------------------
427  *              pq_getmsgbyte   - get a raw byte from a message buffer
428  * --------------------------------
429  */
430 int
431 pq_getmsgbyte(StringInfo msg)
432 {
433         if (msg->cursor >= msg->len)
434                 ereport(ERROR,
435                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
436                                  errmsg("no data left in message")));
437         return (unsigned char) msg->data[msg->cursor++];
438 }
439
440 /* --------------------------------
441  *              pq_getmsgint    - get a binary integer from a message buffer
442  *
443  *              Values are treated as unsigned.
444  * --------------------------------
445  */
446 unsigned int
447 pq_getmsgint(StringInfo msg, int b)
448 {
449         unsigned int result;
450         unsigned char n8;
451         uint16          n16;
452         uint32          n32;
453
454         switch (b)
455         {
456                 case 1:
457                         pq_copymsgbytes(msg, (char *) &n8, 1);
458                         result = n8;
459                         break;
460                 case 2:
461                         pq_copymsgbytes(msg, (char *) &n16, 2);
462                         result = ntohs(n16);
463                         break;
464                 case 4:
465                         pq_copymsgbytes(msg, (char *) &n32, 4);
466                         result = ntohl(n32);
467                         break;
468                 default:
469                         elog(ERROR, "unsupported integer size %d", b);
470                         result = 0;                     /* keep compiler quiet */
471                         break;
472         }
473         return result;
474 }
475
476 /* --------------------------------
477  *              pq_getmsgint64  - get a binary 8-byte int from a message buffer
478  *
479  * It is tempting to merge this with pq_getmsgint, but we'd have to make the
480  * result int64 for all data widths --- that could be a big performance
481  * hit on machines where int64 isn't efficient.
482  * --------------------------------
483  */
484 int64
485 pq_getmsgint64(StringInfo msg)
486 {
487         int64           result;
488         uint32          h32;
489         uint32          l32;
490
491         pq_copymsgbytes(msg, (char *) &h32, 4);
492         pq_copymsgbytes(msg, (char *) &l32, 4);
493         h32 = ntohl(h32);
494         l32 = ntohl(l32);
495
496         result = h32;
497         result <<= 32;
498         result |= l32;
499
500         return result;
501 }
502
503 /* --------------------------------
504  *              pq_getmsgfloat4 - get a float4 from a message buffer
505  *
506  * See notes for pq_sendfloat4.
507  * --------------------------------
508  */
509 float4
510 pq_getmsgfloat4(StringInfo msg)
511 {
512         union
513         {
514                 float4          f;
515                 uint32          i;
516         }                       swap;
517
518         swap.i = pq_getmsgint(msg, 4);
519         return swap.f;
520 }
521
522 /* --------------------------------
523  *              pq_getmsgfloat8 - get a float8 from a message buffer
524  *
525  * See notes for pq_sendfloat8.
526  * --------------------------------
527  */
528 float8
529 pq_getmsgfloat8(StringInfo msg)
530 {
531         union
532         {
533                 float8          f;
534                 int64           i;
535         }                       swap;
536
537         swap.i = pq_getmsgint64(msg);
538         return swap.f;
539 }
540
541 /* --------------------------------
542  *              pq_getmsgbytes  - get raw data from a message buffer
543  *
544  *              Returns a pointer directly into the message buffer; note this
545  *              may not have any particular alignment.
546  * --------------------------------
547  */
548 const char *
549 pq_getmsgbytes(StringInfo msg, int datalen)
550 {
551         const char *result;
552
553         if (datalen < 0 || datalen > (msg->len - msg->cursor))
554                 ereport(ERROR,
555                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
556                                  errmsg("insufficient data left in message")));
557         result = &msg->data[msg->cursor];
558         msg->cursor += datalen;
559         return result;
560 }
561
562 /* --------------------------------
563  *              pq_copymsgbytes - copy raw data from a message buffer
564  *
565  *              Same as above, except data is copied to caller's buffer.
566  * --------------------------------
567  */
568 void
569 pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
570 {
571         if (datalen < 0 || datalen > (msg->len - msg->cursor))
572                 ereport(ERROR,
573                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
574                                  errmsg("insufficient data left in message")));
575         memcpy(buf, &msg->data[msg->cursor], datalen);
576         msg->cursor += datalen;
577 }
578
579 /* --------------------------------
580  *              pq_getmsgtext   - get a counted text string (with conversion)
581  *
582  *              Always returns a pointer to a freshly palloc'd result.
583  *              The result has a trailing null, *and* we return its strlen in *nbytes.
584  * --------------------------------
585  */
586 char *
587 pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
588 {
589         char       *str;
590         char       *p;
591
592         if (rawbytes < 0 || rawbytes > (msg->len - msg->cursor))
593                 ereport(ERROR,
594                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
595                                  errmsg("insufficient data left in message")));
596         str = &msg->data[msg->cursor];
597         msg->cursor += rawbytes;
598
599         p = pg_client_to_server(str, rawbytes);
600         if (p != str)                           /* actual conversion has been done? */
601                 *nbytes = strlen(p);
602         else
603         {
604                 p = (char *) palloc(rawbytes + 1);
605                 memcpy(p, str, rawbytes);
606                 p[rawbytes] = '\0';
607                 *nbytes = rawbytes;
608         }
609         return p;
610 }
611
612 /* --------------------------------
613  *              pq_getmsgstring - get a null-terminated text string (with conversion)
614  *
615  *              May return a pointer directly into the message buffer, or a pointer
616  *              to a palloc'd conversion result.
617  * --------------------------------
618  */
619 const char *
620 pq_getmsgstring(StringInfo msg)
621 {
622         char       *str;
623         int                     slen;
624
625         str = &msg->data[msg->cursor];
626
627         /*
628          * It's safe to use strlen() here because a StringInfo is guaranteed to
629          * have a trailing null byte.  But check we found a null inside the
630          * message.
631          */
632         slen = strlen(str);
633         if (msg->cursor + slen >= msg->len)
634                 ereport(ERROR,
635                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
636                                  errmsg("invalid string in message")));
637         msg->cursor += slen + 1;
638
639         return pg_client_to_server(str, slen);
640 }
641
642 /* --------------------------------
643  *              pq_getmsgend    - verify message fully consumed
644  * --------------------------------
645  */
646 void
647 pq_getmsgend(StringInfo msg)
648 {
649         if (msg->cursor != msg->len)
650                 ereport(ERROR,
651                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
652                                  errmsg("invalid message format")));
653 }