Header And Logo

PostgreSQL
| The world's most advanced open source database.

fe-protocol3.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * fe-protocol3.c
00004  *    functions that are specific to frontend/backend protocol version 3
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/interfaces/libpq/fe-protocol3.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres_fe.h"
00016 
00017 #include <ctype.h>
00018 #include <fcntl.h>
00019 
00020 #include "libpq-fe.h"
00021 #include "libpq-int.h"
00022 
00023 #include "mb/pg_wchar.h"
00024 
00025 #ifdef WIN32
00026 #include "win32.h"
00027 #else
00028 #include <unistd.h>
00029 #include <netinet/in.h>
00030 #ifdef HAVE_NETINET_TCP_H
00031 #include <netinet/tcp.h>
00032 #endif
00033 #include <arpa/inet.h>
00034 #endif
00035 
00036 
00037 /*
00038  * This macro lists the backend message types that could be "long" (more
00039  * than a couple of kilobytes).
00040  */
00041 #define VALID_LONG_MESSAGE_TYPE(id) \
00042     ((id) == 'T' || (id) == 'D' || (id) == 'd' || (id) == 'V' || \
00043      (id) == 'E' || (id) == 'N' || (id) == 'A')
00044 
00045 
00046 static void handleSyncLoss(PGconn *conn, char id, int msgLength);
00047 static int  getRowDescriptions(PGconn *conn, int msgLength);
00048 static int  getParamDescriptions(PGconn *conn);
00049 static int  getAnotherTuple(PGconn *conn, int msgLength);
00050 static int  getParameterStatus(PGconn *conn);
00051 static int  getNotify(PGconn *conn);
00052 static int  getCopyStart(PGconn *conn, ExecStatusType copytype);
00053 static int  getReadyForQuery(PGconn *conn);
00054 static void reportErrorPosition(PQExpBuffer msg, const char *query,
00055                     int loc, int encoding);
00056 static int build_startup_packet(const PGconn *conn, char *packet,
00057                      const PQEnvironmentOption *options);
00058 
00059 
00060 /*
00061  * parseInput: if appropriate, parse input data from backend
00062  * until input is exhausted or a stopping state is reached.
00063  * Note that this function will NOT attempt to read more data from the backend.
00064  */
00065 void
00066 pqParseInput3(PGconn *conn)
00067 {
00068     char        id;
00069     int         msgLength;
00070     int         avail;
00071 
00072     /*
00073      * Loop to parse successive complete messages available in the buffer.
00074      */
00075     for (;;)
00076     {
00077         /*
00078          * Try to read a message.  First get the type code and length. Return
00079          * if not enough data.
00080          */
00081         conn->inCursor = conn->inStart;
00082         if (pqGetc(&id, conn))
00083             return;
00084         if (pqGetInt(&msgLength, 4, conn))
00085             return;
00086 
00087         /*
00088          * Try to validate message type/length here.  A length less than 4 is
00089          * definitely broken.  Large lengths should only be believed for a few
00090          * message types.
00091          */
00092         if (msgLength < 4)
00093         {
00094             handleSyncLoss(conn, id, msgLength);
00095             return;
00096         }
00097         if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
00098         {
00099             handleSyncLoss(conn, id, msgLength);
00100             return;
00101         }
00102 
00103         /*
00104          * Can't process if message body isn't all here yet.
00105          */
00106         msgLength -= 4;
00107         avail = conn->inEnd - conn->inCursor;
00108         if (avail < msgLength)
00109         {
00110             /*
00111              * Before returning, enlarge the input buffer if needed to hold
00112              * the whole message.  This is better than leaving it to
00113              * pqReadData because we can avoid multiple cycles of realloc()
00114              * when the message is large; also, we can implement a reasonable
00115              * recovery strategy if we are unable to make the buffer big
00116              * enough.
00117              */
00118             if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
00119                                      conn))
00120             {
00121                 /*
00122                  * XXX add some better recovery code... plan is to skip over
00123                  * the message using its length, then report an error. For the
00124                  * moment, just treat this like loss of sync (which indeed it
00125                  * might be!)
00126                  */
00127                 handleSyncLoss(conn, id, msgLength);
00128             }
00129             return;
00130         }
00131 
00132         /*
00133          * NOTIFY and NOTICE messages can happen in any state; always process
00134          * them right away.
00135          *
00136          * Most other messages should only be processed while in BUSY state.
00137          * (In particular, in READY state we hold off further parsing until
00138          * the application collects the current PGresult.)
00139          *
00140          * However, if the state is IDLE then we got trouble; we need to deal
00141          * with the unexpected message somehow.
00142          *
00143          * ParameterStatus ('S') messages are a special case: in IDLE state we
00144          * must process 'em (this case could happen if a new value was adopted
00145          * from config file due to SIGHUP), but otherwise we hold off until
00146          * BUSY state.
00147          */
00148         if (id == 'A')
00149         {
00150             if (getNotify(conn))
00151                 return;
00152         }
00153         else if (id == 'N')
00154         {
00155             if (pqGetErrorNotice3(conn, false))
00156                 return;
00157         }
00158         else if (conn->asyncStatus != PGASYNC_BUSY)
00159         {
00160             /* If not IDLE state, just wait ... */
00161             if (conn->asyncStatus != PGASYNC_IDLE)
00162                 return;
00163 
00164             /*
00165              * Unexpected message in IDLE state; need to recover somehow.
00166              * ERROR messages are displayed using the notice processor;
00167              * ParameterStatus is handled normally; anything else is just
00168              * dropped on the floor after displaying a suitable warning
00169              * notice.  (An ERROR is very possibly the backend telling us why
00170              * it is about to close the connection, so we don't want to just
00171              * discard it...)
00172              */
00173             if (id == 'E')
00174             {
00175                 if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
00176                     return;
00177             }
00178             else if (id == 'S')
00179             {
00180                 if (getParameterStatus(conn))
00181                     return;
00182             }
00183             else
00184             {
00185                 pqInternalNotice(&conn->noticeHooks,
00186                         "message type 0x%02x arrived from server while idle",
00187                                  id);
00188                 /* Discard the unexpected message */
00189                 conn->inCursor += msgLength;
00190             }
00191         }
00192         else
00193         {
00194             /*
00195              * In BUSY state, we can process everything.
00196              */
00197             switch (id)
00198             {
00199                 case 'C':       /* command complete */
00200                     if (pqGets(&conn->workBuffer, conn))
00201                         return;
00202                     if (conn->result == NULL)
00203                     {
00204                         conn->result = PQmakeEmptyPGresult(conn,
00205                                                            PGRES_COMMAND_OK);
00206                         if (!conn->result)
00207                             return;
00208                     }
00209                     strncpy(conn->result->cmdStatus, conn->workBuffer.data,
00210                             CMDSTATUS_LEN);
00211                     conn->asyncStatus = PGASYNC_READY;
00212                     break;
00213                 case 'E':       /* error return */
00214                     if (pqGetErrorNotice3(conn, true))
00215                         return;
00216                     conn->asyncStatus = PGASYNC_READY;
00217                     break;
00218                 case 'Z':       /* backend is ready for new query */
00219                     if (getReadyForQuery(conn))
00220                         return;
00221                     conn->asyncStatus = PGASYNC_IDLE;
00222                     break;
00223                 case 'I':       /* empty query */
00224                     if (conn->result == NULL)
00225                     {
00226                         conn->result = PQmakeEmptyPGresult(conn,
00227                                                            PGRES_EMPTY_QUERY);
00228                         if (!conn->result)
00229                             return;
00230                     }
00231                     conn->asyncStatus = PGASYNC_READY;
00232                     break;
00233                 case '1':       /* Parse Complete */
00234                     /* If we're doing PQprepare, we're done; else ignore */
00235                     if (conn->queryclass == PGQUERY_PREPARE)
00236                     {
00237                         if (conn->result == NULL)
00238                         {
00239                             conn->result = PQmakeEmptyPGresult(conn,
00240                                                            PGRES_COMMAND_OK);
00241                             if (!conn->result)
00242                                 return;
00243                         }
00244                         conn->asyncStatus = PGASYNC_READY;
00245                     }
00246                     break;
00247                 case '2':       /* Bind Complete */
00248                 case '3':       /* Close Complete */
00249                     /* Nothing to do for these message types */
00250                     break;
00251                 case 'S':       /* parameter status */
00252                     if (getParameterStatus(conn))
00253                         return;
00254                     break;
00255                 case 'K':       /* secret key data from the backend */
00256 
00257                     /*
00258                      * This is expected only during backend startup, but it's
00259                      * just as easy to handle it as part of the main loop.
00260                      * Save the data and continue processing.
00261                      */
00262                     if (pqGetInt(&(conn->be_pid), 4, conn))
00263                         return;
00264                     if (pqGetInt(&(conn->be_key), 4, conn))
00265                         return;
00266                     break;
00267                 case 'T':       /* Row Description */
00268                     if (conn->result == NULL ||
00269                         conn->queryclass == PGQUERY_DESCRIBE)
00270                     {
00271                         /* First 'T' in a query sequence */
00272                         if (getRowDescriptions(conn, msgLength))
00273                             return;
00274                         /* getRowDescriptions() moves inStart itself */
00275                         continue;
00276                     }
00277                     else
00278                     {
00279                         /*
00280                          * A new 'T' message is treated as the start of
00281                          * another PGresult.  (It is not clear that this is
00282                          * really possible with the current backend.) We stop
00283                          * parsing until the application accepts the current
00284                          * result.
00285                          */
00286                         conn->asyncStatus = PGASYNC_READY;
00287                         return;
00288                     }
00289                     break;
00290                 case 'n':       /* No Data */
00291 
00292                     /*
00293                      * NoData indicates that we will not be seeing a
00294                      * RowDescription message because the statement or portal
00295                      * inquired about doesn't return rows.
00296                      *
00297                      * If we're doing a Describe, we have to pass something
00298                      * back to the client, so set up a COMMAND_OK result,
00299                      * instead of TUPLES_OK.  Otherwise we can just ignore
00300                      * this message.
00301                      */
00302                     if (conn->queryclass == PGQUERY_DESCRIBE)
00303                     {
00304                         if (conn->result == NULL)
00305                         {
00306                             conn->result = PQmakeEmptyPGresult(conn,
00307                                                            PGRES_COMMAND_OK);
00308                             if (!conn->result)
00309                                 return;
00310                         }
00311                         conn->asyncStatus = PGASYNC_READY;
00312                     }
00313                     break;
00314                 case 't':       /* Parameter Description */
00315                     if (getParamDescriptions(conn))
00316                         return;
00317                     break;
00318                 case 'D':       /* Data Row */
00319                     if (conn->result != NULL &&
00320                         conn->result->resultStatus == PGRES_TUPLES_OK)
00321                     {
00322                         /* Read another tuple of a normal query response */
00323                         if (getAnotherTuple(conn, msgLength))
00324                             return;
00325                         /* getAnotherTuple() moves inStart itself */
00326                         continue;
00327                     }
00328                     else if (conn->result != NULL &&
00329                              conn->result->resultStatus == PGRES_FATAL_ERROR)
00330                     {
00331                         /*
00332                          * We've already choked for some reason.  Just discard
00333                          * tuples till we get to the end of the query.
00334                          */
00335                         conn->inCursor += msgLength;
00336                     }
00337                     else
00338                     {
00339                         /* Set up to report error at end of query */
00340                         printfPQExpBuffer(&conn->errorMessage,
00341                                           libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)\n"));
00342                         pqSaveErrorResult(conn);
00343                         /* Discard the unexpected message */
00344                         conn->inCursor += msgLength;
00345                     }
00346                     break;
00347                 case 'G':       /* Start Copy In */
00348                     if (getCopyStart(conn, PGRES_COPY_IN))
00349                         return;
00350                     conn->asyncStatus = PGASYNC_COPY_IN;
00351                     break;
00352                 case 'H':       /* Start Copy Out */
00353                     if (getCopyStart(conn, PGRES_COPY_OUT))
00354                         return;
00355                     conn->asyncStatus = PGASYNC_COPY_OUT;
00356                     conn->copy_already_done = 0;
00357                     break;
00358                 case 'W':       /* Start Copy Both */
00359                     if (getCopyStart(conn, PGRES_COPY_BOTH))
00360                         return;
00361                     conn->asyncStatus = PGASYNC_COPY_BOTH;
00362                     conn->copy_already_done = 0;
00363                     break;
00364                 case 'd':       /* Copy Data */
00365 
00366                     /*
00367                      * If we see Copy Data, just silently drop it.  This would
00368                      * only occur if application exits COPY OUT mode too
00369                      * early.
00370                      */
00371                     conn->inCursor += msgLength;
00372                     break;
00373                 case 'c':       /* Copy Done */
00374 
00375                     /*
00376                      * If we see Copy Done, just silently drop it.  This is
00377                      * the normal case during PQendcopy.  We will keep
00378                      * swallowing data, expecting to see command-complete for
00379                      * the COPY command.
00380                      */
00381                     break;
00382                 default:
00383                     printfPQExpBuffer(&conn->errorMessage,
00384                                       libpq_gettext(
00385                                                     "unexpected response from server; first received character was \"%c\"\n"),
00386                                       id);
00387                     /* build an error result holding the error message */
00388                     pqSaveErrorResult(conn);
00389                     /* not sure if we will see more, so go to ready state */
00390                     conn->asyncStatus = PGASYNC_READY;
00391                     /* Discard the unexpected message */
00392                     conn->inCursor += msgLength;
00393                     break;
00394             }                   /* switch on protocol character */
00395         }
00396         /* Successfully consumed this message */
00397         if (conn->inCursor == conn->inStart + 5 + msgLength)
00398         {
00399             /* Normal case: parsing agrees with specified length */
00400             conn->inStart = conn->inCursor;
00401         }
00402         else
00403         {
00404             /* Trouble --- report it */
00405             printfPQExpBuffer(&conn->errorMessage,
00406                               libpq_gettext("message contents do not agree with length in message type \"%c\"\n"),
00407                               id);
00408             /* build an error result holding the error message */
00409             pqSaveErrorResult(conn);
00410             conn->asyncStatus = PGASYNC_READY;
00411             /* trust the specified message length as what to skip */
00412             conn->inStart += 5 + msgLength;
00413         }
00414     }
00415 }
00416 
00417 /*
00418  * handleSyncLoss: clean up after loss of message-boundary sync
00419  *
00420  * There isn't really a lot we can do here except abandon the connection.
00421  */
00422 static void
00423 handleSyncLoss(PGconn *conn, char id, int msgLength)
00424 {
00425     printfPQExpBuffer(&conn->errorMessage,
00426                       libpq_gettext(
00427     "lost synchronization with server: got message type \"%c\", length %d\n"),
00428                       id, msgLength);
00429     /* build an error result holding the error message */
00430     pqSaveErrorResult(conn);
00431     conn->asyncStatus = PGASYNC_READY;  /* drop out of GetResult wait loop */
00432 
00433     pqDropConnection(conn);
00434     conn->status = CONNECTION_BAD;      /* No more connection to backend */
00435 }
00436 
00437 /*
00438  * parseInput subroutine to read a 'T' (row descriptions) message.
00439  * We'll build a new PGresult structure (unless called for a Describe
00440  * command for a prepared statement) containing the attribute data.
00441  * Returns: 0 if processed message successfully, EOF to suspend parsing
00442  * (the latter case is not actually used currently).
00443  * In either case, conn->inStart has been advanced past the message.
00444  */
00445 static int
00446 getRowDescriptions(PGconn *conn, int msgLength)
00447 {
00448     PGresult   *result;
00449     int         nfields;
00450     const char *errmsg;
00451     int         i;
00452 
00453     /*
00454      * When doing Describe for a prepared statement, there'll already be a
00455      * PGresult created by getParamDescriptions, and we should fill data into
00456      * that.  Otherwise, create a new, empty PGresult.
00457      */
00458     if (conn->queryclass == PGQUERY_DESCRIBE)
00459     {
00460         if (conn->result)
00461             result = conn->result;
00462         else
00463             result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK);
00464     }
00465     else
00466         result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
00467     if (!result)
00468     {
00469         errmsg = NULL;          /* means "out of memory", see below */
00470         goto advance_and_error;
00471     }
00472 
00473     /* parseInput already read the 'T' label and message length. */
00474     /* the next two bytes are the number of fields */
00475     if (pqGetInt(&(result->numAttributes), 2, conn))
00476     {
00477         /* We should not run out of data here, so complain */
00478         errmsg = libpq_gettext("insufficient data in \"T\" message");
00479         goto advance_and_error;
00480     }
00481     nfields = result->numAttributes;
00482 
00483     /* allocate space for the attribute descriptors */
00484     if (nfields > 0)
00485     {
00486         result->attDescs = (PGresAttDesc *)
00487             pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
00488         if (!result->attDescs)
00489         {
00490             errmsg = NULL;      /* means "out of memory", see below */
00491             goto advance_and_error;
00492         }
00493         MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
00494     }
00495 
00496     /* result->binary is true only if ALL columns are binary */
00497     result->binary = (nfields > 0) ? 1 : 0;
00498 
00499     /* get type info */
00500     for (i = 0; i < nfields; i++)
00501     {
00502         int         tableid;
00503         int         columnid;
00504         int         typid;
00505         int         typlen;
00506         int         atttypmod;
00507         int         format;
00508 
00509         if (pqGets(&conn->workBuffer, conn) ||
00510             pqGetInt(&tableid, 4, conn) ||
00511             pqGetInt(&columnid, 2, conn) ||
00512             pqGetInt(&typid, 4, conn) ||
00513             pqGetInt(&typlen, 2, conn) ||
00514             pqGetInt(&atttypmod, 4, conn) ||
00515             pqGetInt(&format, 2, conn))
00516         {
00517             /* We should not run out of data here, so complain */
00518             errmsg = libpq_gettext("insufficient data in \"T\" message");
00519             goto advance_and_error;
00520         }
00521 
00522         /*
00523          * Since pqGetInt treats 2-byte integers as unsigned, we need to
00524          * coerce these results to signed form.
00525          */
00526         columnid = (int) ((int16) columnid);
00527         typlen = (int) ((int16) typlen);
00528         format = (int) ((int16) format);
00529 
00530         result->attDescs[i].name = pqResultStrdup(result,
00531                                                   conn->workBuffer.data);
00532         if (!result->attDescs[i].name)
00533         {
00534             errmsg = NULL;      /* means "out of memory", see below */
00535             goto advance_and_error;
00536         }
00537         result->attDescs[i].tableid = tableid;
00538         result->attDescs[i].columnid = columnid;
00539         result->attDescs[i].format = format;
00540         result->attDescs[i].typid = typid;
00541         result->attDescs[i].typlen = typlen;
00542         result->attDescs[i].atttypmod = atttypmod;
00543 
00544         if (format != 1)
00545             result->binary = 0;
00546     }
00547 
00548     /* Sanity check that we absorbed all the data */
00549     if (conn->inCursor != conn->inStart + 5 + msgLength)
00550     {
00551         errmsg = libpq_gettext("extraneous data in \"T\" message");
00552         goto advance_and_error;
00553     }
00554 
00555     /* Success! */
00556     conn->result = result;
00557 
00558     /* Advance inStart to show that the "T" message has been processed. */
00559     conn->inStart = conn->inCursor;
00560 
00561     /*
00562      * If we're doing a Describe, we're done, and ready to pass the result
00563      * back to the client.
00564      */
00565     if (conn->queryclass == PGQUERY_DESCRIBE)
00566     {
00567         conn->asyncStatus = PGASYNC_READY;
00568         return 0;
00569     }
00570 
00571     /*
00572      * We could perform additional setup for the new result set here, but for
00573      * now there's nothing else to do.
00574      */
00575 
00576     /* And we're done. */
00577     return 0;
00578 
00579 advance_and_error:
00580     /* Discard unsaved result, if any */
00581     if (result && result != conn->result)
00582         PQclear(result);
00583 
00584     /* Discard the failed message by pretending we read it */
00585     conn->inStart += 5 + msgLength;
00586 
00587     /*
00588      * Replace partially constructed result with an error result. First
00589      * discard the old result to try to win back some memory.
00590      */
00591     pqClearAsyncResult(conn);
00592 
00593     /*
00594      * If preceding code didn't provide an error message, assume "out of
00595      * memory" was meant.  The advantage of having this special case is that
00596      * freeing the old result first greatly improves the odds that gettext()
00597      * will succeed in providing a translation.
00598      */
00599     if (!errmsg)
00600         errmsg = libpq_gettext("out of memory for query result");
00601 
00602     printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
00603     pqSaveErrorResult(conn);
00604 
00605     /*
00606      * Return zero to allow input parsing to continue.  Subsequent "D"
00607      * messages will be ignored until we get to end of data, since an error
00608      * result is already set up.
00609      */
00610     return 0;
00611 }
00612 
00613 /*
00614  * parseInput subroutine to read a 't' (ParameterDescription) message.
00615  * We'll build a new PGresult structure containing the parameter data.
00616  * Returns: 0 if completed message, EOF if not enough data yet.
00617  *
00618  * Note that if we run out of data, we have to release the partially
00619  * constructed PGresult, and rebuild it again next time.  Fortunately,
00620  * that shouldn't happen often, since 't' messages usually fit in a packet.
00621  */
00622 static int
00623 getParamDescriptions(PGconn *conn)
00624 {
00625     PGresult   *result;
00626     int         nparams;
00627     int         i;
00628 
00629     result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK);
00630     if (!result)
00631         goto failure;
00632 
00633     /* parseInput already read the 't' label and message length. */
00634     /* the next two bytes are the number of parameters */
00635     if (pqGetInt(&(result->numParameters), 2, conn))
00636         goto failure;
00637     nparams = result->numParameters;
00638 
00639     /* allocate space for the parameter descriptors */
00640     if (nparams > 0)
00641     {
00642         result->paramDescs = (PGresParamDesc *)
00643             pqResultAlloc(result, nparams * sizeof(PGresParamDesc), TRUE);
00644         if (!result->paramDescs)
00645             goto failure;
00646         MemSet(result->paramDescs, 0, nparams * sizeof(PGresParamDesc));
00647     }
00648 
00649     /* get parameter info */
00650     for (i = 0; i < nparams; i++)
00651     {
00652         int         typid;
00653 
00654         if (pqGetInt(&typid, 4, conn))
00655             goto failure;
00656         result->paramDescs[i].typid = typid;
00657     }
00658 
00659     /* Success! */
00660     conn->result = result;
00661     return 0;
00662 
00663 failure:
00664     PQclear(result);
00665     return EOF;
00666 }
00667 
00668 /*
00669  * parseInput subroutine to read a 'D' (row data) message.
00670  * We fill rowbuf with column pointers and then call the row processor.
00671  * Returns: 0 if processed message successfully, EOF to suspend parsing
00672  * (the latter case is not actually used currently).
00673  * In either case, conn->inStart has been advanced past the message.
00674  */
00675 static int
00676 getAnotherTuple(PGconn *conn, int msgLength)
00677 {
00678     PGresult   *result = conn->result;
00679     int         nfields = result->numAttributes;
00680     const char *errmsg;
00681     PGdataValue *rowbuf;
00682     int         tupnfields;     /* # fields from tuple */
00683     int         vlen;           /* length of the current field value */
00684     int         i;
00685 
00686     /* Get the field count and make sure it's what we expect */
00687     if (pqGetInt(&tupnfields, 2, conn))
00688     {
00689         /* We should not run out of data here, so complain */
00690         errmsg = libpq_gettext("insufficient data in \"D\" message");
00691         goto advance_and_error;
00692     }
00693 
00694     if (tupnfields != nfields)
00695     {
00696         errmsg = libpq_gettext("unexpected field count in \"D\" message");
00697         goto advance_and_error;
00698     }
00699 
00700     /* Resize row buffer if needed */
00701     rowbuf = conn->rowBuf;
00702     if (nfields > conn->rowBufLen)
00703     {
00704         rowbuf = (PGdataValue *) realloc(rowbuf,
00705                                          nfields * sizeof(PGdataValue));
00706         if (!rowbuf)
00707         {
00708             errmsg = NULL;      /* means "out of memory", see below */
00709             goto advance_and_error;
00710         }
00711         conn->rowBuf = rowbuf;
00712         conn->rowBufLen = nfields;
00713     }
00714 
00715     /* Scan the fields */
00716     for (i = 0; i < nfields; i++)
00717     {
00718         /* get the value length */
00719         if (pqGetInt(&vlen, 4, conn))
00720         {
00721             /* We should not run out of data here, so complain */
00722             errmsg = libpq_gettext("insufficient data in \"D\" message");
00723             goto advance_and_error;
00724         }
00725         rowbuf[i].len = vlen;
00726 
00727         /*
00728          * rowbuf[i].value always points to the next address in the data
00729          * buffer even if the value is NULL.  This allows row processors to
00730          * estimate data sizes more easily.
00731          */
00732         rowbuf[i].value = conn->inBuffer + conn->inCursor;
00733 
00734         /* Skip over the data value */
00735         if (vlen > 0)
00736         {
00737             if (pqSkipnchar(vlen, conn))
00738             {
00739                 /* We should not run out of data here, so complain */
00740                 errmsg = libpq_gettext("insufficient data in \"D\" message");
00741                 goto advance_and_error;
00742             }
00743         }
00744     }
00745 
00746     /* Sanity check that we absorbed all the data */
00747     if (conn->inCursor != conn->inStart + 5 + msgLength)
00748     {
00749         errmsg = libpq_gettext("extraneous data in \"D\" message");
00750         goto advance_and_error;
00751     }
00752 
00753     /* Advance inStart to show that the "D" message has been processed. */
00754     conn->inStart = conn->inCursor;
00755 
00756     /* Process the collected row */
00757     errmsg = NULL;
00758     if (pqRowProcessor(conn, &errmsg))
00759         return 0;               /* normal, successful exit */
00760 
00761     goto set_error_result;      /* pqRowProcessor failed, report it */
00762 
00763 advance_and_error:
00764     /* Discard the failed message by pretending we read it */
00765     conn->inStart += 5 + msgLength;
00766 
00767 set_error_result:
00768 
00769     /*
00770      * Replace partially constructed result with an error result. First
00771      * discard the old result to try to win back some memory.
00772      */
00773     pqClearAsyncResult(conn);
00774 
00775     /*
00776      * If preceding code didn't provide an error message, assume "out of
00777      * memory" was meant.  The advantage of having this special case is that
00778      * freeing the old result first greatly improves the odds that gettext()
00779      * will succeed in providing a translation.
00780      */
00781     if (!errmsg)
00782         errmsg = libpq_gettext("out of memory for query result");
00783 
00784     printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
00785     pqSaveErrorResult(conn);
00786 
00787     /*
00788      * Return zero to allow input parsing to continue.  Subsequent "D"
00789      * messages will be ignored until we get to end of data, since an error
00790      * result is already set up.
00791      */
00792     return 0;
00793 }
00794 
00795 
00796 /*
00797  * Attempt to read an Error or Notice response message.
00798  * This is possible in several places, so we break it out as a subroutine.
00799  * Entry: 'E' or 'N' message type and length have already been consumed.
00800  * Exit: returns 0 if successfully consumed message.
00801  *       returns EOF if not enough data.
00802  */
00803 int
00804 pqGetErrorNotice3(PGconn *conn, bool isError)
00805 {
00806     PGresult   *res = NULL;
00807     PQExpBufferData workBuf;
00808     char        id;
00809     const char *val;
00810     const char *querytext = NULL;
00811     int         querypos = 0;
00812 
00813     /*
00814      * Since the fields might be pretty long, we create a temporary
00815      * PQExpBuffer rather than using conn->workBuffer.  workBuffer is intended
00816      * for stuff that is expected to be short.  We shouldn't use
00817      * conn->errorMessage either, since this might be only a notice.
00818      */
00819     initPQExpBuffer(&workBuf);
00820 
00821     /*
00822      * Make a PGresult to hold the accumulated fields.  We temporarily lie
00823      * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
00824      * copy conn->errorMessage.
00825      */
00826     res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
00827     if (!res)
00828         goto fail;
00829     res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
00830 
00831     /*
00832      * Read the fields and save into res.
00833      */
00834     for (;;)
00835     {
00836         if (pqGetc(&id, conn))
00837             goto fail;
00838         if (id == '\0')
00839             break;              /* terminator found */
00840         if (pqGets(&workBuf, conn))
00841             goto fail;
00842         pqSaveMessageField(res, id, workBuf.data);
00843     }
00844 
00845     /*
00846      * Now build the "overall" error message for PQresultErrorMessage.
00847      *
00848      * Also, save the SQLSTATE in conn->last_sqlstate.
00849      */
00850     resetPQExpBuffer(&workBuf);
00851     val = PQresultErrorField(res, PG_DIAG_SEVERITY);
00852     if (val)
00853         appendPQExpBuffer(&workBuf, "%s:  ", val);
00854     val = PQresultErrorField(res, PG_DIAG_SQLSTATE);
00855     if (val)
00856     {
00857         if (strlen(val) < sizeof(conn->last_sqlstate))
00858             strcpy(conn->last_sqlstate, val);
00859         if (conn->verbosity == PQERRORS_VERBOSE)
00860             appendPQExpBuffer(&workBuf, "%s: ", val);
00861     }
00862     val = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
00863     if (val)
00864         appendPQExpBufferStr(&workBuf, val);
00865     val = PQresultErrorField(res, PG_DIAG_STATEMENT_POSITION);
00866     if (val)
00867     {
00868         if (conn->verbosity != PQERRORS_TERSE && conn->last_query != NULL)
00869         {
00870             /* emit position as a syntax cursor display */
00871             querytext = conn->last_query;
00872             querypos = atoi(val);
00873         }
00874         else
00875         {
00876             /* emit position as text addition to primary message */
00877             /* translator: %s represents a digit string */
00878             appendPQExpBuffer(&workBuf, libpq_gettext(" at character %s"),
00879                               val);
00880         }
00881     }
00882     else
00883     {
00884         val = PQresultErrorField(res, PG_DIAG_INTERNAL_POSITION);
00885         if (val)
00886         {
00887             querytext = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
00888             if (conn->verbosity != PQERRORS_TERSE && querytext != NULL)
00889             {
00890                 /* emit position as a syntax cursor display */
00891                 querypos = atoi(val);
00892             }
00893             else
00894             {
00895                 /* emit position as text addition to primary message */
00896                 /* translator: %s represents a digit string */
00897                 appendPQExpBuffer(&workBuf, libpq_gettext(" at character %s"),
00898                                   val);
00899             }
00900         }
00901     }
00902     appendPQExpBufferChar(&workBuf, '\n');
00903     if (conn->verbosity != PQERRORS_TERSE)
00904     {
00905         if (querytext && querypos > 0)
00906             reportErrorPosition(&workBuf, querytext, querypos,
00907                                 conn->client_encoding);
00908         val = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
00909         if (val)
00910             appendPQExpBuffer(&workBuf, libpq_gettext("DETAIL:  %s\n"), val);
00911         val = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
00912         if (val)
00913             appendPQExpBuffer(&workBuf, libpq_gettext("HINT:  %s\n"), val);
00914         val = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
00915         if (val)
00916             appendPQExpBuffer(&workBuf, libpq_gettext("QUERY:  %s\n"), val);
00917         val = PQresultErrorField(res, PG_DIAG_CONTEXT);
00918         if (val)
00919             appendPQExpBuffer(&workBuf, libpq_gettext("CONTEXT:  %s\n"), val);
00920     }
00921     if (conn->verbosity == PQERRORS_VERBOSE)
00922     {
00923         val = PQresultErrorField(res, PG_DIAG_SCHEMA_NAME);
00924         if (val)
00925             appendPQExpBuffer(&workBuf,
00926                               libpq_gettext("SCHEMA NAME:  %s\n"), val);
00927         val = PQresultErrorField(res, PG_DIAG_TABLE_NAME);
00928         if (val)
00929             appendPQExpBuffer(&workBuf,
00930                               libpq_gettext("TABLE NAME:  %s\n"), val);
00931         val = PQresultErrorField(res, PG_DIAG_COLUMN_NAME);
00932         if (val)
00933             appendPQExpBuffer(&workBuf,
00934                               libpq_gettext("COLUMN NAME:  %s\n"), val);
00935         val = PQresultErrorField(res, PG_DIAG_DATATYPE_NAME);
00936         if (val)
00937             appendPQExpBuffer(&workBuf,
00938                               libpq_gettext("DATATYPE NAME:  %s\n"), val);
00939         val = PQresultErrorField(res, PG_DIAG_CONSTRAINT_NAME);
00940         if (val)
00941             appendPQExpBuffer(&workBuf,
00942                               libpq_gettext("CONSTRAINT NAME:  %s\n"), val);
00943     }
00944     if (conn->verbosity == PQERRORS_VERBOSE)
00945     {
00946         const char *valf;
00947         const char *vall;
00948 
00949         valf = PQresultErrorField(res, PG_DIAG_SOURCE_FILE);
00950         vall = PQresultErrorField(res, PG_DIAG_SOURCE_LINE);
00951         val = PQresultErrorField(res, PG_DIAG_SOURCE_FUNCTION);
00952         if (val || valf || vall)
00953         {
00954             appendPQExpBufferStr(&workBuf, libpq_gettext("LOCATION:  "));
00955             if (val)
00956                 appendPQExpBuffer(&workBuf, libpq_gettext("%s, "), val);
00957             if (valf && vall)   /* unlikely we'd have just one */
00958                 appendPQExpBuffer(&workBuf, libpq_gettext("%s:%s"),
00959                                   valf, vall);
00960             appendPQExpBufferChar(&workBuf, '\n');
00961         }
00962     }
00963 
00964     /*
00965      * Either save error as current async result, or just emit the notice.
00966      */
00967     if (isError)
00968     {
00969         res->errMsg = pqResultStrdup(res, workBuf.data);
00970         if (!res->errMsg)
00971             goto fail;
00972         pqClearAsyncResult(conn);
00973         conn->result = res;
00974         appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
00975     }
00976     else
00977     {
00978         /* We can cheat a little here and not copy the message. */
00979         res->errMsg = workBuf.data;
00980         if (res->noticeHooks.noticeRec != NULL)
00981             (*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
00982         PQclear(res);
00983     }
00984 
00985     termPQExpBuffer(&workBuf);
00986     return 0;
00987 
00988 fail:
00989     PQclear(res);
00990     termPQExpBuffer(&workBuf);
00991     return EOF;
00992 }
00993 
00994 /*
00995  * Add an error-location display to the error message under construction.
00996  *
00997  * The cursor location is measured in logical characters; the query string
00998  * is presumed to be in the specified encoding.
00999  */
01000 static void
01001 reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
01002 {
01003 #define DISPLAY_SIZE    60      /* screen width limit, in screen cols */
01004 #define MIN_RIGHT_CUT   10      /* try to keep this far away from EOL */
01005 
01006     char       *wquery;
01007     int         slen,
01008                 cno,
01009                 i,
01010                *qidx,
01011                *scridx,
01012                 qoffset,
01013                 scroffset,
01014                 ibeg,
01015                 iend,
01016                 loc_line;
01017     bool        mb_encoding,
01018                 beg_trunc,
01019                 end_trunc;
01020 
01021     /* Convert loc from 1-based to 0-based; no-op if out of range */
01022     loc--;
01023     if (loc < 0)
01024         return;
01025 
01026     /* Need a writable copy of the query */
01027     wquery = strdup(query);
01028     if (wquery == NULL)
01029         return;                 /* fail silently if out of memory */
01030 
01031     /*
01032      * Each character might occupy multiple physical bytes in the string, and
01033      * in some Far Eastern character sets it might take more than one screen
01034      * column as well.  We compute the starting byte offset and starting
01035      * screen column of each logical character, and store these in qidx[] and
01036      * scridx[] respectively.
01037      */
01038 
01039     /* we need a safe allocation size... */
01040     slen = strlen(wquery) + 1;
01041 
01042     qidx = (int *) malloc(slen * sizeof(int));
01043     if (qidx == NULL)
01044     {
01045         free(wquery);
01046         return;
01047     }
01048     scridx = (int *) malloc(slen * sizeof(int));
01049     if (scridx == NULL)
01050     {
01051         free(qidx);
01052         free(wquery);
01053         return;
01054     }
01055 
01056     /* We can optimize a bit if it's a single-byte encoding */
01057     mb_encoding = (pg_encoding_max_length(encoding) != 1);
01058 
01059     /*
01060      * Within the scanning loop, cno is the current character's logical
01061      * number, qoffset is its offset in wquery, and scroffset is its starting
01062      * logical screen column (all indexed from 0).  "loc" is the logical
01063      * character number of the error location.  We scan to determine loc_line
01064      * (the 1-based line number containing loc) and ibeg/iend (first character
01065      * number and last+1 character number of the line containing loc). Note
01066      * that qidx[] and scridx[] are filled only as far as iend.
01067      */
01068     qoffset = 0;
01069     scroffset = 0;
01070     loc_line = 1;
01071     ibeg = 0;
01072     iend = -1;                  /* -1 means not set yet */
01073 
01074     for (cno = 0; wquery[qoffset] != '\0'; cno++)
01075     {
01076         char        ch = wquery[qoffset];
01077 
01078         qidx[cno] = qoffset;
01079         scridx[cno] = scroffset;
01080 
01081         /*
01082          * Replace tabs with spaces in the writable copy.  (Later we might
01083          * want to think about coping with their variable screen width, but
01084          * not today.)
01085          */
01086         if (ch == '\t')
01087             wquery[qoffset] = ' ';
01088 
01089         /*
01090          * If end-of-line, count lines and mark positions. Each \r or \n
01091          * counts as a line except when \r \n appear together.
01092          */
01093         else if (ch == '\r' || ch == '\n')
01094         {
01095             if (cno < loc)
01096             {
01097                 if (ch == '\r' ||
01098                     cno == 0 ||
01099                     wquery[qidx[cno - 1]] != '\r')
01100                     loc_line++;
01101                 /* extract beginning = last line start before loc. */
01102                 ibeg = cno + 1;
01103             }
01104             else
01105             {
01106                 /* set extract end. */
01107                 iend = cno;
01108                 /* done scanning. */
01109                 break;
01110             }
01111         }
01112 
01113         /* Advance */
01114         if (mb_encoding)
01115         {
01116             int         w;
01117 
01118             w = pg_encoding_dsplen(encoding, &wquery[qoffset]);
01119             /* treat any non-tab control chars as width 1 */
01120             if (w <= 0)
01121                 w = 1;
01122             scroffset += w;
01123             qoffset += pg_encoding_mblen(encoding, &wquery[qoffset]);
01124         }
01125         else
01126         {
01127             /* We assume wide chars only exist in multibyte encodings */
01128             scroffset++;
01129             qoffset++;
01130         }
01131     }
01132     /* Fix up if we didn't find an end-of-line after loc */
01133     if (iend < 0)
01134     {
01135         iend = cno;             /* query length in chars, +1 */
01136         qidx[iend] = qoffset;
01137         scridx[iend] = scroffset;
01138     }
01139 
01140     /* Print only if loc is within computed query length */
01141     if (loc <= cno)
01142     {
01143         /* If the line extracted is too long, we truncate it. */
01144         beg_trunc = false;
01145         end_trunc = false;
01146         if (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
01147         {
01148             /*
01149              * We first truncate right if it is enough.  This code might be
01150              * off a space or so on enforcing MIN_RIGHT_CUT if there's a wide
01151              * character right there, but that should be okay.
01152              */
01153             if (scridx[ibeg] + DISPLAY_SIZE >= scridx[loc] + MIN_RIGHT_CUT)
01154             {
01155                 while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
01156                     iend--;
01157                 end_trunc = true;
01158             }
01159             else
01160             {
01161                 /* Truncate right if not too close to loc. */
01162                 while (scridx[loc] + MIN_RIGHT_CUT < scridx[iend])
01163                 {
01164                     iend--;
01165                     end_trunc = true;
01166                 }
01167 
01168                 /* Truncate left if still too long. */
01169                 while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
01170                 {
01171                     ibeg++;
01172                     beg_trunc = true;
01173                 }
01174             }
01175         }
01176 
01177         /* truncate working copy at desired endpoint */
01178         wquery[qidx[iend]] = '\0';
01179 
01180         /* Begin building the finished message. */
01181         i = msg->len;
01182         appendPQExpBuffer(msg, libpq_gettext("LINE %d: "), loc_line);
01183         if (beg_trunc)
01184             appendPQExpBufferStr(msg, "...");
01185 
01186         /*
01187          * While we have the prefix in the msg buffer, compute its screen
01188          * width.
01189          */
01190         scroffset = 0;
01191         for (; i < msg->len; i += pg_encoding_mblen(encoding, &msg->data[i]))
01192         {
01193             int         w = pg_encoding_dsplen(encoding, &msg->data[i]);
01194 
01195             if (w <= 0)
01196                 w = 1;
01197             scroffset += w;
01198         }
01199 
01200         /* Finish up the LINE message line. */
01201         appendPQExpBufferStr(msg, &wquery[qidx[ibeg]]);
01202         if (end_trunc)
01203             appendPQExpBufferStr(msg, "...");
01204         appendPQExpBufferChar(msg, '\n');
01205 
01206         /* Now emit the cursor marker line. */
01207         scroffset += scridx[loc] - scridx[ibeg];
01208         for (i = 0; i < scroffset; i++)
01209             appendPQExpBufferChar(msg, ' ');
01210         appendPQExpBufferChar(msg, '^');
01211         appendPQExpBufferChar(msg, '\n');
01212     }
01213 
01214     /* Clean up. */
01215     free(scridx);
01216     free(qidx);
01217     free(wquery);
01218 }
01219 
01220 
01221 /*
01222  * Attempt to read a ParameterStatus message.
01223  * This is possible in several places, so we break it out as a subroutine.
01224  * Entry: 'S' message type and length have already been consumed.
01225  * Exit: returns 0 if successfully consumed message.
01226  *       returns EOF if not enough data.
01227  */
01228 static int
01229 getParameterStatus(PGconn *conn)
01230 {
01231     PQExpBufferData valueBuf;
01232 
01233     /* Get the parameter name */
01234     if (pqGets(&conn->workBuffer, conn))
01235         return EOF;
01236     /* Get the parameter value (could be large) */
01237     initPQExpBuffer(&valueBuf);
01238     if (pqGets(&valueBuf, conn))
01239     {
01240         termPQExpBuffer(&valueBuf);
01241         return EOF;
01242     }
01243     /* And save it */
01244     pqSaveParameterStatus(conn, conn->workBuffer.data, valueBuf.data);
01245     termPQExpBuffer(&valueBuf);
01246     return 0;
01247 }
01248 
01249 
01250 /*
01251  * Attempt to read a Notify response message.
01252  * This is possible in several places, so we break it out as a subroutine.
01253  * Entry: 'A' message type and length have already been consumed.
01254  * Exit: returns 0 if successfully consumed Notify message.
01255  *       returns EOF if not enough data.
01256  */
01257 static int
01258 getNotify(PGconn *conn)
01259 {
01260     int         be_pid;
01261     char       *svname;
01262     int         nmlen;
01263     int         extralen;
01264     PGnotify   *newNotify;
01265 
01266     if (pqGetInt(&be_pid, 4, conn))
01267         return EOF;
01268     if (pqGets(&conn->workBuffer, conn))
01269         return EOF;
01270     /* must save name while getting extra string */
01271     svname = strdup(conn->workBuffer.data);
01272     if (!svname)
01273         return EOF;
01274     if (pqGets(&conn->workBuffer, conn))
01275     {
01276         free(svname);
01277         return EOF;
01278     }
01279 
01280     /*
01281      * Store the strings right after the PQnotify structure so it can all be
01282      * freed at once.  We don't use NAMEDATALEN because we don't want to tie
01283      * this interface to a specific server name length.
01284      */
01285     nmlen = strlen(svname);
01286     extralen = strlen(conn->workBuffer.data);
01287     newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + extralen + 2);
01288     if (newNotify)
01289     {
01290         newNotify->relname = (char *) newNotify + sizeof(PGnotify);
01291         strcpy(newNotify->relname, svname);
01292         newNotify->extra = newNotify->relname + nmlen + 1;
01293         strcpy(newNotify->extra, conn->workBuffer.data);
01294         newNotify->be_pid = be_pid;
01295         newNotify->next = NULL;
01296         if (conn->notifyTail)
01297             conn->notifyTail->next = newNotify;
01298         else
01299             conn->notifyHead = newNotify;
01300         conn->notifyTail = newNotify;
01301     }
01302 
01303     free(svname);
01304     return 0;
01305 }
01306 
01307 /*
01308  * getCopyStart - process CopyInResponse, CopyOutResponse or
01309  * CopyBothResponse message
01310  *
01311  * parseInput already read the message type and length.
01312  */
01313 static int
01314 getCopyStart(PGconn *conn, ExecStatusType copytype)
01315 {
01316     PGresult   *result;
01317     int         nfields;
01318     int         i;
01319 
01320     result = PQmakeEmptyPGresult(conn, copytype);
01321     if (!result)
01322         goto failure;
01323 
01324     if (pqGetc(&conn->copy_is_binary, conn))
01325         goto failure;
01326     result->binary = conn->copy_is_binary;
01327     /* the next two bytes are the number of fields  */
01328     if (pqGetInt(&(result->numAttributes), 2, conn))
01329         goto failure;
01330     nfields = result->numAttributes;
01331 
01332     /* allocate space for the attribute descriptors */
01333     if (nfields > 0)
01334     {
01335         result->attDescs = (PGresAttDesc *)
01336             pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
01337         if (!result->attDescs)
01338             goto failure;
01339         MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
01340     }
01341 
01342     for (i = 0; i < nfields; i++)
01343     {
01344         int         format;
01345 
01346         if (pqGetInt(&format, 2, conn))
01347             goto failure;
01348 
01349         /*
01350          * Since pqGetInt treats 2-byte integers as unsigned, we need to
01351          * coerce these results to signed form.
01352          */
01353         format = (int) ((int16) format);
01354         result->attDescs[i].format = format;
01355     }
01356 
01357     /* Success! */
01358     conn->result = result;
01359     return 0;
01360 
01361 failure:
01362     PQclear(result);
01363     return EOF;
01364 }
01365 
01366 /*
01367  * getReadyForQuery - process ReadyForQuery message
01368  */
01369 static int
01370 getReadyForQuery(PGconn *conn)
01371 {
01372     char        xact_status;
01373 
01374     if (pqGetc(&xact_status, conn))
01375         return EOF;
01376     switch (xact_status)
01377     {
01378         case 'I':
01379             conn->xactStatus = PQTRANS_IDLE;
01380             break;
01381         case 'T':
01382             conn->xactStatus = PQTRANS_INTRANS;
01383             break;
01384         case 'E':
01385             conn->xactStatus = PQTRANS_INERROR;
01386             break;
01387         default:
01388             conn->xactStatus = PQTRANS_UNKNOWN;
01389             break;
01390     }
01391 
01392     return 0;
01393 }
01394 
01395 /*
01396  * getCopyDataMessage - fetch next CopyData message, process async messages
01397  *
01398  * Returns length word of CopyData message (> 0), or 0 if no complete
01399  * message available, -1 if end of copy, -2 if error.
01400  */
01401 static int
01402 getCopyDataMessage(PGconn *conn)
01403 {
01404     char        id;
01405     int         msgLength;
01406     int         avail;
01407 
01408     for (;;)
01409     {
01410         /*
01411          * Do we have the next input message?  To make life simpler for async
01412          * callers, we keep returning 0 until the next message is fully
01413          * available, even if it is not Copy Data.
01414          */
01415         conn->inCursor = conn->inStart;
01416         if (pqGetc(&id, conn))
01417             return 0;
01418         if (pqGetInt(&msgLength, 4, conn))
01419             return 0;
01420         if (msgLength < 4)
01421         {
01422             handleSyncLoss(conn, id, msgLength);
01423             return -2;
01424         }
01425         avail = conn->inEnd - conn->inCursor;
01426         if (avail < msgLength - 4)
01427         {
01428             /*
01429              * Before returning, enlarge the input buffer if needed to hold
01430              * the whole message.  See notes in parseInput.
01431              */
01432             if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength - 4,
01433                                      conn))
01434             {
01435                 /*
01436                  * XXX add some better recovery code... plan is to skip over
01437                  * the message using its length, then report an error. For the
01438                  * moment, just treat this like loss of sync (which indeed it
01439                  * might be!)
01440                  */
01441                 handleSyncLoss(conn, id, msgLength);
01442                 return -2;
01443             }
01444             return 0;
01445         }
01446 
01447         /*
01448          * If it's a legitimate async message type, process it.  (NOTIFY
01449          * messages are not currently possible here, but we handle them for
01450          * completeness.)  Otherwise, if it's anything except Copy Data,
01451          * report end-of-copy.
01452          */
01453         switch (id)
01454         {
01455             case 'A':           /* NOTIFY */
01456                 if (getNotify(conn))
01457                     return 0;
01458                 break;
01459             case 'N':           /* NOTICE */
01460                 if (pqGetErrorNotice3(conn, false))
01461                     return 0;
01462                 break;
01463             case 'S':           /* ParameterStatus */
01464                 if (getParameterStatus(conn))
01465                     return 0;
01466                 break;
01467             case 'd':           /* Copy Data, pass it back to caller */
01468                 return msgLength;
01469             case 'c':
01470                 /*
01471                  * If this is a CopyDone message, exit COPY_OUT mode and let
01472                  * caller read status with PQgetResult().  If we're in
01473                  * COPY_BOTH mode, return to COPY_IN mode.
01474                  */
01475                 if (conn->asyncStatus == PGASYNC_COPY_BOTH)
01476                     conn->asyncStatus = PGASYNC_COPY_IN;
01477                 else
01478                     conn->asyncStatus = PGASYNC_BUSY;
01479                 return -1;
01480             default:            /* treat as end of copy */
01481                 /*
01482                  * Any other message terminates either COPY_IN or COPY_BOTH
01483                  * mode.
01484                  */
01485                 conn->asyncStatus = PGASYNC_BUSY;
01486                 return -1;
01487         }
01488 
01489         /* Drop the processed message and loop around for another */
01490         conn->inStart = conn->inCursor;
01491     }
01492 }
01493 
01494 /*
01495  * PQgetCopyData - read a row of data from the backend during COPY OUT
01496  * or COPY BOTH
01497  *
01498  * If successful, sets *buffer to point to a malloc'd row of data, and
01499  * returns row length (always > 0) as result.
01500  * Returns 0 if no row available yet (only possible if async is true),
01501  * -1 if end of copy (consult PQgetResult), or -2 if error (consult
01502  * PQerrorMessage).
01503  */
01504 int
01505 pqGetCopyData3(PGconn *conn, char **buffer, int async)
01506 {
01507     int         msgLength;
01508 
01509     for (;;)
01510     {
01511         /*
01512          * Collect the next input message.  To make life simpler for async
01513          * callers, we keep returning 0 until the next message is fully
01514          * available, even if it is not Copy Data.
01515          */
01516         msgLength = getCopyDataMessage(conn);
01517         if (msgLength < 0)
01518             return msgLength;   /* end-of-copy or error */
01519         if (msgLength == 0)
01520         {
01521             /* Don't block if async read requested */
01522             if (async)
01523                 return 0;
01524             /* Need to load more data */
01525             if (pqWait(TRUE, FALSE, conn) ||
01526                 pqReadData(conn) < 0)
01527                 return -2;
01528             continue;
01529         }
01530 
01531         /*
01532          * Drop zero-length messages (shouldn't happen anyway).  Otherwise
01533          * pass the data back to the caller.
01534          */
01535         msgLength -= 4;
01536         if (msgLength > 0)
01537         {
01538             *buffer = (char *) malloc(msgLength + 1);
01539             if (*buffer == NULL)
01540             {
01541                 printfPQExpBuffer(&conn->errorMessage,
01542                                   libpq_gettext("out of memory\n"));
01543                 return -2;
01544             }
01545             memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
01546             (*buffer)[msgLength] = '\0';        /* Add terminating null */
01547 
01548             /* Mark message consumed */
01549             conn->inStart = conn->inCursor + msgLength;
01550 
01551             return msgLength;
01552         }
01553 
01554         /* Empty, so drop it and loop around for another */
01555         conn->inStart = conn->inCursor;
01556     }
01557 }
01558 
01559 /*
01560  * PQgetline - gets a newline-terminated string from the backend.
01561  *
01562  * See fe-exec.c for documentation.
01563  */
01564 int
01565 pqGetline3(PGconn *conn, char *s, int maxlen)
01566 {
01567     int         status;
01568 
01569     if (conn->sock < 0 ||
01570         (conn->asyncStatus != PGASYNC_COPY_OUT &&
01571          conn->asyncStatus != PGASYNC_COPY_BOTH) ||
01572         conn->copy_is_binary)
01573     {
01574         printfPQExpBuffer(&conn->errorMessage,
01575                       libpq_gettext("PQgetline: not doing text COPY OUT\n"));
01576         *s = '\0';
01577         return EOF;
01578     }
01579 
01580     while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
01581     {
01582         /* need to load more data */
01583         if (pqWait(TRUE, FALSE, conn) ||
01584             pqReadData(conn) < 0)
01585         {
01586             *s = '\0';
01587             return EOF;
01588         }
01589     }
01590 
01591     if (status < 0)
01592     {
01593         /* End of copy detected; gin up old-style terminator */
01594         strcpy(s, "\\.");
01595         return 0;
01596     }
01597 
01598     /* Add null terminator, and strip trailing \n if present */
01599     if (s[status - 1] == '\n')
01600     {
01601         s[status - 1] = '\0';
01602         return 0;
01603     }
01604     else
01605     {
01606         s[status] = '\0';
01607         return 1;
01608     }
01609 }
01610 
01611 /*
01612  * PQgetlineAsync - gets a COPY data row without blocking.
01613  *
01614  * See fe-exec.c for documentation.
01615  */
01616 int
01617 pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize)
01618 {
01619     int         msgLength;
01620     int         avail;
01621 
01622     if (conn->asyncStatus != PGASYNC_COPY_OUT
01623         && conn->asyncStatus != PGASYNC_COPY_BOTH)
01624         return -1;              /* we are not doing a copy... */
01625 
01626     /*
01627      * Recognize the next input message.  To make life simpler for async
01628      * callers, we keep returning 0 until the next message is fully available
01629      * even if it is not Copy Data.  This should keep PQendcopy from blocking.
01630      * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
01631      */
01632     msgLength = getCopyDataMessage(conn);
01633     if (msgLength < 0)
01634         return -1;              /* end-of-copy or error */
01635     if (msgLength == 0)
01636         return 0;               /* no data yet */
01637 
01638     /*
01639      * Move data from libpq's buffer to the caller's.  In the case where a
01640      * prior call found the caller's buffer too small, we use
01641      * conn->copy_already_done to remember how much of the row was already
01642      * returned to the caller.
01643      */
01644     conn->inCursor += conn->copy_already_done;
01645     avail = msgLength - 4 - conn->copy_already_done;
01646     if (avail <= bufsize)
01647     {
01648         /* Able to consume the whole message */
01649         memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
01650         /* Mark message consumed */
01651         conn->inStart = conn->inCursor + avail;
01652         /* Reset state for next time */
01653         conn->copy_already_done = 0;
01654         return avail;
01655     }
01656     else
01657     {
01658         /* We must return a partial message */
01659         memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
01660         /* The message is NOT consumed from libpq's buffer */
01661         conn->copy_already_done += bufsize;
01662         return bufsize;
01663     }
01664 }
01665 
01666 /*
01667  * PQendcopy
01668  *
01669  * See fe-exec.c for documentation.
01670  */
01671 int
01672 pqEndcopy3(PGconn *conn)
01673 {
01674     PGresult   *result;
01675 
01676     if (conn->asyncStatus != PGASYNC_COPY_IN &&
01677         conn->asyncStatus != PGASYNC_COPY_OUT &&
01678         conn->asyncStatus != PGASYNC_COPY_BOTH)
01679     {
01680         printfPQExpBuffer(&conn->errorMessage,
01681                           libpq_gettext("no COPY in progress\n"));
01682         return 1;
01683     }
01684 
01685     /* Send the CopyDone message if needed */
01686     if (conn->asyncStatus == PGASYNC_COPY_IN ||
01687         conn->asyncStatus == PGASYNC_COPY_BOTH)
01688     {
01689         if (pqPutMsgStart('c', false, conn) < 0 ||
01690             pqPutMsgEnd(conn) < 0)
01691             return 1;
01692 
01693         /*
01694          * If we sent the COPY command in extended-query mode, we must issue a
01695          * Sync as well.
01696          */
01697         if (conn->queryclass != PGQUERY_SIMPLE)
01698         {
01699             if (pqPutMsgStart('S', false, conn) < 0 ||
01700                 pqPutMsgEnd(conn) < 0)
01701                 return 1;
01702         }
01703     }
01704 
01705     /*
01706      * make sure no data is waiting to be sent, abort if we are non-blocking
01707      * and the flush fails
01708      */
01709     if (pqFlush(conn) && pqIsnonblocking(conn))
01710         return 1;
01711 
01712     /* Return to active duty */
01713     conn->asyncStatus = PGASYNC_BUSY;
01714     resetPQExpBuffer(&conn->errorMessage);
01715 
01716     /*
01717      * Non blocking connections may have to abort at this point.  If everyone
01718      * played the game there should be no problem, but in error scenarios the
01719      * expected messages may not have arrived yet.  (We are assuming that the
01720      * backend's packetizing will ensure that CommandComplete arrives along
01721      * with the CopyDone; are there corner cases where that doesn't happen?)
01722      */
01723     if (pqIsnonblocking(conn) && PQisBusy(conn))
01724         return 1;
01725 
01726     /* Wait for the completion response */
01727     result = PQgetResult(conn);
01728 
01729     /* Expecting a successful result */
01730     if (result && result->resultStatus == PGRES_COMMAND_OK)
01731     {
01732         PQclear(result);
01733         return 0;
01734     }
01735 
01736     /*
01737      * Trouble. For backwards-compatibility reasons, we issue the error
01738      * message as if it were a notice (would be nice to get rid of this
01739      * silliness, but too many apps probably don't handle errors from
01740      * PQendcopy reasonably).  Note that the app can still obtain the error
01741      * status from the PGconn object.
01742      */
01743     if (conn->errorMessage.len > 0)
01744     {
01745         /* We have to strip the trailing newline ... pain in neck... */
01746         char        svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
01747 
01748         if (svLast == '\n')
01749             conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
01750         pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
01751         conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
01752     }
01753 
01754     PQclear(result);
01755 
01756     return 1;
01757 }
01758 
01759 
01760 /*
01761  * PQfn - Send a function call to the POSTGRES backend.
01762  *
01763  * See fe-exec.c for documentation.
01764  */
01765 PGresult *
01766 pqFunctionCall3(PGconn *conn, Oid fnid,
01767                 int *result_buf, int *actual_result_len,
01768                 int result_is_int,
01769                 const PQArgBlock *args, int nargs)
01770 {
01771     bool        needInput = false;
01772     ExecStatusType status = PGRES_FATAL_ERROR;
01773     char        id;
01774     int         msgLength;
01775     int         avail;
01776     int         i;
01777 
01778     /* PQfn already validated connection state */
01779 
01780     if (pqPutMsgStart('F', false, conn) < 0 ||  /* function call msg */
01781         pqPutInt(fnid, 4, conn) < 0 ||  /* function id */
01782         pqPutInt(1, 2, conn) < 0 ||     /* # of format codes */
01783         pqPutInt(1, 2, conn) < 0 ||     /* format code: BINARY */
01784         pqPutInt(nargs, 2, conn) < 0)   /* # of args */
01785     {
01786         pqHandleSendFailure(conn);
01787         return NULL;
01788     }
01789 
01790     for (i = 0; i < nargs; ++i)
01791     {                           /* len.int4 + contents     */
01792         if (pqPutInt(args[i].len, 4, conn))
01793         {
01794             pqHandleSendFailure(conn);
01795             return NULL;
01796         }
01797         if (args[i].len == -1)
01798             continue;           /* it's NULL */
01799 
01800         if (args[i].isint)
01801         {
01802             if (pqPutInt(args[i].u.integer, args[i].len, conn))
01803             {
01804                 pqHandleSendFailure(conn);
01805                 return NULL;
01806             }
01807         }
01808         else
01809         {
01810             if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
01811             {
01812                 pqHandleSendFailure(conn);
01813                 return NULL;
01814             }
01815         }
01816     }
01817 
01818     if (pqPutInt(1, 2, conn) < 0)       /* result format code: BINARY */
01819     {
01820         pqHandleSendFailure(conn);
01821         return NULL;
01822     }
01823 
01824     if (pqPutMsgEnd(conn) < 0 ||
01825         pqFlush(conn))
01826     {
01827         pqHandleSendFailure(conn);
01828         return NULL;
01829     }
01830 
01831     for (;;)
01832     {
01833         if (needInput)
01834         {
01835             /* Wait for some data to arrive (or for the channel to close) */
01836             if (pqWait(TRUE, FALSE, conn) ||
01837                 pqReadData(conn) < 0)
01838                 break;
01839         }
01840 
01841         /*
01842          * Scan the message. If we run out of data, loop around to try again.
01843          */
01844         needInput = true;
01845 
01846         conn->inCursor = conn->inStart;
01847         if (pqGetc(&id, conn))
01848             continue;
01849         if (pqGetInt(&msgLength, 4, conn))
01850             continue;
01851 
01852         /*
01853          * Try to validate message type/length here.  A length less than 4 is
01854          * definitely broken.  Large lengths should only be believed for a few
01855          * message types.
01856          */
01857         if (msgLength < 4)
01858         {
01859             handleSyncLoss(conn, id, msgLength);
01860             break;
01861         }
01862         if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
01863         {
01864             handleSyncLoss(conn, id, msgLength);
01865             break;
01866         }
01867 
01868         /*
01869          * Can't process if message body isn't all here yet.
01870          */
01871         msgLength -= 4;
01872         avail = conn->inEnd - conn->inCursor;
01873         if (avail < msgLength)
01874         {
01875             /*
01876              * Before looping, enlarge the input buffer if needed to hold the
01877              * whole message.  See notes in parseInput.
01878              */
01879             if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
01880                                      conn))
01881             {
01882                 /*
01883                  * XXX add some better recovery code... plan is to skip over
01884                  * the message using its length, then report an error. For the
01885                  * moment, just treat this like loss of sync (which indeed it
01886                  * might be!)
01887                  */
01888                 handleSyncLoss(conn, id, msgLength);
01889                 break;
01890             }
01891             continue;
01892         }
01893 
01894         /*
01895          * We should see V or E response to the command, but might get N
01896          * and/or A notices first. We also need to swallow the final Z before
01897          * returning.
01898          */
01899         switch (id)
01900         {
01901             case 'V':           /* function result */
01902                 if (pqGetInt(actual_result_len, 4, conn))
01903                     continue;
01904                 if (*actual_result_len != -1)
01905                 {
01906                     if (result_is_int)
01907                     {
01908                         if (pqGetInt(result_buf, *actual_result_len, conn))
01909                             continue;
01910                     }
01911                     else
01912                     {
01913                         if (pqGetnchar((char *) result_buf,
01914                                        *actual_result_len,
01915                                        conn))
01916                             continue;
01917                     }
01918                 }
01919                 /* correctly finished function result message */
01920                 status = PGRES_COMMAND_OK;
01921                 break;
01922             case 'E':           /* error return */
01923                 if (pqGetErrorNotice3(conn, true))
01924                     continue;
01925                 status = PGRES_FATAL_ERROR;
01926                 break;
01927             case 'A':           /* notify message */
01928                 /* handle notify and go back to processing return values */
01929                 if (getNotify(conn))
01930                     continue;
01931                 break;
01932             case 'N':           /* notice */
01933                 /* handle notice and go back to processing return values */
01934                 if (pqGetErrorNotice3(conn, false))
01935                     continue;
01936                 break;
01937             case 'Z':           /* backend is ready for new query */
01938                 if (getReadyForQuery(conn))
01939                     continue;
01940                 /* consume the message and exit */
01941                 conn->inStart += 5 + msgLength;
01942                 /* if we saved a result object (probably an error), use it */
01943                 if (conn->result)
01944                     return pqPrepareAsyncResult(conn);
01945                 return PQmakeEmptyPGresult(conn, status);
01946             case 'S':           /* parameter status */
01947                 if (getParameterStatus(conn))
01948                     continue;
01949                 break;
01950             default:
01951                 /* The backend violates the protocol. */
01952                 printfPQExpBuffer(&conn->errorMessage,
01953                                   libpq_gettext("protocol error: id=0x%x\n"),
01954                                   id);
01955                 pqSaveErrorResult(conn);
01956                 /* trust the specified message length as what to skip */
01957                 conn->inStart += 5 + msgLength;
01958                 return pqPrepareAsyncResult(conn);
01959         }
01960         /* Completed this message, keep going */
01961         /* trust the specified message length as what to skip */
01962         conn->inStart += 5 + msgLength;
01963         needInput = false;
01964     }
01965 
01966     /*
01967      * We fall out of the loop only upon failing to read data.
01968      * conn->errorMessage has been set by pqWait or pqReadData. We want to
01969      * append it to any already-received error message.
01970      */
01971     pqSaveErrorResult(conn);
01972     return pqPrepareAsyncResult(conn);
01973 }
01974 
01975 
01976 /*
01977  * Construct startup packet
01978  *
01979  * Returns a malloc'd packet buffer, or NULL if out of memory
01980  */
01981 char *
01982 pqBuildStartupPacket3(PGconn *conn, int *packetlen,
01983                       const PQEnvironmentOption *options)
01984 {
01985     char       *startpacket;
01986 
01987     *packetlen = build_startup_packet(conn, NULL, options);
01988     startpacket = (char *) malloc(*packetlen);
01989     if (!startpacket)
01990         return NULL;
01991     *packetlen = build_startup_packet(conn, startpacket, options);
01992     return startpacket;
01993 }
01994 
01995 /*
01996  * Build a startup packet given a filled-in PGconn structure.
01997  *
01998  * We need to figure out how much space is needed, then fill it in.
01999  * To avoid duplicate logic, this routine is called twice: the first time
02000  * (with packet == NULL) just counts the space needed, the second time
02001  * (with packet == allocated space) fills it in.  Return value is the number
02002  * of bytes used.
02003  */
02004 static int
02005 build_startup_packet(const PGconn *conn, char *packet,
02006                      const PQEnvironmentOption *options)
02007 {
02008     int         packet_len = 0;
02009     const PQEnvironmentOption *next_eo;
02010     const char *val;
02011 
02012     /* Protocol version comes first. */
02013     if (packet)
02014     {
02015         ProtocolVersion pv = htonl(conn->pversion);
02016 
02017         memcpy(packet + packet_len, &pv, sizeof(ProtocolVersion));
02018     }
02019     packet_len += sizeof(ProtocolVersion);
02020 
02021     /* Add user name, database name, options */
02022 
02023 #define ADD_STARTUP_OPTION(optname, optval) \
02024     do { \
02025         if (packet) \
02026             strcpy(packet + packet_len, optname); \
02027         packet_len += strlen(optname) + 1; \
02028         if (packet) \
02029             strcpy(packet + packet_len, optval); \
02030         packet_len += strlen(optval) + 1; \
02031     } while(0)
02032 
02033     if (conn->pguser && conn->pguser[0])
02034         ADD_STARTUP_OPTION("user", conn->pguser);
02035     if (conn->dbName && conn->dbName[0])
02036         ADD_STARTUP_OPTION("database", conn->dbName);
02037     if (conn->replication && conn->replication[0])
02038         ADD_STARTUP_OPTION("replication", conn->replication);
02039     if (conn->pgoptions && conn->pgoptions[0])
02040         ADD_STARTUP_OPTION("options", conn->pgoptions);
02041     if (conn->send_appname)
02042     {
02043         /* Use appname if present, otherwise use fallback */
02044         val = conn->appname ? conn->appname : conn->fbappname;
02045         if (val && val[0])
02046             ADD_STARTUP_OPTION("application_name", val);
02047     }
02048 
02049     if (conn->client_encoding_initial && conn->client_encoding_initial[0])
02050         ADD_STARTUP_OPTION("client_encoding", conn->client_encoding_initial);
02051 
02052     /* Add any environment-driven GUC settings needed */
02053     for (next_eo = options; next_eo->envName; next_eo++)
02054     {
02055         if ((val = getenv(next_eo->envName)) != NULL)
02056         {
02057             if (pg_strcasecmp(val, "default") != 0)
02058                 ADD_STARTUP_OPTION(next_eo->pgName, val);
02059         }
02060     }
02061 
02062     /* Add trailing terminator */
02063     if (packet)
02064         packet[packet_len] = '\0';
02065     packet_len++;
02066 
02067     return packet_len;
02068 }