1 /*-------------------------------------------------------------------------
2 *
3 * fe-protocol3.c
4 * functions that are specific to frontend/backend protocol version 3
5 *
6 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/interfaces/libpq/fe-protocol3.c
12 *
13 *-------------------------------------------------------------------------
14 */
15 #include "postgres_fe.h"
16
17 #include <ctype.h>
18 #include <fcntl.h>
19
20 #ifdef WIN32
21 #include "win32.h"
22 #else
23 #include <unistd.h>
24 #ifdef HAVE_NETINET_TCP_H
25 #include <netinet/tcp.h>
26 #endif
27 #endif
28
29 #include "libpq-fe.h"
30 #include "libpq-int.h"
31 #include "mb/pg_wchar.h"
32 #include "port/pg_bswap.h"
33
34 /*
35 * This macro lists the backend message types that could be "long" (more
36 * than a couple of kilobytes).
37 */
38 #define VALID_LONG_MESSAGE_TYPE(id) \
39 ((id) == 'T' || (id) == 'D' || (id) == 'd' || (id) == 'V' || \
40 (id) == 'E' || (id) == 'N' || (id) == 'A')
41
42 #define PQmblenBounded(s, e) strnlen(s, PQmblen(s, e))
43
44
45 static void handleSyncLoss(PGconn *conn, char id, int msgLength);
46 static int getRowDescriptions(PGconn *conn, int msgLength);
47 static int getParamDescriptions(PGconn *conn, int msgLength);
48 static int getAnotherTuple(PGconn *conn, int msgLength);
49 static int getParameterStatus(PGconn *conn);
50 static int getNotify(PGconn *conn);
51 static int getCopyStart(PGconn *conn, ExecStatusType copytype);
52 static int getReadyForQuery(PGconn *conn);
53 static void reportErrorPosition(PQExpBuffer msg, const char *query,
54 int loc, int encoding);
55 static int build_startup_packet(const PGconn *conn, char *packet,
56 const PQEnvironmentOption *options);
57
58
59 /*
60 * parseInput: if appropriate, parse input data from backend
61 * until input is exhausted or a stopping state is reached.
62 * Note that this function will NOT attempt to read more data from the backend.
63 */
64 void
pqParseInput3(PGconn * conn)65 pqParseInput3(PGconn *conn)
66 {
67 char id;
68 int msgLength;
69 int avail;
70
71 /*
72 * Loop to parse successive complete messages available in the buffer.
73 */
74 for (;;)
75 {
76 /*
77 * Try to read a message. First get the type code and length. Return
78 * if not enough data.
79 */
80 conn->inCursor = conn->inStart;
81 if (pqGetc(&id, conn))
82 return;
83 if (pqGetInt(&msgLength, 4, conn))
84 return;
85
86 /*
87 * Try to validate message type/length here. A length less than 4 is
88 * definitely broken. Large lengths should only be believed for a few
89 * message types.
90 */
91 if (msgLength < 4)
92 {
93 handleSyncLoss(conn, id, msgLength);
94 return;
95 }
96 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
97 {
98 handleSyncLoss(conn, id, msgLength);
99 return;
100 }
101
102 /*
103 * Can't process if message body isn't all here yet.
104 */
105 msgLength -= 4;
106 avail = conn->inEnd - conn->inCursor;
107 if (avail < msgLength)
108 {
109 /*
110 * Before returning, enlarge the input buffer if needed to hold
111 * the whole message. This is better than leaving it to
112 * pqReadData because we can avoid multiple cycles of realloc()
113 * when the message is large; also, we can implement a reasonable
114 * recovery strategy if we are unable to make the buffer big
115 * enough.
116 */
117 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
118 conn))
119 {
120 /*
121 * XXX add some better recovery code... plan is to skip over
122 * the message using its length, then report an error. For the
123 * moment, just treat this like loss of sync (which indeed it
124 * might be!)
125 */
126 handleSyncLoss(conn, id, msgLength);
127 }
128 return;
129 }
130
131 /*
132 * NOTIFY and NOTICE messages can happen in any state; always process
133 * them right away.
134 *
135 * Most other messages should only be processed while in BUSY state.
136 * (In particular, in READY state we hold off further parsing until
137 * the application collects the current PGresult.)
138 *
139 * However, if the state is IDLE then we got trouble; we need to deal
140 * with the unexpected message somehow.
141 *
142 * ParameterStatus ('S') messages are a special case: in IDLE state we
143 * must process 'em (this case could happen if a new value was adopted
144 * from config file due to SIGHUP), but otherwise we hold off until
145 * BUSY state.
146 */
147 if (id == 'A')
148 {
149 if (getNotify(conn))
150 return;
151 }
152 else if (id == 'N')
153 {
154 if (pqGetErrorNotice3(conn, false))
155 return;
156 }
157 else if (conn->asyncStatus != PGASYNC_BUSY)
158 {
159 /* If not IDLE state, just wait ... */
160 if (conn->asyncStatus != PGASYNC_IDLE)
161 return;
162
163 /*
164 * Unexpected message in IDLE state; need to recover somehow.
165 * ERROR messages are handled using the notice processor;
166 * ParameterStatus is handled normally; anything else is just
167 * dropped on the floor after displaying a suitable warning
168 * notice. (An ERROR is very possibly the backend telling us why
169 * it is about to close the connection, so we don't want to just
170 * discard it...)
171 */
172 if (id == 'E')
173 {
174 if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
175 return;
176 }
177 else if (id == 'S')
178 {
179 if (getParameterStatus(conn))
180 return;
181 }
182 else
183 {
184 pqInternalNotice(&conn->noticeHooks,
185 "message type 0x%02x arrived from server while idle",
186 id);
187 /* Discard the unexpected message */
188 conn->inCursor += msgLength;
189 }
190 }
191 else
192 {
193 /*
194 * In BUSY state, we can process everything.
195 */
196 switch (id)
197 {
198 case 'C': /* command complete */
199 if (pqGets(&conn->workBuffer, conn))
200 return;
201 if (conn->result == NULL)
202 {
203 conn->result = PQmakeEmptyPGresult(conn,
204 PGRES_COMMAND_OK);
205 if (!conn->result)
206 {
207 printfPQExpBuffer(&conn->errorMessage,
208 libpq_gettext("out of memory"));
209 pqSaveErrorResult(conn);
210 }
211 }
212 if (conn->result)
213 strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
214 CMDSTATUS_LEN);
215 conn->asyncStatus = PGASYNC_READY;
216 break;
217 case 'E': /* error return */
218 if (pqGetErrorNotice3(conn, true))
219 return;
220 conn->asyncStatus = PGASYNC_READY;
221 break;
222 case 'Z': /* backend is ready for new query */
223 if (getReadyForQuery(conn))
224 return;
225 conn->asyncStatus = PGASYNC_IDLE;
226 break;
227 case 'I': /* empty query */
228 if (conn->result == NULL)
229 {
230 conn->result = PQmakeEmptyPGresult(conn,
231 PGRES_EMPTY_QUERY);
232 if (!conn->result)
233 {
234 printfPQExpBuffer(&conn->errorMessage,
235 libpq_gettext("out of memory"));
236 pqSaveErrorResult(conn);
237 }
238 }
239 conn->asyncStatus = PGASYNC_READY;
240 break;
241 case '1': /* Parse Complete */
242 /* If we're doing PQprepare, we're done; else ignore */
243 if (conn->queryclass == PGQUERY_PREPARE)
244 {
245 if (conn->result == NULL)
246 {
247 conn->result = PQmakeEmptyPGresult(conn,
248 PGRES_COMMAND_OK);
249 if (!conn->result)
250 {
251 printfPQExpBuffer(&conn->errorMessage,
252 libpq_gettext("out of memory"));
253 pqSaveErrorResult(conn);
254 }
255 }
256 conn->asyncStatus = PGASYNC_READY;
257 }
258 break;
259 case '2': /* Bind Complete */
260 case '3': /* Close Complete */
261 /* Nothing to do for these message types */
262 break;
263 case 'S': /* parameter status */
264 if (getParameterStatus(conn))
265 return;
266 break;
267 case 'K': /* secret key data from the backend */
268
269 /*
270 * This is expected only during backend startup, but it's
271 * just as easy to handle it as part of the main loop.
272 * Save the data and continue processing.
273 */
274 if (pqGetInt(&(conn->be_pid), 4, conn))
275 return;
276 if (pqGetInt(&(conn->be_key), 4, conn))
277 return;
278 break;
279 case 'T': /* Row Description */
280 if (conn->result != NULL &&
281 conn->result->resultStatus == PGRES_FATAL_ERROR)
282 {
283 /*
284 * We've already choked for some reason. Just discard
285 * the data till we get to the end of the query.
286 */
287 conn->inCursor += msgLength;
288 }
289 else if (conn->result == NULL ||
290 conn->queryclass == PGQUERY_DESCRIBE)
291 {
292 /* First 'T' in a query sequence */
293 if (getRowDescriptions(conn, msgLength))
294 return;
295 }
296 else
297 {
298 /*
299 * A new 'T' message is treated as the start of
300 * another PGresult. (It is not clear that this is
301 * really possible with the current backend.) We stop
302 * parsing until the application accepts the current
303 * result.
304 */
305 conn->asyncStatus = PGASYNC_READY;
306 return;
307 }
308 break;
309 case 'n': /* No Data */
310
311 /*
312 * NoData indicates that we will not be seeing a
313 * RowDescription message because the statement or portal
314 * inquired about doesn't return rows.
315 *
316 * If we're doing a Describe, we have to pass something
317 * back to the client, so set up a COMMAND_OK result,
318 * instead of PGRES_TUPLES_OK. Otherwise we can just
319 * ignore this message.
320 */
321 if (conn->queryclass == PGQUERY_DESCRIBE)
322 {
323 if (conn->result == NULL)
324 {
325 conn->result = PQmakeEmptyPGresult(conn,
326 PGRES_COMMAND_OK);
327 if (!conn->result)
328 {
329 printfPQExpBuffer(&conn->errorMessage,
330 libpq_gettext("out of memory"));
331 pqSaveErrorResult(conn);
332 }
333 }
334 conn->asyncStatus = PGASYNC_READY;
335 }
336 break;
337 case 't': /* Parameter Description */
338 if (getParamDescriptions(conn, msgLength))
339 return;
340 break;
341 case 'D': /* Data Row */
342 if (conn->result != NULL &&
343 conn->result->resultStatus == PGRES_TUPLES_OK)
344 {
345 /* Read another tuple of a normal query response */
346 if (getAnotherTuple(conn, msgLength))
347 return;
348 }
349 else if (conn->result != NULL &&
350 conn->result->resultStatus == PGRES_FATAL_ERROR)
351 {
352 /*
353 * We've already choked for some reason. Just discard
354 * tuples till we get to the end of the query.
355 */
356 conn->inCursor += msgLength;
357 }
358 else
359 {
360 /* Set up to report error at end of query */
361 printfPQExpBuffer(&conn->errorMessage,
362 libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)\n"));
363 pqSaveErrorResult(conn);
364 /* Discard the unexpected message */
365 conn->inCursor += msgLength;
366 }
367 break;
368 case 'G': /* Start Copy In */
369 if (getCopyStart(conn, PGRES_COPY_IN))
370 return;
371 conn->asyncStatus = PGASYNC_COPY_IN;
372 break;
373 case 'H': /* Start Copy Out */
374 if (getCopyStart(conn, PGRES_COPY_OUT))
375 return;
376 conn->asyncStatus = PGASYNC_COPY_OUT;
377 conn->copy_already_done = 0;
378 break;
379 case 'W': /* Start Copy Both */
380 if (getCopyStart(conn, PGRES_COPY_BOTH))
381 return;
382 conn->asyncStatus = PGASYNC_COPY_BOTH;
383 conn->copy_already_done = 0;
384 break;
385 case 'd': /* Copy Data */
386
387 /*
388 * If we see Copy Data, just silently drop it. This would
389 * only occur if application exits COPY OUT mode too
390 * early.
391 */
392 conn->inCursor += msgLength;
393 break;
394 case 'c': /* Copy Done */
395
396 /*
397 * If we see Copy Done, just silently drop it. This is
398 * the normal case during PQendcopy. We will keep
399 * swallowing data, expecting to see command-complete for
400 * the COPY command.
401 */
402 break;
403 default:
404 printfPQExpBuffer(&conn->errorMessage,
405 libpq_gettext("unexpected response from server; first received character was \"%c\"\n"),
406 id);
407 /* build an error result holding the error message */
408 pqSaveErrorResult(conn);
409 /* not sure if we will see more, so go to ready state */
410 conn->asyncStatus = PGASYNC_READY;
411 /* Discard the unexpected message */
412 conn->inCursor += msgLength;
413 break;
414 } /* switch on protocol character */
415 }
416 /* Successfully consumed this message */
417 if (conn->inCursor == conn->inStart + 5 + msgLength)
418 {
419 /* Normal case: parsing agrees with specified length */
420 conn->inStart = conn->inCursor;
421 }
422 else
423 {
424 /* Trouble --- report it */
425 printfPQExpBuffer(&conn->errorMessage,
426 libpq_gettext("message contents do not agree with length in message type \"%c\"\n"),
427 id);
428 /* build an error result holding the error message */
429 pqSaveErrorResult(conn);
430 conn->asyncStatus = PGASYNC_READY;
431 /* trust the specified message length as what to skip */
432 conn->inStart += 5 + msgLength;
433 }
434 }
435 }
436
437 /*
438 * handleSyncLoss: clean up after loss of message-boundary sync
439 *
440 * There isn't really a lot we can do here except abandon the connection.
441 */
442 static void
handleSyncLoss(PGconn * conn,char id,int msgLength)443 handleSyncLoss(PGconn *conn, char id, int msgLength)
444 {
445 printfPQExpBuffer(&conn->errorMessage,
446 libpq_gettext("lost synchronization with server: got message type \"%c\", length %d\n"),
447 id, msgLength);
448 /* build an error result holding the error message */
449 pqSaveErrorResult(conn);
450 conn->asyncStatus = PGASYNC_READY; /* drop out of GetResult wait loop */
451 /* flush input data since we're giving up on processing it */
452 pqDropConnection(conn, true);
453 conn->status = CONNECTION_BAD; /* No more connection to backend */
454 }
455
456 /*
457 * parseInput subroutine to read a 'T' (row descriptions) message.
458 * We'll build a new PGresult structure (unless called for a Describe
459 * command for a prepared statement) containing the attribute data.
460 * Returns: 0 if processed message successfully, EOF to suspend parsing
461 * (the latter case is not actually used currently).
462 */
463 static int
getRowDescriptions(PGconn * conn,int msgLength)464 getRowDescriptions(PGconn *conn, int msgLength)
465 {
466 PGresult *result;
467 int nfields;
468 const char *errmsg;
469 int i;
470
471 /*
472 * When doing Describe for a prepared statement, there'll already be a
473 * PGresult created by getParamDescriptions, and we should fill data into
474 * that. Otherwise, create a new, empty PGresult.
475 */
476 if (conn->queryclass == PGQUERY_DESCRIBE)
477 {
478 if (conn->result)
479 result = conn->result;
480 else
481 result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK);
482 }
483 else
484 result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
485 if (!result)
486 {
487 errmsg = NULL; /* means "out of memory", see below */
488 goto advance_and_error;
489 }
490
491 /* parseInput already read the 'T' label and message length. */
492 /* the next two bytes are the number of fields */
493 if (pqGetInt(&(result->numAttributes), 2, conn))
494 {
495 /* We should not run out of data here, so complain */
496 errmsg = libpq_gettext("insufficient data in \"T\" message");
497 goto advance_and_error;
498 }
499 nfields = result->numAttributes;
500
501 /* allocate space for the attribute descriptors */
502 if (nfields > 0)
503 {
504 result->attDescs = (PGresAttDesc *)
505 pqResultAlloc(result, nfields * sizeof(PGresAttDesc), true);
506 if (!result->attDescs)
507 {
508 errmsg = NULL; /* means "out of memory", see below */
509 goto advance_and_error;
510 }
511 MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
512 }
513
514 /* result->binary is true only if ALL columns are binary */
515 result->binary = (nfields > 0) ? 1 : 0;
516
517 /* get type info */
518 for (i = 0; i < nfields; i++)
519 {
520 int tableid;
521 int columnid;
522 int typid;
523 int typlen;
524 int atttypmod;
525 int format;
526
527 if (pqGets(&conn->workBuffer, conn) ||
528 pqGetInt(&tableid, 4, conn) ||
529 pqGetInt(&columnid, 2, conn) ||
530 pqGetInt(&typid, 4, conn) ||
531 pqGetInt(&typlen, 2, conn) ||
532 pqGetInt(&atttypmod, 4, conn) ||
533 pqGetInt(&format, 2, conn))
534 {
535 /* We should not run out of data here, so complain */
536 errmsg = libpq_gettext("insufficient data in \"T\" message");
537 goto advance_and_error;
538 }
539
540 /*
541 * Since pqGetInt treats 2-byte integers as unsigned, we need to
542 * coerce these results to signed form.
543 */
544 columnid = (int) ((int16) columnid);
545 typlen = (int) ((int16) typlen);
546 format = (int) ((int16) format);
547
548 result->attDescs[i].name = pqResultStrdup(result,
549 conn->workBuffer.data);
550 if (!result->attDescs[i].name)
551 {
552 errmsg = NULL; /* means "out of memory", see below */
553 goto advance_and_error;
554 }
555 result->attDescs[i].tableid = tableid;
556 result->attDescs[i].columnid = columnid;
557 result->attDescs[i].format = format;
558 result->attDescs[i].typid = typid;
559 result->attDescs[i].typlen = typlen;
560 result->attDescs[i].atttypmod = atttypmod;
561
562 if (format != 1)
563 result->binary = 0;
564 }
565
566 /* Success! */
567 conn->result = result;
568
569 /*
570 * If we're doing a Describe, we're done, and ready to pass the result
571 * back to the client.
572 */
573 if (conn->queryclass == PGQUERY_DESCRIBE)
574 {
575 conn->asyncStatus = PGASYNC_READY;
576 return 0;
577 }
578
579 /*
580 * We could perform additional setup for the new result set here, but for
581 * now there's nothing else to do.
582 */
583
584 /* And we're done. */
585 return 0;
586
587 advance_and_error:
588 /* Discard unsaved result, if any */
589 if (result && result != conn->result)
590 PQclear(result);
591
592 /*
593 * Replace partially constructed result with an error result. First
594 * discard the old result to try to win back some memory.
595 */
596 pqClearAsyncResult(conn);
597
598 /*
599 * If preceding code didn't provide an error message, assume "out of
600 * memory" was meant. The advantage of having this special case is that
601 * freeing the old result first greatly improves the odds that gettext()
602 * will succeed in providing a translation.
603 */
604 if (!errmsg)
605 errmsg = libpq_gettext("out of memory for query result");
606
607 printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
608 pqSaveErrorResult(conn);
609
610 /*
611 * Show the message as fully consumed, else pqParseInput3 will overwrite
612 * our error with a complaint about that.
613 */
614 conn->inCursor = conn->inStart + 5 + msgLength;
615
616 /*
617 * Return zero to allow input parsing to continue. Subsequent "D"
618 * messages will be ignored until we get to end of data, since an error
619 * result is already set up.
620 */
621 return 0;
622 }
623
624 /*
625 * parseInput subroutine to read a 't' (ParameterDescription) message.
626 * We'll build a new PGresult structure containing the parameter data.
627 * Returns: 0 if processed message successfully, EOF to suspend parsing
628 * (the latter case is not actually used currently).
629 */
630 static int
getParamDescriptions(PGconn * conn,int msgLength)631 getParamDescriptions(PGconn *conn, int msgLength)
632 {
633 PGresult *result;
634 const char *errmsg = NULL; /* means "out of memory", see below */
635 int nparams;
636 int i;
637
638 result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK);
639 if (!result)
640 goto advance_and_error;
641
642 /* parseInput already read the 't' label and message length. */
643 /* the next two bytes are the number of parameters */
644 if (pqGetInt(&(result->numParameters), 2, conn))
645 goto not_enough_data;
646 nparams = result->numParameters;
647
648 /* allocate space for the parameter descriptors */
649 if (nparams > 0)
650 {
651 result->paramDescs = (PGresParamDesc *)
652 pqResultAlloc(result, nparams * sizeof(PGresParamDesc), true);
653 if (!result->paramDescs)
654 goto advance_and_error;
655 MemSet(result->paramDescs, 0, nparams * sizeof(PGresParamDesc));
656 }
657
658 /* get parameter info */
659 for (i = 0; i < nparams; i++)
660 {
661 int typid;
662
663 if (pqGetInt(&typid, 4, conn))
664 goto not_enough_data;
665 result->paramDescs[i].typid = typid;
666 }
667
668 /* Success! */
669 conn->result = result;
670
671 return 0;
672
673 not_enough_data:
674 errmsg = libpq_gettext("insufficient data in \"t\" message");
675
676 advance_and_error:
677 /* Discard unsaved result, if any */
678 if (result && result != conn->result)
679 PQclear(result);
680
681 /*
682 * Replace partially constructed result with an error result. First
683 * discard the old result to try to win back some memory.
684 */
685 pqClearAsyncResult(conn);
686
687 /*
688 * If preceding code didn't provide an error message, assume "out of
689 * memory" was meant. The advantage of having this special case is that
690 * freeing the old result first greatly improves the odds that gettext()
691 * will succeed in providing a translation.
692 */
693 if (!errmsg)
694 errmsg = libpq_gettext("out of memory");
695 printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
696 pqSaveErrorResult(conn);
697
698 /*
699 * Show the message as fully consumed, else pqParseInput3 will overwrite
700 * our error with a complaint about that.
701 */
702 conn->inCursor = conn->inStart + 5 + msgLength;
703
704 /*
705 * Return zero to allow input parsing to continue. Essentially, we've
706 * replaced the COMMAND_OK result with an error result, but since this
707 * doesn't affect the protocol state, it's fine.
708 */
709 return 0;
710 }
711
712 /*
713 * parseInput subroutine to read a 'D' (row data) message.
714 * We fill rowbuf with column pointers and then call the row processor.
715 * Returns: 0 if processed message successfully, EOF to suspend parsing
716 * (the latter case is not actually used currently).
717 */
718 static int
getAnotherTuple(PGconn * conn,int msgLength)719 getAnotherTuple(PGconn *conn, int msgLength)
720 {
721 PGresult *result = conn->result;
722 int nfields = result->numAttributes;
723 const char *errmsg;
724 PGdataValue *rowbuf;
725 int tupnfields; /* # fields from tuple */
726 int vlen; /* length of the current field value */
727 int i;
728
729 /* Get the field count and make sure it's what we expect */
730 if (pqGetInt(&tupnfields, 2, conn))
731 {
732 /* We should not run out of data here, so complain */
733 errmsg = libpq_gettext("insufficient data in \"D\" message");
734 goto advance_and_error;
735 }
736
737 if (tupnfields != nfields)
738 {
739 errmsg = libpq_gettext("unexpected field count in \"D\" message");
740 goto advance_and_error;
741 }
742
743 /* Resize row buffer if needed */
744 rowbuf = conn->rowBuf;
745 if (nfields > conn->rowBufLen)
746 {
747 rowbuf = (PGdataValue *) realloc(rowbuf,
748 nfields * sizeof(PGdataValue));
749 if (!rowbuf)
750 {
751 errmsg = NULL; /* means "out of memory", see below */
752 goto advance_and_error;
753 }
754 conn->rowBuf = rowbuf;
755 conn->rowBufLen = nfields;
756 }
757
758 /* Scan the fields */
759 for (i = 0; i < nfields; i++)
760 {
761 /* get the value length */
762 if (pqGetInt(&vlen, 4, conn))
763 {
764 /* We should not run out of data here, so complain */
765 errmsg = libpq_gettext("insufficient data in \"D\" message");
766 goto advance_and_error;
767 }
768 rowbuf[i].len = vlen;
769
770 /*
771 * rowbuf[i].value always points to the next address in the data
772 * buffer even if the value is NULL. This allows row processors to
773 * estimate data sizes more easily.
774 */
775 rowbuf[i].value = conn->inBuffer + conn->inCursor;
776
777 /* Skip over the data value */
778 if (vlen > 0)
779 {
780 if (pqSkipnchar(vlen, conn))
781 {
782 /* We should not run out of data here, so complain */
783 errmsg = libpq_gettext("insufficient data in \"D\" message");
784 goto advance_and_error;
785 }
786 }
787 }
788
789 /* Process the collected row */
790 errmsg = NULL;
791 if (pqRowProcessor(conn, &errmsg))
792 return 0; /* normal, successful exit */
793
794 /* pqRowProcessor failed, fall through to report it */
795
796 advance_and_error:
797
798 /*
799 * Replace partially constructed result with an error result. First
800 * discard the old result to try to win back some memory.
801 */
802 pqClearAsyncResult(conn);
803
804 /*
805 * If preceding code didn't provide an error message, assume "out of
806 * memory" was meant. The advantage of having this special case is that
807 * freeing the old result first greatly improves the odds that gettext()
808 * will succeed in providing a translation.
809 */
810 if (!errmsg)
811 errmsg = libpq_gettext("out of memory for query result");
812
813 printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
814 pqSaveErrorResult(conn);
815
816 /*
817 * Show the message as fully consumed, else pqParseInput3 will overwrite
818 * our error with a complaint about that.
819 */
820 conn->inCursor = conn->inStart + 5 + msgLength;
821
822 /*
823 * Return zero to allow input parsing to continue. Subsequent "D"
824 * messages will be ignored until we get to end of data, since an error
825 * result is already set up.
826 */
827 return 0;
828 }
829
830
831 /*
832 * Attempt to read an Error or Notice response message.
833 * This is possible in several places, so we break it out as a subroutine.
834 * Entry: 'E' or 'N' message type and length have already been consumed.
835 * Exit: returns 0 if successfully consumed message.
836 * returns EOF if not enough data.
837 */
838 int
pqGetErrorNotice3(PGconn * conn,bool isError)839 pqGetErrorNotice3(PGconn *conn, bool isError)
840 {
841 PGresult *res = NULL;
842 bool have_position = false;
843 PQExpBufferData workBuf;
844 char id;
845
846 /*
847 * If this is an error message, pre-emptively clear any incomplete query
848 * result we may have. We'd just throw it away below anyway, and
849 * releasing it before collecting the error might avoid out-of-memory.
850 */
851 if (isError)
852 pqClearAsyncResult(conn);
853
854 /*
855 * Since the fields might be pretty long, we create a temporary
856 * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
857 * for stuff that is expected to be short. We shouldn't use
858 * conn->errorMessage either, since this might be only a notice.
859 */
860 initPQExpBuffer(&workBuf);
861
862 /*
863 * Make a PGresult to hold the accumulated fields. We temporarily lie
864 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
865 * copy conn->errorMessage.
866 *
867 * NB: This allocation can fail, if you run out of memory. The rest of the
868 * function handles that gracefully, and we still try to set the error
869 * message as the connection's error message.
870 */
871 res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
872 if (res)
873 res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
874
875 /*
876 * Read the fields and save into res.
877 *
878 * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
879 * we saw a PG_DIAG_STATEMENT_POSITION field.
880 */
881 for (;;)
882 {
883 if (pqGetc(&id, conn))
884 goto fail;
885 if (id == '\0')
886 break; /* terminator found */
887 if (pqGets(&workBuf, conn))
888 goto fail;
889 pqSaveMessageField(res, id, workBuf.data);
890 if (id == PG_DIAG_SQLSTATE)
891 strlcpy(conn->last_sqlstate, workBuf.data,
892 sizeof(conn->last_sqlstate));
893 else if (id == PG_DIAG_STATEMENT_POSITION)
894 have_position = true;
895 }
896
897 /*
898 * Save the active query text, if any, into res as well; but only if we
899 * might need it for an error cursor display, which is only true if there
900 * is a PG_DIAG_STATEMENT_POSITION field.
901 */
902 if (have_position && conn->last_query && res)
903 res->errQuery = pqResultStrdup(res, conn->last_query);
904
905 /*
906 * Now build the "overall" error message for PQresultErrorMessage.
907 */
908 resetPQExpBuffer(&workBuf);
909 pqBuildErrorMessage3(&workBuf, res, conn->verbosity, conn->show_context);
910
911 /*
912 * Either save error as current async result, or just emit the notice.
913 */
914 if (isError)
915 {
916 if (res)
917 res->errMsg = pqResultStrdup(res, workBuf.data);
918 pqClearAsyncResult(conn); /* redundant, but be safe */
919 conn->result = res;
920 if (PQExpBufferDataBroken(workBuf))
921 printfPQExpBuffer(&conn->errorMessage,
922 libpq_gettext("out of memory"));
923 else
924 appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
925 }
926 else
927 {
928 /* if we couldn't allocate the result set, just discard the NOTICE */
929 if (res)
930 {
931 /* We can cheat a little here and not copy the message. */
932 res->errMsg = workBuf.data;
933 if (res->noticeHooks.noticeRec != NULL)
934 res->noticeHooks.noticeRec(res->noticeHooks.noticeRecArg, res);
935 PQclear(res);
936 }
937 }
938
939 termPQExpBuffer(&workBuf);
940 return 0;
941
942 fail:
943 PQclear(res);
944 termPQExpBuffer(&workBuf);
945 return EOF;
946 }
947
948 /*
949 * Construct an error message from the fields in the given PGresult,
950 * appending it to the contents of "msg".
951 */
952 void
pqBuildErrorMessage3(PQExpBuffer msg,const PGresult * res,PGVerbosity verbosity,PGContextVisibility show_context)953 pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res,
954 PGVerbosity verbosity, PGContextVisibility show_context)
955 {
956 const char *val;
957 const char *querytext = NULL;
958 int querypos = 0;
959
960 /* If we couldn't allocate a PGresult, just say "out of memory" */
961 if (res == NULL)
962 {
963 appendPQExpBufferStr(msg, libpq_gettext("out of memory\n"));
964 return;
965 }
966
967 /*
968 * If we don't have any broken-down fields, just return the base message.
969 * This mainly applies if we're given a libpq-generated error result.
970 */
971 if (res->errFields == NULL)
972 {
973 if (res->errMsg && res->errMsg[0])
974 appendPQExpBufferStr(msg, res->errMsg);
975 else
976 appendPQExpBufferStr(msg, libpq_gettext("no error message available\n"));
977 return;
978 }
979
980 /* Else build error message from relevant fields */
981 val = PQresultErrorField(res, PG_DIAG_SEVERITY);
982 if (val)
983 appendPQExpBuffer(msg, "%s: ", val);
984
985 if (verbosity == PQERRORS_SQLSTATE)
986 {
987 /*
988 * If we have a SQLSTATE, print that and nothing else. If not (which
989 * shouldn't happen for server-generated errors, but might possibly
990 * happen for libpq-generated ones), fall back to TERSE format, as
991 * that seems better than printing nothing at all.
992 */
993 val = PQresultErrorField(res, PG_DIAG_SQLSTATE);
994 if (val)
995 {
996 appendPQExpBuffer(msg, "%s\n", val);
997 return;
998 }
999 verbosity = PQERRORS_TERSE;
1000 }
1001
1002 if (verbosity == PQERRORS_VERBOSE)
1003 {
1004 val = PQresultErrorField(res, PG_DIAG_SQLSTATE);
1005 if (val)
1006 appendPQExpBuffer(msg, "%s: ", val);
1007 }
1008 val = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
1009 if (val)
1010 appendPQExpBufferStr(msg, val);
1011 val = PQresultErrorField(res, PG_DIAG_STATEMENT_POSITION);
1012 if (val)
1013 {
1014 if (verbosity != PQERRORS_TERSE && res->errQuery != NULL)
1015 {
1016 /* emit position as a syntax cursor display */
1017 querytext = res->errQuery;
1018 querypos = atoi(val);
1019 }
1020 else
1021 {
1022 /* emit position as text addition to primary message */
1023 /* translator: %s represents a digit string */
1024 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1025 val);
1026 }
1027 }
1028 else
1029 {
1030 val = PQresultErrorField(res, PG_DIAG_INTERNAL_POSITION);
1031 if (val)
1032 {
1033 querytext = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
1034 if (verbosity != PQERRORS_TERSE && querytext != NULL)
1035 {
1036 /* emit position as a syntax cursor display */
1037 querypos = atoi(val);
1038 }
1039 else
1040 {
1041 /* emit position as text addition to primary message */
1042 /* translator: %s represents a digit string */
1043 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1044 val);
1045 }
1046 }
1047 }
1048 appendPQExpBufferChar(msg, '\n');
1049 if (verbosity != PQERRORS_TERSE)
1050 {
1051 if (querytext && querypos > 0)
1052 reportErrorPosition(msg, querytext, querypos,
1053 res->client_encoding);
1054 val = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
1055 if (val)
1056 appendPQExpBuffer(msg, libpq_gettext("DETAIL: %s\n"), val);
1057 val = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
1058 if (val)
1059 appendPQExpBuffer(msg, libpq_gettext("HINT: %s\n"), val);
1060 val = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
1061 if (val)
1062 appendPQExpBuffer(msg, libpq_gettext("QUERY: %s\n"), val);
1063 if (show_context == PQSHOW_CONTEXT_ALWAYS ||
1064 (show_context == PQSHOW_CONTEXT_ERRORS &&
1065 res->resultStatus == PGRES_FATAL_ERROR))
1066 {
1067 val = PQresultErrorField(res, PG_DIAG_CONTEXT);
1068 if (val)
1069 appendPQExpBuffer(msg, libpq_gettext("CONTEXT: %s\n"),
1070 val);
1071 }
1072 }
1073 if (verbosity == PQERRORS_VERBOSE)
1074 {
1075 val = PQresultErrorField(res, PG_DIAG_SCHEMA_NAME);
1076 if (val)
1077 appendPQExpBuffer(msg,
1078 libpq_gettext("SCHEMA NAME: %s\n"), val);
1079 val = PQresultErrorField(res, PG_DIAG_TABLE_NAME);
1080 if (val)
1081 appendPQExpBuffer(msg,
1082 libpq_gettext("TABLE NAME: %s\n"), val);
1083 val = PQresultErrorField(res, PG_DIAG_COLUMN_NAME);
1084 if (val)
1085 appendPQExpBuffer(msg,
1086 libpq_gettext("COLUMN NAME: %s\n"), val);
1087 val = PQresultErrorField(res, PG_DIAG_DATATYPE_NAME);
1088 if (val)
1089 appendPQExpBuffer(msg,
1090 libpq_gettext("DATATYPE NAME: %s\n"), val);
1091 val = PQresultErrorField(res, PG_DIAG_CONSTRAINT_NAME);
1092 if (val)
1093 appendPQExpBuffer(msg,
1094 libpq_gettext("CONSTRAINT NAME: %s\n"), val);
1095 }
1096 if (verbosity == PQERRORS_VERBOSE)
1097 {
1098 const char *valf;
1099 const char *vall;
1100
1101 valf = PQresultErrorField(res, PG_DIAG_SOURCE_FILE);
1102 vall = PQresultErrorField(res, PG_DIAG_SOURCE_LINE);
1103 val = PQresultErrorField(res, PG_DIAG_SOURCE_FUNCTION);
1104 if (val || valf || vall)
1105 {
1106 appendPQExpBufferStr(msg, libpq_gettext("LOCATION: "));
1107 if (val)
1108 appendPQExpBuffer(msg, libpq_gettext("%s, "), val);
1109 if (valf && vall) /* unlikely we'd have just one */
1110 appendPQExpBuffer(msg, libpq_gettext("%s:%s"),
1111 valf, vall);
1112 appendPQExpBufferChar(msg, '\n');
1113 }
1114 }
1115 }
1116
1117 /*
1118 * Add an error-location display to the error message under construction.
1119 *
1120 * The cursor location is measured in logical characters; the query string
1121 * is presumed to be in the specified encoding.
1122 */
1123 static void
reportErrorPosition(PQExpBuffer msg,const char * query,int loc,int encoding)1124 reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
1125 {
1126 #define DISPLAY_SIZE 60 /* screen width limit, in screen cols */
1127 #define MIN_RIGHT_CUT 10 /* try to keep this far away from EOL */
1128
1129 char *wquery;
1130 int slen,
1131 cno,
1132 i,
1133 *qidx,
1134 *scridx,
1135 qoffset,
1136 scroffset,
1137 ibeg,
1138 iend,
1139 loc_line;
1140 bool mb_encoding,
1141 beg_trunc,
1142 end_trunc;
1143
1144 /* Convert loc from 1-based to 0-based; no-op if out of range */
1145 loc--;
1146 if (loc < 0)
1147 return;
1148
1149 /* Need a writable copy of the query */
1150 wquery = strdup(query);
1151 if (wquery == NULL)
1152 return; /* fail silently if out of memory */
1153
1154 /*
1155 * Each character might occupy multiple physical bytes in the string, and
1156 * in some Far Eastern character sets it might take more than one screen
1157 * column as well. We compute the starting byte offset and starting
1158 * screen column of each logical character, and store these in qidx[] and
1159 * scridx[] respectively.
1160 */
1161
1162 /* we need a safe allocation size... */
1163 slen = strlen(wquery) + 1;
1164
1165 qidx = (int *) malloc(slen * sizeof(int));
1166 if (qidx == NULL)
1167 {
1168 free(wquery);
1169 return;
1170 }
1171 scridx = (int *) malloc(slen * sizeof(int));
1172 if (scridx == NULL)
1173 {
1174 free(qidx);
1175 free(wquery);
1176 return;
1177 }
1178
1179 /* We can optimize a bit if it's a single-byte encoding */
1180 mb_encoding = (pg_encoding_max_length(encoding) != 1);
1181
1182 /*
1183 * Within the scanning loop, cno is the current character's logical
1184 * number, qoffset is its offset in wquery, and scroffset is its starting
1185 * logical screen column (all indexed from 0). "loc" is the logical
1186 * character number of the error location. We scan to determine loc_line
1187 * (the 1-based line number containing loc) and ibeg/iend (first character
1188 * number and last+1 character number of the line containing loc). Note
1189 * that qidx[] and scridx[] are filled only as far as iend.
1190 */
1191 qoffset = 0;
1192 scroffset = 0;
1193 loc_line = 1;
1194 ibeg = 0;
1195 iend = -1; /* -1 means not set yet */
1196
1197 for (cno = 0; wquery[qoffset] != '\0'; cno++)
1198 {
1199 char ch = wquery[qoffset];
1200
1201 qidx[cno] = qoffset;
1202 scridx[cno] = scroffset;
1203
1204 /*
1205 * Replace tabs with spaces in the writable copy. (Later we might
1206 * want to think about coping with their variable screen width, but
1207 * not today.)
1208 */
1209 if (ch == '\t')
1210 wquery[qoffset] = ' ';
1211
1212 /*
1213 * If end-of-line, count lines and mark positions. Each \r or \n
1214 * counts as a line except when \r \n appear together.
1215 */
1216 else if (ch == '\r' || ch == '\n')
1217 {
1218 if (cno < loc)
1219 {
1220 if (ch == '\r' ||
1221 cno == 0 ||
1222 wquery[qidx[cno - 1]] != '\r')
1223 loc_line++;
1224 /* extract beginning = last line start before loc. */
1225 ibeg = cno + 1;
1226 }
1227 else
1228 {
1229 /* set extract end. */
1230 iend = cno;
1231 /* done scanning. */
1232 break;
1233 }
1234 }
1235
1236 /* Advance */
1237 if (mb_encoding)
1238 {
1239 int w;
1240
1241 w = pg_encoding_dsplen(encoding, &wquery[qoffset]);
1242 /* treat any non-tab control chars as width 1 */
1243 if (w <= 0)
1244 w = 1;
1245 scroffset += w;
1246 qoffset += PQmblenBounded(&wquery[qoffset], encoding);
1247 }
1248 else
1249 {
1250 /* We assume wide chars only exist in multibyte encodings */
1251 scroffset++;
1252 qoffset++;
1253 }
1254 }
1255 /* Fix up if we didn't find an end-of-line after loc */
1256 if (iend < 0)
1257 {
1258 iend = cno; /* query length in chars, +1 */
1259 qidx[iend] = qoffset;
1260 scridx[iend] = scroffset;
1261 }
1262
1263 /* Print only if loc is within computed query length */
1264 if (loc <= cno)
1265 {
1266 /* If the line extracted is too long, we truncate it. */
1267 beg_trunc = false;
1268 end_trunc = false;
1269 if (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1270 {
1271 /*
1272 * We first truncate right if it is enough. This code might be
1273 * off a space or so on enforcing MIN_RIGHT_CUT if there's a wide
1274 * character right there, but that should be okay.
1275 */
1276 if (scridx[ibeg] + DISPLAY_SIZE >= scridx[loc] + MIN_RIGHT_CUT)
1277 {
1278 while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1279 iend--;
1280 end_trunc = true;
1281 }
1282 else
1283 {
1284 /* Truncate right if not too close to loc. */
1285 while (scridx[loc] + MIN_RIGHT_CUT < scridx[iend])
1286 {
1287 iend--;
1288 end_trunc = true;
1289 }
1290
1291 /* Truncate left if still too long. */
1292 while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1293 {
1294 ibeg++;
1295 beg_trunc = true;
1296 }
1297 }
1298 }
1299
1300 /* truncate working copy at desired endpoint */
1301 wquery[qidx[iend]] = '\0';
1302
1303 /* Begin building the finished message. */
1304 i = msg->len;
1305 appendPQExpBuffer(msg, libpq_gettext("LINE %d: "), loc_line);
1306 if (beg_trunc)
1307 appendPQExpBufferStr(msg, "...");
1308
1309 /*
1310 * While we have the prefix in the msg buffer, compute its screen
1311 * width.
1312 */
1313 scroffset = 0;
1314 for (; i < msg->len; i += PQmblenBounded(&msg->data[i], encoding))
1315 {
1316 int w = pg_encoding_dsplen(encoding, &msg->data[i]);
1317
1318 if (w <= 0)
1319 w = 1;
1320 scroffset += w;
1321 }
1322
1323 /* Finish up the LINE message line. */
1324 appendPQExpBufferStr(msg, &wquery[qidx[ibeg]]);
1325 if (end_trunc)
1326 appendPQExpBufferStr(msg, "...");
1327 appendPQExpBufferChar(msg, '\n');
1328
1329 /* Now emit the cursor marker line. */
1330 scroffset += scridx[loc] - scridx[ibeg];
1331 for (i = 0; i < scroffset; i++)
1332 appendPQExpBufferChar(msg, ' ');
1333 appendPQExpBufferChar(msg, '^');
1334 appendPQExpBufferChar(msg, '\n');
1335 }
1336
1337 /* Clean up. */
1338 free(scridx);
1339 free(qidx);
1340 free(wquery);
1341 }
1342
1343
1344 /*
1345 * Attempt to read a ParameterStatus message.
1346 * This is possible in several places, so we break it out as a subroutine.
1347 * Entry: 'S' message type and length have already been consumed.
1348 * Exit: returns 0 if successfully consumed message.
1349 * returns EOF if not enough data.
1350 */
1351 static int
getParameterStatus(PGconn * conn)1352 getParameterStatus(PGconn *conn)
1353 {
1354 PQExpBufferData valueBuf;
1355
1356 /* Get the parameter name */
1357 if (pqGets(&conn->workBuffer, conn))
1358 return EOF;
1359 /* Get the parameter value (could be large) */
1360 initPQExpBuffer(&valueBuf);
1361 if (pqGets(&valueBuf, conn))
1362 {
1363 termPQExpBuffer(&valueBuf);
1364 return EOF;
1365 }
1366 /* And save it */
1367 pqSaveParameterStatus(conn, conn->workBuffer.data, valueBuf.data);
1368 termPQExpBuffer(&valueBuf);
1369 return 0;
1370 }
1371
1372
1373 /*
1374 * Attempt to read a Notify response message.
1375 * This is possible in several places, so we break it out as a subroutine.
1376 * Entry: 'A' message type and length have already been consumed.
1377 * Exit: returns 0 if successfully consumed Notify message.
1378 * returns EOF if not enough data.
1379 */
1380 static int
getNotify(PGconn * conn)1381 getNotify(PGconn *conn)
1382 {
1383 int be_pid;
1384 char *svname;
1385 int nmlen;
1386 int extralen;
1387 PGnotify *newNotify;
1388
1389 if (pqGetInt(&be_pid, 4, conn))
1390 return EOF;
1391 if (pqGets(&conn->workBuffer, conn))
1392 return EOF;
1393 /* must save name while getting extra string */
1394 svname = strdup(conn->workBuffer.data);
1395 if (!svname)
1396 return EOF;
1397 if (pqGets(&conn->workBuffer, conn))
1398 {
1399 free(svname);
1400 return EOF;
1401 }
1402
1403 /*
1404 * Store the strings right after the PQnotify structure so it can all be
1405 * freed at once. We don't use NAMEDATALEN because we don't want to tie
1406 * this interface to a specific server name length.
1407 */
1408 nmlen = strlen(svname);
1409 extralen = strlen(conn->workBuffer.data);
1410 newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + extralen + 2);
1411 if (newNotify)
1412 {
1413 newNotify->relname = (char *) newNotify + sizeof(PGnotify);
1414 strcpy(newNotify->relname, svname);
1415 newNotify->extra = newNotify->relname + nmlen + 1;
1416 strcpy(newNotify->extra, conn->workBuffer.data);
1417 newNotify->be_pid = be_pid;
1418 newNotify->next = NULL;
1419 if (conn->notifyTail)
1420 conn->notifyTail->next = newNotify;
1421 else
1422 conn->notifyHead = newNotify;
1423 conn->notifyTail = newNotify;
1424 }
1425
1426 free(svname);
1427 return 0;
1428 }
1429
1430 /*
1431 * getCopyStart - process CopyInResponse, CopyOutResponse or
1432 * CopyBothResponse message
1433 *
1434 * parseInput already read the message type and length.
1435 */
1436 static int
getCopyStart(PGconn * conn,ExecStatusType copytype)1437 getCopyStart(PGconn *conn, ExecStatusType copytype)
1438 {
1439 PGresult *result;
1440 int nfields;
1441 int i;
1442
1443 result = PQmakeEmptyPGresult(conn, copytype);
1444 if (!result)
1445 goto failure;
1446
1447 if (pqGetc(&conn->copy_is_binary, conn))
1448 goto failure;
1449 result->binary = conn->copy_is_binary;
1450 /* the next two bytes are the number of fields */
1451 if (pqGetInt(&(result->numAttributes), 2, conn))
1452 goto failure;
1453 nfields = result->numAttributes;
1454
1455 /* allocate space for the attribute descriptors */
1456 if (nfields > 0)
1457 {
1458 result->attDescs = (PGresAttDesc *)
1459 pqResultAlloc(result, nfields * sizeof(PGresAttDesc), true);
1460 if (!result->attDescs)
1461 goto failure;
1462 MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
1463 }
1464
1465 for (i = 0; i < nfields; i++)
1466 {
1467 int format;
1468
1469 if (pqGetInt(&format, 2, conn))
1470 goto failure;
1471
1472 /*
1473 * Since pqGetInt treats 2-byte integers as unsigned, we need to
1474 * coerce these results to signed form.
1475 */
1476 format = (int) ((int16) format);
1477 result->attDescs[i].format = format;
1478 }
1479
1480 /* Success! */
1481 conn->result = result;
1482 return 0;
1483
1484 failure:
1485 PQclear(result);
1486 return EOF;
1487 }
1488
1489 /*
1490 * getReadyForQuery - process ReadyForQuery message
1491 */
1492 static int
getReadyForQuery(PGconn * conn)1493 getReadyForQuery(PGconn *conn)
1494 {
1495 char xact_status;
1496
1497 if (pqGetc(&xact_status, conn))
1498 return EOF;
1499 switch (xact_status)
1500 {
1501 case 'I':
1502 conn->xactStatus = PQTRANS_IDLE;
1503 break;
1504 case 'T':
1505 conn->xactStatus = PQTRANS_INTRANS;
1506 break;
1507 case 'E':
1508 conn->xactStatus = PQTRANS_INERROR;
1509 break;
1510 default:
1511 conn->xactStatus = PQTRANS_UNKNOWN;
1512 break;
1513 }
1514
1515 return 0;
1516 }
1517
1518 /*
1519 * getCopyDataMessage - fetch next CopyData message, process async messages
1520 *
1521 * Returns length word of CopyData message (> 0), or 0 if no complete
1522 * message available, -1 if end of copy, -2 if error.
1523 */
1524 static int
getCopyDataMessage(PGconn * conn)1525 getCopyDataMessage(PGconn *conn)
1526 {
1527 char id;
1528 int msgLength;
1529 int avail;
1530
1531 for (;;)
1532 {
1533 /*
1534 * Do we have the next input message? To make life simpler for async
1535 * callers, we keep returning 0 until the next message is fully
1536 * available, even if it is not Copy Data.
1537 */
1538 conn->inCursor = conn->inStart;
1539 if (pqGetc(&id, conn))
1540 return 0;
1541 if (pqGetInt(&msgLength, 4, conn))
1542 return 0;
1543 if (msgLength < 4)
1544 {
1545 handleSyncLoss(conn, id, msgLength);
1546 return -2;
1547 }
1548 avail = conn->inEnd - conn->inCursor;
1549 if (avail < msgLength - 4)
1550 {
1551 /*
1552 * Before returning, enlarge the input buffer if needed to hold
1553 * the whole message. See notes in parseInput.
1554 */
1555 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength - 4,
1556 conn))
1557 {
1558 /*
1559 * XXX add some better recovery code... plan is to skip over
1560 * the message using its length, then report an error. For the
1561 * moment, just treat this like loss of sync (which indeed it
1562 * might be!)
1563 */
1564 handleSyncLoss(conn, id, msgLength);
1565 return -2;
1566 }
1567 return 0;
1568 }
1569
1570 /*
1571 * If it's a legitimate async message type, process it. (NOTIFY
1572 * messages are not currently possible here, but we handle them for
1573 * completeness.) Otherwise, if it's anything except Copy Data,
1574 * report end-of-copy.
1575 */
1576 switch (id)
1577 {
1578 case 'A': /* NOTIFY */
1579 if (getNotify(conn))
1580 return 0;
1581 break;
1582 case 'N': /* NOTICE */
1583 if (pqGetErrorNotice3(conn, false))
1584 return 0;
1585 break;
1586 case 'S': /* ParameterStatus */
1587 if (getParameterStatus(conn))
1588 return 0;
1589 break;
1590 case 'd': /* Copy Data, pass it back to caller */
1591 return msgLength;
1592 case 'c':
1593
1594 /*
1595 * If this is a CopyDone message, exit COPY_OUT mode and let
1596 * caller read status with PQgetResult(). If we're in
1597 * COPY_BOTH mode, return to COPY_IN mode.
1598 */
1599 if (conn->asyncStatus == PGASYNC_COPY_BOTH)
1600 conn->asyncStatus = PGASYNC_COPY_IN;
1601 else
1602 conn->asyncStatus = PGASYNC_BUSY;
1603 return -1;
1604 default: /* treat as end of copy */
1605
1606 /*
1607 * Any other message terminates either COPY_IN or COPY_BOTH
1608 * mode.
1609 */
1610 conn->asyncStatus = PGASYNC_BUSY;
1611 return -1;
1612 }
1613
1614 /* Drop the processed message and loop around for another */
1615 conn->inStart = conn->inCursor;
1616 }
1617 }
1618
1619 /*
1620 * PQgetCopyData - read a row of data from the backend during COPY OUT
1621 * or COPY BOTH
1622 *
1623 * If successful, sets *buffer to point to a malloc'd row of data, and
1624 * returns row length (always > 0) as result.
1625 * Returns 0 if no row available yet (only possible if async is true),
1626 * -1 if end of copy (consult PQgetResult), or -2 if error (consult
1627 * PQerrorMessage).
1628 */
1629 int
pqGetCopyData3(PGconn * conn,char ** buffer,int async)1630 pqGetCopyData3(PGconn *conn, char **buffer, int async)
1631 {
1632 int msgLength;
1633
1634 for (;;)
1635 {
1636 /*
1637 * Collect the next input message. To make life simpler for async
1638 * callers, we keep returning 0 until the next message is fully
1639 * available, even if it is not Copy Data.
1640 */
1641 msgLength = getCopyDataMessage(conn);
1642 if (msgLength < 0)
1643 return msgLength; /* end-of-copy or error */
1644 if (msgLength == 0)
1645 {
1646 /* Don't block if async read requested */
1647 if (async)
1648 return 0;
1649 /* Need to load more data */
1650 if (pqWait(true, false, conn) ||
1651 pqReadData(conn) < 0)
1652 return -2;
1653 continue;
1654 }
1655
1656 /*
1657 * Drop zero-length messages (shouldn't happen anyway). Otherwise
1658 * pass the data back to the caller.
1659 */
1660 msgLength -= 4;
1661 if (msgLength > 0)
1662 {
1663 *buffer = (char *) malloc(msgLength + 1);
1664 if (*buffer == NULL)
1665 {
1666 printfPQExpBuffer(&conn->errorMessage,
1667 libpq_gettext("out of memory\n"));
1668 return -2;
1669 }
1670 memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1671 (*buffer)[msgLength] = '\0'; /* Add terminating null */
1672
1673 /* Mark message consumed */
1674 conn->inStart = conn->inCursor + msgLength;
1675
1676 return msgLength;
1677 }
1678
1679 /* Empty, so drop it and loop around for another */
1680 conn->inStart = conn->inCursor;
1681 }
1682 }
1683
1684 /*
1685 * PQgetline - gets a newline-terminated string from the backend.
1686 *
1687 * See fe-exec.c for documentation.
1688 */
1689 int
pqGetline3(PGconn * conn,char * s,int maxlen)1690 pqGetline3(PGconn *conn, char *s, int maxlen)
1691 {
1692 int status;
1693
1694 if (conn->sock == PGINVALID_SOCKET ||
1695 (conn->asyncStatus != PGASYNC_COPY_OUT &&
1696 conn->asyncStatus != PGASYNC_COPY_BOTH) ||
1697 conn->copy_is_binary)
1698 {
1699 printfPQExpBuffer(&conn->errorMessage,
1700 libpq_gettext("PQgetline: not doing text COPY OUT\n"));
1701 *s = '\0';
1702 return EOF;
1703 }
1704
1705 while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1706 {
1707 /* need to load more data */
1708 if (pqWait(true, false, conn) ||
1709 pqReadData(conn) < 0)
1710 {
1711 *s = '\0';
1712 return EOF;
1713 }
1714 }
1715
1716 if (status < 0)
1717 {
1718 /* End of copy detected; gin up old-style terminator */
1719 strcpy(s, "\\.");
1720 return 0;
1721 }
1722
1723 /* Add null terminator, and strip trailing \n if present */
1724 if (s[status - 1] == '\n')
1725 {
1726 s[status - 1] = '\0';
1727 return 0;
1728 }
1729 else
1730 {
1731 s[status] = '\0';
1732 return 1;
1733 }
1734 }
1735
1736 /*
1737 * PQgetlineAsync - gets a COPY data row without blocking.
1738 *
1739 * See fe-exec.c for documentation.
1740 */
1741 int
pqGetlineAsync3(PGconn * conn,char * buffer,int bufsize)1742 pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize)
1743 {
1744 int msgLength;
1745 int avail;
1746
1747 if (conn->asyncStatus != PGASYNC_COPY_OUT
1748 && conn->asyncStatus != PGASYNC_COPY_BOTH)
1749 return -1; /* we are not doing a copy... */
1750
1751 /*
1752 * Recognize the next input message. To make life simpler for async
1753 * callers, we keep returning 0 until the next message is fully available
1754 * even if it is not Copy Data. This should keep PQendcopy from blocking.
1755 * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
1756 */
1757 msgLength = getCopyDataMessage(conn);
1758 if (msgLength < 0)
1759 return -1; /* end-of-copy or error */
1760 if (msgLength == 0)
1761 return 0; /* no data yet */
1762
1763 /*
1764 * Move data from libpq's buffer to the caller's. In the case where a
1765 * prior call found the caller's buffer too small, we use
1766 * conn->copy_already_done to remember how much of the row was already
1767 * returned to the caller.
1768 */
1769 conn->inCursor += conn->copy_already_done;
1770 avail = msgLength - 4 - conn->copy_already_done;
1771 if (avail <= bufsize)
1772 {
1773 /* Able to consume the whole message */
1774 memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
1775 /* Mark message consumed */
1776 conn->inStart = conn->inCursor + avail;
1777 /* Reset state for next time */
1778 conn->copy_already_done = 0;
1779 return avail;
1780 }
1781 else
1782 {
1783 /* We must return a partial message */
1784 memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
1785 /* The message is NOT consumed from libpq's buffer */
1786 conn->copy_already_done += bufsize;
1787 return bufsize;
1788 }
1789 }
1790
1791 /*
1792 * PQendcopy
1793 *
1794 * See fe-exec.c for documentation.
1795 */
1796 int
pqEndcopy3(PGconn * conn)1797 pqEndcopy3(PGconn *conn)
1798 {
1799 PGresult *result;
1800
1801 if (conn->asyncStatus != PGASYNC_COPY_IN &&
1802 conn->asyncStatus != PGASYNC_COPY_OUT &&
1803 conn->asyncStatus != PGASYNC_COPY_BOTH)
1804 {
1805 printfPQExpBuffer(&conn->errorMessage,
1806 libpq_gettext("no COPY in progress\n"));
1807 return 1;
1808 }
1809
1810 /* Send the CopyDone message if needed */
1811 if (conn->asyncStatus == PGASYNC_COPY_IN ||
1812 conn->asyncStatus == PGASYNC_COPY_BOTH)
1813 {
1814 if (pqPutMsgStart('c', false, conn) < 0 ||
1815 pqPutMsgEnd(conn) < 0)
1816 return 1;
1817
1818 /*
1819 * If we sent the COPY command in extended-query mode, we must issue a
1820 * Sync as well.
1821 */
1822 if (conn->queryclass != PGQUERY_SIMPLE)
1823 {
1824 if (pqPutMsgStart('S', false, conn) < 0 ||
1825 pqPutMsgEnd(conn) < 0)
1826 return 1;
1827 }
1828 }
1829
1830 /*
1831 * make sure no data is waiting to be sent, abort if we are non-blocking
1832 * and the flush fails
1833 */
1834 if (pqFlush(conn) && pqIsnonblocking(conn))
1835 return 1;
1836
1837 /* Return to active duty */
1838 conn->asyncStatus = PGASYNC_BUSY;
1839 resetPQExpBuffer(&conn->errorMessage);
1840
1841 /*
1842 * Non blocking connections may have to abort at this point. If everyone
1843 * played the game there should be no problem, but in error scenarios the
1844 * expected messages may not have arrived yet. (We are assuming that the
1845 * backend's packetizing will ensure that CommandComplete arrives along
1846 * with the CopyDone; are there corner cases where that doesn't happen?)
1847 */
1848 if (pqIsnonblocking(conn) && PQisBusy(conn))
1849 return 1;
1850
1851 /* Wait for the completion response */
1852 result = PQgetResult(conn);
1853
1854 /* Expecting a successful result */
1855 if (result && result->resultStatus == PGRES_COMMAND_OK)
1856 {
1857 PQclear(result);
1858 return 0;
1859 }
1860
1861 /*
1862 * Trouble. For backwards-compatibility reasons, we issue the error
1863 * message as if it were a notice (would be nice to get rid of this
1864 * silliness, but too many apps probably don't handle errors from
1865 * PQendcopy reasonably). Note that the app can still obtain the error
1866 * status from the PGconn object.
1867 */
1868 if (conn->errorMessage.len > 0)
1869 {
1870 /* We have to strip the trailing newline ... pain in neck... */
1871 char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1872
1873 if (svLast == '\n')
1874 conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1875 pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
1876 conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1877 }
1878
1879 PQclear(result);
1880
1881 return 1;
1882 }
1883
1884
1885 /*
1886 * PQfn - Send a function call to the POSTGRES backend.
1887 *
1888 * See fe-exec.c for documentation.
1889 */
1890 PGresult *
pqFunctionCall3(PGconn * conn,Oid fnid,int * result_buf,int * actual_result_len,int result_is_int,const PQArgBlock * args,int nargs)1891 pqFunctionCall3(PGconn *conn, Oid fnid,
1892 int *result_buf, int *actual_result_len,
1893 int result_is_int,
1894 const PQArgBlock *args, int nargs)
1895 {
1896 bool needInput = false;
1897 ExecStatusType status = PGRES_FATAL_ERROR;
1898 char id;
1899 int msgLength;
1900 int avail;
1901 int i;
1902
1903 /* PQfn already validated connection state */
1904
1905 if (pqPutMsgStart('F', false, conn) < 0 || /* function call msg */
1906 pqPutInt(fnid, 4, conn) < 0 || /* function id */
1907 pqPutInt(1, 2, conn) < 0 || /* # of format codes */
1908 pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
1909 pqPutInt(nargs, 2, conn) < 0) /* # of args */
1910 {
1911 /* error message should be set up already */
1912 return NULL;
1913 }
1914
1915 for (i = 0; i < nargs; ++i)
1916 { /* len.int4 + contents */
1917 if (pqPutInt(args[i].len, 4, conn))
1918 return NULL;
1919 if (args[i].len == -1)
1920 continue; /* it's NULL */
1921
1922 if (args[i].isint)
1923 {
1924 if (pqPutInt(args[i].u.integer, args[i].len, conn))
1925 return NULL;
1926 }
1927 else
1928 {
1929 if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
1930 return NULL;
1931 }
1932 }
1933
1934 if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */
1935 return NULL;
1936
1937 if (pqPutMsgEnd(conn) < 0 ||
1938 pqFlush(conn))
1939 return NULL;
1940
1941 for (;;)
1942 {
1943 if (needInput)
1944 {
1945 /* Wait for some data to arrive (or for the channel to close) */
1946 if (pqWait(true, false, conn) ||
1947 pqReadData(conn) < 0)
1948 break;
1949 }
1950
1951 /*
1952 * Scan the message. If we run out of data, loop around to try again.
1953 */
1954 needInput = true;
1955
1956 conn->inCursor = conn->inStart;
1957 if (pqGetc(&id, conn))
1958 continue;
1959 if (pqGetInt(&msgLength, 4, conn))
1960 continue;
1961
1962 /*
1963 * Try to validate message type/length here. A length less than 4 is
1964 * definitely broken. Large lengths should only be believed for a few
1965 * message types.
1966 */
1967 if (msgLength < 4)
1968 {
1969 handleSyncLoss(conn, id, msgLength);
1970 break;
1971 }
1972 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
1973 {
1974 handleSyncLoss(conn, id, msgLength);
1975 break;
1976 }
1977
1978 /*
1979 * Can't process if message body isn't all here yet.
1980 */
1981 msgLength -= 4;
1982 avail = conn->inEnd - conn->inCursor;
1983 if (avail < msgLength)
1984 {
1985 /*
1986 * Before looping, enlarge the input buffer if needed to hold the
1987 * whole message. See notes in parseInput.
1988 */
1989 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
1990 conn))
1991 {
1992 /*
1993 * XXX add some better recovery code... plan is to skip over
1994 * the message using its length, then report an error. For the
1995 * moment, just treat this like loss of sync (which indeed it
1996 * might be!)
1997 */
1998 handleSyncLoss(conn, id, msgLength);
1999 break;
2000 }
2001 continue;
2002 }
2003
2004 /*
2005 * We should see V or E response to the command, but might get N
2006 * and/or A notices first. We also need to swallow the final Z before
2007 * returning.
2008 */
2009 switch (id)
2010 {
2011 case 'V': /* function result */
2012 if (pqGetInt(actual_result_len, 4, conn))
2013 continue;
2014 if (*actual_result_len != -1)
2015 {
2016 if (result_is_int)
2017 {
2018 if (pqGetInt(result_buf, *actual_result_len, conn))
2019 continue;
2020 }
2021 else
2022 {
2023 if (pqGetnchar((char *) result_buf,
2024 *actual_result_len,
2025 conn))
2026 continue;
2027 }
2028 }
2029 /* correctly finished function result message */
2030 status = PGRES_COMMAND_OK;
2031 break;
2032 case 'E': /* error return */
2033 if (pqGetErrorNotice3(conn, true))
2034 continue;
2035 status = PGRES_FATAL_ERROR;
2036 break;
2037 case 'A': /* notify message */
2038 /* handle notify and go back to processing return values */
2039 if (getNotify(conn))
2040 continue;
2041 break;
2042 case 'N': /* notice */
2043 /* handle notice and go back to processing return values */
2044 if (pqGetErrorNotice3(conn, false))
2045 continue;
2046 break;
2047 case 'Z': /* backend is ready for new query */
2048 if (getReadyForQuery(conn))
2049 continue;
2050 /* consume the message and exit */
2051 conn->inStart += 5 + msgLength;
2052 /* if we saved a result object (probably an error), use it */
2053 if (conn->result)
2054 return pqPrepareAsyncResult(conn);
2055 return PQmakeEmptyPGresult(conn, status);
2056 case 'S': /* parameter status */
2057 if (getParameterStatus(conn))
2058 continue;
2059 break;
2060 default:
2061 /* The backend violates the protocol. */
2062 printfPQExpBuffer(&conn->errorMessage,
2063 libpq_gettext("protocol error: id=0x%x\n"),
2064 id);
2065 pqSaveErrorResult(conn);
2066 /* trust the specified message length as what to skip */
2067 conn->inStart += 5 + msgLength;
2068 return pqPrepareAsyncResult(conn);
2069 }
2070 /* Completed this message, keep going */
2071 /* trust the specified message length as what to skip */
2072 conn->inStart += 5 + msgLength;
2073 needInput = false;
2074 }
2075
2076 /*
2077 * We fall out of the loop only upon failing to read data.
2078 * conn->errorMessage has been set by pqWait or pqReadData. We want to
2079 * append it to any already-received error message.
2080 */
2081 pqSaveErrorResult(conn);
2082 return pqPrepareAsyncResult(conn);
2083 }
2084
2085
2086 /*
2087 * Construct startup packet
2088 *
2089 * Returns a malloc'd packet buffer, or NULL if out of memory
2090 */
2091 char *
pqBuildStartupPacket3(PGconn * conn,int * packetlen,const PQEnvironmentOption * options)2092 pqBuildStartupPacket3(PGconn *conn, int *packetlen,
2093 const PQEnvironmentOption *options)
2094 {
2095 char *startpacket;
2096
2097 *packetlen = build_startup_packet(conn, NULL, options);
2098 startpacket = (char *) malloc(*packetlen);
2099 if (!startpacket)
2100 return NULL;
2101 *packetlen = build_startup_packet(conn, startpacket, options);
2102 return startpacket;
2103 }
2104
2105 /*
2106 * Build a startup packet given a filled-in PGconn structure.
2107 *
2108 * We need to figure out how much space is needed, then fill it in.
2109 * To avoid duplicate logic, this routine is called twice: the first time
2110 * (with packet == NULL) just counts the space needed, the second time
2111 * (with packet == allocated space) fills it in. Return value is the number
2112 * of bytes used.
2113 */
2114 static int
build_startup_packet(const PGconn * conn,char * packet,const PQEnvironmentOption * options)2115 build_startup_packet(const PGconn *conn, char *packet,
2116 const PQEnvironmentOption *options)
2117 {
2118 int packet_len = 0;
2119 const PQEnvironmentOption *next_eo;
2120 const char *val;
2121
2122 /* Protocol version comes first. */
2123 if (packet)
2124 {
2125 ProtocolVersion pv = pg_hton32(conn->pversion);
2126
2127 memcpy(packet + packet_len, &pv, sizeof(ProtocolVersion));
2128 }
2129 packet_len += sizeof(ProtocolVersion);
2130
2131 /* Add user name, database name, options */
2132
2133 #define ADD_STARTUP_OPTION(optname, optval) \
2134 do { \
2135 if (packet) \
2136 strcpy(packet + packet_len, optname); \
2137 packet_len += strlen(optname) + 1; \
2138 if (packet) \
2139 strcpy(packet + packet_len, optval); \
2140 packet_len += strlen(optval) + 1; \
2141 } while(0)
2142
2143 if (conn->pguser && conn->pguser[0])
2144 ADD_STARTUP_OPTION("user", conn->pguser);
2145 if (conn->dbName && conn->dbName[0])
2146 ADD_STARTUP_OPTION("database", conn->dbName);
2147 if (conn->replication && conn->replication[0])
2148 ADD_STARTUP_OPTION("replication", conn->replication);
2149 if (conn->pgoptions && conn->pgoptions[0])
2150 ADD_STARTUP_OPTION("options", conn->pgoptions);
2151 if (conn->send_appname)
2152 {
2153 /* Use appname if present, otherwise use fallback */
2154 val = conn->appname ? conn->appname : conn->fbappname;
2155 if (val && val[0])
2156 ADD_STARTUP_OPTION("application_name", val);
2157 }
2158
2159 if (conn->client_encoding_initial && conn->client_encoding_initial[0])
2160 ADD_STARTUP_OPTION("client_encoding", conn->client_encoding_initial);
2161
2162 /* Add any environment-driven GUC settings needed */
2163 for (next_eo = options; next_eo->envName; next_eo++)
2164 {
2165 if ((val = getenv(next_eo->envName)) != NULL)
2166 {
2167 if (pg_strcasecmp(val, "default") != 0)
2168 ADD_STARTUP_OPTION(next_eo->pgName, val);
2169 }
2170 }
2171
2172 /* Add trailing terminator */
2173 if (packet)
2174 packet[packet_len] = '\0';
2175 packet_len++;
2176
2177 return packet_len;
2178 }
2179