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