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