OSDN Git Service

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