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