1 /*-------------------------------------------------------------------------
2  *
3  * fe-protocol2.c
4  *	  functions that are specific to frontend/backend protocol version 2
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-protocol2.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 
24 #ifdef WIN32
25 #include "win32.h"
26 #else
27 #include <unistd.h>
28 #include <netinet/in.h>
29 #ifdef HAVE_NETINET_TCP_H
30 #include <netinet/tcp.h>
31 #endif
32 #include <arpa/inet.h>
33 #endif
34 
35 
36 static int	getRowDescriptions(PGconn *conn);
37 static int	getAnotherTuple(PGconn *conn, bool binary);
38 static int	pqGetErrorNotice2(PGconn *conn, bool isError);
39 static void checkXactStatus(PGconn *conn, const char *cmdTag);
40 static int	getNotify(PGconn *conn);
41 
42 
43 /*
44  *		pqSetenvPoll
45  *
46  * Polls the process of passing the values of a standard set of environment
47  * variables to the backend.
48  */
49 PostgresPollingStatusType
pqSetenvPoll(PGconn * conn)50 pqSetenvPoll(PGconn *conn)
51 {
52 	PGresult   *res;
53 
54 	if (conn == NULL || conn->status == CONNECTION_BAD)
55 		return PGRES_POLLING_FAILED;
56 
57 	/* Check whether there are any data for us */
58 	switch (conn->setenv_state)
59 	{
60 			/* These are reading states */
61 		case SETENV_STATE_CLIENT_ENCODING_WAIT:
62 		case SETENV_STATE_OPTION_WAIT:
63 		case SETENV_STATE_QUERY1_WAIT:
64 		case SETENV_STATE_QUERY2_WAIT:
65 			{
66 				/* Load waiting data */
67 				int			n = pqReadData(conn);
68 
69 				if (n < 0)
70 					goto error_return;
71 				if (n == 0)
72 					return PGRES_POLLING_READING;
73 
74 				break;
75 			}
76 
77 			/* These are writing states, so we just proceed. */
78 		case SETENV_STATE_CLIENT_ENCODING_SEND:
79 		case SETENV_STATE_OPTION_SEND:
80 		case SETENV_STATE_QUERY1_SEND:
81 		case SETENV_STATE_QUERY2_SEND:
82 			break;
83 
84 			/* Should we raise an error if called when not active? */
85 		case SETENV_STATE_IDLE:
86 			return PGRES_POLLING_OK;
87 
88 		default:
89 			printfPQExpBuffer(&conn->errorMessage,
90 							  libpq_gettext(
91 											"invalid setenv state %c, "
92 											"probably indicative of memory corruption\n"
93 											),
94 							  conn->setenv_state);
95 			goto error_return;
96 	}
97 
98 	/* We will loop here until there is nothing left to do in this call. */
99 	for (;;)
100 	{
101 		switch (conn->setenv_state)
102 		{
103 				/*
104 				 * The _CLIENT_ENCODING_SEND code is slightly different from
105 				 * _OPTION_SEND below (e.g., no getenv() call), which is why a
106 				 * different state is used.
107 				 */
108 			case SETENV_STATE_CLIENT_ENCODING_SEND:
109 				{
110 					char		setQuery[100];	/* note length limit in
111 												 * sprintf below */
112 					const char *val = conn->client_encoding_initial;
113 
114 					if (val)
115 					{
116 						if (pg_strcasecmp(val, "default") == 0)
117 							sprintf(setQuery, "SET client_encoding = DEFAULT");
118 						else
119 							sprintf(setQuery, "SET client_encoding = '%.60s'",
120 									val);
121 #ifdef CONNECTDEBUG
122 						fprintf(stderr,
123 								"Sending client_encoding with %s\n",
124 								setQuery);
125 #endif
126 						if (!PQsendQuery(conn, setQuery))
127 							goto error_return;
128 
129 						conn->setenv_state = SETENV_STATE_CLIENT_ENCODING_WAIT;
130 					}
131 					else
132 						conn->setenv_state = SETENV_STATE_OPTION_SEND;
133 					break;
134 				}
135 
136 			case SETENV_STATE_OPTION_SEND:
137 				{
138 					/*
139 					 * Send SET commands for stuff directed by Environment
140 					 * Options.  Note: we assume that SET commands won't start
141 					 * transaction blocks, even in a 7.3 server with
142 					 * autocommit off.
143 					 */
144 					char		setQuery[100];	/* note length limit in
145 												 * sprintf below */
146 
147 					if (conn->next_eo->envName)
148 					{
149 						const char *val;
150 
151 						if ((val = getenv(conn->next_eo->envName)))
152 						{
153 							if (pg_strcasecmp(val, "default") == 0)
154 								sprintf(setQuery, "SET %s = DEFAULT",
155 										conn->next_eo->pgName);
156 							else
157 								sprintf(setQuery, "SET %s = '%.60s'",
158 										conn->next_eo->pgName, val);
159 #ifdef CONNECTDEBUG
160 							fprintf(stderr,
161 									"Use environment variable %s to send %s\n",
162 									conn->next_eo->envName, setQuery);
163 #endif
164 							if (!PQsendQuery(conn, setQuery))
165 								goto error_return;
166 
167 							conn->setenv_state = SETENV_STATE_OPTION_WAIT;
168 						}
169 						else
170 							conn->next_eo++;
171 					}
172 					else
173 					{
174 						/* No more options to send, so move on to querying */
175 						conn->setenv_state = SETENV_STATE_QUERY1_SEND;
176 					}
177 					break;
178 				}
179 
180 			case SETENV_STATE_CLIENT_ENCODING_WAIT:
181 				{
182 					if (PQisBusy(conn))
183 						return PGRES_POLLING_READING;
184 
185 					res = PQgetResult(conn);
186 
187 					if (res)
188 					{
189 						if (PQresultStatus(res) != PGRES_COMMAND_OK)
190 						{
191 							PQclear(res);
192 							goto error_return;
193 						}
194 						PQclear(res);
195 						/* Keep reading until PQgetResult returns NULL */
196 					}
197 					else
198 					{
199 						/* Query finished, so send the next option */
200 						conn->setenv_state = SETENV_STATE_OPTION_SEND;
201 					}
202 					break;
203 				}
204 
205 			case SETENV_STATE_OPTION_WAIT:
206 				{
207 					if (PQisBusy(conn))
208 						return PGRES_POLLING_READING;
209 
210 					res = PQgetResult(conn);
211 
212 					if (res)
213 					{
214 						if (PQresultStatus(res) != PGRES_COMMAND_OK)
215 						{
216 							PQclear(res);
217 							goto error_return;
218 						}
219 						PQclear(res);
220 						/* Keep reading until PQgetResult returns NULL */
221 					}
222 					else
223 					{
224 						/* Query finished, so send the next option */
225 						conn->next_eo++;
226 						conn->setenv_state = SETENV_STATE_OPTION_SEND;
227 					}
228 					break;
229 				}
230 
231 			case SETENV_STATE_QUERY1_SEND:
232 				{
233 					/*
234 					 * Issue query to get information we need.  Here we must
235 					 * use begin/commit in case autocommit is off by default
236 					 * in a 7.3 server.
237 					 *
238 					 * Note: version() exists in all protocol-2.0-supporting
239 					 * backends.  In 7.3 it would be safer to write
240 					 * pg_catalog.version(), but we can't do that without
241 					 * causing problems on older versions.
242 					 */
243 					if (!PQsendQuery(conn, "begin; select version(); end"))
244 						goto error_return;
245 
246 					conn->setenv_state = SETENV_STATE_QUERY1_WAIT;
247 					return PGRES_POLLING_READING;
248 				}
249 
250 			case SETENV_STATE_QUERY1_WAIT:
251 				{
252 					if (PQisBusy(conn))
253 						return PGRES_POLLING_READING;
254 
255 					res = PQgetResult(conn);
256 
257 					if (res)
258 					{
259 						char	   *val;
260 
261 						if (PQresultStatus(res) == PGRES_COMMAND_OK)
262 						{
263 							/* ignore begin/commit command results */
264 							PQclear(res);
265 							continue;
266 						}
267 
268 						if (PQresultStatus(res) != PGRES_TUPLES_OK ||
269 							PQntuples(res) != 1)
270 						{
271 							PQclear(res);
272 							goto error_return;
273 						}
274 
275 						/*
276 						 * Extract server version and save as if
277 						 * ParameterStatus
278 						 */
279 						val = PQgetvalue(res, 0, 0);
280 						if (val && strncmp(val, "PostgreSQL ", 11) == 0)
281 						{
282 							char	   *ptr;
283 
284 							/* strip off PostgreSQL part */
285 							val += 11;
286 
287 							/*
288 							 * strip off platform part (scribbles on result,
289 							 * naughty naughty)
290 							 */
291 							ptr = strchr(val, ' ');
292 							if (ptr)
293 								*ptr = '\0';
294 
295 							pqSaveParameterStatus(conn, "server_version",
296 												  val);
297 						}
298 
299 						PQclear(res);
300 						/* Keep reading until PQgetResult returns NULL */
301 					}
302 					else
303 					{
304 						/* Query finished, move to next */
305 						conn->setenv_state = SETENV_STATE_QUERY2_SEND;
306 					}
307 					break;
308 				}
309 
310 			case SETENV_STATE_QUERY2_SEND:
311 				{
312 					const char *query;
313 
314 					/*
315 					 * pg_client_encoding does not exist in pre-7.2 servers.
316 					 * So we need to be prepared for an error here.  Do *not*
317 					 * start a transaction block, except in 7.3 servers where
318 					 * we need to prevent autocommit-off from starting a
319 					 * transaction anyway.
320 					 */
321 					if (conn->sversion >= 70300 &&
322 						conn->sversion < 70400)
323 						query = "begin; select pg_catalog.pg_client_encoding(); end";
324 					else
325 						query = "select pg_client_encoding()";
326 					if (!PQsendQuery(conn, query))
327 						goto error_return;
328 
329 					conn->setenv_state = SETENV_STATE_QUERY2_WAIT;
330 					return PGRES_POLLING_READING;
331 				}
332 
333 			case SETENV_STATE_QUERY2_WAIT:
334 				{
335 					if (PQisBusy(conn))
336 						return PGRES_POLLING_READING;
337 
338 					res = PQgetResult(conn);
339 
340 					if (res)
341 					{
342 						const char *val;
343 
344 						if (PQresultStatus(res) == PGRES_COMMAND_OK)
345 						{
346 							/* ignore begin/commit command results */
347 							PQclear(res);
348 							continue;
349 						}
350 
351 						if (PQresultStatus(res) == PGRES_TUPLES_OK &&
352 							PQntuples(res) == 1)
353 						{
354 							/* Extract client encoding and save it */
355 							val = PQgetvalue(res, 0, 0);
356 							if (val && *val)	/* null should not happen, but */
357 								pqSaveParameterStatus(conn, "client_encoding",
358 													  val);
359 						}
360 						else
361 						{
362 							/*
363 							 * Error: presumably function not available, so
364 							 * use PGCLIENTENCODING or SQL_ASCII as the
365 							 * fallback.
366 							 */
367 							val = getenv("PGCLIENTENCODING");
368 							if (val && *val)
369 								pqSaveParameterStatus(conn, "client_encoding",
370 													  val);
371 							else
372 								pqSaveParameterStatus(conn, "client_encoding",
373 													  "SQL_ASCII");
374 						}
375 
376 						PQclear(res);
377 						/* Keep reading until PQgetResult returns NULL */
378 					}
379 					else
380 					{
381 						/* Query finished, so we're done */
382 						conn->setenv_state = SETENV_STATE_IDLE;
383 						return PGRES_POLLING_OK;
384 					}
385 					break;
386 				}
387 
388 			default:
389 				printfPQExpBuffer(&conn->errorMessage,
390 								  libpq_gettext("invalid state %c, "
391 												"probably indicative of memory corruption\n"),
392 								  conn->setenv_state);
393 				goto error_return;
394 		}
395 	}
396 
397 	/* Unreachable */
398 
399 error_return:
400 	conn->setenv_state = SETENV_STATE_IDLE;
401 	return PGRES_POLLING_FAILED;
402 }
403 
404 
405 /*
406  * parseInput: if appropriate, parse input data from backend
407  * until input is exhausted or a stopping state is reached.
408  * Note that this function will NOT attempt to read more data from the backend.
409  */
410 void
pqParseInput2(PGconn * conn)411 pqParseInput2(PGconn *conn)
412 {
413 	char		id;
414 
415 	/*
416 	 * Loop to parse successive complete messages available in the buffer.
417 	 */
418 	for (;;)
419 	{
420 		/*
421 		 * Quit if in COPY_OUT state: we expect raw data from the server until
422 		 * PQendcopy is called.  Don't try to parse it according to the normal
423 		 * protocol.  (This is bogus.  The data lines ought to be part of the
424 		 * protocol and have identifying leading characters.)
425 		 */
426 		if (conn->asyncStatus == PGASYNC_COPY_OUT)
427 			return;
428 
429 		/*
430 		 * OK to try to read a message type code.
431 		 */
432 		conn->inCursor = conn->inStart;
433 		if (pqGetc(&id, conn))
434 			return;
435 
436 		/*
437 		 * NOTIFY and NOTICE messages can happen in any state besides COPY
438 		 * OUT; always process them right away.
439 		 *
440 		 * Most other messages should only be processed while in BUSY state.
441 		 * (In particular, in READY state we hold off further parsing until
442 		 * the application collects the current PGresult.)
443 		 *
444 		 * However, if the state is IDLE then we got trouble; we need to deal
445 		 * with the unexpected message somehow.
446 		 */
447 		if (id == 'A')
448 		{
449 			if (getNotify(conn))
450 				return;
451 		}
452 		else if (id == 'N')
453 		{
454 			if (pqGetErrorNotice2(conn, false))
455 				return;
456 		}
457 		else if (conn->asyncStatus != PGASYNC_BUSY)
458 		{
459 			/* If not IDLE state, just wait ... */
460 			if (conn->asyncStatus != PGASYNC_IDLE)
461 				return;
462 
463 			/*
464 			 * Unexpected message in IDLE state; need to recover somehow.
465 			 * ERROR messages are displayed using the notice processor;
466 			 * anything else is just dropped on the floor after displaying a
467 			 * suitable warning notice.  (An ERROR is very possibly the
468 			 * backend telling us why it is about to close the connection, so
469 			 * we don't want to just discard it...)
470 			 */
471 			if (id == 'E')
472 			{
473 				if (pqGetErrorNotice2(conn, false /* treat as notice */ ))
474 					return;
475 			}
476 			else
477 			{
478 				pqInternalNotice(&conn->noticeHooks,
479 								 "message type 0x%02x arrived from server while idle",
480 								 id);
481 				/* Discard the unexpected message; good idea?? */
482 				conn->inStart = conn->inEnd;
483 				break;
484 			}
485 		}
486 		else
487 		{
488 			/*
489 			 * In BUSY state, we can process everything.
490 			 */
491 			switch (id)
492 			{
493 				case 'C':		/* command complete */
494 					if (pqGets(&conn->workBuffer, conn))
495 						return;
496 					if (conn->result == NULL)
497 					{
498 						conn->result = PQmakeEmptyPGresult(conn,
499 														   PGRES_COMMAND_OK);
500 						if (!conn->result)
501 						{
502 							printfPQExpBuffer(&conn->errorMessage,
503 											  libpq_gettext("out of memory"));
504 							pqSaveErrorResult(conn);
505 						}
506 					}
507 					if (conn->result)
508 					{
509 						strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
510 								CMDSTATUS_LEN);
511 					}
512 					checkXactStatus(conn, conn->workBuffer.data);
513 					conn->asyncStatus = PGASYNC_READY;
514 					break;
515 				case 'E':		/* error return */
516 					if (pqGetErrorNotice2(conn, true))
517 						return;
518 					conn->asyncStatus = PGASYNC_READY;
519 					break;
520 				case 'Z':		/* backend is ready for new query */
521 					conn->asyncStatus = PGASYNC_IDLE;
522 					break;
523 				case 'I':		/* empty query */
524 					/* read and throw away the closing '\0' */
525 					if (pqGetc(&id, conn))
526 						return;
527 					if (id != '\0')
528 						pqInternalNotice(&conn->noticeHooks,
529 										 "unexpected character %c following empty query response (\"I\" message)",
530 										 id);
531 					if (conn->result == NULL)
532 					{
533 						conn->result = PQmakeEmptyPGresult(conn,
534 														   PGRES_EMPTY_QUERY);
535 						if (!conn->result)
536 						{
537 							printfPQExpBuffer(&conn->errorMessage,
538 											  libpq_gettext("out of memory"));
539 							pqSaveErrorResult(conn);
540 						}
541 					}
542 					conn->asyncStatus = PGASYNC_READY;
543 					break;
544 				case 'K':		/* secret key data from the backend */
545 
546 					/*
547 					 * This is expected only during backend startup, but it's
548 					 * just as easy to handle it as part of the main loop.
549 					 * Save the data and continue processing.
550 					 */
551 					if (pqGetInt(&(conn->be_pid), 4, conn))
552 						return;
553 					if (pqGetInt(&(conn->be_key), 4, conn))
554 						return;
555 					break;
556 				case 'P':		/* synchronous (normal) portal */
557 					if (pqGets(&conn->workBuffer, conn))
558 						return;
559 					/* We pretty much ignore this message type... */
560 					break;
561 				case 'T':		/* row descriptions (start of query results) */
562 					if (conn->result == NULL)
563 					{
564 						/* First 'T' in a query sequence */
565 						if (getRowDescriptions(conn))
566 							return;
567 						/* getRowDescriptions() moves inStart itself */
568 						continue;
569 					}
570 					else
571 					{
572 						/*
573 						 * A new 'T' message is treated as the start of
574 						 * another PGresult.  (It is not clear that this is
575 						 * really possible with the current backend.) We stop
576 						 * parsing until the application accepts the current
577 						 * result.
578 						 */
579 						conn->asyncStatus = PGASYNC_READY;
580 						return;
581 					}
582 					break;
583 				case 'D':		/* ASCII data tuple */
584 					if (conn->result != NULL)
585 					{
586 						/* Read another tuple of a normal query response */
587 						if (getAnotherTuple(conn, FALSE))
588 							return;
589 						/* getAnotherTuple() moves inStart itself */
590 						continue;
591 					}
592 					else
593 					{
594 						pqInternalNotice(&conn->noticeHooks,
595 										 "server sent data (\"D\" message) without prior row description (\"T\" message)");
596 						/* Discard the unexpected message; good idea?? */
597 						conn->inStart = conn->inEnd;
598 						return;
599 					}
600 					break;
601 				case 'B':		/* Binary data tuple */
602 					if (conn->result != NULL)
603 					{
604 						/* Read another tuple of a normal query response */
605 						if (getAnotherTuple(conn, TRUE))
606 							return;
607 						/* getAnotherTuple() moves inStart itself */
608 						continue;
609 					}
610 					else
611 					{
612 						pqInternalNotice(&conn->noticeHooks,
613 										 "server sent binary data (\"B\" message) without prior row description (\"T\" message)");
614 						/* Discard the unexpected message; good idea?? */
615 						conn->inStart = conn->inEnd;
616 						return;
617 					}
618 					break;
619 				case 'G':		/* Start Copy In */
620 					conn->asyncStatus = PGASYNC_COPY_IN;
621 					break;
622 				case 'H':		/* Start Copy Out */
623 					conn->asyncStatus = PGASYNC_COPY_OUT;
624 					break;
625 
626 					/*
627 					 * Don't need to process CopyBothResponse here because it
628 					 * never arrives from the server during protocol 2.0.
629 					 */
630 				default:
631 					printfPQExpBuffer(&conn->errorMessage,
632 									  libpq_gettext(
633 													"unexpected response from server; first received character was \"%c\"\n"),
634 									  id);
635 					/* build an error result holding the error message */
636 					pqSaveErrorResult(conn);
637 					/* Discard the unexpected message; good idea?? */
638 					conn->inStart = conn->inEnd;
639 					conn->asyncStatus = PGASYNC_READY;
640 					return;
641 			}					/* switch on protocol character */
642 		}
643 		/* Successfully consumed this message */
644 		conn->inStart = conn->inCursor;
645 	}
646 }
647 
648 /*
649  * parseInput subroutine to read a 'T' (row descriptions) message.
650  * We build a PGresult structure containing the attribute data.
651  * Returns: 0 if completed message, EOF if error or not enough data
652  * received yet.
653  *
654  * Note that if we run out of data, we have to suspend and reprocess
655  * the message after more data is received.  Otherwise, conn->inStart
656  * must get advanced past the processed data.
657  */
658 static int
getRowDescriptions(PGconn * conn)659 getRowDescriptions(PGconn *conn)
660 {
661 	PGresult   *result;
662 	int			nfields;
663 	const char *errmsg;
664 	int			i;
665 
666 	result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
667 	if (!result)
668 	{
669 		errmsg = NULL;			/* means "out of memory", see below */
670 		goto advance_and_error;
671 	}
672 
673 	/* parseInput already read the 'T' label. */
674 	/* the next two bytes are the number of fields	*/
675 	if (pqGetInt(&(result->numAttributes), 2, conn))
676 		goto EOFexit;
677 	nfields = result->numAttributes;
678 
679 	/* allocate space for the attribute descriptors */
680 	if (nfields > 0)
681 	{
682 		result->attDescs = (PGresAttDesc *)
683 			pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
684 		if (!result->attDescs)
685 		{
686 			errmsg = NULL;		/* means "out of memory", see below */
687 			goto advance_and_error;
688 		}
689 		MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
690 	}
691 
692 	/* get type info */
693 	for (i = 0; i < nfields; i++)
694 	{
695 		int			typid;
696 		int			typlen;
697 		int			atttypmod;
698 
699 		if (pqGets(&conn->workBuffer, conn) ||
700 			pqGetInt(&typid, 4, conn) ||
701 			pqGetInt(&typlen, 2, conn) ||
702 			pqGetInt(&atttypmod, 4, conn))
703 			goto EOFexit;
704 
705 		/*
706 		 * Since pqGetInt treats 2-byte integers as unsigned, we need to
707 		 * coerce the result to signed form.
708 		 */
709 		typlen = (int) ((int16) typlen);
710 
711 		result->attDescs[i].name = pqResultStrdup(result,
712 												  conn->workBuffer.data);
713 		if (!result->attDescs[i].name)
714 		{
715 			errmsg = NULL;		/* means "out of memory", see below */
716 			goto advance_and_error;
717 		}
718 		result->attDescs[i].tableid = 0;
719 		result->attDescs[i].columnid = 0;
720 		result->attDescs[i].format = 0;
721 		result->attDescs[i].typid = typid;
722 		result->attDescs[i].typlen = typlen;
723 		result->attDescs[i].atttypmod = atttypmod;
724 	}
725 
726 	/* Success! */
727 	conn->result = result;
728 
729 	/* Advance inStart to show that the "T" message has been processed. */
730 	conn->inStart = conn->inCursor;
731 
732 	/*
733 	 * We could perform additional setup for the new result set here, but for
734 	 * now there's nothing else to do.
735 	 */
736 
737 	/* And we're done. */
738 	return 0;
739 
740 advance_and_error:
741 
742 	/*
743 	 * Discard the failed message.  Unfortunately we don't know for sure where
744 	 * the end is, so just throw away everything in the input buffer. This is
745 	 * not very desirable but it's the best we can do in protocol v2.
746 	 */
747 	conn->inStart = conn->inEnd;
748 
749 	/*
750 	 * Replace partially constructed result with an error result. First
751 	 * discard the old result to try to win back some memory.
752 	 */
753 	pqClearAsyncResult(conn);
754 
755 	/*
756 	 * If preceding code didn't provide an error message, assume "out of
757 	 * memory" was meant.  The advantage of having this special case is that
758 	 * freeing the old result first greatly improves the odds that gettext()
759 	 * will succeed in providing a translation.
760 	 */
761 	if (!errmsg)
762 		errmsg = libpq_gettext("out of memory for query result");
763 
764 	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
765 
766 	/*
767 	 * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can
768 	 * do to recover...
769 	 */
770 	conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
771 	conn->asyncStatus = PGASYNC_READY;
772 
773 EOFexit:
774 	if (result && result != conn->result)
775 		PQclear(result);
776 	return EOF;
777 }
778 
779 /*
780  * parseInput subroutine to read a 'B' or 'D' (row data) message.
781  * We fill rowbuf with column pointers and then call the row processor.
782  * Returns: 0 if completed message, EOF if error or not enough data
783  * received yet.
784  *
785  * Note that if we run out of data, we have to suspend and reprocess
786  * the message after more data is received.  Otherwise, conn->inStart
787  * must get advanced past the processed data.
788  */
789 static int
getAnotherTuple(PGconn * conn,bool binary)790 getAnotherTuple(PGconn *conn, bool binary)
791 {
792 	PGresult   *result = conn->result;
793 	int			nfields = result->numAttributes;
794 	const char *errmsg;
795 	PGdataValue *rowbuf;
796 
797 	/* the backend sends us a bitmap of which attributes are null */
798 	char		std_bitmap[64]; /* used unless it doesn't fit */
799 	char	   *bitmap = std_bitmap;
800 	int			i;
801 	size_t		nbytes;			/* the number of bytes in bitmap  */
802 	char		bmap;			/* One byte of the bitmap */
803 	int			bitmap_index;	/* Its index */
804 	int			bitcnt;			/* number of bits examined in current byte */
805 	int			vlen;			/* length of the current field value */
806 
807 	/* Resize row buffer if needed */
808 	rowbuf = conn->rowBuf;
809 	if (nfields > conn->rowBufLen)
810 	{
811 		rowbuf = (PGdataValue *) realloc(rowbuf,
812 										 nfields * sizeof(PGdataValue));
813 		if (!rowbuf)
814 		{
815 			errmsg = NULL;		/* means "out of memory", see below */
816 			goto advance_and_error;
817 		}
818 		conn->rowBuf = rowbuf;
819 		conn->rowBufLen = nfields;
820 	}
821 
822 	/* Save format specifier */
823 	result->binary = binary;
824 
825 	/*
826 	 * If it's binary, fix the column format indicators.  We assume the
827 	 * backend will consistently send either B or D, not a mix.
828 	 */
829 	if (binary)
830 	{
831 		for (i = 0; i < nfields; i++)
832 			result->attDescs[i].format = 1;
833 	}
834 
835 	/* Get the null-value bitmap */
836 	nbytes = (nfields + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
837 	/* malloc() only for unusually large field counts... */
838 	if (nbytes > sizeof(std_bitmap))
839 	{
840 		bitmap = (char *) malloc(nbytes);
841 		if (!bitmap)
842 		{
843 			errmsg = NULL;		/* means "out of memory", see below */
844 			goto advance_and_error;
845 		}
846 	}
847 
848 	if (pqGetnchar(bitmap, nbytes, conn))
849 		goto EOFexit;
850 
851 	/* Scan the fields */
852 	bitmap_index = 0;
853 	bmap = bitmap[bitmap_index];
854 	bitcnt = 0;
855 
856 	for (i = 0; i < nfields; i++)
857 	{
858 		/* get the value length */
859 		if (!(bmap & 0200))
860 			vlen = NULL_LEN;
861 		else if (pqGetInt(&vlen, 4, conn))
862 			goto EOFexit;
863 		else
864 		{
865 			if (!binary)
866 				vlen = vlen - 4;
867 			if (vlen < 0)
868 				vlen = 0;
869 		}
870 		rowbuf[i].len = vlen;
871 
872 		/*
873 		 * rowbuf[i].value always points to the next address in the data
874 		 * buffer even if the value is NULL.  This allows row processors to
875 		 * estimate data sizes more easily.
876 		 */
877 		rowbuf[i].value = conn->inBuffer + conn->inCursor;
878 
879 		/* Skip over the data value */
880 		if (vlen > 0)
881 		{
882 			if (pqSkipnchar(vlen, conn))
883 				goto EOFexit;
884 		}
885 
886 		/* advance the bitmap stuff */
887 		bitcnt++;
888 		if (bitcnt == BITS_PER_BYTE)
889 		{
890 			bitmap_index++;
891 			bmap = bitmap[bitmap_index];
892 			bitcnt = 0;
893 		}
894 		else
895 			bmap <<= 1;
896 	}
897 
898 	/* Release bitmap now if we allocated it */
899 	if (bitmap != std_bitmap)
900 		free(bitmap);
901 	bitmap = NULL;
902 
903 	/* Advance inStart to show that the "D" message has been processed. */
904 	conn->inStart = conn->inCursor;
905 
906 	/* Process the collected row */
907 	errmsg = NULL;
908 	if (pqRowProcessor(conn, &errmsg))
909 		return 0;				/* normal, successful exit */
910 
911 	goto set_error_result;		/* pqRowProcessor failed, report it */
912 
913 advance_and_error:
914 
915 	/*
916 	 * Discard the failed message.  Unfortunately we don't know for sure where
917 	 * the end is, so just throw away everything in the input buffer. This is
918 	 * not very desirable but it's the best we can do in protocol v2.
919 	 */
920 	conn->inStart = conn->inEnd;
921 
922 set_error_result:
923 
924 	/*
925 	 * Replace partially constructed result with an error result. First
926 	 * discard the old result to try to win back some memory.
927 	 */
928 	pqClearAsyncResult(conn);
929 
930 	/*
931 	 * If preceding code didn't provide an error message, assume "out of
932 	 * memory" was meant.  The advantage of having this special case is that
933 	 * freeing the old result first greatly improves the odds that gettext()
934 	 * will succeed in providing a translation.
935 	 */
936 	if (!errmsg)
937 		errmsg = libpq_gettext("out of memory for query result");
938 
939 	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
940 
941 	/*
942 	 * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can
943 	 * do to recover...
944 	 */
945 	conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
946 	conn->asyncStatus = PGASYNC_READY;
947 
948 EOFexit:
949 	if (bitmap != NULL && bitmap != std_bitmap)
950 		free(bitmap);
951 	return EOF;
952 }
953 
954 
955 /*
956  * Attempt to read an Error or Notice response message.
957  * This is possible in several places, so we break it out as a subroutine.
958  * Entry: 'E' or 'N' message type has already been consumed.
959  * Exit: returns 0 if successfully consumed message.
960  *		 returns EOF if not enough data.
961  */
962 static int
pqGetErrorNotice2(PGconn * conn,bool isError)963 pqGetErrorNotice2(PGconn *conn, bool isError)
964 {
965 	PGresult   *res = NULL;
966 	PQExpBufferData workBuf;
967 	char	   *startp;
968 	char	   *splitp;
969 
970 	/*
971 	 * If this is an error message, pre-emptively clear any incomplete query
972 	 * result we may have.  We'd just throw it away below anyway, and
973 	 * releasing it before collecting the error might avoid out-of-memory.
974 	 */
975 	if (isError)
976 		pqClearAsyncResult(conn);
977 
978 	/*
979 	 * Since the message might be pretty long, we create a temporary
980 	 * PQExpBuffer rather than using conn->workBuffer.  workBuffer is intended
981 	 * for stuff that is expected to be short.
982 	 */
983 	initPQExpBuffer(&workBuf);
984 	if (pqGets(&workBuf, conn))
985 		goto failure;
986 
987 	/*
988 	 * Make a PGresult to hold the message.  We temporarily lie about the
989 	 * result status, so that PQmakeEmptyPGresult doesn't uselessly copy
990 	 * conn->errorMessage.
991 	 *
992 	 * NB: This allocation can fail, if you run out of memory. The rest of the
993 	 * function handles that gracefully, and we still try to set the error
994 	 * message as the connection's error message.
995 	 */
996 	res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
997 	if (res)
998 	{
999 		res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
1000 		res->errMsg = pqResultStrdup(res, workBuf.data);
1001 	}
1002 
1003 	/*
1004 	 * Break the message into fields.  We can't do very much here, but we can
1005 	 * split the severity code off, and remove trailing newlines. Also, we use
1006 	 * the heuristic that the primary message extends only to the first
1007 	 * newline --- anything after that is detail message.  (In some cases it'd
1008 	 * be better classed as hint, but we can hardly be expected to guess that
1009 	 * here.)
1010 	 */
1011 	while (workBuf.len > 0 && workBuf.data[workBuf.len - 1] == '\n')
1012 		workBuf.data[--workBuf.len] = '\0';
1013 	splitp = strstr(workBuf.data, ":  ");
1014 	if (splitp)
1015 	{
1016 		/* what comes before the colon is severity */
1017 		*splitp = '\0';
1018 		pqSaveMessageField(res, PG_DIAG_SEVERITY, workBuf.data);
1019 		startp = splitp + 3;
1020 	}
1021 	else
1022 	{
1023 		/* can't find a colon?  oh well... */
1024 		startp = workBuf.data;
1025 	}
1026 	splitp = strchr(startp, '\n');
1027 	if (splitp)
1028 	{
1029 		/* what comes before the newline is primary message */
1030 		*splitp++ = '\0';
1031 		pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, startp);
1032 		/* the rest is detail; strip any leading whitespace */
1033 		while (*splitp && isspace((unsigned char) *splitp))
1034 			splitp++;
1035 		pqSaveMessageField(res, PG_DIAG_MESSAGE_DETAIL, splitp);
1036 	}
1037 	else
1038 	{
1039 		/* single-line message, so all primary */
1040 		pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, startp);
1041 	}
1042 
1043 	/*
1044 	 * Either save error as current async result, or just emit the notice.
1045 	 * Also, if it's an error and we were in a transaction block, assume the
1046 	 * server has now gone to error-in-transaction state.
1047 	 */
1048 	if (isError)
1049 	{
1050 		pqClearAsyncResult(conn);	/* redundant, but be safe */
1051 		conn->result = res;
1052 		resetPQExpBuffer(&conn->errorMessage);
1053 		if (res && !PQExpBufferDataBroken(workBuf) && res->errMsg)
1054 			appendPQExpBufferStr(&conn->errorMessage, res->errMsg);
1055 		else
1056 			printfPQExpBuffer(&conn->errorMessage,
1057 							  libpq_gettext("out of memory"));
1058 		if (conn->xactStatus == PQTRANS_INTRANS)
1059 			conn->xactStatus = PQTRANS_INERROR;
1060 	}
1061 	else
1062 	{
1063 		if (res)
1064 		{
1065 			if (res->noticeHooks.noticeRec != NULL)
1066 				(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
1067 			PQclear(res);
1068 		}
1069 	}
1070 
1071 	termPQExpBuffer(&workBuf);
1072 	return 0;
1073 
1074 failure:
1075 	if (res)
1076 		PQclear(res);
1077 	termPQExpBuffer(&workBuf);
1078 	return EOF;
1079 }
1080 
1081 /*
1082  * checkXactStatus - attempt to track transaction-block status of server
1083  *
1084  * This is called each time we receive a command-complete message.  By
1085  * watching for messages from BEGIN/COMMIT/ROLLBACK commands, we can do
1086  * a passable job of tracking the server's xact status.  BUT: this does
1087  * not work at all on 7.3 servers with AUTOCOMMIT OFF.  (Man, was that
1088  * feature ever a mistake.)  Caveat user.
1089  *
1090  * The tags known here are all those used as far back as 7.0; is it worth
1091  * adding those from even-older servers?
1092  */
1093 static void
checkXactStatus(PGconn * conn,const char * cmdTag)1094 checkXactStatus(PGconn *conn, const char *cmdTag)
1095 {
1096 	if (strcmp(cmdTag, "BEGIN") == 0)
1097 		conn->xactStatus = PQTRANS_INTRANS;
1098 	else if (strcmp(cmdTag, "COMMIT") == 0)
1099 		conn->xactStatus = PQTRANS_IDLE;
1100 	else if (strcmp(cmdTag, "ROLLBACK") == 0)
1101 		conn->xactStatus = PQTRANS_IDLE;
1102 	else if (strcmp(cmdTag, "START TRANSACTION") == 0)	/* 7.3 only */
1103 		conn->xactStatus = PQTRANS_INTRANS;
1104 
1105 	/*
1106 	 * Normally we get into INERROR state by detecting an Error message.
1107 	 * However, if we see one of these tags then we know for sure the server
1108 	 * is in abort state ...
1109 	 */
1110 	else if (strcmp(cmdTag, "*ABORT STATE*") == 0)	/* pre-7.3 only */
1111 		conn->xactStatus = PQTRANS_INERROR;
1112 }
1113 
1114 /*
1115  * Attempt to read a Notify response message.
1116  * This is possible in several places, so we break it out as a subroutine.
1117  * Entry: 'A' message type and length have already been consumed.
1118  * Exit: returns 0 if successfully consumed Notify message.
1119  *		 returns EOF if not enough data.
1120  */
1121 static int
getNotify(PGconn * conn)1122 getNotify(PGconn *conn)
1123 {
1124 	int			be_pid;
1125 	int			nmlen;
1126 	PGnotify   *newNotify;
1127 
1128 	if (pqGetInt(&be_pid, 4, conn))
1129 		return EOF;
1130 	if (pqGets(&conn->workBuffer, conn))
1131 		return EOF;
1132 
1133 	/*
1134 	 * Store the relation name right after the PQnotify structure so it can
1135 	 * all be freed at once.  We don't use NAMEDATALEN because we don't want
1136 	 * to tie this interface to a specific server name length.
1137 	 */
1138 	nmlen = strlen(conn->workBuffer.data);
1139 	newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + 1);
1140 	if (newNotify)
1141 	{
1142 		newNotify->relname = (char *) newNotify + sizeof(PGnotify);
1143 		strcpy(newNotify->relname, conn->workBuffer.data);
1144 		/* fake up an empty-string extra field */
1145 		newNotify->extra = newNotify->relname + nmlen;
1146 		newNotify->be_pid = be_pid;
1147 		newNotify->next = NULL;
1148 		if (conn->notifyTail)
1149 			conn->notifyTail->next = newNotify;
1150 		else
1151 			conn->notifyHead = newNotify;
1152 		conn->notifyTail = newNotify;
1153 	}
1154 
1155 	return 0;
1156 }
1157 
1158 
1159 /*
1160  * PQgetCopyData - read a row of data from the backend during COPY OUT
1161  *
1162  * If successful, sets *buffer to point to a malloc'd row of data, and
1163  * returns row length (always > 0) as result.
1164  * Returns 0 if no row available yet (only possible if async is true),
1165  * -1 if end of copy (consult PQgetResult), or -2 if error (consult
1166  * PQerrorMessage).
1167  */
1168 int
pqGetCopyData2(PGconn * conn,char ** buffer,int async)1169 pqGetCopyData2(PGconn *conn, char **buffer, int async)
1170 {
1171 	bool		found;
1172 	int			msgLength;
1173 
1174 	for (;;)
1175 	{
1176 		/*
1177 		 * Do we have a complete line of data?
1178 		 */
1179 		conn->inCursor = conn->inStart;
1180 		found = false;
1181 		while (conn->inCursor < conn->inEnd)
1182 		{
1183 			char		c = conn->inBuffer[conn->inCursor++];
1184 
1185 			if (c == '\n')
1186 			{
1187 				found = true;
1188 				break;
1189 			}
1190 		}
1191 		if (!found)
1192 			goto nodata;
1193 		msgLength = conn->inCursor - conn->inStart;
1194 
1195 		/*
1196 		 * If it's the end-of-data marker, consume it, exit COPY_OUT mode, and
1197 		 * let caller read status with PQgetResult().
1198 		 */
1199 		if (msgLength == 3 &&
1200 			strncmp(&conn->inBuffer[conn->inStart], "\\.\n", 3) == 0)
1201 		{
1202 			conn->inStart = conn->inCursor;
1203 			conn->asyncStatus = PGASYNC_BUSY;
1204 			return -1;
1205 		}
1206 
1207 		/*
1208 		 * Pass the line back to the caller.
1209 		 */
1210 		*buffer = (char *) malloc(msgLength + 1);
1211 		if (*buffer == NULL)
1212 		{
1213 			printfPQExpBuffer(&conn->errorMessage,
1214 							  libpq_gettext("out of memory\n"));
1215 			return -2;
1216 		}
1217 		memcpy(*buffer, &conn->inBuffer[conn->inStart], msgLength);
1218 		(*buffer)[msgLength] = '\0';	/* Add terminating null */
1219 
1220 		/* Mark message consumed */
1221 		conn->inStart = conn->inCursor;
1222 
1223 		return msgLength;
1224 
1225 nodata:
1226 		/* Don't block if async read requested */
1227 		if (async)
1228 			return 0;
1229 		/* Need to load more data */
1230 		if (pqWait(TRUE, FALSE, conn) ||
1231 			pqReadData(conn) < 0)
1232 			return -2;
1233 	}
1234 }
1235 
1236 
1237 /*
1238  * PQgetline - gets a newline-terminated string from the backend.
1239  *
1240  * See fe-exec.c for documentation.
1241  */
1242 int
pqGetline2(PGconn * conn,char * s,int maxlen)1243 pqGetline2(PGconn *conn, char *s, int maxlen)
1244 {
1245 	int			result = 1;		/* return value if buffer overflows */
1246 
1247 	if (conn->sock == PGINVALID_SOCKET ||
1248 		conn->asyncStatus != PGASYNC_COPY_OUT)
1249 	{
1250 		*s = '\0';
1251 		return EOF;
1252 	}
1253 
1254 	/*
1255 	 * Since this is a purely synchronous routine, we don't bother to maintain
1256 	 * conn->inCursor; there is no need to back up.
1257 	 */
1258 	while (maxlen > 1)
1259 	{
1260 		if (conn->inStart < conn->inEnd)
1261 		{
1262 			char		c = conn->inBuffer[conn->inStart++];
1263 
1264 			if (c == '\n')
1265 			{
1266 				result = 0;		/* success exit */
1267 				break;
1268 			}
1269 			*s++ = c;
1270 			maxlen--;
1271 		}
1272 		else
1273 		{
1274 			/* need to load more data */
1275 			if (pqWait(TRUE, FALSE, conn) ||
1276 				pqReadData(conn) < 0)
1277 			{
1278 				result = EOF;
1279 				break;
1280 			}
1281 		}
1282 	}
1283 	*s = '\0';
1284 
1285 	return result;
1286 }
1287 
1288 /*
1289  * PQgetlineAsync - gets a COPY data row without blocking.
1290  *
1291  * See fe-exec.c for documentation.
1292  */
1293 int
pqGetlineAsync2(PGconn * conn,char * buffer,int bufsize)1294 pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize)
1295 {
1296 	int			avail;
1297 
1298 	if (conn->asyncStatus != PGASYNC_COPY_OUT)
1299 		return -1;				/* we are not doing a copy... */
1300 
1301 	/*
1302 	 * Move data from libpq's buffer to the caller's. We want to accept data
1303 	 * only in units of whole lines, not partial lines.  This ensures that we
1304 	 * can recognize the terminator line "\\.\n".  (Otherwise, if it happened
1305 	 * to cross a packet/buffer boundary, we might hand the first one or two
1306 	 * characters off to the caller, which we shouldn't.)
1307 	 */
1308 
1309 	conn->inCursor = conn->inStart;
1310 
1311 	avail = bufsize;
1312 	while (avail > 0 && conn->inCursor < conn->inEnd)
1313 	{
1314 		char		c = conn->inBuffer[conn->inCursor++];
1315 
1316 		*buffer++ = c;
1317 		--avail;
1318 		if (c == '\n')
1319 		{
1320 			/* Got a complete line; mark the data removed from libpq */
1321 			conn->inStart = conn->inCursor;
1322 			/* Is it the endmarker line? */
1323 			if (bufsize - avail == 3 && buffer[-3] == '\\' && buffer[-2] == '.')
1324 				return -1;
1325 			/* No, return the data line to the caller */
1326 			return bufsize - avail;
1327 		}
1328 	}
1329 
1330 	/*
1331 	 * We don't have a complete line. We'd prefer to leave it in libpq's
1332 	 * buffer until the rest arrives, but there is a special case: what if the
1333 	 * line is longer than the buffer the caller is offering us?  In that case
1334 	 * we'd better hand over a partial line, else we'd get into an infinite
1335 	 * loop. Do this in a way that ensures we can't misrecognize a terminator
1336 	 * line later: leave last 3 characters in libpq buffer.
1337 	 */
1338 	if (avail == 0 && bufsize > 3)
1339 	{
1340 		conn->inStart = conn->inCursor - 3;
1341 		return bufsize - 3;
1342 	}
1343 	return 0;
1344 }
1345 
1346 /*
1347  * PQendcopy
1348  *
1349  * See fe-exec.c for documentation.
1350  */
1351 int
pqEndcopy2(PGconn * conn)1352 pqEndcopy2(PGconn *conn)
1353 {
1354 	PGresult   *result;
1355 
1356 	if (conn->asyncStatus != PGASYNC_COPY_IN &&
1357 		conn->asyncStatus != PGASYNC_COPY_OUT)
1358 	{
1359 		printfPQExpBuffer(&conn->errorMessage,
1360 						  libpq_gettext("no COPY in progress\n"));
1361 		return 1;
1362 	}
1363 
1364 	/*
1365 	 * make sure no data is waiting to be sent, abort if we are non-blocking
1366 	 * and the flush fails
1367 	 */
1368 	if (pqFlush(conn) && pqIsnonblocking(conn))
1369 		return 1;
1370 
1371 	/* non blocking connections may have to abort at this point. */
1372 	if (pqIsnonblocking(conn) && PQisBusy(conn))
1373 		return 1;
1374 
1375 	/* Return to active duty */
1376 	conn->asyncStatus = PGASYNC_BUSY;
1377 	resetPQExpBuffer(&conn->errorMessage);
1378 
1379 	/* Wait for the completion response */
1380 	result = PQgetResult(conn);
1381 
1382 	/* Expecting a successful result */
1383 	if (result && result->resultStatus == PGRES_COMMAND_OK)
1384 	{
1385 		PQclear(result);
1386 		return 0;
1387 	}
1388 
1389 	/*
1390 	 * Trouble. For backwards-compatibility reasons, we issue the error
1391 	 * message as if it were a notice (would be nice to get rid of this
1392 	 * silliness, but too many apps probably don't handle errors from
1393 	 * PQendcopy reasonably).  Note that the app can still obtain the error
1394 	 * status from the PGconn object.
1395 	 */
1396 	if (conn->errorMessage.len > 0)
1397 	{
1398 		/* We have to strip the trailing newline ... pain in neck... */
1399 		char		svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1400 
1401 		if (svLast == '\n')
1402 			conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1403 		pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
1404 		conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1405 	}
1406 
1407 	PQclear(result);
1408 
1409 	/*
1410 	 * The worst case is that we've lost sync with the backend entirely due to
1411 	 * application screwup of the copy in/out protocol. To recover, reset the
1412 	 * connection (talk about using a sledgehammer...)
1413 	 */
1414 	pqInternalNotice(&conn->noticeHooks,
1415 					 "lost synchronization with server, resetting connection");
1416 
1417 	/*
1418 	 * Users doing non-blocking connections need to handle the reset
1419 	 * themselves, they'll need to check the connection status if we return an
1420 	 * error.
1421 	 */
1422 	if (pqIsnonblocking(conn))
1423 		PQresetStart(conn);
1424 	else
1425 		PQreset(conn);
1426 
1427 	return 1;
1428 }
1429 
1430 
1431 /*
1432  * PQfn - Send a function call to the POSTGRES backend.
1433  *
1434  * See fe-exec.c for documentation.
1435  */
1436 PGresult *
pqFunctionCall2(PGconn * conn,Oid fnid,int * result_buf,int * actual_result_len,int result_is_int,const PQArgBlock * args,int nargs)1437 pqFunctionCall2(PGconn *conn, Oid fnid,
1438 				int *result_buf, int *actual_result_len,
1439 				int result_is_int,
1440 				const PQArgBlock *args, int nargs)
1441 {
1442 	bool		needInput = false;
1443 	ExecStatusType status = PGRES_FATAL_ERROR;
1444 	char		id;
1445 	int			i;
1446 
1447 	/* PQfn already validated connection state */
1448 
1449 	if (pqPutMsgStart('F', false, conn) < 0 ||	/* function call msg */
1450 		pqPuts(" ", conn) < 0 ||	/* dummy string */
1451 		pqPutInt(fnid, 4, conn) != 0 || /* function id */
1452 		pqPutInt(nargs, 4, conn) != 0)	/* # of args */
1453 	{
1454 		pqHandleSendFailure(conn);
1455 		return NULL;
1456 	}
1457 
1458 	for (i = 0; i < nargs; ++i)
1459 	{							/* len.int4 + contents	   */
1460 		if (pqPutInt(args[i].len, 4, conn))
1461 		{
1462 			pqHandleSendFailure(conn);
1463 			return NULL;
1464 		}
1465 
1466 		if (args[i].isint)
1467 		{
1468 			if (pqPutInt(args[i].u.integer, 4, conn))
1469 			{
1470 				pqHandleSendFailure(conn);
1471 				return NULL;
1472 			}
1473 		}
1474 		else
1475 		{
1476 			if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
1477 			{
1478 				pqHandleSendFailure(conn);
1479 				return NULL;
1480 			}
1481 		}
1482 	}
1483 
1484 	if (pqPutMsgEnd(conn) < 0 ||
1485 		pqFlush(conn))
1486 	{
1487 		pqHandleSendFailure(conn);
1488 		return NULL;
1489 	}
1490 
1491 	for (;;)
1492 	{
1493 		if (needInput)
1494 		{
1495 			/* Wait for some data to arrive (or for the channel to close) */
1496 			if (pqWait(TRUE, FALSE, conn) ||
1497 				pqReadData(conn) < 0)
1498 				break;
1499 		}
1500 
1501 		/*
1502 		 * Scan the message. If we run out of data, loop around to try again.
1503 		 */
1504 		conn->inCursor = conn->inStart;
1505 		needInput = true;
1506 
1507 		if (pqGetc(&id, conn))
1508 			continue;
1509 
1510 		/*
1511 		 * We should see V or E response to the command, but might get N
1512 		 * and/or A notices first. We also need to swallow the final Z before
1513 		 * returning.
1514 		 */
1515 		switch (id)
1516 		{
1517 			case 'V':			/* function result */
1518 				if (pqGetc(&id, conn))
1519 					continue;
1520 				if (id == 'G')
1521 				{
1522 					/* function returned nonempty value */
1523 					if (pqGetInt(actual_result_len, 4, conn))
1524 						continue;
1525 					if (result_is_int)
1526 					{
1527 						if (pqGetInt(result_buf, 4, conn))
1528 							continue;
1529 					}
1530 					else
1531 					{
1532 						if (pqGetnchar((char *) result_buf,
1533 									   *actual_result_len,
1534 									   conn))
1535 							continue;
1536 					}
1537 					if (pqGetc(&id, conn))	/* get the last '0' */
1538 						continue;
1539 				}
1540 				if (id == '0')
1541 				{
1542 					/* correctly finished function result message */
1543 					status = PGRES_COMMAND_OK;
1544 				}
1545 				else
1546 				{
1547 					/* The backend violates the protocol. */
1548 					printfPQExpBuffer(&conn->errorMessage,
1549 									  libpq_gettext("protocol error: id=0x%x\n"),
1550 									  id);
1551 					pqSaveErrorResult(conn);
1552 					conn->inStart = conn->inCursor;
1553 					return pqPrepareAsyncResult(conn);
1554 				}
1555 				break;
1556 			case 'E':			/* error return */
1557 				if (pqGetErrorNotice2(conn, true))
1558 					continue;
1559 				status = PGRES_FATAL_ERROR;
1560 				break;
1561 			case 'A':			/* notify message */
1562 				/* handle notify and go back to processing return values */
1563 				if (getNotify(conn))
1564 					continue;
1565 				break;
1566 			case 'N':			/* notice */
1567 				/* handle notice and go back to processing return values */
1568 				if (pqGetErrorNotice2(conn, false))
1569 					continue;
1570 				break;
1571 			case 'Z':			/* backend is ready for new query */
1572 				/* consume the message and exit */
1573 				conn->inStart = conn->inCursor;
1574 				/* if we saved a result object (probably an error), use it */
1575 				if (conn->result)
1576 					return pqPrepareAsyncResult(conn);
1577 				return PQmakeEmptyPGresult(conn, status);
1578 			default:
1579 				/* The backend violates the protocol. */
1580 				printfPQExpBuffer(&conn->errorMessage,
1581 								  libpq_gettext("protocol error: id=0x%x\n"),
1582 								  id);
1583 				pqSaveErrorResult(conn);
1584 				conn->inStart = conn->inCursor;
1585 				return pqPrepareAsyncResult(conn);
1586 		}
1587 		/* Completed this message, keep going */
1588 		conn->inStart = conn->inCursor;
1589 		needInput = false;
1590 	}
1591 
1592 	/*
1593 	 * We fall out of the loop only upon failing to read data.
1594 	 * conn->errorMessage has been set by pqWait or pqReadData. We want to
1595 	 * append it to any already-received error message.
1596 	 */
1597 	pqSaveErrorResult(conn);
1598 	return pqPrepareAsyncResult(conn);
1599 }
1600 
1601 
1602 /*
1603  * Construct startup packet
1604  *
1605  * Returns a malloc'd packet buffer, or NULL if out of memory
1606  */
1607 char *
pqBuildStartupPacket2(PGconn * conn,int * packetlen,const PQEnvironmentOption * options)1608 pqBuildStartupPacket2(PGconn *conn, int *packetlen,
1609 					  const PQEnvironmentOption *options)
1610 {
1611 	StartupPacket *startpacket;
1612 
1613 	*packetlen = sizeof(StartupPacket);
1614 	startpacket = (StartupPacket *) malloc(sizeof(StartupPacket));
1615 	if (!startpacket)
1616 		return NULL;
1617 
1618 	MemSet(startpacket, 0, sizeof(StartupPacket));
1619 
1620 	startpacket->protoVersion = htonl(conn->pversion);
1621 
1622 	/* strncpy is safe here: postmaster will handle full fields correctly */
1623 	strncpy(startpacket->user, conn->pguser, SM_USER);
1624 	strncpy(startpacket->database, conn->dbName, SM_DATABASE);
1625 	strncpy(startpacket->tty, conn->pgtty, SM_TTY);
1626 
1627 	if (conn->pgoptions)
1628 		strncpy(startpacket->options, conn->pgoptions, SM_OPTIONS);
1629 
1630 	return (char *) startpacket;
1631 }
1632