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