LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-exec.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 961 1588 60.5 %
Date: 2024-04-24 19:11:33 Functions: 97 118 82.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * fe-exec.c
       4             :  *    functions related to sending a query down to the backend
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/interfaces/libpq/fe-exec.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres_fe.h"
      16             : 
      17             : #include <ctype.h>
      18             : #include <fcntl.h>
      19             : #include <limits.h>
      20             : 
      21             : #ifdef WIN32
      22             : #include "win32.h"
      23             : #else
      24             : #include <unistd.h>
      25             : #endif
      26             : 
      27             : #include "libpq-fe.h"
      28             : #include "libpq-int.h"
      29             : #include "mb/pg_wchar.h"
      30             : 
      31             : /* keep this in same order as ExecStatusType in libpq-fe.h */
      32             : char       *const pgresStatus[] = {
      33             :     "PGRES_EMPTY_QUERY",
      34             :     "PGRES_COMMAND_OK",
      35             :     "PGRES_TUPLES_OK",
      36             :     "PGRES_COPY_OUT",
      37             :     "PGRES_COPY_IN",
      38             :     "PGRES_BAD_RESPONSE",
      39             :     "PGRES_NONFATAL_ERROR",
      40             :     "PGRES_FATAL_ERROR",
      41             :     "PGRES_COPY_BOTH",
      42             :     "PGRES_SINGLE_TUPLE",
      43             :     "PGRES_PIPELINE_SYNC",
      44             :     "PGRES_PIPELINE_ABORTED",
      45             :     "PGRES_TUPLES_CHUNK"
      46             : };
      47             : 
      48             : /* We return this if we're unable to make a PGresult at all */
      49             : static const PGresult OOM_result = {
      50             :     .resultStatus = PGRES_FATAL_ERROR,
      51             :     .client_encoding = PG_SQL_ASCII,
      52             :     .errMsg = "out of memory\n",
      53             : };
      54             : 
      55             : /*
      56             :  * static state needed by PQescapeString and PQescapeBytea; initialize to
      57             :  * values that result in backward-compatible behavior
      58             :  */
      59             : static int  static_client_encoding = PG_SQL_ASCII;
      60             : static bool static_std_strings = false;
      61             : 
      62             : 
      63             : static PGEvent *dupEvents(PGEvent *events, int count, size_t *memSize);
      64             : static bool pqAddTuple(PGresult *res, PGresAttValue *tup,
      65             :                        const char **errmsgp);
      66             : static int  PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery);
      67             : static bool PQsendQueryStart(PGconn *conn, bool newQuery);
      68             : static int  PQsendQueryGuts(PGconn *conn,
      69             :                             const char *command,
      70             :                             const char *stmtName,
      71             :                             int nParams,
      72             :                             const Oid *paramTypes,
      73             :                             const char *const *paramValues,
      74             :                             const int *paramLengths,
      75             :                             const int *paramFormats,
      76             :                             int resultFormat);
      77             : static void parseInput(PGconn *conn);
      78             : static PGresult *getCopyResult(PGconn *conn, ExecStatusType copytype);
      79             : static bool PQexecStart(PGconn *conn);
      80             : static PGresult *PQexecFinish(PGconn *conn);
      81             : static int  PQsendTypedCommand(PGconn *conn, char command, char type,
      82             :                                const char *target);
      83             : static int  check_field_number(const PGresult *res, int field_num);
      84             : static void pqPipelineProcessQueue(PGconn *conn);
      85             : static int  pqPipelineSyncInternal(PGconn *conn, bool immediate_flush);
      86             : static int  pqPipelineFlush(PGconn *conn);
      87             : 
      88             : 
      89             : /* ----------------
      90             :  * Space management for PGresult.
      91             :  *
      92             :  * Formerly, libpq did a separate malloc() for each field of each tuple
      93             :  * returned by a query.  This was remarkably expensive --- malloc/free
      94             :  * consumed a sizable part of the application's runtime.  And there is
      95             :  * no real need to keep track of the fields separately, since they will
      96             :  * all be freed together when the PGresult is released.  So now, we grab
      97             :  * large blocks of storage from malloc and allocate space for query data
      98             :  * within these blocks, using a trivially simple allocator.  This reduces
      99             :  * the number of malloc/free calls dramatically, and it also avoids
     100             :  * fragmentation of the malloc storage arena.
     101             :  * The PGresult structure itself is still malloc'd separately.  We could
     102             :  * combine it with the first allocation block, but that would waste space
     103             :  * for the common case that no extra storage is actually needed (that is,
     104             :  * the SQL command did not return tuples).
     105             :  *
     106             :  * We also malloc the top-level array of tuple pointers separately, because
     107             :  * we need to be able to enlarge it via realloc, and our trivial space
     108             :  * allocator doesn't handle that effectively.  (Too bad the FE/BE protocol
     109             :  * doesn't tell us up front how many tuples will be returned.)
     110             :  * All other subsidiary storage for a PGresult is kept in PGresult_data blocks
     111             :  * of size PGRESULT_DATA_BLOCKSIZE.  The overhead at the start of each block
     112             :  * is just a link to the next one, if any.  Free-space management info is
     113             :  * kept in the owning PGresult.
     114             :  * A query returning a small amount of data will thus require three malloc
     115             :  * calls: one for the PGresult, one for the tuples pointer array, and one
     116             :  * PGresult_data block.
     117             :  *
     118             :  * Only the most recently allocated PGresult_data block is a candidate to
     119             :  * have more stuff added to it --- any extra space left over in older blocks
     120             :  * is wasted.  We could be smarter and search the whole chain, but the point
     121             :  * here is to be simple and fast.  Typical applications do not keep a PGresult
     122             :  * around very long anyway, so some wasted space within one is not a problem.
     123             :  *
     124             :  * Tuning constants for the space allocator are:
     125             :  * PGRESULT_DATA_BLOCKSIZE: size of a standard allocation block, in bytes
     126             :  * PGRESULT_ALIGN_BOUNDARY: assumed alignment requirement for binary data
     127             :  * PGRESULT_SEP_ALLOC_THRESHOLD: objects bigger than this are given separate
     128             :  *   blocks, instead of being crammed into a regular allocation block.
     129             :  * Requirements for correct function are:
     130             :  * PGRESULT_ALIGN_BOUNDARY must be a multiple of the alignment requirements
     131             :  *      of all machine data types.  (Currently this is set from configure
     132             :  *      tests, so it should be OK automatically.)
     133             :  * PGRESULT_SEP_ALLOC_THRESHOLD + PGRESULT_BLOCK_OVERHEAD <=
     134             :  *          PGRESULT_DATA_BLOCKSIZE
     135             :  *      pqResultAlloc assumes an object smaller than the threshold will fit
     136             :  *      in a new block.
     137             :  * The amount of space wasted at the end of a block could be as much as
     138             :  * PGRESULT_SEP_ALLOC_THRESHOLD, so it doesn't pay to make that too large.
     139             :  * ----------------
     140             :  */
     141             : 
     142             : #define PGRESULT_DATA_BLOCKSIZE     2048
     143             : #define PGRESULT_ALIGN_BOUNDARY     MAXIMUM_ALIGNOF /* from configure */
     144             : #define PGRESULT_BLOCK_OVERHEAD     Max(sizeof(PGresult_data), PGRESULT_ALIGN_BOUNDARY)
     145             : #define PGRESULT_SEP_ALLOC_THRESHOLD    (PGRESULT_DATA_BLOCKSIZE / 2)
     146             : 
     147             : 
     148             : /*
     149             :  * PQmakeEmptyPGresult
     150             :  *   returns a newly allocated, initialized PGresult with given status.
     151             :  *   If conn is not NULL and status indicates an error, the conn's
     152             :  *   errorMessage is copied.  Also, any PGEvents are copied from the conn.
     153             :  *
     154             :  * Note: the logic to copy the conn's errorMessage is now vestigial;
     155             :  * no internal caller uses it.  However, that behavior is documented for
     156             :  * outside callers, so we'd better keep it.
     157             :  */
     158             : PGresult *
     159     3844952 : PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
     160             : {
     161             :     PGresult   *result;
     162             : 
     163     3844952 :     result = (PGresult *) malloc(sizeof(PGresult));
     164     3844952 :     if (!result)
     165           0 :         return NULL;
     166             : 
     167     3844952 :     result->ntups = 0;
     168     3844952 :     result->numAttributes = 0;
     169     3844952 :     result->attDescs = NULL;
     170     3844952 :     result->tuples = NULL;
     171     3844952 :     result->tupArrSize = 0;
     172     3844952 :     result->numParameters = 0;
     173     3844952 :     result->paramDescs = NULL;
     174     3844952 :     result->resultStatus = status;
     175     3844952 :     result->cmdStatus[0] = '\0';
     176     3844952 :     result->binary = 0;
     177     3844952 :     result->events = NULL;
     178     3844952 :     result->nEvents = 0;
     179     3844952 :     result->errMsg = NULL;
     180     3844952 :     result->errFields = NULL;
     181     3844952 :     result->errQuery = NULL;
     182     3844952 :     result->null_field[0] = '\0';
     183     3844952 :     result->curBlock = NULL;
     184     3844952 :     result->curOffset = 0;
     185     3844952 :     result->spaceLeft = 0;
     186     3844952 :     result->memorySize = sizeof(PGresult);
     187             : 
     188     3844952 :     if (conn)
     189             :     {
     190             :         /* copy connection data we might need for operations on PGresult */
     191      639626 :         result->noticeHooks = conn->noticeHooks;
     192      639626 :         result->client_encoding = conn->client_encoding;
     193             : 
     194             :         /* consider copying conn's errorMessage */
     195      639626 :         switch (status)
     196             :         {
     197      639128 :             case PGRES_EMPTY_QUERY:
     198             :             case PGRES_COMMAND_OK:
     199             :             case PGRES_TUPLES_OK:
     200             :             case PGRES_COPY_OUT:
     201             :             case PGRES_COPY_IN:
     202             :             case PGRES_COPY_BOTH:
     203             :             case PGRES_SINGLE_TUPLE:
     204             :             case PGRES_TUPLES_CHUNK:
     205             :                 /* non-error cases */
     206      639128 :                 break;
     207         498 :             default:
     208             :                 /* we intentionally do not use or modify errorReported here */
     209         498 :                 pqSetResultError(result, &conn->errorMessage, 0);
     210         498 :                 break;
     211             :         }
     212             : 
     213             :         /* copy events last; result must be valid if we need to PQclear */
     214      639626 :         if (conn->nEvents > 0)
     215             :         {
     216           0 :             result->events = dupEvents(conn->events, conn->nEvents,
     217             :                                        &result->memorySize);
     218           0 :             if (!result->events)
     219             :             {
     220           0 :                 PQclear(result);
     221           0 :                 return NULL;
     222             :             }
     223           0 :             result->nEvents = conn->nEvents;
     224             :         }
     225             :     }
     226             :     else
     227             :     {
     228             :         /* defaults... */
     229     3205326 :         result->noticeHooks.noticeRec = NULL;
     230     3205326 :         result->noticeHooks.noticeRecArg = NULL;
     231     3205326 :         result->noticeHooks.noticeProc = NULL;
     232     3205326 :         result->noticeHooks.noticeProcArg = NULL;
     233     3205326 :         result->client_encoding = PG_SQL_ASCII;
     234             :     }
     235             : 
     236     3844952 :     return result;
     237             : }
     238             : 
     239             : /*
     240             :  * PQsetResultAttrs
     241             :  *
     242             :  * Set the attributes for a given result.  This function fails if there are
     243             :  * already attributes contained in the provided result.  The call is
     244             :  * ignored if numAttributes is zero or attDescs is NULL.  If the
     245             :  * function fails, it returns zero.  If the function succeeds, it
     246             :  * returns a non-zero value.
     247             :  */
     248             : int
     249        5258 : PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs)
     250             : {
     251             :     int         i;
     252             : 
     253             :     /* Fail if argument is NULL or OOM_result */
     254        5258 :     if (!res || (const PGresult *) res == &OOM_result)
     255           0 :         return false;
     256             : 
     257             :     /* If attrs already exist, they cannot be overwritten. */
     258        5258 :     if (res->numAttributes > 0)
     259           0 :         return false;
     260             : 
     261             :     /* ignore no-op request */
     262        5258 :     if (numAttributes <= 0 || !attDescs)
     263           0 :         return true;
     264             : 
     265        5258 :     res->attDescs = (PGresAttDesc *)
     266        5258 :         PQresultAlloc(res, numAttributes * sizeof(PGresAttDesc));
     267             : 
     268        5258 :     if (!res->attDescs)
     269           0 :         return false;
     270             : 
     271        5258 :     res->numAttributes = numAttributes;
     272        5258 :     memcpy(res->attDescs, attDescs, numAttributes * sizeof(PGresAttDesc));
     273             : 
     274             :     /* deep-copy the attribute names, and determine format */
     275        5258 :     res->binary = 1;
     276       20824 :     for (i = 0; i < res->numAttributes; i++)
     277             :     {
     278       15566 :         if (res->attDescs[i].name)
     279       15566 :             res->attDescs[i].name = pqResultStrdup(res, res->attDescs[i].name);
     280             :         else
     281           0 :             res->attDescs[i].name = res->null_field;
     282             : 
     283       15566 :         if (!res->attDescs[i].name)
     284           0 :             return false;
     285             : 
     286       15566 :         if (res->attDescs[i].format == 0)
     287         914 :             res->binary = 0;
     288             :     }
     289             : 
     290        5258 :     return true;
     291             : }
     292             : 
     293             : /*
     294             :  * PQcopyResult
     295             :  *
     296             :  * Returns a deep copy of the provided 'src' PGresult, which cannot be NULL.
     297             :  * The 'flags' argument controls which portions of the result will or will
     298             :  * NOT be copied.  The created result is always put into the
     299             :  * PGRES_TUPLES_OK status.  The source result error message is not copied,
     300             :  * although cmdStatus is.
     301             :  *
     302             :  * To set custom attributes, use PQsetResultAttrs.  That function requires
     303             :  * that there are no attrs contained in the result, so to use that
     304             :  * function you cannot use the PG_COPYRES_ATTRS or PG_COPYRES_TUPLES
     305             :  * options with this function.
     306             :  *
     307             :  * Options:
     308             :  *   PG_COPYRES_ATTRS - Copy the source result's attributes
     309             :  *
     310             :  *   PG_COPYRES_TUPLES - Copy the source result's tuples.  This implies
     311             :  *   copying the attrs, seeing how the attrs are needed by the tuples.
     312             :  *
     313             :  *   PG_COPYRES_EVENTS - Copy the source result's events.
     314             :  *
     315             :  *   PG_COPYRES_NOTICEHOOKS - Copy the source result's notice hooks.
     316             :  */
     317             : PGresult *
     318        5258 : PQcopyResult(const PGresult *src, int flags)
     319             : {
     320             :     PGresult   *dest;
     321             :     int         i;
     322             : 
     323        5258 :     if (!src)
     324           0 :         return NULL;
     325             : 
     326        5258 :     dest = PQmakeEmptyPGresult(NULL, PGRES_TUPLES_OK);
     327        5258 :     if (!dest)
     328           0 :         return NULL;
     329             : 
     330             :     /* Always copy these over.  Is cmdStatus really useful here? */
     331        5258 :     dest->client_encoding = src->client_encoding;
     332        5258 :     strcpy(dest->cmdStatus, src->cmdStatus);
     333             : 
     334             :     /* Wants attrs? */
     335        5258 :     if (flags & (PG_COPYRES_ATTRS | PG_COPYRES_TUPLES))
     336             :     {
     337        5258 :         if (!PQsetResultAttrs(dest, src->numAttributes, src->attDescs))
     338             :         {
     339           0 :             PQclear(dest);
     340           0 :             return NULL;
     341             :         }
     342             :     }
     343             : 
     344             :     /* Wants to copy tuples? */
     345        5258 :     if (flags & PG_COPYRES_TUPLES)
     346             :     {
     347             :         int         tup,
     348             :                     field;
     349             : 
     350           0 :         for (tup = 0; tup < src->ntups; tup++)
     351             :         {
     352           0 :             for (field = 0; field < src->numAttributes; field++)
     353             :             {
     354           0 :                 if (!PQsetvalue(dest, tup, field,
     355           0 :                                 src->tuples[tup][field].value,
     356           0 :                                 src->tuples[tup][field].len))
     357             :                 {
     358           0 :                     PQclear(dest);
     359           0 :                     return NULL;
     360             :                 }
     361             :             }
     362             :         }
     363             :     }
     364             : 
     365             :     /* Wants to copy notice hooks? */
     366        5258 :     if (flags & PG_COPYRES_NOTICEHOOKS)
     367        5258 :         dest->noticeHooks = src->noticeHooks;
     368             : 
     369             :     /* Wants to copy PGEvents? */
     370        5258 :     if ((flags & PG_COPYRES_EVENTS) && src->nEvents > 0)
     371             :     {
     372           0 :         dest->events = dupEvents(src->events, src->nEvents,
     373             :                                  &dest->memorySize);
     374           0 :         if (!dest->events)
     375             :         {
     376           0 :             PQclear(dest);
     377           0 :             return NULL;
     378             :         }
     379           0 :         dest->nEvents = src->nEvents;
     380             :     }
     381             : 
     382             :     /* Okay, trigger PGEVT_RESULTCOPY event */
     383        5258 :     for (i = 0; i < dest->nEvents; i++)
     384             :     {
     385             :         /* We don't fire events that had some previous failure */
     386           0 :         if (src->events[i].resultInitialized)
     387             :         {
     388             :             PGEventResultCopy evt;
     389             : 
     390           0 :             evt.src = src;
     391           0 :             evt.dest = dest;
     392           0 :             if (dest->events[i].proc(PGEVT_RESULTCOPY, &evt,
     393           0 :                                      dest->events[i].passThrough))
     394           0 :                 dest->events[i].resultInitialized = true;
     395             :         }
     396             :     }
     397             : 
     398        5258 :     return dest;
     399             : }
     400             : 
     401             : /*
     402             :  * Copy an array of PGEvents (with no extra space for more).
     403             :  * Does not duplicate the event instance data, sets this to NULL.
     404             :  * Also, the resultInitialized flags are all cleared.
     405             :  * The total space allocated is added to *memSize.
     406             :  */
     407             : static PGEvent *
     408           0 : dupEvents(PGEvent *events, int count, size_t *memSize)
     409             : {
     410             :     PGEvent    *newEvents;
     411             :     size_t      msize;
     412             :     int         i;
     413             : 
     414           0 :     if (!events || count <= 0)
     415           0 :         return NULL;
     416             : 
     417           0 :     msize = count * sizeof(PGEvent);
     418           0 :     newEvents = (PGEvent *) malloc(msize);
     419           0 :     if (!newEvents)
     420           0 :         return NULL;
     421             : 
     422           0 :     for (i = 0; i < count; i++)
     423             :     {
     424           0 :         newEvents[i].proc = events[i].proc;
     425           0 :         newEvents[i].passThrough = events[i].passThrough;
     426           0 :         newEvents[i].data = NULL;
     427           0 :         newEvents[i].resultInitialized = false;
     428           0 :         newEvents[i].name = strdup(events[i].name);
     429           0 :         if (!newEvents[i].name)
     430             :         {
     431           0 :             while (--i >= 0)
     432           0 :                 free(newEvents[i].name);
     433           0 :             free(newEvents);
     434           0 :             return NULL;
     435             :         }
     436           0 :         msize += strlen(events[i].name) + 1;
     437             :     }
     438             : 
     439           0 :     *memSize += msize;
     440           0 :     return newEvents;
     441             : }
     442             : 
     443             : 
     444             : /*
     445             :  * Sets the value for a tuple field.  The tup_num must be less than or
     446             :  * equal to PQntuples(res).  If it is equal, a new tuple is created and
     447             :  * added to the result.
     448             :  * Returns a non-zero value for success and zero for failure.
     449             :  * (On failure, we report the specific problem via pqInternalNotice.)
     450             :  */
     451             : int
     452           0 : PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len)
     453             : {
     454             :     PGresAttValue *attval;
     455           0 :     const char *errmsg = NULL;
     456             : 
     457             :     /* Fail if argument is NULL or OOM_result */
     458           0 :     if (!res || (const PGresult *) res == &OOM_result)
     459           0 :         return false;
     460             : 
     461             :     /* Invalid field_num? */
     462           0 :     if (!check_field_number(res, field_num))
     463           0 :         return false;
     464             : 
     465             :     /* Invalid tup_num, must be <= ntups */
     466           0 :     if (tup_num < 0 || tup_num > res->ntups)
     467             :     {
     468           0 :         pqInternalNotice(&res->noticeHooks,
     469             :                          "row number %d is out of range 0..%d",
     470             :                          tup_num, res->ntups);
     471           0 :         return false;
     472             :     }
     473             : 
     474             :     /* need to allocate a new tuple? */
     475           0 :     if (tup_num == res->ntups)
     476             :     {
     477             :         PGresAttValue *tup;
     478             :         int         i;
     479             : 
     480             :         tup = (PGresAttValue *)
     481           0 :             pqResultAlloc(res, res->numAttributes * sizeof(PGresAttValue),
     482             :                           true);
     483             : 
     484           0 :         if (!tup)
     485           0 :             goto fail;
     486             : 
     487             :         /* initialize each column to NULL */
     488           0 :         for (i = 0; i < res->numAttributes; i++)
     489             :         {
     490           0 :             tup[i].len = NULL_LEN;
     491           0 :             tup[i].value = res->null_field;
     492             :         }
     493             : 
     494             :         /* add it to the array */
     495           0 :         if (!pqAddTuple(res, tup, &errmsg))
     496           0 :             goto fail;
     497             :     }
     498             : 
     499           0 :     attval = &res->tuples[tup_num][field_num];
     500             : 
     501             :     /* treat either NULL_LEN or NULL value pointer as a NULL field */
     502           0 :     if (len == NULL_LEN || value == NULL)
     503             :     {
     504           0 :         attval->len = NULL_LEN;
     505           0 :         attval->value = res->null_field;
     506             :     }
     507           0 :     else if (len <= 0)
     508             :     {
     509           0 :         attval->len = 0;
     510           0 :         attval->value = res->null_field;
     511             :     }
     512             :     else
     513             :     {
     514           0 :         attval->value = (char *) pqResultAlloc(res, len + 1, true);
     515           0 :         if (!attval->value)
     516           0 :             goto fail;
     517           0 :         attval->len = len;
     518           0 :         memcpy(attval->value, value, len);
     519           0 :         attval->value[len] = '\0';
     520             :     }
     521             : 
     522           0 :     return true;
     523             : 
     524             :     /*
     525             :      * Report failure via pqInternalNotice.  If preceding code didn't provide
     526             :      * an error message, assume "out of memory" was meant.
     527             :      */
     528           0 : fail:
     529           0 :     if (!errmsg)
     530           0 :         errmsg = libpq_gettext("out of memory");
     531           0 :     pqInternalNotice(&res->noticeHooks, "%s", errmsg);
     532             : 
     533           0 :     return false;
     534             : }
     535             : 
     536             : /*
     537             :  * pqResultAlloc - exported routine to allocate local storage in a PGresult.
     538             :  *
     539             :  * We force all such allocations to be maxaligned, since we don't know
     540             :  * whether the value might be binary.
     541             :  */
     542             : void *
     543        5258 : PQresultAlloc(PGresult *res, size_t nBytes)
     544             : {
     545             :     /* Fail if argument is NULL or OOM_result */
     546        5258 :     if (!res || (const PGresult *) res == &OOM_result)
     547           0 :         return NULL;
     548             : 
     549        5258 :     return pqResultAlloc(res, nBytes, true);
     550             : }
     551             : 
     552             : /*
     553             :  * pqResultAlloc -
     554             :  *      Allocate subsidiary storage for a PGresult.
     555             :  *
     556             :  * nBytes is the amount of space needed for the object.
     557             :  * If isBinary is true, we assume that we need to align the object on
     558             :  * a machine allocation boundary.
     559             :  * If isBinary is false, we assume the object is a char string and can
     560             :  * be allocated on any byte boundary.
     561             :  */
     562             : void *
     563    35754510 : pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
     564             : {
     565             :     char       *space;
     566             :     PGresult_data *block;
     567             : 
     568    35754510 :     if (!res)
     569           0 :         return NULL;
     570             : 
     571    35754510 :     if (nBytes <= 0)
     572         224 :         return res->null_field;
     573             : 
     574             :     /*
     575             :      * If alignment is needed, round up the current position to an alignment
     576             :      * boundary.
     577             :      */
     578    35754286 :     if (isBinary)
     579             :     {
     580     7122560 :         int         offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY;
     581             : 
     582     7122560 :         if (offset)
     583             :         {
     584     5461422 :             res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset;
     585     5461422 :             res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset;
     586             :         }
     587             :     }
     588             : 
     589             :     /* If there's enough space in the current block, no problem. */
     590    35754286 :     if (nBytes <= (size_t) res->spaceLeft)
     591             :     {
     592    35082440 :         space = res->curBlock->space + res->curOffset;
     593    35082440 :         res->curOffset += nBytes;
     594    35082440 :         res->spaceLeft -= nBytes;
     595    35082440 :         return space;
     596             :     }
     597             : 
     598             :     /*
     599             :      * If the requested object is very large, give it its own block; this
     600             :      * avoids wasting what might be most of the current block to start a new
     601             :      * block.  (We'd have to special-case requests bigger than the block size
     602             :      * anyway.)  The object is always given binary alignment in this case.
     603             :      */
     604      671846 :     if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD)
     605             :     {
     606        5316 :         size_t      alloc_size = nBytes + PGRESULT_BLOCK_OVERHEAD;
     607             : 
     608        5316 :         block = (PGresult_data *) malloc(alloc_size);
     609        5316 :         if (!block)
     610           0 :             return NULL;
     611        5316 :         res->memorySize += alloc_size;
     612        5316 :         space = block->space + PGRESULT_BLOCK_OVERHEAD;
     613        5316 :         if (res->curBlock)
     614             :         {
     615             :             /*
     616             :              * Tuck special block below the active block, so that we don't
     617             :              * have to waste the free space in the active block.
     618             :              */
     619        4944 :             block->next = res->curBlock->next;
     620        4944 :             res->curBlock->next = block;
     621             :         }
     622             :         else
     623             :         {
     624             :             /* Must set up the new block as the first active block. */
     625         372 :             block->next = NULL;
     626         372 :             res->curBlock = block;
     627         372 :             res->spaceLeft = 0; /* be sure it's marked full */
     628             :         }
     629        5316 :         return space;
     630             :     }
     631             : 
     632             :     /* Otherwise, start a new block. */
     633      666530 :     block = (PGresult_data *) malloc(PGRESULT_DATA_BLOCKSIZE);
     634      666530 :     if (!block)
     635           0 :         return NULL;
     636      666530 :     res->memorySize += PGRESULT_DATA_BLOCKSIZE;
     637      666530 :     block->next = res->curBlock;
     638      666530 :     res->curBlock = block;
     639      666530 :     if (isBinary)
     640             :     {
     641             :         /* object needs full alignment */
     642      593784 :         res->curOffset = PGRESULT_BLOCK_OVERHEAD;
     643      593784 :         res->spaceLeft = PGRESULT_DATA_BLOCKSIZE - PGRESULT_BLOCK_OVERHEAD;
     644             :     }
     645             :     else
     646             :     {
     647             :         /* we can cram it right after the overhead pointer */
     648       72746 :         res->curOffset = sizeof(PGresult_data);
     649       72746 :         res->spaceLeft = PGRESULT_DATA_BLOCKSIZE - sizeof(PGresult_data);
     650             :     }
     651             : 
     652      666530 :     space = block->space + res->curOffset;
     653      666530 :     res->curOffset += nBytes;
     654      666530 :     res->spaceLeft -= nBytes;
     655      666530 :     return space;
     656             : }
     657             : 
     658             : /*
     659             :  * PQresultMemorySize -
     660             :  *      Returns total space allocated for the PGresult.
     661             :  */
     662             : size_t
     663           0 : PQresultMemorySize(const PGresult *res)
     664             : {
     665           0 :     if (!res)
     666           0 :         return 0;
     667           0 :     return res->memorySize;
     668             : }
     669             : 
     670             : /*
     671             :  * pqResultStrdup -
     672             :  *      Like strdup, but the space is subsidiary PGresult space.
     673             :  */
     674             : char *
     675      903004 : pqResultStrdup(PGresult *res, const char *str)
     676             : {
     677      903004 :     char       *space = (char *) pqResultAlloc(res, strlen(str) + 1, false);
     678             : 
     679      903004 :     if (space)
     680      903004 :         strcpy(space, str);
     681      903004 :     return space;
     682             : }
     683             : 
     684             : /*
     685             :  * pqSetResultError -
     686             :  *      assign a new error message to a PGresult
     687             :  *
     688             :  * Copy text from errorMessage buffer beginning at given offset
     689             :  * (it's caller's responsibility that offset is valid)
     690             :  */
     691             : void
     692       40816 : pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset)
     693             : {
     694             :     char       *msg;
     695             : 
     696       40816 :     if (!res)
     697           0 :         return;
     698             : 
     699             :     /*
     700             :      * We handle two OOM scenarios here.  The errorMessage buffer might be
     701             :      * marked "broken" due to having previously failed to allocate enough
     702             :      * memory for the message, or it might be fine but pqResultStrdup fails
     703             :      * and returns NULL.  In either case, just make res->errMsg point directly
     704             :      * at a constant "out of memory" string.
     705             :      */
     706       40816 :     if (!PQExpBufferBroken(errorMessage))
     707       40816 :         msg = pqResultStrdup(res, errorMessage->data + offset);
     708             :     else
     709           0 :         msg = NULL;
     710       40816 :     if (msg)
     711       40816 :         res->errMsg = msg;
     712             :     else
     713           0 :         res->errMsg = libpq_gettext("out of memory\n");
     714             : }
     715             : 
     716             : /*
     717             :  * PQclear -
     718             :  *    free's the memory associated with a PGresult
     719             :  */
     720             : void
     721     5387570 : PQclear(PGresult *res)
     722             : {
     723             :     PGresult_data *block;
     724             :     int         i;
     725             : 
     726             :     /* As a convenience, do nothing for a NULL pointer */
     727     5387570 :     if (!res)
     728     1546454 :         return;
     729             :     /* Also, do nothing if the argument is OOM_result */
     730     3841116 :     if ((const PGresult *) res == &OOM_result)
     731           0 :         return;
     732             : 
     733             :     /* Close down any events we may have */
     734     3841116 :     for (i = 0; i < res->nEvents; i++)
     735             :     {
     736             :         /* only send DESTROY to successfully-initialized event procs */
     737           0 :         if (res->events[i].resultInitialized)
     738             :         {
     739             :             PGEventResultDestroy evt;
     740             : 
     741           0 :             evt.result = res;
     742           0 :             (void) res->events[i].proc(PGEVT_RESULTDESTROY, &evt,
     743           0 :                                        res->events[i].passThrough);
     744             :         }
     745           0 :         free(res->events[i].name);
     746             :     }
     747             : 
     748     3841116 :     free(res->events);
     749             : 
     750             :     /* Free all the subsidiary blocks */
     751     4509006 :     while ((block = res->curBlock) != NULL)
     752             :     {
     753      667890 :         res->curBlock = block->next;
     754      667890 :         free(block);
     755             :     }
     756             : 
     757             :     /* Free the top-level tuple pointer array */
     758     3841116 :     free(res->tuples);
     759             : 
     760             :     /* zero out the pointer fields to catch programming errors */
     761     3841116 :     res->attDescs = NULL;
     762     3841116 :     res->tuples = NULL;
     763     3841116 :     res->paramDescs = NULL;
     764     3841116 :     res->errFields = NULL;
     765     3841116 :     res->events = NULL;
     766     3841116 :     res->nEvents = 0;
     767             :     /* res->curBlock was zeroed out earlier */
     768             : 
     769             :     /* Free the PGresult structure itself */
     770     3841116 :     free(res);
     771             : }
     772             : 
     773             : /*
     774             :  * Handy subroutine to deallocate any partially constructed async result.
     775             :  *
     776             :  * Any "saved" result gets cleared too.
     777             :  */
     778             : void
     779      688850 : pqClearAsyncResult(PGconn *conn)
     780             : {
     781      688850 :     PQclear(conn->result);
     782      688850 :     conn->result = NULL;
     783      688850 :     conn->error_result = false;
     784      688850 :     PQclear(conn->saved_result);
     785      688850 :     conn->saved_result = NULL;
     786      688850 : }
     787             : 
     788             : /*
     789             :  * pqSaveErrorResult -
     790             :  *    remember that we have an error condition
     791             :  *
     792             :  * In much of libpq, reporting an error just requires appending text to
     793             :  * conn->errorMessage and returning a failure code to one's caller.
     794             :  * Where returning a failure code is impractical, instead call this
     795             :  * function to remember that an error needs to be reported.
     796             :  *
     797             :  * (It might seem that appending text to conn->errorMessage should be
     798             :  * sufficient, but we can't rely on that working under out-of-memory
     799             :  * conditions.  The OOM hazard is also why we don't try to make a new
     800             :  * PGresult right here.)
     801             :  */
     802             : void
     803          30 : pqSaveErrorResult(PGconn *conn)
     804             : {
     805             :     /* Drop any pending result ... */
     806          30 :     pqClearAsyncResult(conn);
     807             :     /* ... and set flag to remember to make an error result later */
     808          30 :     conn->error_result = true;
     809          30 : }
     810             : 
     811             : /*
     812             :  * pqSaveWriteError -
     813             :  *    report a write failure
     814             :  *
     815             :  * As above, after appending conn->write_err_msg to whatever other error we
     816             :  * have.  This is used when we've detected a write failure and have exhausted
     817             :  * our chances of reporting something else instead.
     818             :  */
     819             : static void
     820           4 : pqSaveWriteError(PGconn *conn)
     821             : {
     822             :     /*
     823             :      * If write_err_msg is null because of previous strdup failure, do what we
     824             :      * can.  (It's likely our machinations here will get OOM failures as well,
     825             :      * but might as well try.)
     826             :      */
     827           4 :     if (conn->write_err_msg)
     828             :     {
     829           4 :         appendPQExpBufferStr(&conn->errorMessage, conn->write_err_msg);
     830             :         /* Avoid possibly appending the same message twice */
     831           4 :         conn->write_err_msg[0] = '\0';
     832             :     }
     833             :     else
     834           0 :         libpq_append_conn_error(conn, "write to server failed");
     835             : 
     836           4 :     pqSaveErrorResult(conn);
     837           4 : }
     838             : 
     839             : /*
     840             :  * pqPrepareAsyncResult -
     841             :  *    prepare the current async result object for return to the caller
     842             :  *
     843             :  * If there is not already an async result object, build an error object
     844             :  * using whatever is in conn->errorMessage.  In any case, clear the async
     845             :  * result storage, and update our notion of how much error text has been
     846             :  * returned to the application.
     847             :  *
     848             :  * Note that in no case (not even OOM) do we return NULL.
     849             :  */
     850             : PGresult *
     851      615136 : pqPrepareAsyncResult(PGconn *conn)
     852             : {
     853             :     PGresult   *res;
     854             : 
     855      615136 :     res = conn->result;
     856      615136 :     if (res)
     857             :     {
     858             :         /*
     859             :          * If the pre-existing result is an ERROR (presumably something
     860             :          * received from the server), assume that it represents whatever is in
     861             :          * conn->errorMessage, and advance errorReported.
     862             :          */
     863      615106 :         if (res->resultStatus == PGRES_FATAL_ERROR)
     864       40018 :             conn->errorReported = conn->errorMessage.len;
     865             :     }
     866             :     else
     867             :     {
     868             :         /*
     869             :          * We get here after internal-to-libpq errors.  We should probably
     870             :          * always have error_result = true, but if we don't, gin up some error
     871             :          * text.
     872             :          */
     873          30 :         if (!conn->error_result)
     874           0 :             libpq_append_conn_error(conn, "no error text available");
     875             : 
     876             :         /* Paranoia: be sure errorReported offset is sane */
     877          30 :         if (conn->errorReported < 0 ||
     878          30 :             conn->errorReported >= conn->errorMessage.len)
     879           0 :             conn->errorReported = 0;
     880             : 
     881             :         /*
     882             :          * Make a PGresult struct for the error.  We temporarily lie about the
     883             :          * result status, so that PQmakeEmptyPGresult doesn't uselessly copy
     884             :          * all of conn->errorMessage.
     885             :          */
     886          30 :         res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
     887          30 :         if (res)
     888             :         {
     889             :             /*
     890             :              * Report whatever new error text we have, and advance
     891             :              * errorReported.
     892             :              */
     893          30 :             res->resultStatus = PGRES_FATAL_ERROR;
     894          30 :             pqSetResultError(res, &conn->errorMessage, conn->errorReported);
     895          30 :             conn->errorReported = conn->errorMessage.len;
     896             :         }
     897             :         else
     898             :         {
     899             :             /*
     900             :              * Ouch, not enough memory for a PGresult.  Fortunately, we have a
     901             :              * card up our sleeve: we can use the static OOM_result.  Casting
     902             :              * away const here is a bit ugly, but it seems best to declare
     903             :              * OOM_result as const, in hopes it will be allocated in read-only
     904             :              * storage.
     905             :              */
     906           0 :             res = unconstify(PGresult *, &OOM_result);
     907             : 
     908             :             /*
     909             :              * Don't advance errorReported.  Perhaps we'll be able to report
     910             :              * the text later.
     911             :              */
     912             :         }
     913             :     }
     914             : 
     915             :     /*
     916             :      * Replace conn->result with saved_result, if any.  In the normal case
     917             :      * there isn't a saved result and we're just dropping ownership of the
     918             :      * current result.  In partial-result mode this restores the situation to
     919             :      * what it was before we created the current partial result.
     920             :      */
     921      615136 :     conn->result = conn->saved_result;
     922      615136 :     conn->error_result = false; /* saved_result is never an error */
     923      615136 :     conn->saved_result = NULL;
     924             : 
     925      615136 :     return res;
     926             : }
     927             : 
     928             : /*
     929             :  * pqInternalNotice - produce an internally-generated notice message
     930             :  *
     931             :  * A format string and optional arguments can be passed.  Note that we do
     932             :  * libpq_gettext() here, so callers need not.
     933             :  *
     934             :  * The supplied text is taken as primary message (ie., it should not include
     935             :  * a trailing newline, and should not be more than one line).
     936             :  */
     937             : void
     938           0 : pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
     939             : {
     940             :     char        msgBuf[1024];
     941             :     va_list     args;
     942             :     PGresult   *res;
     943             : 
     944           0 :     if (hooks->noticeRec == NULL)
     945           0 :         return;                 /* nobody home to receive notice? */
     946             : 
     947             :     /* Format the message */
     948           0 :     va_start(args, fmt);
     949           0 :     vsnprintf(msgBuf, sizeof(msgBuf), libpq_gettext(fmt), args);
     950           0 :     va_end(args);
     951           0 :     msgBuf[sizeof(msgBuf) - 1] = '\0';  /* make real sure it's terminated */
     952             : 
     953             :     /* Make a PGresult to pass to the notice receiver */
     954           0 :     res = PQmakeEmptyPGresult(NULL, PGRES_NONFATAL_ERROR);
     955           0 :     if (!res)
     956           0 :         return;
     957           0 :     res->noticeHooks = *hooks;
     958             : 
     959             :     /*
     960             :      * Set up fields of notice.
     961             :      */
     962           0 :     pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, msgBuf);
     963           0 :     pqSaveMessageField(res, PG_DIAG_SEVERITY, libpq_gettext("NOTICE"));
     964           0 :     pqSaveMessageField(res, PG_DIAG_SEVERITY_NONLOCALIZED, "NOTICE");
     965             :     /* XXX should provide a SQLSTATE too? */
     966             : 
     967             :     /*
     968             :      * Result text is always just the primary message + newline.  If we can't
     969             :      * allocate it, substitute "out of memory", as in pqSetResultError.
     970             :      */
     971           0 :     res->errMsg = (char *) pqResultAlloc(res, strlen(msgBuf) + 2, false);
     972           0 :     if (res->errMsg)
     973           0 :         sprintf(res->errMsg, "%s\n", msgBuf);
     974             :     else
     975           0 :         res->errMsg = libpq_gettext("out of memory\n");
     976             : 
     977             :     /*
     978             :      * Pass to receiver, then free it.
     979             :      */
     980           0 :     res->noticeHooks.noticeRec(res->noticeHooks.noticeRecArg, res);
     981           0 :     PQclear(res);
     982             : }
     983             : 
     984             : /*
     985             :  * pqAddTuple
     986             :  *    add a row pointer to the PGresult structure, growing it if necessary
     987             :  *    Returns true if OK, false if an error prevented adding the row
     988             :  *
     989             :  * On error, *errmsgp can be set to an error string to be returned.
     990             :  * If it is left NULL, the error is presumed to be "out of memory".
     991             :  */
     992             : static bool
     993     6329110 : pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp)
     994             : {
     995     6329110 :     if (res->ntups >= res->tupArrSize)
     996             :     {
     997             :         /*
     998             :          * Try to grow the array.
     999             :          *
    1000             :          * We can use realloc because shallow copying of the structure is
    1001             :          * okay. Note that the first time through, res->tuples is NULL. While
    1002             :          * ANSI says that realloc() should act like malloc() in that case,
    1003             :          * some old C libraries (like SunOS 4.1.x) coredump instead. On
    1004             :          * failure realloc is supposed to return NULL without damaging the
    1005             :          * existing allocation. Note that the positions beyond res->ntups are
    1006             :          * garbage, not necessarily NULL.
    1007             :          */
    1008             :         int         newSize;
    1009             :         PGresAttValue **newTuples;
    1010             : 
    1011             :         /*
    1012             :          * Since we use integers for row numbers, we can't support more than
    1013             :          * INT_MAX rows.  Make sure we allow that many, though.
    1014             :          */
    1015      246398 :         if (res->tupArrSize <= INT_MAX / 2)
    1016      246398 :             newSize = (res->tupArrSize > 0) ? res->tupArrSize * 2 : 128;
    1017           0 :         else if (res->tupArrSize < INT_MAX)
    1018           0 :             newSize = INT_MAX;
    1019             :         else
    1020             :         {
    1021           0 :             *errmsgp = libpq_gettext("PGresult cannot support more than INT_MAX tuples");
    1022           0 :             return false;
    1023             :         }
    1024             : 
    1025             :         /*
    1026             :          * Also, on 32-bit platforms we could, in theory, overflow size_t even
    1027             :          * before newSize gets to INT_MAX.  (In practice we'd doubtless hit
    1028             :          * OOM long before that, but let's check.)
    1029             :          */
    1030             : #if INT_MAX >= (SIZE_MAX / 2)
    1031             :         if (newSize > SIZE_MAX / sizeof(PGresAttValue *))
    1032             :         {
    1033             :             *errmsgp = libpq_gettext("size_t overflow");
    1034             :             return false;
    1035             :         }
    1036             : #endif
    1037             : 
    1038      246398 :         if (res->tuples == NULL)
    1039             :             newTuples = (PGresAttValue **)
    1040      234472 :                 malloc(newSize * sizeof(PGresAttValue *));
    1041             :         else
    1042             :             newTuples = (PGresAttValue **)
    1043       11926 :                 realloc(res->tuples, newSize * sizeof(PGresAttValue *));
    1044      246398 :         if (!newTuples)
    1045           0 :             return false;       /* malloc or realloc failed */
    1046      246398 :         res->memorySize +=
    1047      246398 :             (newSize - res->tupArrSize) * sizeof(PGresAttValue *);
    1048      246398 :         res->tupArrSize = newSize;
    1049      246398 :         res->tuples = newTuples;
    1050             :     }
    1051     6329110 :     res->tuples[res->ntups] = tup;
    1052     6329110 :     res->ntups++;
    1053     6329110 :     return true;
    1054             : }
    1055             : 
    1056             : /*
    1057             :  * pqSaveMessageField - save one field of an error or notice message
    1058             :  */
    1059             : void
    1060      492944 : pqSaveMessageField(PGresult *res, char code, const char *value)
    1061             : {
    1062             :     PGMessageField *pfield;
    1063             : 
    1064             :     pfield = (PGMessageField *)
    1065      492944 :         pqResultAlloc(res,
    1066             :                       offsetof(PGMessageField, contents) +
    1067      492944 :                       strlen(value) + 1,
    1068             :                       true);
    1069      492944 :     if (!pfield)
    1070           0 :         return;                 /* out of memory? */
    1071      492944 :     pfield->code = code;
    1072      492944 :     strcpy(pfield->contents, value);
    1073      492944 :     pfield->next = res->errFields;
    1074      492944 :     res->errFields = pfield;
    1075             : }
    1076             : 
    1077             : /*
    1078             :  * pqSaveParameterStatus - remember parameter status sent by backend
    1079             :  */
    1080             : void
    1081      307818 : pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
    1082             : {
    1083             :     pgParameterStatus *pstatus;
    1084             :     pgParameterStatus *prev;
    1085             : 
    1086             :     /*
    1087             :      * Forget any old information about the parameter
    1088             :      */
    1089     2275960 :     for (pstatus = conn->pstatus, prev = NULL;
    1090             :          pstatus != NULL;
    1091     1968142 :          prev = pstatus, pstatus = pstatus->next)
    1092             :     {
    1093     1976444 :         if (strcmp(pstatus->name, name) == 0)
    1094             :         {
    1095        8302 :             if (prev)
    1096        5224 :                 prev->next = pstatus->next;
    1097             :             else
    1098        3078 :                 conn->pstatus = pstatus->next;
    1099        8302 :             free(pstatus);      /* frees name and value strings too */
    1100        8302 :             break;
    1101             :         }
    1102             :     }
    1103             : 
    1104             :     /*
    1105             :      * Store new info as a single malloc block
    1106             :      */
    1107      307818 :     pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) +
    1108      307818 :                                            strlen(name) + strlen(value) + 2);
    1109      307818 :     if (pstatus)
    1110             :     {
    1111             :         char       *ptr;
    1112             : 
    1113      307818 :         ptr = ((char *) pstatus) + sizeof(pgParameterStatus);
    1114      307818 :         pstatus->name = ptr;
    1115      307818 :         strcpy(ptr, name);
    1116      307818 :         ptr += strlen(name) + 1;
    1117      307818 :         pstatus->value = ptr;
    1118      307818 :         strcpy(ptr, value);
    1119      307818 :         pstatus->next = conn->pstatus;
    1120      307818 :         conn->pstatus = pstatus;
    1121             :     }
    1122             : 
    1123             :     /*
    1124             :      * Save values of settings that are of interest to libpq in fields of the
    1125             :      * PGconn object.  We keep client_encoding and standard_conforming_strings
    1126             :      * in static variables as well, so that PQescapeString and PQescapeBytea
    1127             :      * can behave somewhat sanely (at least in single-connection-using
    1128             :      * programs).
    1129             :      */
    1130      307818 :     if (strcmp(name, "client_encoding") == 0)
    1131             :     {
    1132       21400 :         conn->client_encoding = pg_char_to_encoding(value);
    1133             :         /* if we don't recognize the encoding name, fall back to SQL_ASCII */
    1134       21400 :         if (conn->client_encoding < 0)
    1135           0 :             conn->client_encoding = PG_SQL_ASCII;
    1136       21400 :         static_client_encoding = conn->client_encoding;
    1137             :     }
    1138      286418 :     else if (strcmp(name, "standard_conforming_strings") == 0)
    1139             :     {
    1140       21466 :         conn->std_strings = (strcmp(value, "on") == 0);
    1141       21466 :         static_std_strings = conn->std_strings;
    1142             :     }
    1143      264952 :     else if (strcmp(name, "server_version") == 0)
    1144             :     {
    1145             :         /* We convert the server version to numeric form. */
    1146             :         int         cnt;
    1147             :         int         vmaj,
    1148             :                     vmin,
    1149             :                     vrev;
    1150             : 
    1151       21394 :         cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev);
    1152             : 
    1153       21394 :         if (cnt == 3)
    1154             :         {
    1155             :             /* old style, e.g. 9.6.1 */
    1156           0 :             conn->sversion = (100 * vmaj + vmin) * 100 + vrev;
    1157             :         }
    1158       21394 :         else if (cnt == 2)
    1159             :         {
    1160           0 :             if (vmaj >= 10)
    1161             :             {
    1162             :                 /* new style, e.g. 10.1 */
    1163           0 :                 conn->sversion = 100 * 100 * vmaj + vmin;
    1164             :             }
    1165             :             else
    1166             :             {
    1167             :                 /* old style without minor version, e.g. 9.6devel */
    1168           0 :                 conn->sversion = (100 * vmaj + vmin) * 100;
    1169             :             }
    1170             :         }
    1171       21394 :         else if (cnt == 1)
    1172             :         {
    1173             :             /* new style without minor version, e.g. 10devel */
    1174       21394 :             conn->sversion = 100 * 100 * vmaj;
    1175             :         }
    1176             :         else
    1177           0 :             conn->sversion = 0; /* unknown */
    1178             :     }
    1179      243558 :     else if (strcmp(name, "default_transaction_read_only") == 0)
    1180             :     {
    1181       21430 :         conn->default_transaction_read_only =
    1182       21430 :             (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
    1183             :     }
    1184      222128 :     else if (strcmp(name, "in_hot_standby") == 0)
    1185             :     {
    1186       21400 :         conn->in_hot_standby =
    1187       21400 :             (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
    1188             :     }
    1189      200728 :     else if (strcmp(name, "scram_iterations") == 0)
    1190             :     {
    1191       21406 :         conn->scram_sha_256_iterations = atoi(value);
    1192             :     }
    1193      307818 : }
    1194             : 
    1195             : 
    1196             : /*
    1197             :  * pqRowProcessor
    1198             :  *    Add the received row to the current async result (conn->result).
    1199             :  *    Returns 1 if OK, 0 if error occurred.
    1200             :  *
    1201             :  * On error, *errmsgp can be set to an error string to be returned.
    1202             :  * (Such a string should already be translated via libpq_gettext().)
    1203             :  * If it is left NULL, the error is presumed to be "out of memory".
    1204             :  */
    1205             : int
    1206     6329110 : pqRowProcessor(PGconn *conn, const char **errmsgp)
    1207             : {
    1208     6329110 :     PGresult   *res = conn->result;
    1209     6329110 :     int         nfields = res->numAttributes;
    1210     6329110 :     const PGdataValue *columns = conn->rowBuf;
    1211             :     PGresAttValue *tup;
    1212             :     int         i;
    1213             : 
    1214             :     /*
    1215             :      * In partial-result mode, if we don't already have a partial PGresult
    1216             :      * then make one by cloning conn->result (which should hold the correct
    1217             :      * result metadata by now).  Then the original conn->result is moved over
    1218             :      * to saved_result so that we can re-use it as a reference for future
    1219             :      * partial results.  The saved result will become active again after
    1220             :      * pqPrepareAsyncResult() returns the partial result to the application.
    1221             :      */
    1222     6329110 :     if (conn->partialResMode && conn->saved_result == NULL)
    1223             :     {
    1224             :         /* Copy everything that should be in the result at this point */
    1225        5258 :         res = PQcopyResult(res,
    1226             :                            PG_COPYRES_ATTRS | PG_COPYRES_EVENTS |
    1227             :                            PG_COPYRES_NOTICEHOOKS);
    1228        5258 :         if (!res)
    1229           0 :             return 0;
    1230             :         /* Change result status to appropriate special value */
    1231        5258 :         res->resultStatus = (conn->singleRowMode ? PGRES_SINGLE_TUPLE : PGRES_TUPLES_CHUNK);
    1232             :         /* And stash it as the active result */
    1233        5258 :         conn->saved_result = conn->result;
    1234        5258 :         conn->result = res;
    1235             :     }
    1236             : 
    1237             :     /*
    1238             :      * Basically we just allocate space in the PGresult for each field and
    1239             :      * copy the data over.
    1240             :      *
    1241             :      * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which
    1242             :      * caller will take to mean "out of memory".  This is preferable to trying
    1243             :      * to set up such a message here, because evidently there's not enough
    1244             :      * memory for gettext() to do anything.
    1245             :      */
    1246             :     tup = (PGresAttValue *)
    1247     6329110 :         pqResultAlloc(res, nfields * sizeof(PGresAttValue), true);
    1248     6329110 :     if (tup == NULL)
    1249           0 :         return 0;
    1250             : 
    1251    35569708 :     for (i = 0; i < nfields; i++)
    1252             :     {
    1253    29240598 :         int         clen = columns[i].len;
    1254             : 
    1255    29240598 :         if (clen < 0)
    1256             :         {
    1257             :             /* null field */
    1258     1497174 :             tup[i].len = NULL_LEN;
    1259     1497174 :             tup[i].value = res->null_field;
    1260             :         }
    1261             :         else
    1262             :         {
    1263    27743424 :             bool        isbinary = (res->attDescs[i].format != 0);
    1264             :             char       *val;
    1265             : 
    1266    27743424 :             val = (char *) pqResultAlloc(res, clen + 1, isbinary);
    1267    27743424 :             if (val == NULL)
    1268           0 :                 return 0;
    1269             : 
    1270             :             /* copy and zero-terminate the data (even if it's binary) */
    1271    27743424 :             memcpy(val, columns[i].value, clen);
    1272    27743424 :             val[clen] = '\0';
    1273             : 
    1274    27743424 :             tup[i].len = clen;
    1275    27743424 :             tup[i].value = val;
    1276             :         }
    1277             :     }
    1278             : 
    1279             :     /* And add the tuple to the PGresult's tuple array */
    1280     6329110 :     if (!pqAddTuple(res, tup, errmsgp))
    1281           0 :         return 0;
    1282             : 
    1283             :     /*
    1284             :      * Success.  In partial-result mode, if we have enough rows then make the
    1285             :      * result available to the client immediately.
    1286             :      */
    1287     6329110 :     if (conn->partialResMode && res->ntups >= conn->maxChunkSize)
    1288        5244 :         conn->asyncStatus = PGASYNC_READY_MORE;
    1289             : 
    1290     6329110 :     return 1;
    1291             : }
    1292             : 
    1293             : 
    1294             : /*
    1295             :  * pqAllocCmdQueueEntry
    1296             :  *      Get a command queue entry for caller to fill.
    1297             :  *
    1298             :  * If the recycle queue has a free element, that is returned; if not, a
    1299             :  * fresh one is allocated.  Caller is responsible for adding it to the
    1300             :  * command queue (pqAppendCmdQueueEntry) once the struct is filled in, or
    1301             :  * releasing the memory (pqRecycleCmdQueueEntry) if an error occurs.
    1302             :  *
    1303             :  * If allocation fails, sets the error message and returns NULL.
    1304             :  */
    1305             : static PGcmdQueueEntry *
    1306      563836 : pqAllocCmdQueueEntry(PGconn *conn)
    1307             : {
    1308             :     PGcmdQueueEntry *entry;
    1309             : 
    1310      563836 :     if (conn->cmd_queue_recycle == NULL)
    1311             :     {
    1312       22690 :         entry = (PGcmdQueueEntry *) malloc(sizeof(PGcmdQueueEntry));
    1313       22690 :         if (entry == NULL)
    1314             :         {
    1315           0 :             libpq_append_conn_error(conn, "out of memory");
    1316           0 :             return NULL;
    1317             :         }
    1318             :     }
    1319             :     else
    1320             :     {
    1321      541146 :         entry = conn->cmd_queue_recycle;
    1322      541146 :         conn->cmd_queue_recycle = entry->next;
    1323             :     }
    1324      563836 :     entry->next = NULL;
    1325      563836 :     entry->query = NULL;
    1326             : 
    1327      563836 :     return entry;
    1328             : }
    1329             : 
    1330             : /*
    1331             :  * pqAppendCmdQueueEntry
    1332             :  *      Append a caller-allocated entry to the command queue, and update
    1333             :  *      conn->asyncStatus to account for it.
    1334             :  *
    1335             :  * The query itself must already have been put in the output buffer by the
    1336             :  * caller.
    1337             :  */
    1338             : static void
    1339      563836 : pqAppendCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
    1340             : {
    1341             :     Assert(entry->next == NULL);
    1342             : 
    1343      563836 :     if (conn->cmd_queue_head == NULL)
    1344      560136 :         conn->cmd_queue_head = entry;
    1345             :     else
    1346        3700 :         conn->cmd_queue_tail->next = entry;
    1347             : 
    1348      563836 :     conn->cmd_queue_tail = entry;
    1349             : 
    1350      563836 :     switch (conn->pipelineStatus)
    1351             :     {
    1352      563752 :         case PQ_PIPELINE_OFF:
    1353             :         case PQ_PIPELINE_ON:
    1354             : 
    1355             :             /*
    1356             :              * When not in pipeline aborted state, if there's a result ready
    1357             :              * to be consumed, let it be so (that is, don't change away from
    1358             :              * READY or READY_MORE); otherwise set us busy to wait for
    1359             :              * something to arrive from the server.
    1360             :              */
    1361      563752 :             if (conn->asyncStatus == PGASYNC_IDLE)
    1362      560134 :                 conn->asyncStatus = PGASYNC_BUSY;
    1363      563752 :             break;
    1364             : 
    1365          84 :         case PQ_PIPELINE_ABORTED:
    1366             : 
    1367             :             /*
    1368             :              * In aborted pipeline state, we don't expect anything from the
    1369             :              * server (since we don't send any queries that are queued).
    1370             :              * Therefore, if IDLE then do what PQgetResult would do to let
    1371             :              * itself consume commands from the queue; if we're in any other
    1372             :              * state, we don't have to do anything.
    1373             :              */
    1374          84 :             if (conn->asyncStatus == PGASYNC_IDLE ||
    1375          82 :                 conn->asyncStatus == PGASYNC_PIPELINE_IDLE)
    1376           2 :                 pqPipelineProcessQueue(conn);
    1377          84 :             break;
    1378             :     }
    1379      563836 : }
    1380             : 
    1381             : /*
    1382             :  * pqRecycleCmdQueueEntry
    1383             :  *      Push a command queue entry onto the freelist.
    1384             :  */
    1385             : static void
    1386      562410 : pqRecycleCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
    1387             : {
    1388      562410 :     if (entry == NULL)
    1389           0 :         return;
    1390             : 
    1391             :     /* recyclable entries should not have a follow-on command */
    1392             :     Assert(entry->next == NULL);
    1393             : 
    1394      562410 :     if (entry->query)
    1395             :     {
    1396      547598 :         free(entry->query);
    1397      547598 :         entry->query = NULL;
    1398             :     }
    1399             : 
    1400      562410 :     entry->next = conn->cmd_queue_recycle;
    1401      562410 :     conn->cmd_queue_recycle = entry;
    1402             : }
    1403             : 
    1404             : 
    1405             : /*
    1406             :  * PQsendQuery
    1407             :  *   Submit a query, but don't wait for it to finish
    1408             :  *
    1409             :  * Returns: 1 if successfully submitted
    1410             :  *          0 if error (conn->errorMessage is set)
    1411             :  *
    1412             :  * PQsendQueryContinue is a non-exported version that behaves identically
    1413             :  * except that it doesn't reset conn->errorMessage.
    1414             :  */
    1415             : int
    1416      538930 : PQsendQuery(PGconn *conn, const char *query)
    1417             : {
    1418      538930 :     return PQsendQueryInternal(conn, query, true);
    1419             : }
    1420             : 
    1421             : int
    1422           0 : PQsendQueryContinue(PGconn *conn, const char *query)
    1423             : {
    1424           0 :     return PQsendQueryInternal(conn, query, false);
    1425             : }
    1426             : 
    1427             : static int
    1428      538930 : PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
    1429             : {
    1430      538930 :     PGcmdQueueEntry *entry = NULL;
    1431             : 
    1432      538930 :     if (!PQsendQueryStart(conn, newQuery))
    1433           0 :         return 0;
    1434             : 
    1435             :     /* check the argument */
    1436      538930 :     if (!query)
    1437             :     {
    1438           0 :         libpq_append_conn_error(conn, "command string is a null pointer");
    1439           0 :         return 0;
    1440             :     }
    1441             : 
    1442      538930 :     if (conn->pipelineStatus != PQ_PIPELINE_OFF)
    1443             :     {
    1444           2 :         libpq_append_conn_error(conn, "%s not allowed in pipeline mode",
    1445             :                                 "PQsendQuery");
    1446           2 :         return 0;
    1447             :     }
    1448             : 
    1449      538928 :     entry = pqAllocCmdQueueEntry(conn);
    1450      538928 :     if (entry == NULL)
    1451           0 :         return 0;               /* error msg already set */
    1452             : 
    1453             :     /* Send the query message(s) */
    1454             :     /* construct the outgoing Query message */
    1455     1077856 :     if (pqPutMsgStart(PqMsg_Query, conn) < 0 ||
    1456     1077856 :         pqPuts(query, conn) < 0 ||
    1457      538928 :         pqPutMsgEnd(conn) < 0)
    1458             :     {
    1459             :         /* error message should be set up already */
    1460           0 :         pqRecycleCmdQueueEntry(conn, entry);
    1461           0 :         return 0;
    1462             :     }
    1463             : 
    1464             :     /* remember we are using simple query protocol */
    1465      538928 :     entry->queryclass = PGQUERY_SIMPLE;
    1466             :     /* and remember the query text too, if possible */
    1467      538928 :     entry->query = strdup(query);
    1468             : 
    1469             :     /*
    1470             :      * Give the data a push.  In nonblock mode, don't complain if we're unable
    1471             :      * to send it all; PQgetResult() will do any additional flushing needed.
    1472             :      */
    1473      538928 :     if (pqFlush(conn) < 0)
    1474           0 :         goto sendFailed;
    1475             : 
    1476             :     /* OK, it's launched! */
    1477      538928 :     pqAppendCmdQueueEntry(conn, entry);
    1478             : 
    1479      538928 :     return 1;
    1480             : 
    1481           0 : sendFailed:
    1482           0 :     pqRecycleCmdQueueEntry(conn, entry);
    1483             :     /* error message should be set up already */
    1484           0 :     return 0;
    1485             : }
    1486             : 
    1487             : /*
    1488             :  * PQsendQueryParams
    1489             :  *      Like PQsendQuery, but use extended query protocol so we can pass parameters
    1490             :  */
    1491             : int
    1492        5776 : PQsendQueryParams(PGconn *conn,
    1493             :                   const char *command,
    1494             :                   int nParams,
    1495             :                   const Oid *paramTypes,
    1496             :                   const char *const *paramValues,
    1497             :                   const int *paramLengths,
    1498             :                   const int *paramFormats,
    1499             :                   int resultFormat)
    1500             : {
    1501        5776 :     if (!PQsendQueryStart(conn, true))
    1502           0 :         return 0;
    1503             : 
    1504             :     /* check the arguments */
    1505        5776 :     if (!command)
    1506             :     {
    1507           0 :         libpq_append_conn_error(conn, "command string is a null pointer");
    1508           0 :         return 0;
    1509             :     }
    1510        5776 :     if (nParams < 0 || nParams > PQ_QUERY_PARAM_MAX_LIMIT)
    1511             :     {
    1512           0 :         libpq_append_conn_error(conn, "number of parameters must be between 0 and %d",
    1513             :                                 PQ_QUERY_PARAM_MAX_LIMIT);
    1514           0 :         return 0;
    1515             :     }
    1516             : 
    1517        5776 :     return PQsendQueryGuts(conn,
    1518             :                            command,
    1519             :                            "",    /* use unnamed statement */
    1520             :                            nParams,
    1521             :                            paramTypes,
    1522             :                            paramValues,
    1523             :                            paramLengths,
    1524             :                            paramFormats,
    1525             :                            resultFormat);
    1526             : }
    1527             : 
    1528             : /*
    1529             :  * PQsendPrepare
    1530             :  *   Submit a Parse message, but don't wait for it to finish
    1531             :  *
    1532             :  * Returns: 1 if successfully submitted
    1533             :  *          0 if error (conn->errorMessage is set)
    1534             :  */
    1535             : int
    1536        4318 : PQsendPrepare(PGconn *conn,
    1537             :               const char *stmtName, const char *query,
    1538             :               int nParams, const Oid *paramTypes)
    1539             : {
    1540        4318 :     PGcmdQueueEntry *entry = NULL;
    1541             : 
    1542        4318 :     if (!PQsendQueryStart(conn, true))
    1543           0 :         return 0;
    1544             : 
    1545             :     /* check the arguments */
    1546        4318 :     if (!stmtName)
    1547             :     {
    1548           0 :         libpq_append_conn_error(conn, "statement name is a null pointer");
    1549           0 :         return 0;
    1550             :     }
    1551        4318 :     if (!query)
    1552             :     {
    1553           0 :         libpq_append_conn_error(conn, "command string is a null pointer");
    1554           0 :         return 0;
    1555             :     }
    1556        4318 :     if (nParams < 0 || nParams > PQ_QUERY_PARAM_MAX_LIMIT)
    1557             :     {
    1558           0 :         libpq_append_conn_error(conn, "number of parameters must be between 0 and %d",
    1559             :                                 PQ_QUERY_PARAM_MAX_LIMIT);
    1560           0 :         return 0;
    1561             :     }
    1562             : 
    1563        4318 :     entry = pqAllocCmdQueueEntry(conn);
    1564        4318 :     if (entry == NULL)
    1565           0 :         return 0;               /* error msg already set */
    1566             : 
    1567             :     /* construct the Parse message */
    1568        8636 :     if (pqPutMsgStart(PqMsg_Parse, conn) < 0 ||
    1569        8636 :         pqPuts(stmtName, conn) < 0 ||
    1570        4318 :         pqPuts(query, conn) < 0)
    1571           0 :         goto sendFailed;
    1572             : 
    1573        4318 :     if (nParams > 0 && paramTypes)
    1574           6 :     {
    1575             :         int         i;
    1576             : 
    1577           6 :         if (pqPutInt(nParams, 2, conn) < 0)
    1578           0 :             goto sendFailed;
    1579          16 :         for (i = 0; i < nParams; i++)
    1580             :         {
    1581          10 :             if (pqPutInt(paramTypes[i], 4, conn) < 0)
    1582           0 :                 goto sendFailed;
    1583             :         }
    1584             :     }
    1585             :     else
    1586             :     {
    1587        4312 :         if (pqPutInt(0, 2, conn) < 0)
    1588           0 :             goto sendFailed;
    1589             :     }
    1590        4318 :     if (pqPutMsgEnd(conn) < 0)
    1591           0 :         goto sendFailed;
    1592             : 
    1593             :     /* Add a Sync, unless in pipeline mode. */
    1594        4318 :     if (conn->pipelineStatus == PQ_PIPELINE_OFF)
    1595             :     {
    1596        8624 :         if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
    1597        4312 :             pqPutMsgEnd(conn) < 0)
    1598           0 :             goto sendFailed;
    1599             :     }
    1600             : 
    1601             :     /* remember we are doing just a Parse */
    1602        4318 :     entry->queryclass = PGQUERY_PREPARE;
    1603             : 
    1604             :     /* and remember the query text too, if possible */
    1605             :     /* if insufficient memory, query just winds up NULL */
    1606        4318 :     entry->query = strdup(query);
    1607             : 
    1608             :     /*
    1609             :      * Give the data a push (in pipeline mode, only if we're past the size
    1610             :      * threshold).  In nonblock mode, don't complain if we're unable to send
    1611             :      * it all; PQgetResult() will do any additional flushing needed.
    1612             :      */
    1613        4318 :     if (pqPipelineFlush(conn) < 0)
    1614           0 :         goto sendFailed;
    1615             : 
    1616             :     /* OK, it's launched! */
    1617        4318 :     pqAppendCmdQueueEntry(conn, entry);
    1618             : 
    1619        4318 :     return 1;
    1620             : 
    1621           0 : sendFailed:
    1622           0 :     pqRecycleCmdQueueEntry(conn, entry);
    1623             :     /* error message should be set up already */
    1624           0 :     return 0;
    1625             : }
    1626             : 
    1627             : /*
    1628             :  * PQsendQueryPrepared
    1629             :  *      Like PQsendQuery, but execute a previously prepared statement,
    1630             :  *      using extended query protocol so we can pass parameters
    1631             :  */
    1632             : int
    1633       14528 : PQsendQueryPrepared(PGconn *conn,
    1634             :                     const char *stmtName,
    1635             :                     int nParams,
    1636             :                     const char *const *paramValues,
    1637             :                     const int *paramLengths,
    1638             :                     const int *paramFormats,
    1639             :                     int resultFormat)
    1640             : {
    1641       14528 :     if (!PQsendQueryStart(conn, true))
    1642           0 :         return 0;
    1643             : 
    1644             :     /* check the arguments */
    1645       14528 :     if (!stmtName)
    1646             :     {
    1647           0 :         libpq_append_conn_error(conn, "statement name is a null pointer");
    1648           0 :         return 0;
    1649             :     }
    1650       14528 :     if (nParams < 0 || nParams > PQ_QUERY_PARAM_MAX_LIMIT)
    1651             :     {
    1652           0 :         libpq_append_conn_error(conn, "number of parameters must be between 0 and %d",
    1653             :                                 PQ_QUERY_PARAM_MAX_LIMIT);
    1654           0 :         return 0;
    1655             :     }
    1656             : 
    1657       14528 :     return PQsendQueryGuts(conn,
    1658             :                            NULL,    /* no command to parse */
    1659             :                            stmtName,
    1660             :                            nParams,
    1661             :                            NULL,    /* no param types */
    1662             :                            paramValues,
    1663             :                            paramLengths,
    1664             :                            paramFormats,
    1665             :                            resultFormat);
    1666             : }
    1667             : 
    1668             : /*
    1669             :  * PQsendQueryStart
    1670             :  *  Common startup code for PQsendQuery and sibling routines
    1671             :  */
    1672             : static bool
    1673      563706 : PQsendQueryStart(PGconn *conn, bool newQuery)
    1674             : {
    1675      563706 :     if (!conn)
    1676           0 :         return false;
    1677             : 
    1678             :     /*
    1679             :      * If this is the beginning of a query cycle, reset the error state.
    1680             :      * However, in pipeline mode with something already queued, the error
    1681             :      * buffer belongs to that command and we shouldn't clear it.
    1682             :      */
    1683      563706 :     if (newQuery && conn->cmd_queue_head == NULL)
    1684      560134 :         pqClearConnErrorState(conn);
    1685             : 
    1686             :     /* Don't try to send if we know there's no live connection. */
    1687      563706 :     if (conn->status != CONNECTION_OK)
    1688             :     {
    1689           0 :         libpq_append_conn_error(conn, "no connection to the server");
    1690           0 :         return false;
    1691             :     }
    1692             : 
    1693             :     /* Can't send while already busy, either, unless enqueuing for later */
    1694      563706 :     if (conn->asyncStatus != PGASYNC_IDLE &&
    1695        3572 :         conn->pipelineStatus == PQ_PIPELINE_OFF)
    1696             :     {
    1697           0 :         libpq_append_conn_error(conn, "another command is already in progress");
    1698           0 :         return false;
    1699             :     }
    1700             : 
    1701      563706 :     if (conn->pipelineStatus != PQ_PIPELINE_OFF)
    1702             :     {
    1703             :         /*
    1704             :          * When enqueuing commands we don't change much of the connection
    1705             :          * state since it's already in use for the current command. The
    1706             :          * connection state will get updated when pqPipelineProcessQueue()
    1707             :          * advances to start processing the queued message.
    1708             :          *
    1709             :          * Just make sure we can safely enqueue given the current connection
    1710             :          * state. We can enqueue behind another queue item, or behind a
    1711             :          * non-queue command (one that sends its own sync), but we can't
    1712             :          * enqueue if the connection is in a copy state.
    1713             :          */
    1714        3702 :         switch (conn->asyncStatus)
    1715             :         {
    1716        3702 :             case PGASYNC_IDLE:
    1717             :             case PGASYNC_PIPELINE_IDLE:
    1718             :             case PGASYNC_READY:
    1719             :             case PGASYNC_READY_MORE:
    1720             :             case PGASYNC_BUSY:
    1721             :                 /* ok to queue */
    1722        3702 :                 break;
    1723             : 
    1724           0 :             case PGASYNC_COPY_IN:
    1725             :             case PGASYNC_COPY_OUT:
    1726             :             case PGASYNC_COPY_BOTH:
    1727           0 :                 libpq_append_conn_error(conn, "cannot queue commands during COPY");
    1728           0 :                 return false;
    1729             :         }
    1730        3702 :     }
    1731             :     else
    1732             :     {
    1733             :         /*
    1734             :          * This command's results will come in immediately. Initialize async
    1735             :          * result-accumulation state
    1736             :          */
    1737      560004 :         pqClearAsyncResult(conn);
    1738             : 
    1739             :         /* reset partial-result mode */
    1740      560004 :         conn->partialResMode = false;
    1741      560004 :         conn->singleRowMode = false;
    1742      560004 :         conn->maxChunkSize = 0;
    1743             :     }
    1744             : 
    1745             :     /* ready to send command message */
    1746      563706 :     return true;
    1747             : }
    1748             : 
    1749             : /*
    1750             :  * PQsendQueryGuts
    1751             :  *      Common code for sending a query with extended query protocol
    1752             :  *      PQsendQueryStart should be done already
    1753             :  *
    1754             :  * command may be NULL to indicate we use an already-prepared statement
    1755             :  */
    1756             : static int
    1757       20304 : PQsendQueryGuts(PGconn *conn,
    1758             :                 const char *command,
    1759             :                 const char *stmtName,
    1760             :                 int nParams,
    1761             :                 const Oid *paramTypes,
    1762             :                 const char *const *paramValues,
    1763             :                 const int *paramLengths,
    1764             :                 const int *paramFormats,
    1765             :                 int resultFormat)
    1766             : {
    1767             :     int         i;
    1768             :     PGcmdQueueEntry *entry;
    1769             : 
    1770       20304 :     entry = pqAllocCmdQueueEntry(conn);
    1771       20304 :     if (entry == NULL)
    1772           0 :         return 0;               /* error msg already set */
    1773             : 
    1774             :     /*
    1775             :      * We will send Parse (if needed), Bind, Describe Portal, Execute, Sync
    1776             :      * (if not in pipeline mode), using specified statement name and the
    1777             :      * unnamed portal.
    1778             :      */
    1779             : 
    1780       20304 :     if (command)
    1781             :     {
    1782             :         /* construct the Parse message */
    1783       11552 :         if (pqPutMsgStart(PqMsg_Parse, conn) < 0 ||
    1784       11552 :             pqPuts(stmtName, conn) < 0 ||
    1785        5776 :             pqPuts(command, conn) < 0)
    1786           0 :             goto sendFailed;
    1787        5776 :         if (nParams > 0 && paramTypes)
    1788             :         {
    1789          52 :             if (pqPutInt(nParams, 2, conn) < 0)
    1790           0 :                 goto sendFailed;
    1791         128 :             for (i = 0; i < nParams; i++)
    1792             :             {
    1793          76 :                 if (pqPutInt(paramTypes[i], 4, conn) < 0)
    1794           0 :                     goto sendFailed;
    1795             :             }
    1796             :         }
    1797             :         else
    1798             :         {
    1799        5724 :             if (pqPutInt(0, 2, conn) < 0)
    1800           0 :                 goto sendFailed;
    1801             :         }
    1802        5776 :         if (pqPutMsgEnd(conn) < 0)
    1803           0 :             goto sendFailed;
    1804             :     }
    1805             : 
    1806             :     /* Construct the Bind message */
    1807       40608 :     if (pqPutMsgStart(PqMsg_Bind, conn) < 0 ||
    1808       40608 :         pqPuts("", conn) < 0 ||
    1809       20304 :         pqPuts(stmtName, conn) < 0)
    1810           0 :         goto sendFailed;
    1811             : 
    1812             :     /* Send parameter formats */
    1813       20304 :     if (nParams > 0 && paramFormats)
    1814             :     {
    1815        5108 :         if (pqPutInt(nParams, 2, conn) < 0)
    1816           0 :             goto sendFailed;
    1817       12036 :         for (i = 0; i < nParams; i++)
    1818             :         {
    1819        6928 :             if (pqPutInt(paramFormats[i], 2, conn) < 0)
    1820           0 :                 goto sendFailed;
    1821             :         }
    1822             :     }
    1823             :     else
    1824             :     {
    1825       15196 :         if (pqPutInt(0, 2, conn) < 0)
    1826           0 :             goto sendFailed;
    1827             :     }
    1828             : 
    1829       20304 :     if (pqPutInt(nParams, 2, conn) < 0)
    1830           0 :         goto sendFailed;
    1831             : 
    1832             :     /* Send parameters */
    1833       48472 :     for (i = 0; i < nParams; i++)
    1834             :     {
    1835       28168 :         if (paramValues && paramValues[i])
    1836       26950 :         {
    1837             :             int         nbytes;
    1838             : 
    1839       26950 :             if (paramFormats && paramFormats[i] != 0)
    1840             :             {
    1841             :                 /* binary parameter */
    1842          52 :                 if (paramLengths)
    1843          52 :                     nbytes = paramLengths[i];
    1844             :                 else
    1845             :                 {
    1846           0 :                     libpq_append_conn_error(conn, "length must be given for binary parameter");
    1847           0 :                     goto sendFailed;
    1848             :                 }
    1849             :             }
    1850             :             else
    1851             :             {
    1852             :                 /* text parameter, do not use paramLengths */
    1853       26898 :                 nbytes = strlen(paramValues[i]);
    1854             :             }
    1855       53900 :             if (pqPutInt(nbytes, 4, conn) < 0 ||
    1856       26950 :                 pqPutnchar(paramValues[i], nbytes, conn) < 0)
    1857           0 :                 goto sendFailed;
    1858             :         }
    1859             :         else
    1860             :         {
    1861             :             /* take the param as NULL */
    1862        1218 :             if (pqPutInt(-1, 4, conn) < 0)
    1863           0 :                 goto sendFailed;
    1864             :         }
    1865             :     }
    1866       40608 :     if (pqPutInt(1, 2, conn) < 0 ||
    1867       20304 :         pqPutInt(resultFormat, 2, conn))
    1868           0 :         goto sendFailed;
    1869       20304 :     if (pqPutMsgEnd(conn) < 0)
    1870           0 :         goto sendFailed;
    1871             : 
    1872             :     /* construct the Describe Portal message */
    1873       40608 :     if (pqPutMsgStart(PqMsg_Describe, conn) < 0 ||
    1874       40608 :         pqPutc('P', conn) < 0 ||
    1875       40608 :         pqPuts("", conn) < 0 ||
    1876       20304 :         pqPutMsgEnd(conn) < 0)
    1877           0 :         goto sendFailed;
    1878             : 
    1879             :     /* construct the Execute message */
    1880       40608 :     if (pqPutMsgStart(PqMsg_Execute, conn) < 0 ||
    1881       40608 :         pqPuts("", conn) < 0 ||
    1882       40608 :         pqPutInt(0, 4, conn) < 0 ||
    1883       20304 :         pqPutMsgEnd(conn) < 0)
    1884           0 :         goto sendFailed;
    1885             : 
    1886             :     /* construct the Sync message if not in pipeline mode */
    1887       20304 :     if (conn->pipelineStatus == PQ_PIPELINE_OFF)
    1888             :     {
    1889       33236 :         if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
    1890       16618 :             pqPutMsgEnd(conn) < 0)
    1891           0 :             goto sendFailed;
    1892             :     }
    1893             : 
    1894             :     /* remember we are using extended query protocol */
    1895       20304 :     entry->queryclass = PGQUERY_EXTENDED;
    1896             : 
    1897             :     /* and remember the query text too, if possible */
    1898             :     /* if insufficient memory, query just winds up NULL */
    1899       20304 :     if (command)
    1900        5776 :         entry->query = strdup(command);
    1901             : 
    1902             :     /*
    1903             :      * Give the data a push (in pipeline mode, only if we're past the size
    1904             :      * threshold).  In nonblock mode, don't complain if we're unable to send
    1905             :      * it all; PQgetResult() will do any additional flushing needed.
    1906             :      */
    1907       20304 :     if (pqPipelineFlush(conn) < 0)
    1908           0 :         goto sendFailed;
    1909             : 
    1910             :     /* OK, it's launched! */
    1911       20304 :     pqAppendCmdQueueEntry(conn, entry);
    1912             : 
    1913       20304 :     return 1;
    1914             : 
    1915           0 : sendFailed:
    1916           0 :     pqRecycleCmdQueueEntry(conn, entry);
    1917             :     /* error message should be set up already */
    1918           0 :     return 0;
    1919             : }
    1920             : 
    1921             : /*
    1922             :  * Is it OK to change partial-result mode now?
    1923             :  */
    1924             : static bool
    1925         144 : canChangeResultMode(PGconn *conn)
    1926             : {
    1927             :     /*
    1928             :      * Only allow changing the mode when we have launched a query and not yet
    1929             :      * received any results.
    1930             :      */
    1931         144 :     if (!conn)
    1932           0 :         return false;
    1933         144 :     if (conn->asyncStatus != PGASYNC_BUSY)
    1934           0 :         return false;
    1935         144 :     if (!conn->cmd_queue_head ||
    1936         144 :         (conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE &&
    1937          22 :          conn->cmd_queue_head->queryclass != PGQUERY_EXTENDED))
    1938           0 :         return false;
    1939         144 :     if (pgHavePendingResult(conn))
    1940           0 :         return false;
    1941         144 :     return true;
    1942             : }
    1943             : 
    1944             : /*
    1945             :  * Select row-by-row processing mode
    1946             :  */
    1947             : int
    1948          62 : PQsetSingleRowMode(PGconn *conn)
    1949             : {
    1950          62 :     if (canChangeResultMode(conn))
    1951             :     {
    1952          62 :         conn->partialResMode = true;
    1953          62 :         conn->singleRowMode = true;
    1954          62 :         conn->maxChunkSize = 1;
    1955          62 :         return 1;
    1956             :     }
    1957             :     else
    1958           0 :         return 0;
    1959             : }
    1960             : 
    1961             : /*
    1962             :  * Select chunked results processing mode
    1963             :  */
    1964             : int
    1965          82 : PQsetChunkedRowsMode(PGconn *conn, int chunkSize)
    1966             : {
    1967          82 :     if (chunkSize > 0 && canChangeResultMode(conn))
    1968             :     {
    1969          82 :         conn->partialResMode = true;
    1970          82 :         conn->singleRowMode = false;
    1971          82 :         conn->maxChunkSize = chunkSize;
    1972          82 :         return 1;
    1973             :     }
    1974             :     else
    1975           0 :         return 0;
    1976             : }
    1977             : 
    1978             : /*
    1979             :  * Consume any available input from the backend
    1980             :  * 0 return: some kind of trouble
    1981             :  * 1 return: no problem
    1982             :  */
    1983             : int
    1984      811086 : PQconsumeInput(PGconn *conn)
    1985             : {
    1986      811086 :     if (!conn)
    1987           0 :         return 0;
    1988             : 
    1989             :     /*
    1990             :      * for non-blocking connections try to flush the send-queue, otherwise we
    1991             :      * may never get a response for something that may not have already been
    1992             :      * sent because it's in our write buffer!
    1993             :      */
    1994      811086 :     if (pqIsnonblocking(conn))
    1995             :     {
    1996          12 :         if (pqFlush(conn) < 0)
    1997           0 :             return 0;
    1998             :     }
    1999             : 
    2000             :     /*
    2001             :      * Load more data, if available. We do this no matter what state we are
    2002             :      * in, since we are probably getting called because the application wants
    2003             :      * to get rid of a read-select condition. Note that we will NOT block
    2004             :      * waiting for more input.
    2005             :      */
    2006      811086 :     if (pqReadData(conn) < 0)
    2007         164 :         return 0;
    2008             : 
    2009             :     /* Parsing of the data waits till later. */
    2010      810922 :     return 1;
    2011             : }
    2012             : 
    2013             : 
    2014             : /*
    2015             :  * parseInput: if appropriate, parse input data from backend
    2016             :  * until input is exhausted or a stopping state is reached.
    2017             :  * Note that this function will NOT attempt to read more data from the backend.
    2018             :  */
    2019             : static void
    2020     3094746 : parseInput(PGconn *conn)
    2021             : {
    2022     3094746 :     pqParseInput3(conn);
    2023     3094746 : }
    2024             : 
    2025             : /*
    2026             :  * PQisBusy
    2027             :  *   Return true if PQgetResult would block waiting for input.
    2028             :  */
    2029             : 
    2030             : int
    2031      275264 : PQisBusy(PGconn *conn)
    2032             : {
    2033      275264 :     if (!conn)
    2034           0 :         return false;
    2035             : 
    2036             :     /* Parse any available data, if our state permits. */
    2037      275264 :     parseInput(conn);
    2038             : 
    2039             :     /*
    2040             :      * PQgetResult will return immediately in all states except BUSY.  Also,
    2041             :      * if we've detected read EOF and dropped the connection, we can expect
    2042             :      * that PQgetResult will fail immediately.  Note that we do *not* check
    2043             :      * conn->write_failed here --- once that's become set, we know we have
    2044             :      * trouble, but we need to keep trying to read until we have a complete
    2045             :      * server message or detect read EOF.
    2046             :      */
    2047      275264 :     return conn->asyncStatus == PGASYNC_BUSY && conn->status != CONNECTION_BAD;
    2048             : }
    2049             : 
    2050             : /*
    2051             :  * PQgetResult
    2052             :  *    Get the next PGresult produced by a query.  Returns NULL if no
    2053             :  *    query work remains or an error has occurred (e.g. out of
    2054             :  *    memory).
    2055             :  *
    2056             :  *    In pipeline mode, once all the result of a query have been returned,
    2057             :  *    PQgetResult returns NULL to let the user know that the next
    2058             :  *    query is being processed.  At the end of the pipeline, returns a
    2059             :  *    result with PQresultStatus(result) == PGRES_PIPELINE_SYNC.
    2060             :  */
    2061             : PGresult *
    2062     1348706 : PQgetResult(PGconn *conn)
    2063             : {
    2064             :     PGresult   *res;
    2065             : 
    2066     1348706 :     if (!conn)
    2067           0 :         return NULL;
    2068             : 
    2069             :     /* Parse any available data, if our state permits. */
    2070     1348706 :     parseInput(conn);
    2071             : 
    2072             :     /* If not ready to return something, block until we are. */
    2073     1916154 :     while (conn->asyncStatus == PGASYNC_BUSY)
    2074             :     {
    2075             :         int         flushResult;
    2076             : 
    2077             :         /*
    2078             :          * If data remains unsent, send it.  Else we might be waiting for the
    2079             :          * result of a command the backend hasn't even got yet.
    2080             :          */
    2081      567478 :         while ((flushResult = pqFlush(conn)) > 0)
    2082             :         {
    2083           0 :             if (pqWait(false, true, conn))
    2084             :             {
    2085           0 :                 flushResult = -1;
    2086           0 :                 break;
    2087             :             }
    2088             :         }
    2089             : 
    2090             :         /*
    2091             :          * Wait for some more data, and load it.  (Note: if the connection has
    2092             :          * been lost, pqWait should return immediately because the socket
    2093             :          * should be read-ready, either with the last server data or with an
    2094             :          * EOF indication.  We expect therefore that this won't result in any
    2095             :          * undue delay in reporting a previous write failure.)
    2096             :          */
    2097     1134956 :         if (flushResult ||
    2098     1134952 :             pqWait(true, false, conn) ||
    2099      567474 :             pqReadData(conn) < 0)
    2100             :         {
    2101             :             /* Report the error saved by pqWait or pqReadData */
    2102          26 :             pqSaveErrorResult(conn);
    2103          26 :             conn->asyncStatus = PGASYNC_IDLE;
    2104          26 :             return pqPrepareAsyncResult(conn);
    2105             :         }
    2106             : 
    2107             :         /* Parse it. */
    2108      567452 :         parseInput(conn);
    2109             : 
    2110             :         /*
    2111             :          * If we had a write error, but nothing above obtained a query result
    2112             :          * or detected a read error, report the write error.
    2113             :          */
    2114      567452 :         if (conn->write_failed && conn->asyncStatus == PGASYNC_BUSY)
    2115             :         {
    2116           4 :             pqSaveWriteError(conn);
    2117           4 :             conn->asyncStatus = PGASYNC_IDLE;
    2118           4 :             return pqPrepareAsyncResult(conn);
    2119             :         }
    2120             :     }
    2121             : 
    2122             :     /* Return the appropriate thing. */
    2123     1348676 :     switch (conn->asyncStatus)
    2124             :     {
    2125      731594 :         case PGASYNC_IDLE:
    2126      731594 :             res = NULL;         /* query is complete */
    2127      731594 :             break;
    2128        3698 :         case PGASYNC_PIPELINE_IDLE:
    2129             :             Assert(conn->pipelineStatus != PQ_PIPELINE_OFF);
    2130             : 
    2131             :             /*
    2132             :              * We're about to return the NULL that terminates the round of
    2133             :              * results from the current query; prepare to send the results of
    2134             :              * the next query, if any, when we're called next.  If there's no
    2135             :              * next element in the command queue, this gets us in IDLE state.
    2136             :              */
    2137        3698 :             pqPipelineProcessQueue(conn);
    2138        3698 :             res = NULL;         /* query is complete */
    2139        3698 :             break;
    2140             : 
    2141      597778 :         case PGASYNC_READY:
    2142      597778 :             res = pqPrepareAsyncResult(conn);
    2143             : 
    2144             :             /*
    2145             :              * Normally pqPrepareAsyncResult will have left conn->result
    2146             :              * empty.  Otherwise, "res" must be a not-full PGRES_TUPLES_CHUNK
    2147             :              * result, which we want to return to the caller while staying in
    2148             :              * PGASYNC_READY state.  Then the next call here will return the
    2149             :              * empty PGRES_TUPLES_OK result that was restored from
    2150             :              * saved_result, after which we can proceed.
    2151             :              */
    2152      597778 :             if (conn->result)
    2153             :             {
    2154             :                 Assert(res->resultStatus == PGRES_TUPLES_CHUNK);
    2155           8 :                 break;
    2156             :             }
    2157             : 
    2158             :             /* Advance the queue as appropriate */
    2159      597770 :             pqCommandQueueAdvance(conn, false,
    2160      597770 :                                   res->resultStatus == PGRES_PIPELINE_SYNC);
    2161             : 
    2162      597770 :             if (conn->pipelineStatus != PQ_PIPELINE_OFF)
    2163             :             {
    2164             :                 /*
    2165             :                  * We're about to send the results of the current query.  Set
    2166             :                  * us idle now, and ...
    2167             :                  */
    2168        3830 :                 conn->asyncStatus = PGASYNC_PIPELINE_IDLE;
    2169             : 
    2170             :                 /*
    2171             :                  * ... in cases when we're sending a pipeline-sync result,
    2172             :                  * move queue processing forwards immediately, so that next
    2173             :                  * time we're called, we're prepared to return the next result
    2174             :                  * received from the server.  In all other cases, leave the
    2175             :                  * queue state change for next time, so that a terminating
    2176             :                  * NULL result is sent.
    2177             :                  *
    2178             :                  * (In other words: we don't return a NULL after a pipeline
    2179             :                  * sync.)
    2180             :                  */
    2181        3830 :                 if (res->resultStatus == PGRES_PIPELINE_SYNC)
    2182         130 :                     pqPipelineProcessQueue(conn);
    2183             :             }
    2184             :             else
    2185             :             {
    2186             :                 /* Set the state back to BUSY, allowing parsing to proceed. */
    2187      593940 :                 conn->asyncStatus = PGASYNC_BUSY;
    2188             :             }
    2189      597770 :             break;
    2190        5244 :         case PGASYNC_READY_MORE:
    2191        5244 :             res = pqPrepareAsyncResult(conn);
    2192             :             /* Set the state back to BUSY, allowing parsing to proceed. */
    2193        5244 :             conn->asyncStatus = PGASYNC_BUSY;
    2194        5244 :             break;
    2195         946 :         case PGASYNC_COPY_IN:
    2196         946 :             res = getCopyResult(conn, PGRES_COPY_IN);
    2197         946 :             break;
    2198        8240 :         case PGASYNC_COPY_OUT:
    2199        8240 :             res = getCopyResult(conn, PGRES_COPY_OUT);
    2200        8240 :             break;
    2201        1176 :         case PGASYNC_COPY_BOTH:
    2202        1176 :             res = getCopyResult(conn, PGRES_COPY_BOTH);
    2203        1176 :             break;
    2204           0 :         default:
    2205           0 :             libpq_append_conn_error(conn, "unexpected asyncStatus: %d", (int) conn->asyncStatus);
    2206           0 :             pqSaveErrorResult(conn);
    2207           0 :             conn->asyncStatus = PGASYNC_IDLE;    /* try to restore valid state */
    2208           0 :             res = pqPrepareAsyncResult(conn);
    2209           0 :             break;
    2210             :     }
    2211             : 
    2212             :     /* Time to fire PGEVT_RESULTCREATE events, if there are any */
    2213     1348676 :     if (res && res->nEvents > 0)
    2214           0 :         (void) PQfireResultCreateEvents(conn, res);
    2215             : 
    2216     1348676 :     return res;
    2217             : }
    2218             : 
    2219             : /*
    2220             :  * getCopyResult
    2221             :  *    Helper for PQgetResult: generate result for COPY-in-progress cases
    2222             :  */
    2223             : static PGresult *
    2224       10362 : getCopyResult(PGconn *conn, ExecStatusType copytype)
    2225             : {
    2226             :     /*
    2227             :      * If the server connection has been lost, don't pretend everything is
    2228             :      * hunky-dory; instead return a PGRES_FATAL_ERROR result, and reset the
    2229             :      * asyncStatus to idle (corresponding to what we'd do if we'd detected I/O
    2230             :      * error in the earlier steps in PQgetResult).  The text returned in the
    2231             :      * result is whatever is in conn->errorMessage; we hope that was filled
    2232             :      * with something relevant when the lost connection was detected.
    2233             :      */
    2234       10362 :     if (conn->status != CONNECTION_OK)
    2235             :     {
    2236           0 :         pqSaveErrorResult(conn);
    2237           0 :         conn->asyncStatus = PGASYNC_IDLE;
    2238           0 :         return pqPrepareAsyncResult(conn);
    2239             :     }
    2240             : 
    2241             :     /* If we have an async result for the COPY, return that */
    2242       10362 :     if (conn->result && conn->result->resultStatus == copytype)
    2243       10000 :         return pqPrepareAsyncResult(conn);
    2244             : 
    2245             :     /* Otherwise, invent a suitable PGresult */
    2246         362 :     return PQmakeEmptyPGresult(conn, copytype);
    2247             : }
    2248             : 
    2249             : 
    2250             : /*
    2251             :  * PQexec
    2252             :  *    send a query to the backend and package up the result in a PGresult
    2253             :  *
    2254             :  * If the query was not even sent, return NULL; conn->errorMessage is set to
    2255             :  * a relevant message.
    2256             :  * If the query was sent, a new PGresult is returned (which could indicate
    2257             :  * either success or failure).
    2258             :  * The user is responsible for freeing the PGresult via PQclear()
    2259             :  * when done with it.
    2260             :  */
    2261             : PGresult *
    2262      138178 : PQexec(PGconn *conn, const char *query)
    2263             : {
    2264      138178 :     if (!PQexecStart(conn))
    2265           2 :         return NULL;
    2266      138176 :     if (!PQsendQuery(conn, query))
    2267           0 :         return NULL;
    2268      138176 :     return PQexecFinish(conn);
    2269             : }
    2270             : 
    2271             : /*
    2272             :  * PQexecParams
    2273             :  *      Like PQexec, but use extended query protocol so we can pass parameters
    2274             :  */
    2275             : PGresult *
    2276        2782 : PQexecParams(PGconn *conn,
    2277             :              const char *command,
    2278             :              int nParams,
    2279             :              const Oid *paramTypes,
    2280             :              const char *const *paramValues,
    2281             :              const int *paramLengths,
    2282             :              const int *paramFormats,
    2283             :              int resultFormat)
    2284             : {
    2285        2782 :     if (!PQexecStart(conn))
    2286           0 :         return NULL;
    2287        2782 :     if (!PQsendQueryParams(conn, command,
    2288             :                            nParams, paramTypes, paramValues, paramLengths,
    2289             :                            paramFormats, resultFormat))
    2290           0 :         return NULL;
    2291        2782 :     return PQexecFinish(conn);
    2292             : }
    2293             : 
    2294             : /*
    2295             :  * PQprepare
    2296             :  *    Creates a prepared statement by issuing a Parse message.
    2297             :  *
    2298             :  * If the query was not even sent, return NULL; conn->errorMessage is set to
    2299             :  * a relevant message.
    2300             :  * If the query was sent, a new PGresult is returned (which could indicate
    2301             :  * either success or failure).
    2302             :  * The user is responsible for freeing the PGresult via PQclear()
    2303             :  * when done with it.
    2304             :  */
    2305             : PGresult *
    2306        3964 : PQprepare(PGconn *conn,
    2307             :           const char *stmtName, const char *query,
    2308             :           int nParams, const Oid *paramTypes)
    2309             : {
    2310        3964 :     if (!PQexecStart(conn))
    2311           0 :         return NULL;
    2312        3964 :     if (!PQsendPrepare(conn, stmtName, query, nParams, paramTypes))
    2313           0 :         return NULL;
    2314        3964 :     return PQexecFinish(conn);
    2315             : }
    2316             : 
    2317             : /*
    2318             :  * PQexecPrepared
    2319             :  *      Like PQexec, but execute a previously prepared statement,
    2320             :  *      using extended query protocol so we can pass parameters
    2321             :  */
    2322             : PGresult *
    2323        6450 : PQexecPrepared(PGconn *conn,
    2324             :                const char *stmtName,
    2325             :                int nParams,
    2326             :                const char *const *paramValues,
    2327             :                const int *paramLengths,
    2328             :                const int *paramFormats,
    2329             :                int resultFormat)
    2330             : {
    2331        6450 :     if (!PQexecStart(conn))
    2332           0 :         return NULL;
    2333        6450 :     if (!PQsendQueryPrepared(conn, stmtName,
    2334             :                              nParams, paramValues, paramLengths,
    2335             :                              paramFormats, resultFormat))
    2336           0 :         return NULL;
    2337        6450 :     return PQexecFinish(conn);
    2338             : }
    2339             : 
    2340             : /*
    2341             :  * Common code for PQexec and sibling routines: prepare to send command
    2342             :  */
    2343             : static bool
    2344      151520 : PQexecStart(PGconn *conn)
    2345             : {
    2346             :     PGresult   *result;
    2347             : 
    2348      151520 :     if (!conn)
    2349           0 :         return false;
    2350             : 
    2351             :     /*
    2352             :      * Since this is the beginning of a query cycle, reset the error state.
    2353             :      * However, in pipeline mode with something already queued, the error
    2354             :      * buffer belongs to that command and we shouldn't clear it.
    2355             :      */
    2356      151520 :     if (conn->cmd_queue_head == NULL)
    2357      151506 :         pqClearConnErrorState(conn);
    2358             : 
    2359      151520 :     if (conn->pipelineStatus != PQ_PIPELINE_OFF)
    2360             :     {
    2361           2 :         libpq_append_conn_error(conn, "synchronous command execution functions are not allowed in pipeline mode");
    2362           2 :         return false;
    2363             :     }
    2364             : 
    2365             :     /*
    2366             :      * Silently discard any prior query result that application didn't eat.
    2367             :      * This is probably poor design, but it's here for backward compatibility.
    2368             :      */
    2369      151518 :     while ((result = PQgetResult(conn)) != NULL)
    2370             :     {
    2371           0 :         ExecStatusType resultStatus = result->resultStatus;
    2372             : 
    2373           0 :         PQclear(result);        /* only need its status */
    2374           0 :         if (resultStatus == PGRES_COPY_IN)
    2375             :         {
    2376             :             /* get out of a COPY IN state */
    2377           0 :             if (PQputCopyEnd(conn,
    2378           0 :                              libpq_gettext("COPY terminated by new PQexec")) < 0)
    2379           0 :                 return false;
    2380             :             /* keep waiting to swallow the copy's failure message */
    2381             :         }
    2382           0 :         else if (resultStatus == PGRES_COPY_OUT)
    2383             :         {
    2384             :             /*
    2385             :              * Get out of a COPY OUT state: we just switch back to BUSY and
    2386             :              * allow the remaining COPY data to be dropped on the floor.
    2387             :              */
    2388           0 :             conn->asyncStatus = PGASYNC_BUSY;
    2389             :             /* keep waiting to swallow the copy's completion message */
    2390             :         }
    2391           0 :         else if (resultStatus == PGRES_COPY_BOTH)
    2392             :         {
    2393             :             /* We don't allow PQexec during COPY BOTH */
    2394           0 :             libpq_append_conn_error(conn, "PQexec not allowed during COPY BOTH");
    2395           0 :             return false;
    2396             :         }
    2397             :         /* check for loss of connection, too */
    2398           0 :         if (conn->status == CONNECTION_BAD)
    2399           0 :             return false;
    2400             :     }
    2401             : 
    2402             :     /* OK to send a command */
    2403      151518 :     return true;
    2404             : }
    2405             : 
    2406             : /*
    2407             :  * Common code for PQexec and sibling routines: wait for command result
    2408             :  */
    2409             : static PGresult *
    2410      151518 : PQexecFinish(PGconn *conn)
    2411             : {
    2412             :     PGresult   *result;
    2413             :     PGresult   *lastResult;
    2414             : 
    2415             :     /*
    2416             :      * For backwards compatibility, return the last result if there are more
    2417             :      * than one.  (We used to have logic here to concatenate successive error
    2418             :      * messages, but now that happens automatically, since conn->errorMessage
    2419             :      * will continue to accumulate errors throughout this loop.)
    2420             :      *
    2421             :      * We have to stop if we see copy in/out/both, however. We will resume
    2422             :      * parsing after application performs the data transfer.
    2423             :      *
    2424             :      * Also stop if the connection is lost (else we'll loop infinitely).
    2425             :      */
    2426      151518 :     lastResult = NULL;
    2427      326870 :     while ((result = PQgetResult(conn)) != NULL)
    2428             :     {
    2429      182452 :         PQclear(lastResult);
    2430      182452 :         lastResult = result;
    2431      182452 :         if (result->resultStatus == PGRES_COPY_IN ||
    2432      182422 :             result->resultStatus == PGRES_COPY_OUT ||
    2433      175630 :             result->resultStatus == PGRES_COPY_BOTH ||
    2434      175352 :             conn->status == CONNECTION_BAD)
    2435             :             break;
    2436             :     }
    2437             : 
    2438      151518 :     return lastResult;
    2439             : }
    2440             : 
    2441             : /*
    2442             :  * PQdescribePrepared
    2443             :  *    Obtain information about a previously prepared statement
    2444             :  *
    2445             :  * If the query was not even sent, return NULL; conn->errorMessage is set to
    2446             :  * a relevant message.
    2447             :  * If the query was sent, a new PGresult is returned (which could indicate
    2448             :  * either success or failure).  On success, the PGresult contains status
    2449             :  * PGRES_COMMAND_OK, and its parameter and column-heading fields describe
    2450             :  * the statement's inputs and outputs respectively.
    2451             :  * The user is responsible for freeing the PGresult via PQclear()
    2452             :  * when done with it.
    2453             :  */
    2454             : PGresult *
    2455         140 : PQdescribePrepared(PGconn *conn, const char *stmt)
    2456             : {
    2457         140 :     if (!PQexecStart(conn))
    2458           0 :         return NULL;
    2459         140 :     if (!PQsendTypedCommand(conn, PqMsg_Describe, 'S', stmt))
    2460           0 :         return NULL;
    2461         140 :     return PQexecFinish(conn);
    2462             : }
    2463             : 
    2464             : /*
    2465             :  * PQdescribePortal
    2466             :  *    Obtain information about a previously created portal
    2467             :  *
    2468             :  * This is much like PQdescribePrepared, except that no parameter info is
    2469             :  * returned.  Note that at the moment, libpq doesn't really expose portals
    2470             :  * to the client; but this can be used with a portal created by a SQL
    2471             :  * DECLARE CURSOR command.
    2472             :  */
    2473             : PGresult *
    2474           2 : PQdescribePortal(PGconn *conn, const char *portal)
    2475             : {
    2476           2 :     if (!PQexecStart(conn))
    2477           0 :         return NULL;
    2478           2 :     if (!PQsendTypedCommand(conn, PqMsg_Describe, 'P', portal))
    2479           0 :         return NULL;
    2480           2 :     return PQexecFinish(conn);
    2481             : }
    2482             : 
    2483             : /*
    2484             :  * PQsendDescribePrepared
    2485             :  *   Submit a Describe Statement command, but don't wait for it to finish
    2486             :  *
    2487             :  * Returns: 1 if successfully submitted
    2488             :  *          0 if error (conn->errorMessage is set)
    2489             :  */
    2490             : int
    2491           2 : PQsendDescribePrepared(PGconn *conn, const char *stmt)
    2492             : {
    2493           2 :     return PQsendTypedCommand(conn, PqMsg_Describe, 'S', stmt);
    2494             : }
    2495             : 
    2496             : /*
    2497             :  * PQsendDescribePortal
    2498             :  *   Submit a Describe Portal command, but don't wait for it to finish
    2499             :  *
    2500             :  * Returns: 1 if successfully submitted
    2501             :  *          0 if error (conn->errorMessage is set)
    2502             :  */
    2503             : int
    2504           2 : PQsendDescribePortal(PGconn *conn, const char *portal)
    2505             : {
    2506           2 :     return PQsendTypedCommand(conn, PqMsg_Describe, 'P', portal);
    2507             : }
    2508             : 
    2509             : /*
    2510             :  * PQclosePrepared
    2511             :  *    Close a previously prepared statement
    2512             :  *
    2513             :  * If the query was not even sent, return NULL; conn->errorMessage is set to
    2514             :  * a relevant message.
    2515             :  * If the query was sent, a new PGresult is returned (which could indicate
    2516             :  * either success or failure).  On success, the PGresult contains status
    2517             :  * PGRES_COMMAND_OK. The user is responsible for freeing the PGresult via
    2518             :  * PQclear() when done with it.
    2519             :  */
    2520             : PGresult *
    2521           2 : PQclosePrepared(PGconn *conn, const char *stmt)
    2522             : {
    2523           2 :     if (!PQexecStart(conn))
    2524           0 :         return NULL;
    2525           2 :     if (!PQsendTypedCommand(conn, PqMsg_Close, 'S', stmt))
    2526           0 :         return NULL;
    2527           2 :     return PQexecFinish(conn);
    2528             : }
    2529             : 
    2530             : /*
    2531             :  * PQclosePortal
    2532             :  *    Close a previously created portal
    2533             :  *
    2534             :  * This is exactly like PQclosePrepared, but for portals.  Note that at the
    2535             :  * moment, libpq doesn't really expose portals to the client; but this can be
    2536             :  * used with a portal created by a SQL DECLARE CURSOR command.
    2537             :  */
    2538             : PGresult *
    2539           2 : PQclosePortal(PGconn *conn, const char *portal)
    2540             : {
    2541           2 :     if (!PQexecStart(conn))
    2542           0 :         return NULL;
    2543           2 :     if (!PQsendTypedCommand(conn, PqMsg_Close, 'P', portal))
    2544           0 :         return NULL;
    2545           2 :     return PQexecFinish(conn);
    2546             : }
    2547             : 
    2548             : /*
    2549             :  * PQsendClosePrepared
    2550             :  *   Submit a Close Statement command, but don't wait for it to finish
    2551             :  *
    2552             :  * Returns: 1 if successfully submitted
    2553             :  *          0 if error (conn->errorMessage is set)
    2554             :  */
    2555             : int
    2556           2 : PQsendClosePrepared(PGconn *conn, const char *stmt)
    2557             : {
    2558           2 :     return PQsendTypedCommand(conn, PqMsg_Close, 'S', stmt);
    2559             : }
    2560             : 
    2561             : /*
    2562             :  * PQsendClosePortal
    2563             :  *   Submit a Close Portal command, but don't wait for it to finish
    2564             :  *
    2565             :  * Returns: 1 if successfully submitted
    2566             :  *          0 if error (conn->errorMessage is set)
    2567             :  */
    2568             : int
    2569           2 : PQsendClosePortal(PGconn *conn, const char *portal)
    2570             : {
    2571           2 :     return PQsendTypedCommand(conn, PqMsg_Close, 'P', portal);
    2572             : }
    2573             : 
    2574             : /*
    2575             :  * PQsendTypedCommand
    2576             :  *   Common code to send a Describe or Close command
    2577             :  *
    2578             :  * Available options for "command" are
    2579             :  *   PqMsg_Close for Close; or
    2580             :  *   PqMsg_Describe for Describe.
    2581             :  *
    2582             :  * Available options for "type" are
    2583             :  *   'S' to run a command on a prepared statement; or
    2584             :  *   'P' to run a command on a portal.
    2585             :  *
    2586             :  * Returns 1 on success and 0 on failure.
    2587             :  */
    2588             : static int
    2589         154 : PQsendTypedCommand(PGconn *conn, char command, char type, const char *target)
    2590             : {
    2591         154 :     PGcmdQueueEntry *entry = NULL;
    2592             : 
    2593             :     /* Treat null target as empty string */
    2594         154 :     if (!target)
    2595           0 :         target = "";
    2596             : 
    2597         154 :     if (!PQsendQueryStart(conn, true))
    2598           0 :         return 0;
    2599             : 
    2600         154 :     entry = pqAllocCmdQueueEntry(conn);
    2601         154 :     if (entry == NULL)
    2602           0 :         return 0;               /* error msg already set */
    2603             : 
    2604             :     /* construct the Close message */
    2605         308 :     if (pqPutMsgStart(command, conn) < 0 ||
    2606         308 :         pqPutc(type, conn) < 0 ||
    2607         308 :         pqPuts(target, conn) < 0 ||
    2608         154 :         pqPutMsgEnd(conn) < 0)
    2609           0 :         goto sendFailed;
    2610             : 
    2611             :     /* construct the Sync message */
    2612         154 :     if (conn->pipelineStatus == PQ_PIPELINE_OFF)
    2613             :     {
    2614         292 :         if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
    2615         146 :             pqPutMsgEnd(conn) < 0)
    2616           0 :             goto sendFailed;
    2617             :     }
    2618             : 
    2619             :     /* remember if we are doing a Close or a Describe */
    2620         154 :     if (command == PqMsg_Close)
    2621             :     {
    2622           8 :         entry->queryclass = PGQUERY_CLOSE;
    2623             :     }
    2624         146 :     else if (command == PqMsg_Describe)
    2625             :     {
    2626         146 :         entry->queryclass = PGQUERY_DESCRIBE;
    2627             :     }
    2628             :     else
    2629             :     {
    2630           0 :         libpq_append_conn_error(conn, "unknown command type provided");
    2631           0 :         goto sendFailed;
    2632             :     }
    2633             : 
    2634             :     /*
    2635             :      * Give the data a push (in pipeline mode, only if we're past the size
    2636             :      * threshold).  In nonblock mode, don't complain if we're unable to send
    2637             :      * it all; PQgetResult() will do any additional flushing needed.
    2638             :      */
    2639         154 :     if (pqPipelineFlush(conn) < 0)
    2640           0 :         goto sendFailed;
    2641             : 
    2642             :     /* OK, it's launched! */
    2643         154 :     pqAppendCmdQueueEntry(conn, entry);
    2644             : 
    2645         154 :     return 1;
    2646             : 
    2647           0 : sendFailed:
    2648           0 :     pqRecycleCmdQueueEntry(conn, entry);
    2649             :     /* error message should be set up already */
    2650           0 :     return 0;
    2651             : }
    2652             : 
    2653             : /*
    2654             :  * PQnotifies
    2655             :  *    returns a PGnotify* structure of the latest async notification
    2656             :  * that has not yet been handled
    2657             :  *
    2658             :  * returns NULL, if there is currently
    2659             :  * no unhandled async notification from the backend
    2660             :  *
    2661             :  * the CALLER is responsible for FREE'ing the structure returned
    2662             :  *
    2663             :  * Note that this function does not read any new data from the socket;
    2664             :  * so usually, caller should call PQconsumeInput() first.
    2665             :  */
    2666             : PGnotify *
    2667      353328 : PQnotifies(PGconn *conn)
    2668             : {
    2669             :     PGnotify   *event;
    2670             : 
    2671      353328 :     if (!conn)
    2672           0 :         return NULL;
    2673             : 
    2674             :     /* Parse any available data to see if we can extract NOTIFY messages. */
    2675      353328 :     parseInput(conn);
    2676             : 
    2677      353328 :     event = conn->notifyHead;
    2678      353328 :     if (event)
    2679             :     {
    2680          62 :         conn->notifyHead = event->next;
    2681          62 :         if (!conn->notifyHead)
    2682          38 :             conn->notifyTail = NULL;
    2683          62 :         event->next = NULL;      /* don't let app see the internal state */
    2684             :     }
    2685      353328 :     return event;
    2686             : }
    2687             : 
    2688             : /*
    2689             :  * PQputCopyData - send some data to the backend during COPY IN or COPY BOTH
    2690             :  *
    2691             :  * Returns 1 if successful, 0 if data could not be sent (only possible
    2692             :  * in nonblock mode), or -1 if an error occurs.
    2693             :  */
    2694             : int
    2695      549996 : PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
    2696             : {
    2697      549996 :     if (!conn)
    2698           0 :         return -1;
    2699      549996 :     if (conn->asyncStatus != PGASYNC_COPY_IN &&
    2700      148810 :         conn->asyncStatus != PGASYNC_COPY_BOTH)
    2701             :     {
    2702           0 :         libpq_append_conn_error(conn, "no COPY in progress");
    2703           0 :         return -1;
    2704             :     }
    2705             : 
    2706             :     /*
    2707             :      * Process any NOTICE or NOTIFY messages that might be pending in the
    2708             :      * input buffer.  Since the server might generate many notices during the
    2709             :      * COPY, we want to clean those out reasonably promptly to prevent
    2710             :      * indefinite expansion of the input buffer.  (Note: the actual read of
    2711             :      * input data into the input buffer happens down inside pqSendSome, but
    2712             :      * it's not authorized to get rid of the data again.)
    2713             :      */
    2714      549996 :     parseInput(conn);
    2715             : 
    2716      549996 :     if (nbytes > 0)
    2717             :     {
    2718             :         /*
    2719             :          * Try to flush any previously sent data in preference to growing the
    2720             :          * output buffer.  If we can't enlarge the buffer enough to hold the
    2721             :          * data, return 0 in the nonblock case, else hard error. (For
    2722             :          * simplicity, always assume 5 bytes of overhead.)
    2723             :          */
    2724      549996 :         if ((conn->outBufSize - conn->outCount - 5) < nbytes)
    2725             :         {
    2726          30 :             if (pqFlush(conn) < 0)
    2727           0 :                 return -1;
    2728          30 :             if (pqCheckOutBufferSpace(conn->outCount + 5 + (size_t) nbytes,
    2729             :                                       conn))
    2730           0 :                 return pqIsnonblocking(conn) ? 0 : -1;
    2731             :         }
    2732             :         /* Send the data (too simple to delegate to fe-protocol files) */
    2733     1099992 :         if (pqPutMsgStart(PqMsg_CopyData, conn) < 0 ||
    2734     1099992 :             pqPutnchar(buffer, nbytes, conn) < 0 ||
    2735      549996 :             pqPutMsgEnd(conn) < 0)
    2736           0 :             return -1;
    2737             :     }
    2738      549996 :     return 1;
    2739             : }
    2740             : 
    2741             : /*
    2742             :  * PQputCopyEnd - send EOF indication to the backend during COPY IN
    2743             :  *
    2744             :  * After calling this, use PQgetResult() to check command completion status.
    2745             :  *
    2746             :  * Returns 1 if successful, or -1 if an error occurs.
    2747             :  */
    2748             : int
    2749        1566 : PQputCopyEnd(PGconn *conn, const char *errormsg)
    2750             : {
    2751        1566 :     if (!conn)
    2752           0 :         return -1;
    2753        1566 :     if (conn->asyncStatus != PGASYNC_COPY_IN &&
    2754         632 :         conn->asyncStatus != PGASYNC_COPY_BOTH)
    2755             :     {
    2756          56 :         libpq_append_conn_error(conn, "no COPY in progress");
    2757          56 :         return -1;
    2758             :     }
    2759             : 
    2760             :     /*
    2761             :      * Send the COPY END indicator.  This is simple enough that we don't
    2762             :      * bother delegating it to the fe-protocol files.
    2763             :      */
    2764        1510 :     if (errormsg)
    2765             :     {
    2766             :         /* Send COPY FAIL */
    2767           0 :         if (pqPutMsgStart(PqMsg_CopyFail, conn) < 0 ||
    2768           0 :             pqPuts(errormsg, conn) < 0 ||
    2769           0 :             pqPutMsgEnd(conn) < 0)
    2770           0 :             return -1;
    2771             :     }
    2772             :     else
    2773             :     {
    2774             :         /* Send COPY DONE */
    2775        3020 :         if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
    2776        1510 :             pqPutMsgEnd(conn) < 0)
    2777           0 :             return -1;
    2778             :     }
    2779             : 
    2780             :     /*
    2781             :      * If we sent the COPY command in extended-query mode, we must issue a
    2782             :      * Sync as well.
    2783             :      */
    2784        1510 :     if (conn->cmd_queue_head &&
    2785        1510 :         conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE)
    2786             :     {
    2787           0 :         if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
    2788           0 :             pqPutMsgEnd(conn) < 0)
    2789           0 :             return -1;
    2790             :     }
    2791             : 
    2792             :     /* Return to active duty */
    2793        1510 :     if (conn->asyncStatus == PGASYNC_COPY_BOTH)
    2794         576 :         conn->asyncStatus = PGASYNC_COPY_OUT;
    2795             :     else
    2796         934 :         conn->asyncStatus = PGASYNC_BUSY;
    2797             : 
    2798             :     /* Try to flush data */
    2799        1510 :     if (pqFlush(conn) < 0)
    2800           0 :         return -1;
    2801             : 
    2802        1510 :     return 1;
    2803             : }
    2804             : 
    2805             : /*
    2806             :  * PQgetCopyData - read a row of data from the backend during COPY OUT
    2807             :  * or COPY BOTH
    2808             :  *
    2809             :  * If successful, sets *buffer to point to a malloc'd row of data, and
    2810             :  * returns row length (always > 0) as result.
    2811             :  * Returns 0 if no row available yet (only possible if async is true),
    2812             :  * -1 if end of copy (consult PQgetResult), or -2 if error (consult
    2813             :  * PQerrorMessage).
    2814             :  */
    2815             : int
    2816     4947948 : PQgetCopyData(PGconn *conn, char **buffer, int async)
    2817             : {
    2818     4947948 :     *buffer = NULL;             /* for all failure cases */
    2819     4947948 :     if (!conn)
    2820           0 :         return -2;
    2821     4947948 :     if (conn->asyncStatus != PGASYNC_COPY_OUT &&
    2822      906724 :         conn->asyncStatus != PGASYNC_COPY_BOTH)
    2823             :     {
    2824           0 :         libpq_append_conn_error(conn, "no COPY in progress");
    2825           0 :         return -2;
    2826             :     }
    2827     4947948 :     return pqGetCopyData3(conn, buffer, async);
    2828             : }
    2829             : 
    2830             : /*
    2831             :  * PQgetline - gets a newline-terminated string from the backend.
    2832             :  *
    2833             :  * Chiefly here so that applications can use "COPY <rel> to stdout"
    2834             :  * and read the output string.  Returns a null-terminated string in `buffer`.
    2835             :  *
    2836             :  * XXX this routine is now deprecated, because it can't handle binary data.
    2837             :  * If called during a COPY BINARY we return EOF.
    2838             :  *
    2839             :  * PQgetline reads up to `length`-1 characters (like fgets(3)) but strips
    2840             :  * the terminating \n (like gets(3)).
    2841             :  *
    2842             :  * CAUTION: the caller is responsible for detecting the end-of-copy signal
    2843             :  * (a line containing just "\.") when using this routine.
    2844             :  *
    2845             :  * RETURNS:
    2846             :  *      EOF if error (eg, invalid arguments are given)
    2847             :  *      0 if EOL is reached (i.e., \n has been read)
    2848             :  *              (this is required for backward-compatibility -- this
    2849             :  *               routine used to always return EOF or 0, assuming that
    2850             :  *               the line ended within `length` bytes.)
    2851             :  *      1 in other cases (i.e., the buffer was filled before \n is reached)
    2852             :  */
    2853             : int
    2854           0 : PQgetline(PGconn *conn, char *buffer, int length)
    2855             : {
    2856           0 :     if (!buffer || length <= 0)
    2857           0 :         return EOF;
    2858           0 :     *buffer = '\0';
    2859             :     /* length must be at least 3 to hold the \. terminator! */
    2860           0 :     if (length < 3)
    2861           0 :         return EOF;
    2862             : 
    2863           0 :     if (!conn)
    2864           0 :         return EOF;
    2865             : 
    2866           0 :     return pqGetline3(conn, buffer, length);
    2867             : }
    2868             : 
    2869             : /*
    2870             :  * PQgetlineAsync - gets a COPY data row without blocking.
    2871             :  *
    2872             :  * This routine is for applications that want to do "COPY <rel> to stdout"
    2873             :  * asynchronously, that is without blocking.  Having issued the COPY command
    2874             :  * and gotten a PGRES_COPY_OUT response, the app should call PQconsumeInput
    2875             :  * and this routine until the end-of-data signal is detected.  Unlike
    2876             :  * PQgetline, this routine takes responsibility for detecting end-of-data.
    2877             :  *
    2878             :  * On each call, PQgetlineAsync will return data if a complete data row
    2879             :  * is available in libpq's input buffer.  Otherwise, no data is returned
    2880             :  * until the rest of the row arrives.
    2881             :  *
    2882             :  * If -1 is returned, the end-of-data signal has been recognized (and removed
    2883             :  * from libpq's input buffer).  The caller *must* next call PQendcopy and
    2884             :  * then return to normal processing.
    2885             :  *
    2886             :  * RETURNS:
    2887             :  *   -1    if the end-of-copy-data marker has been recognized
    2888             :  *   0     if no data is available
    2889             :  *   >0    the number of bytes returned.
    2890             :  *
    2891             :  * The data returned will not extend beyond a data-row boundary.  If possible
    2892             :  * a whole row will be returned at one time.  But if the buffer offered by
    2893             :  * the caller is too small to hold a row sent by the backend, then a partial
    2894             :  * data row will be returned.  In text mode this can be detected by testing
    2895             :  * whether the last returned byte is '\n' or not.
    2896             :  *
    2897             :  * The returned data is *not* null-terminated.
    2898             :  */
    2899             : 
    2900             : int
    2901           0 : PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
    2902             : {
    2903           0 :     if (!conn)
    2904           0 :         return -1;
    2905             : 
    2906           0 :     return pqGetlineAsync3(conn, buffer, bufsize);
    2907             : }
    2908             : 
    2909             : /*
    2910             :  * PQputline -- sends a string to the backend during COPY IN.
    2911             :  * Returns 0 if OK, EOF if not.
    2912             :  *
    2913             :  * This is deprecated primarily because the return convention doesn't allow
    2914             :  * caller to tell the difference between a hard error and a nonblock-mode
    2915             :  * send failure.
    2916             :  */
    2917             : int
    2918      400056 : PQputline(PGconn *conn, const char *string)
    2919             : {
    2920      400056 :     return PQputnbytes(conn, string, strlen(string));
    2921             : }
    2922             : 
    2923             : /*
    2924             :  * PQputnbytes -- like PQputline, but buffer need not be null-terminated.
    2925             :  * Returns 0 if OK, EOF if not.
    2926             :  */
    2927             : int
    2928      400056 : PQputnbytes(PGconn *conn, const char *buffer, int nbytes)
    2929             : {
    2930      400056 :     if (PQputCopyData(conn, buffer, nbytes) > 0)
    2931      400056 :         return 0;
    2932             :     else
    2933           0 :         return EOF;
    2934             : }
    2935             : 
    2936             : /*
    2937             :  * PQendcopy
    2938             :  *      After completing the data transfer portion of a copy in/out,
    2939             :  *      the application must call this routine to finish the command protocol.
    2940             :  *
    2941             :  * This is deprecated; it's cleaner to use PQgetResult to get the transfer
    2942             :  * status.
    2943             :  *
    2944             :  * RETURNS:
    2945             :  *      0 on success
    2946             :  *      1 on failure
    2947             :  */
    2948             : int
    2949         332 : PQendcopy(PGconn *conn)
    2950             : {
    2951         332 :     if (!conn)
    2952           0 :         return 0;
    2953             : 
    2954         332 :     return pqEndcopy3(conn);
    2955             : }
    2956             : 
    2957             : 
    2958             : /* ----------------
    2959             :  *      PQfn -  Send a function call to the POSTGRES backend.
    2960             :  *
    2961             :  *      conn            : backend connection
    2962             :  *      fnid            : OID of function to be called
    2963             :  *      result_buf      : pointer to result buffer
    2964             :  *      result_len      : actual length of result is returned here
    2965             :  *      result_is_int   : If the result is an integer, this must be 1,
    2966             :  *                        otherwise this should be 0
    2967             :  *      args            : pointer to an array of function arguments
    2968             :  *                        (each has length, if integer, and value/pointer)
    2969             :  *      nargs           : # of arguments in args array.
    2970             :  *
    2971             :  * RETURNS
    2972             :  *      PGresult with status = PGRES_COMMAND_OK if successful.
    2973             :  *          *result_len is > 0 if there is a return value, 0 if not.
    2974             :  *      PGresult with status = PGRES_FATAL_ERROR if backend returns an error.
    2975             :  *      NULL on communications failure.  conn->errorMessage will be set.
    2976             :  * ----------------
    2977             :  */
    2978             : 
    2979             : PGresult *
    2980        2084 : PQfn(PGconn *conn,
    2981             :      int fnid,
    2982             :      int *result_buf,
    2983             :      int *result_len,
    2984             :      int result_is_int,
    2985             :      const PQArgBlock *args,
    2986             :      int nargs)
    2987             : {
    2988        2084 :     *result_len = 0;
    2989             : 
    2990        2084 :     if (!conn)
    2991           0 :         return NULL;
    2992             : 
    2993             :     /*
    2994             :      * Since this is the beginning of a query cycle, reset the error state.
    2995             :      * However, in pipeline mode with something already queued, the error
    2996             :      * buffer belongs to that command and we shouldn't clear it.
    2997             :      */
    2998        2084 :     if (conn->cmd_queue_head == NULL)
    2999        2084 :         pqClearConnErrorState(conn);
    3000             : 
    3001        2084 :     if (conn->pipelineStatus != PQ_PIPELINE_OFF)
    3002             :     {
    3003           0 :         libpq_append_conn_error(conn, "%s not allowed in pipeline mode", "PQfn");
    3004           0 :         return NULL;
    3005             :     }
    3006             : 
    3007        2084 :     if (conn->sock == PGINVALID_SOCKET || conn->asyncStatus != PGASYNC_IDLE ||
    3008        2084 :         pgHavePendingResult(conn))
    3009             :     {
    3010           0 :         libpq_append_conn_error(conn, "connection in wrong state");
    3011           0 :         return NULL;
    3012             :     }
    3013             : 
    3014        2084 :     return pqFunctionCall3(conn, fnid,
    3015             :                            result_buf, result_len,
    3016             :                            result_is_int,
    3017             :                            args, nargs);
    3018             : }
    3019             : 
    3020             : /* ====== Pipeline mode support ======== */
    3021             : 
    3022             : /*
    3023             :  * PQenterPipelineMode
    3024             :  *      Put an idle connection in pipeline mode.
    3025             :  *
    3026             :  * Returns 1 on success. On failure, errorMessage is set and 0 is returned.
    3027             :  *
    3028             :  * Commands submitted after this can be pipelined on the connection;
    3029             :  * there's no requirement to wait for one to finish before the next is
    3030             :  * dispatched.
    3031             :  *
    3032             :  * Queuing of a new query or syncing during COPY is not allowed.
    3033             :  *
    3034             :  * A set of commands is terminated by a PQpipelineSync.  Multiple sync
    3035             :  * points can be established while in pipeline mode.  Pipeline mode can
    3036             :  * be exited by calling PQexitPipelineMode() once all results are processed.
    3037             :  *
    3038             :  * This doesn't actually send anything on the wire, it just puts libpq
    3039             :  * into a state where it can pipeline work.
    3040             :  */
    3041             : int
    3042         126 : PQenterPipelineMode(PGconn *conn)
    3043             : {
    3044         126 :     if (!conn)
    3045           0 :         return 0;
    3046             : 
    3047             :     /* succeed with no action if already in pipeline mode */
    3048         126 :     if (conn->pipelineStatus != PQ_PIPELINE_OFF)
    3049           2 :         return 1;
    3050             : 
    3051         124 :     if (conn->asyncStatus != PGASYNC_IDLE)
    3052             :     {
    3053           0 :         libpq_append_conn_error(conn, "cannot enter pipeline mode, connection not idle");
    3054           0 :         return 0;
    3055             :     }
    3056             : 
    3057         124 :     conn->pipelineStatus = PQ_PIPELINE_ON;
    3058             : 
    3059         124 :     return 1;
    3060             : }
    3061             : 
    3062             : /*
    3063             :  * PQexitPipelineMode
    3064             :  *      End pipeline mode and return to normal command mode.
    3065             :  *
    3066             :  * Returns 1 in success (pipeline mode successfully ended, or not in pipeline
    3067             :  * mode).
    3068             :  *
    3069             :  * Returns 0 if in pipeline mode and cannot be ended yet.  Error message will
    3070             :  * be set.
    3071             :  */
    3072             : int
    3073         122 : PQexitPipelineMode(PGconn *conn)
    3074             : {
    3075         122 :     if (!conn)
    3076           0 :         return 0;
    3077             : 
    3078         122 :     if (conn->pipelineStatus == PQ_PIPELINE_OFF &&
    3079           2 :         (conn->asyncStatus == PGASYNC_IDLE ||
    3080           0 :          conn->asyncStatus == PGASYNC_PIPELINE_IDLE) &&
    3081           2 :         conn->cmd_queue_head == NULL)
    3082           2 :         return 1;
    3083             : 
    3084         120 :     switch (conn->asyncStatus)
    3085             :     {
    3086           0 :         case PGASYNC_READY:
    3087             :         case PGASYNC_READY_MORE:
    3088             :             /* there are some uncollected results */
    3089           0 :             libpq_append_conn_error(conn, "cannot exit pipeline mode with uncollected results");
    3090           0 :             return 0;
    3091             : 
    3092          10 :         case PGASYNC_BUSY:
    3093          10 :             libpq_append_conn_error(conn, "cannot exit pipeline mode while busy");
    3094          10 :             return 0;
    3095             : 
    3096         110 :         case PGASYNC_IDLE:
    3097             :         case PGASYNC_PIPELINE_IDLE:
    3098             :             /* OK */
    3099         110 :             break;
    3100             : 
    3101           0 :         case PGASYNC_COPY_IN:
    3102             :         case PGASYNC_COPY_OUT:
    3103             :         case PGASYNC_COPY_BOTH:
    3104           0 :             libpq_append_conn_error(conn, "cannot exit pipeline mode while in COPY");
    3105             :     }
    3106             : 
    3107             :     /* still work to process */
    3108         110 :     if (conn->cmd_queue_head != NULL)
    3109             :     {
    3110           0 :         libpq_append_conn_error(conn, "cannot exit pipeline mode with uncollected results");
    3111           0 :         return 0;
    3112             :     }
    3113             : 
    3114         110 :     conn->pipelineStatus = PQ_PIPELINE_OFF;
    3115         110 :     conn->asyncStatus = PGASYNC_IDLE;
    3116             : 
    3117             :     /* Flush any pending data in out buffer */
    3118         110 :     if (pqFlush(conn) < 0)
    3119           0 :         return 0;               /* error message is setup already */
    3120         110 :     return 1;
    3121             : }
    3122             : 
    3123             : /*
    3124             :  * pqCommandQueueAdvance
    3125             :  *      Remove one query from the command queue, if appropriate.
    3126             :  *
    3127             :  * If we have received all results corresponding to the head element
    3128             :  * in the command queue, remove it.
    3129             :  *
    3130             :  * In simple query protocol we must not advance the command queue until the
    3131             :  * ReadyForQuery message has been received.  This is because in simple mode a
    3132             :  * command can have multiple queries, and we must process result for all of
    3133             :  * them before moving on to the next command.
    3134             :  *
    3135             :  * Another consideration is synchronization during error processing in
    3136             :  * extended query protocol: we refuse to advance the queue past a SYNC queue
    3137             :  * element, unless the result we've received is also a SYNC.  In particular
    3138             :  * this protects us from advancing when an error is received at an
    3139             :  * inappropriate moment.
    3140             :  */
    3141             : void
    3142     1177744 : pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
    3143             : {
    3144             :     PGcmdQueueEntry *prevquery;
    3145             : 
    3146     1177744 :     if (conn->cmd_queue_head == NULL)
    3147       42510 :         return;
    3148             : 
    3149             :     /*
    3150             :      * If processing a query of simple query protocol, we only advance the
    3151             :      * queue when we receive the ReadyForQuery message for it.
    3152             :      */
    3153     1135234 :     if (conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE && !isReadyForQuery)
    3154      572824 :         return;
    3155             : 
    3156             :     /*
    3157             :      * If we're waiting for a SYNC, don't advance the queue until we get one.
    3158             :      */
    3159      562410 :     if (conn->cmd_queue_head->queryclass == PGQUERY_SYNC && !gotSync)
    3160           0 :         return;
    3161             : 
    3162             :     /* delink element from queue */
    3163      562410 :     prevquery = conn->cmd_queue_head;
    3164      562410 :     conn->cmd_queue_head = conn->cmd_queue_head->next;
    3165             : 
    3166             :     /* If the queue is now empty, reset the tail too */
    3167      562410 :     if (conn->cmd_queue_head == NULL)
    3168      558710 :         conn->cmd_queue_tail = NULL;
    3169             : 
    3170             :     /* and make the queue element recyclable */
    3171      562410 :     prevquery->next = NULL;
    3172      562410 :     pqRecycleCmdQueueEntry(conn, prevquery);
    3173             : }
    3174             : 
    3175             : /*
    3176             :  * pqPipelineProcessQueue: subroutine for PQgetResult
    3177             :  *      In pipeline mode, start processing the results of the next query in the queue.
    3178             :  */
    3179             : static void
    3180        3830 : pqPipelineProcessQueue(PGconn *conn)
    3181             : {
    3182        3830 :     switch (conn->asyncStatus)
    3183             :     {
    3184           0 :         case PGASYNC_COPY_IN:
    3185             :         case PGASYNC_COPY_OUT:
    3186             :         case PGASYNC_COPY_BOTH:
    3187             :         case PGASYNC_READY:
    3188             :         case PGASYNC_READY_MORE:
    3189             :         case PGASYNC_BUSY:
    3190             :             /* client still has to process current query or results */
    3191           0 :             return;
    3192             : 
    3193           2 :         case PGASYNC_IDLE:
    3194             : 
    3195             :             /*
    3196             :              * If we're in IDLE mode and there's some command in the queue,
    3197             :              * get us into PIPELINE_IDLE mode and process normally.  Otherwise
    3198             :              * there's nothing for us to do.
    3199             :              */
    3200           2 :             if (conn->cmd_queue_head != NULL)
    3201             :             {
    3202           2 :                 conn->asyncStatus = PGASYNC_PIPELINE_IDLE;
    3203           2 :                 break;
    3204             :             }
    3205           0 :             return;
    3206             : 
    3207        3828 :         case PGASYNC_PIPELINE_IDLE:
    3208             :             Assert(conn->pipelineStatus != PQ_PIPELINE_OFF);
    3209             :             /* next query please */
    3210        3828 :             break;
    3211             :     }
    3212             : 
    3213             :     /*
    3214             :      * Reset partial-result mode.  (Client has to set it up for each query, if
    3215             :      * desired.)
    3216             :      */
    3217        3830 :     conn->partialResMode = false;
    3218        3830 :     conn->singleRowMode = false;
    3219        3830 :     conn->maxChunkSize = 0;
    3220             : 
    3221             :     /*
    3222             :      * If there are no further commands to process in the queue, get us in
    3223             :      * "real idle" mode now.
    3224             :      */
    3225        3830 :     if (conn->cmd_queue_head == NULL)
    3226             :     {
    3227         128 :         conn->asyncStatus = PGASYNC_IDLE;
    3228         128 :         return;
    3229             :     }
    3230             : 
    3231             :     /*
    3232             :      * Reset the error state.  This and the next couple of steps correspond to
    3233             :      * what PQsendQueryStart didn't do for this query.
    3234             :      */
    3235        3702 :     pqClearConnErrorState(conn);
    3236             : 
    3237             :     /* Initialize async result-accumulation state */
    3238        3702 :     pqClearAsyncResult(conn);
    3239             : 
    3240        3702 :     if (conn->pipelineStatus == PQ_PIPELINE_ABORTED &&
    3241         378 :         conn->cmd_queue_head->queryclass != PGQUERY_SYNC)
    3242             :     {
    3243             :         /*
    3244             :          * In an aborted pipeline we don't get anything from the server for
    3245             :          * each result; we're just discarding commands from the queue until we
    3246             :          * get to the next sync from the server.
    3247             :          *
    3248             :          * The PGRES_PIPELINE_ABORTED results tell the client that its queries
    3249             :          * got aborted.
    3250             :          */
    3251         368 :         conn->result = PQmakeEmptyPGresult(conn, PGRES_PIPELINE_ABORTED);
    3252         368 :         if (!conn->result)
    3253             :         {
    3254           0 :             libpq_append_conn_error(conn, "out of memory");
    3255           0 :             pqSaveErrorResult(conn);
    3256           0 :             return;
    3257             :         }
    3258         368 :         conn->asyncStatus = PGASYNC_READY;
    3259             :     }
    3260             :     else
    3261             :     {
    3262             :         /* allow parsing to continue */
    3263        3334 :         conn->asyncStatus = PGASYNC_BUSY;
    3264             :     }
    3265             : }
    3266             : 
    3267             : /*
    3268             :  * PQpipelineSync
    3269             :  *      Send a Sync message as part of a pipeline, and flush to server
    3270             :  */
    3271             : int
    3272         122 : PQpipelineSync(PGconn *conn)
    3273             : {
    3274         122 :     return pqPipelineSyncInternal(conn, true);
    3275             : }
    3276             : 
    3277             : /*
    3278             :  * PQsendPipelineSync
    3279             :  *      Send a Sync message as part of a pipeline, without flushing to server
    3280             :  */
    3281             : int
    3282          10 : PQsendPipelineSync(PGconn *conn)
    3283             : {
    3284          10 :     return pqPipelineSyncInternal(conn, false);
    3285             : }
    3286             : 
    3287             : /*
    3288             :  * Workhorse function for PQpipelineSync and PQsendPipelineSync.
    3289             :  *
    3290             :  * immediate_flush controls if the flush happens immediately after sending the
    3291             :  * Sync message or not.
    3292             :  */
    3293             : static int
    3294         132 : pqPipelineSyncInternal(PGconn *conn, bool immediate_flush)
    3295             : {
    3296             :     PGcmdQueueEntry *entry;
    3297             : 
    3298         132 :     if (!conn)
    3299           0 :         return 0;
    3300             : 
    3301         132 :     if (conn->pipelineStatus == PQ_PIPELINE_OFF)
    3302             :     {
    3303           0 :         libpq_append_conn_error(conn, "cannot send pipeline when not in pipeline mode");
    3304           0 :         return 0;
    3305             :     }
    3306             : 
    3307         132 :     switch (conn->asyncStatus)
    3308             :     {
    3309           0 :         case PGASYNC_COPY_IN:
    3310             :         case PGASYNC_COPY_OUT:
    3311             :         case PGASYNC_COPY_BOTH:
    3312             :             /* should be unreachable */
    3313           0 :             appendPQExpBufferStr(&conn->errorMessage,
    3314             :                                  "internal error: cannot send pipeline while in COPY\n");
    3315           0 :             return 0;
    3316         132 :         case PGASYNC_READY:
    3317             :         case PGASYNC_READY_MORE:
    3318             :         case PGASYNC_BUSY:
    3319             :         case PGASYNC_IDLE:
    3320             :         case PGASYNC_PIPELINE_IDLE:
    3321             :             /* OK to send sync */
    3322         132 :             break;
    3323             :     }
    3324             : 
    3325         132 :     entry = pqAllocCmdQueueEntry(conn);
    3326         132 :     if (entry == NULL)
    3327           0 :         return 0;               /* error msg already set */
    3328             : 
    3329         132 :     entry->queryclass = PGQUERY_SYNC;
    3330         132 :     entry->query = NULL;
    3331             : 
    3332             :     /* construct the Sync message */
    3333         264 :     if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
    3334         132 :         pqPutMsgEnd(conn) < 0)
    3335           0 :         goto sendFailed;
    3336             : 
    3337             :     /*
    3338             :      * Give the data a push.  In nonblock mode, don't complain if we're unable
    3339             :      * to send it all; PQgetResult() will do any additional flushing needed.
    3340             :      * If immediate_flush is disabled, the data is pushed if we are past the
    3341             :      * size threshold.
    3342             :      */
    3343         132 :     if (immediate_flush)
    3344             :     {
    3345         122 :         if (pqFlush(conn) < 0)
    3346           0 :             goto sendFailed;
    3347             :     }
    3348             :     else
    3349             :     {
    3350          10 :         if (pqPipelineFlush(conn) < 0)
    3351           0 :             goto sendFailed;
    3352             :     }
    3353             : 
    3354             :     /* OK, it's launched! */
    3355         132 :     pqAppendCmdQueueEntry(conn, entry);
    3356             : 
    3357         132 :     return 1;
    3358             : 
    3359           0 : sendFailed:
    3360           0 :     pqRecycleCmdQueueEntry(conn, entry);
    3361             :     /* error message should be set up already */
    3362           0 :     return 0;
    3363             : }
    3364             : 
    3365             : /*
    3366             :  * PQsendFlushRequest
    3367             :  *      Send request for server to flush its buffer.  Useful in pipeline
    3368             :  *      mode when a sync point is not desired.
    3369             :  */
    3370             : int
    3371          16 : PQsendFlushRequest(PGconn *conn)
    3372             : {
    3373          16 :     if (!conn)
    3374           0 :         return 0;
    3375             : 
    3376             :     /* Don't try to send if we know there's no live connection. */
    3377          16 :     if (conn->status != CONNECTION_OK)
    3378             :     {
    3379           0 :         libpq_append_conn_error(conn, "no connection to the server");
    3380           0 :         return 0;
    3381             :     }
    3382             : 
    3383             :     /* Can't send while already busy, either, unless enqueuing for later */
    3384          16 :     if (conn->asyncStatus != PGASYNC_IDLE &&
    3385          16 :         conn->pipelineStatus == PQ_PIPELINE_OFF)
    3386             :     {
    3387           0 :         libpq_append_conn_error(conn, "another command is already in progress");
    3388           0 :         return 0;
    3389             :     }
    3390             : 
    3391          32 :     if (pqPutMsgStart(PqMsg_Flush, conn) < 0 ||
    3392          16 :         pqPutMsgEnd(conn) < 0)
    3393             :     {
    3394           0 :         return 0;
    3395             :     }
    3396             : 
    3397             :     /*
    3398             :      * Give the data a push (in pipeline mode, only if we're past the size
    3399             :      * threshold).  In nonblock mode, don't complain if we're unable to send
    3400             :      * it all; PQgetResult() will do any additional flushing needed.
    3401             :      */
    3402          16 :     if (pqPipelineFlush(conn) < 0)
    3403           0 :         return 0;
    3404             : 
    3405          16 :     return 1;
    3406             : }
    3407             : 
    3408             : /* ====== accessor funcs for PGresult ======== */
    3409             : 
    3410             : ExecStatusType
    3411     2176780 : PQresultStatus(const PGresult *res)
    3412             : {
    3413     2176780 :     if (!res)
    3414           2 :         return PGRES_FATAL_ERROR;
    3415     2176778 :     return res->resultStatus;
    3416             : }
    3417             : 
    3418             : char *
    3419          44 : PQresStatus(ExecStatusType status)
    3420             : {
    3421          44 :     if ((unsigned int) status >= lengthof(pgresStatus))
    3422           0 :         return libpq_gettext("invalid ExecStatusType code");
    3423          44 :     return pgresStatus[status];
    3424             : }
    3425             : 
    3426             : char *
    3427       61214 : PQresultErrorMessage(const PGresult *res)
    3428             : {
    3429       61214 :     if (!res || !res->errMsg)
    3430           2 :         return "";
    3431       61212 :     return res->errMsg;
    3432             : }
    3433             : 
    3434             : char *
    3435           6 : PQresultVerboseErrorMessage(const PGresult *res,
    3436             :                             PGVerbosity verbosity,
    3437             :                             PGContextVisibility show_context)
    3438             : {
    3439             :     PQExpBufferData workBuf;
    3440             : 
    3441             :     /*
    3442             :      * Because the caller is expected to free the result string, we must
    3443             :      * strdup any constant result.  We use plain strdup and document that
    3444             :      * callers should expect NULL if out-of-memory.
    3445             :      */
    3446           6 :     if (!res ||
    3447           6 :         (res->resultStatus != PGRES_FATAL_ERROR &&
    3448           0 :          res->resultStatus != PGRES_NONFATAL_ERROR))
    3449           0 :         return strdup(libpq_gettext("PGresult is not an error result\n"));
    3450             : 
    3451           6 :     initPQExpBuffer(&workBuf);
    3452             : 
    3453           6 :     pqBuildErrorMessage3(&workBuf, res, verbosity, show_context);
    3454             : 
    3455             :     /* If insufficient memory to format the message, fail cleanly */
    3456           6 :     if (PQExpBufferDataBroken(workBuf))
    3457             :     {
    3458           0 :         termPQExpBuffer(&workBuf);
    3459           0 :         return strdup(libpq_gettext("out of memory\n"));
    3460             :     }
    3461             : 
    3462           6 :     return workBuf.data;
    3463             : }
    3464             : 
    3465             : char *
    3466      548840 : PQresultErrorField(const PGresult *res, int fieldcode)
    3467             : {
    3468             :     PGMessageField *pfield;
    3469             : 
    3470      548840 :     if (!res)
    3471           4 :         return NULL;
    3472     4121866 :     for (pfield = res->errFields; pfield != NULL; pfield = pfield->next)
    3473             :     {
    3474     3804822 :         if (pfield->code == fieldcode)
    3475      231792 :             return pfield->contents;
    3476             :     }
    3477      317044 :     return NULL;
    3478             : }
    3479             : 
    3480             : int
    3481      326206 : PQntuples(const PGresult *res)
    3482             : {
    3483      326206 :     if (!res)
    3484           0 :         return 0;
    3485      326206 :     return res->ntups;
    3486             : }
    3487             : 
    3488             : int
    3489      321284 : PQnfields(const PGresult *res)
    3490             : {
    3491      321284 :     if (!res)
    3492           0 :         return 0;
    3493      321284 :     return res->numAttributes;
    3494             : }
    3495             : 
    3496             : int
    3497         860 : PQbinaryTuples(const PGresult *res)
    3498             : {
    3499         860 :     if (!res)
    3500           0 :         return 0;
    3501         860 :     return res->binary;
    3502             : }
    3503             : 
    3504             : /*
    3505             :  * Helper routines to range-check field numbers and tuple numbers.
    3506             :  * Return true if OK, false if not
    3507             :  */
    3508             : 
    3509             : static int
    3510      514530 : check_field_number(const PGresult *res, int field_num)
    3511             : {
    3512      514530 :     if (!res)
    3513           0 :         return false;           /* no way to display error message... */
    3514      514530 :     if (field_num < 0 || field_num >= res->numAttributes)
    3515             :     {
    3516           0 :         pqInternalNotice(&res->noticeHooks,
    3517             :                          "column number %d is out of range 0..%d",
    3518           0 :                          field_num, res->numAttributes - 1);
    3519           0 :         return false;
    3520             :     }
    3521      514530 :     return true;
    3522             : }
    3523             : 
    3524             : static int
    3525    33552920 : check_tuple_field_number(const PGresult *res,
    3526             :                          int tup_num, int field_num)
    3527             : {
    3528    33552920 :     if (!res)
    3529           0 :         return false;           /* no way to display error message... */
    3530    33552920 :     if (tup_num < 0 || tup_num >= res->ntups)
    3531             :     {
    3532           0 :         pqInternalNotice(&res->noticeHooks,
    3533             :                          "row number %d is out of range 0..%d",
    3534           0 :                          tup_num, res->ntups - 1);
    3535           0 :         return false;
    3536             :     }
    3537    33552920 :     if (field_num < 0 || field_num >= res->numAttributes)
    3538             :     {
    3539           0 :         pqInternalNotice(&res->noticeHooks,
    3540             :                          "column number %d is out of range 0..%d",
    3541           0 :                          field_num, res->numAttributes - 1);
    3542           0 :         return false;
    3543             :     }
    3544    33552920 :     return true;
    3545             : }
    3546             : 
    3547             : static int
    3548           0 : check_param_number(const PGresult *res, int param_num)
    3549             : {
    3550           0 :     if (!res)
    3551           0 :         return false;           /* no way to display error message... */
    3552           0 :     if (param_num < 0 || param_num >= res->numParameters)
    3553             :     {
    3554           0 :         pqInternalNotice(&res->noticeHooks,
    3555             :                          "parameter number %d is out of range 0..%d",
    3556           0 :                          param_num, res->numParameters - 1);
    3557           0 :         return false;
    3558             :     }
    3559             : 
    3560           0 :     return true;
    3561             : }
    3562             : 
    3563             : /*
    3564             :  * returns NULL if the field_num is invalid
    3565             :  */
    3566             : char *
    3567      248784 : PQfname(const PGresult *res, int field_num)
    3568             : {
    3569      248784 :     if (!check_field_number(res, field_num))
    3570           0 :         return NULL;
    3571      248784 :     if (res->attDescs)
    3572      248784 :         return res->attDescs[field_num].name;
    3573             :     else
    3574           0 :         return NULL;
    3575             : }
    3576             : 
    3577             : /*
    3578             :  * PQfnumber: find column number given column name
    3579             :  *
    3580             :  * The column name is parsed as if it were in a SQL statement, including
    3581             :  * case-folding and double-quote processing.  But note a possible gotcha:
    3582             :  * downcasing in the frontend might follow different locale rules than
    3583             :  * downcasing in the backend...
    3584             :  *
    3585             :  * Returns -1 if no match.  In the present backend it is also possible
    3586             :  * to have multiple matches, in which case the first one is found.
    3587             :  */
    3588             : int
    3589      273142 : PQfnumber(const PGresult *res, const char *field_name)
    3590             : {
    3591             :     char       *field_case;
    3592             :     bool        in_quotes;
    3593      273142 :     bool        all_lower = true;
    3594             :     const char *iptr;
    3595             :     char       *optr;
    3596             :     int         i;
    3597             : 
    3598      273142 :     if (!res)
    3599           0 :         return -1;
    3600             : 
    3601             :     /*
    3602             :      * Note: it is correct to reject a zero-length input string; the proper
    3603             :      * input to match a zero-length field name would be "".
    3604             :      */
    3605      273142 :     if (field_name == NULL ||
    3606      273142 :         field_name[0] == '\0' ||
    3607      273142 :         res->attDescs == NULL)
    3608           0 :         return -1;
    3609             : 
    3610             :     /*
    3611             :      * Check if we can avoid the strdup() and related work because the
    3612             :      * passed-in string wouldn't be changed before we do the check anyway.
    3613             :      */
    3614     2821704 :     for (iptr = field_name; *iptr; iptr++)
    3615             :     {
    3616     2548562 :         char        c = *iptr;
    3617             : 
    3618     2548562 :         if (c == '"' || c != pg_tolower((unsigned char) c))
    3619             :         {
    3620           0 :             all_lower = false;
    3621           0 :             break;
    3622             :         }
    3623             :     }
    3624             : 
    3625      273142 :     if (all_lower)
    3626     2060162 :         for (i = 0; i < res->numAttributes; i++)
    3627     2060162 :             if (strcmp(field_name, res->attDescs[i].name) == 0)
    3628      273142 :                 return i;
    3629             : 
    3630             :     /* Fall through to the normal check if that didn't work out. */
    3631             : 
    3632             :     /*
    3633             :      * Note: this code will not reject partially quoted strings, eg
    3634             :      * foo"BAR"foo will become fooBARfoo when it probably ought to be an error
    3635             :      * condition.
    3636             :      */
    3637           0 :     field_case = strdup(field_name);
    3638           0 :     if (field_case == NULL)
    3639           0 :         return -1;              /* grotty */
    3640             : 
    3641           0 :     in_quotes = false;
    3642           0 :     optr = field_case;
    3643           0 :     for (iptr = field_case; *iptr; iptr++)
    3644             :     {
    3645           0 :         char        c = *iptr;
    3646             : 
    3647           0 :         if (in_quotes)
    3648             :         {
    3649           0 :             if (c == '"')
    3650             :             {
    3651           0 :                 if (iptr[1] == '"')
    3652             :                 {
    3653             :                     /* doubled quotes become a single quote */
    3654           0 :                     *optr++ = '"';
    3655           0 :                     iptr++;
    3656             :                 }
    3657             :                 else
    3658           0 :                     in_quotes = false;
    3659             :             }
    3660             :             else
    3661           0 :                 *optr++ = c;
    3662             :         }
    3663           0 :         else if (c == '"')
    3664           0 :             in_quotes = true;
    3665             :         else
    3666             :         {
    3667           0 :             c = pg_tolower((unsigned char) c);
    3668           0 :             *optr++ = c;
    3669             :         }
    3670             :     }
    3671           0 :     *optr = '\0';
    3672             : 
    3673           0 :     for (i = 0; i < res->numAttributes; i++)
    3674             :     {
    3675           0 :         if (strcmp(field_case, res->attDescs[i].name) == 0)
    3676             :         {
    3677           0 :             free(field_case);
    3678           0 :             return i;
    3679             :         }
    3680             :     }
    3681           0 :     free(field_case);
    3682           0 :     return -1;
    3683             : }
    3684             : 
    3685             : Oid
    3686           0 : PQftable(const PGresult *res, int field_num)
    3687             : {
    3688           0 :     if (!check_field_number(res, field_num))
    3689           0 :         return InvalidOid;
    3690           0 :     if (res->attDescs)
    3691           0 :         return res->attDescs[field_num].tableid;
    3692             :     else
    3693           0 :         return InvalidOid;
    3694             : }
    3695             : 
    3696             : int
    3697           0 : PQftablecol(const PGresult *res, int field_num)
    3698             : {
    3699           0 :     if (!check_field_number(res, field_num))
    3700           0 :         return 0;
    3701           0 :     if (res->attDescs)
    3702           0 :         return res->attDescs[field_num].columnid;
    3703             :     else
    3704           0 :         return 0;
    3705             : }
    3706             : 
    3707             : int
    3708       13920 : PQfformat(const PGresult *res, int field_num)
    3709             : {
    3710       13920 :     if (!check_field_number(res, field_num))
    3711           0 :         return 0;
    3712       13920 :     if (res->attDescs)
    3713       13920 :         return res->attDescs[field_num].format;
    3714             :     else
    3715           0 :         return 0;
    3716             : }
    3717             : 
    3718             : Oid
    3719      251036 : PQftype(const PGresult *res, int field_num)
    3720             : {
    3721      251036 :     if (!check_field_number(res, field_num))
    3722           0 :         return InvalidOid;
    3723      251036 :     if (res->attDescs)
    3724      251036 :         return res->attDescs[field_num].typid;
    3725             :     else
    3726           0 :         return InvalidOid;
    3727             : }
    3728             : 
    3729             : int
    3730         320 : PQfsize(const PGresult *res, int field_num)
    3731             : {
    3732         320 :     if (!check_field_number(res, field_num))
    3733           0 :         return 0;
    3734         320 :     if (res->attDescs)
    3735         320 :         return res->attDescs[field_num].typlen;
    3736             :     else
    3737           0 :         return 0;
    3738             : }
    3739             : 
    3740             : int
    3741         470 : PQfmod(const PGresult *res, int field_num)
    3742             : {
    3743         470 :     if (!check_field_number(res, field_num))
    3744           0 :         return 0;
    3745         470 :     if (res->attDescs)
    3746         470 :         return res->attDescs[field_num].atttypmod;
    3747             :     else
    3748           0 :         return 0;
    3749             : }
    3750             : 
    3751             : char *
    3752      570606 : PQcmdStatus(PGresult *res)
    3753             : {
    3754      570606 :     if (!res)
    3755           0 :         return NULL;
    3756      570606 :     return res->cmdStatus;
    3757             : }
    3758             : 
    3759             : /*
    3760             :  * PQoidStatus -
    3761             :  *  if the last command was an INSERT, return the oid string
    3762             :  *  if not, return ""
    3763             :  */
    3764             : char *
    3765           0 : PQoidStatus(const PGresult *res)
    3766             : {
    3767             :     /*
    3768             :      * This must be enough to hold the result. Don't laugh, this is better
    3769             :      * than what this function used to do.
    3770             :      */
    3771             :     static char buf[24];
    3772             : 
    3773             :     size_t      len;
    3774             : 
    3775           0 :     if (!res || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
    3776           0 :         return "";
    3777             : 
    3778           0 :     len = strspn(res->cmdStatus + 7, "0123456789");
    3779           0 :     if (len > sizeof(buf) - 1)
    3780           0 :         len = sizeof(buf) - 1;
    3781           0 :     memcpy(buf, res->cmdStatus + 7, len);
    3782           0 :     buf[len] = '\0';
    3783             : 
    3784           0 :     return buf;
    3785             : }
    3786             : 
    3787             : /*
    3788             :  * PQoidValue -
    3789             :  *  a perhaps preferable form of the above which just returns
    3790             :  *  an Oid type
    3791             :  */
    3792             : Oid
    3793      166096 : PQoidValue(const PGresult *res)
    3794             : {
    3795      166096 :     char       *endptr = NULL;
    3796             :     unsigned long result;
    3797             : 
    3798      166096 :     if (!res ||
    3799      166096 :         strncmp(res->cmdStatus, "INSERT ", 7) != 0 ||
    3800       34216 :         res->cmdStatus[7] < '0' ||
    3801       34216 :         res->cmdStatus[7] > '9')
    3802      131880 :         return InvalidOid;
    3803             : 
    3804       34216 :     result = strtoul(res->cmdStatus + 7, &endptr, 10);
    3805             : 
    3806       34216 :     if (!endptr || (*endptr != ' ' && *endptr != '\0'))
    3807           0 :         return InvalidOid;
    3808             :     else
    3809       34216 :         return (Oid) result;
    3810             : }
    3811             : 
    3812             : 
    3813             : /*
    3814             :  * PQcmdTuples -
    3815             :  *  If the last command was INSERT/UPDATE/DELETE/MERGE/MOVE/FETCH/COPY,
    3816             :  *  return a string containing the number of inserted/affected tuples.
    3817             :  *  If not, return "".
    3818             :  *
    3819             :  *  XXX: this should probably return an int
    3820             :  */
    3821             : char *
    3822      288330 : PQcmdTuples(PGresult *res)
    3823             : {
    3824             :     char       *p,
    3825             :                *c;
    3826             : 
    3827      288330 :     if (!res)
    3828         440 :         return "";
    3829             : 
    3830      287890 :     if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
    3831             :     {
    3832       35838 :         p = res->cmdStatus + 7;
    3833             :         /* INSERT: skip oid and space */
    3834       71676 :         while (*p && *p != ' ')
    3835       35838 :             p++;
    3836       35838 :         if (*p == 0)
    3837           0 :             goto interpret_error;   /* no space? */
    3838       35838 :         p++;
    3839             :     }
    3840      252052 :     else if (strncmp(res->cmdStatus, "SELECT ", 7) == 0 ||
    3841      143554 :              strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
    3842      140810 :              strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
    3843      115596 :         p = res->cmdStatus + 7;
    3844      136456 :     else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0 ||
    3845      135080 :              strncmp(res->cmdStatus, "MERGE ", 6) == 0)
    3846        2220 :         p = res->cmdStatus + 6;
    3847      134236 :     else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0 ||
    3848      134168 :              strncmp(res->cmdStatus, "COPY ", 5) == 0)
    3849        1046 :         p = res->cmdStatus + 5;
    3850             :     else
    3851      133190 :         return "";
    3852             : 
    3853             :     /* check that we have an integer (at least one digit, nothing else) */
    3854      327074 :     for (c = p; *c; c++)
    3855             :     {
    3856      172374 :         if (!isdigit((unsigned char) *c))
    3857           0 :             goto interpret_error;
    3858             :     }
    3859      154700 :     if (c == p)
    3860           0 :         goto interpret_error;
    3861             : 
    3862      154700 :     return p;
    3863             : 
    3864           0 : interpret_error:
    3865           0 :     pqInternalNotice(&res->noticeHooks,
    3866             :                      "could not interpret result from server: %s",
    3867           0 :                      res->cmdStatus);
    3868           0 :     return "";
    3869             : }
    3870             : 
    3871             : /*
    3872             :  * PQgetvalue:
    3873             :  *  return the value of field 'field_num' of row 'tup_num'
    3874             :  */
    3875             : char *
    3876    27480140 : PQgetvalue(const PGresult *res, int tup_num, int field_num)
    3877             : {
    3878    27480140 :     if (!check_tuple_field_number(res, tup_num, field_num))
    3879           0 :         return NULL;
    3880    27480140 :     return res->tuples[tup_num][field_num].value;
    3881             : }
    3882             : 
    3883             : /* PQgetlength:
    3884             :  *  returns the actual length of a field value in bytes.
    3885             :  */
    3886             : int
    3887       40628 : PQgetlength(const PGresult *res, int tup_num, int field_num)
    3888             : {
    3889       40628 :     if (!check_tuple_field_number(res, tup_num, field_num))
    3890           0 :         return 0;
    3891       40628 :     if (res->tuples[tup_num][field_num].len != NULL_LEN)
    3892       40190 :         return res->tuples[tup_num][field_num].len;
    3893             :     else
    3894         438 :         return 0;
    3895             : }
    3896             : 
    3897             : /* PQgetisnull:
    3898             :  *  returns the null status of a field value.
    3899             :  */
    3900             : int
    3901     6032152 : PQgetisnull(const PGresult *res, int tup_num, int field_num)
    3902             : {
    3903     6032152 :     if (!check_tuple_field_number(res, tup_num, field_num))
    3904           0 :         return 1;               /* pretend it is null */
    3905     6032152 :     if (res->tuples[tup_num][field_num].len == NULL_LEN)
    3906      723572 :         return 1;
    3907             :     else
    3908     5308580 :         return 0;
    3909             : }
    3910             : 
    3911             : /* PQnparams:
    3912             :  *  returns the number of input parameters of a prepared statement.
    3913             :  */
    3914             : int
    3915           0 : PQnparams(const PGresult *res)
    3916             : {
    3917           0 :     if (!res)
    3918           0 :         return 0;
    3919           0 :     return res->numParameters;
    3920             : }
    3921             : 
    3922             : /* PQparamtype:
    3923             :  *  returns type Oid of the specified statement parameter.
    3924             :  */
    3925             : Oid
    3926           0 : PQparamtype(const PGresult *res, int param_num)
    3927             : {
    3928           0 :     if (!check_param_number(res, param_num))
    3929           0 :         return InvalidOid;
    3930           0 :     if (res->paramDescs)
    3931           0 :         return res->paramDescs[param_num].typid;
    3932             :     else
    3933           0 :         return InvalidOid;
    3934             : }
    3935             : 
    3936             : 
    3937             : /* PQsetnonblocking:
    3938             :  *  sets the PGconn's database connection non-blocking if the arg is true
    3939             :  *  or makes it blocking if the arg is false, this will not protect
    3940             :  *  you from PQexec(), you'll only be safe when using the non-blocking API.
    3941             :  *  Needs to be called only on a connected database connection.
    3942             :  */
    3943             : int
    3944           8 : PQsetnonblocking(PGconn *conn, int arg)
    3945             : {
    3946             :     bool        barg;
    3947             : 
    3948           8 :     if (!conn || conn->status == CONNECTION_BAD)
    3949           0 :         return -1;
    3950             : 
    3951           8 :     barg = (arg ? true : false);
    3952             : 
    3953             :     /* early out if the socket is already in the state requested */
    3954           8 :     if (barg == conn->nonblocking)
    3955           0 :         return 0;
    3956             : 
    3957             :     /*
    3958             :      * to guarantee constancy for flushing/query/result-polling behavior we
    3959             :      * need to flush the send queue at this point in order to guarantee proper
    3960             :      * behavior. this is ok because either they are making a transition _from_
    3961             :      * or _to_ blocking mode, either way we can block them.
    3962             :      *
    3963             :      * Clear error state in case pqFlush adds to it, unless we're actively
    3964             :      * pipelining, in which case it seems best not to.
    3965             :      */
    3966           8 :     if (conn->cmd_queue_head == NULL)
    3967           6 :         pqClearConnErrorState(conn);
    3968             : 
    3969             :     /* if we are going from blocking to non-blocking flush here */
    3970           8 :     if (pqFlush(conn))
    3971           0 :         return -1;
    3972             : 
    3973           8 :     conn->nonblocking = barg;
    3974             : 
    3975           8 :     return 0;
    3976             : }
    3977             : 
    3978             : /*
    3979             :  * return the blocking status of the database connection
    3980             :  *      true == nonblocking, false == blocking
    3981             :  */
    3982             : int
    3983           4 : PQisnonblocking(const PGconn *conn)
    3984             : {
    3985           4 :     if (!conn || conn->status == CONNECTION_BAD)
    3986           0 :         return false;
    3987           4 :     return pqIsnonblocking(conn);
    3988             : }
    3989             : 
    3990             : /* libpq is thread-safe? */
    3991             : int
    3992           0 : PQisthreadsafe(void)
    3993             : {
    3994           0 :     return true;
    3995             : }
    3996             : 
    3997             : 
    3998             : /* try to force data out, really only useful for non-blocking users */
    3999             : int
    4000      180158 : PQflush(PGconn *conn)
    4001             : {
    4002      180158 :     if (!conn || conn->status == CONNECTION_BAD)
    4003           0 :         return -1;
    4004      180158 :     return pqFlush(conn);
    4005             : }
    4006             : 
    4007             : /*
    4008             :  * pqPipelineFlush
    4009             :  *
    4010             :  * In pipeline mode, data will be flushed only when the out buffer reaches the
    4011             :  * threshold value.  In non-pipeline mode, it behaves as stock pqFlush.
    4012             :  *
    4013             :  * Returns 0 on success.
    4014             :  */
    4015             : static int
    4016       24802 : pqPipelineFlush(PGconn *conn)
    4017             : {
    4018       24802 :     if ((conn->pipelineStatus != PQ_PIPELINE_ON) ||
    4019        3640 :         (conn->outCount >= OUTBUFFER_THRESHOLD))
    4020       21162 :         return pqFlush(conn);
    4021        3640 :     return 0;
    4022             : }
    4023             : 
    4024             : 
    4025             : /*
    4026             :  *      PQfreemem - safely frees memory allocated
    4027             :  *
    4028             :  * Needed mostly by Win32, unless multithreaded DLL (/MD in VC6)
    4029             :  * Used for freeing memory from PQescapeBytea()/PQunescapeBytea()
    4030             :  */
    4031             : void
    4032     4599416 : PQfreemem(void *ptr)
    4033             : {
    4034     4599416 :     free(ptr);
    4035     4599416 : }
    4036             : 
    4037             : /*
    4038             :  * PQfreeNotify - free's the memory associated with a PGnotify
    4039             :  *
    4040             :  * This function is here only for binary backward compatibility.
    4041             :  * New code should use PQfreemem().  A macro will automatically map
    4042             :  * calls to PQfreemem.  It should be removed in the future.  bjm 2003-03-24
    4043             :  */
    4044             : 
    4045             : #undef PQfreeNotify
    4046             : void        PQfreeNotify(PGnotify *notify);
    4047             : 
    4048             : void
    4049           0 : PQfreeNotify(PGnotify *notify)
    4050             : {
    4051           0 :     PQfreemem(notify);
    4052           0 : }
    4053             : 
    4054             : 
    4055             : /*
    4056             :  * Escaping arbitrary strings to get valid SQL literal strings.
    4057             :  *
    4058             :  * Replaces "'" with "''", and if not std_strings, replaces "\" with "\\".
    4059             :  *
    4060             :  * length is the length of the source string.  (Note: if a terminating NUL
    4061             :  * is encountered sooner, PQescapeString stops short of "length"; the behavior
    4062             :  * is thus rather like strncpy.)
    4063             :  *
    4064             :  * For safety the buffer at "to" must be at least 2*length + 1 bytes long.
    4065             :  * A terminating NUL character is added to the output string, whether the
    4066             :  * input is NUL-terminated or not.
    4067             :  *
    4068             :  * Returns the actual length of the output (not counting the terminating NUL).
    4069             :  */
    4070             : static size_t
    4071        9822 : PQescapeStringInternal(PGconn *conn,
    4072             :                        char *to, const char *from, size_t length,
    4073             :                        int *error,
    4074             :                        int encoding, bool std_strings)
    4075             : {
    4076        9822 :     const char *source = from;
    4077        9822 :     char       *target = to;
    4078        9822 :     size_t      remaining = length;
    4079             : 
    4080        9822 :     if (error)
    4081           0 :         *error = 0;
    4082             : 
    4083      142646 :     while (remaining > 0 && *source != '\0')
    4084             :     {
    4085      132824 :         char        c = *source;
    4086             :         int         len;
    4087             :         int         i;
    4088             : 
    4089             :         /* Fast path for plain ASCII */
    4090      132824 :         if (!IS_HIGHBIT_SET(c))
    4091             :         {
    4092             :             /* Apply quoting if needed */
    4093      131340 :             if (SQL_STR_DOUBLE(c, !std_strings))
    4094          22 :                 *target++ = c;
    4095             :             /* Copy the character */
    4096      131340 :             *target++ = c;
    4097      131340 :             source++;
    4098      131340 :             remaining--;
    4099      131340 :             continue;
    4100             :         }
    4101             : 
    4102             :         /* Slow path for possible multibyte characters */
    4103        1484 :         len = pg_encoding_mblen(encoding, source);
    4104             : 
    4105             :         /* Copy the character */
    4106        2968 :         for (i = 0; i < len; i++)
    4107             :         {
    4108        1484 :             if (remaining == 0 || *source == '\0')
    4109             :                 break;
    4110        1484 :             *target++ = *source++;
    4111        1484 :             remaining--;
    4112             :         }
    4113             : 
    4114             :         /*
    4115             :          * If we hit premature end of string (ie, incomplete multibyte
    4116             :          * character), try to pad out to the correct length with spaces. We
    4117             :          * may not be able to pad completely, but we will always be able to
    4118             :          * insert at least one pad space (since we'd not have quoted a
    4119             :          * multibyte character).  This should be enough to make a string that
    4120             :          * the server will error out on.
    4121             :          */
    4122        1484 :         if (i < len)
    4123             :         {
    4124           0 :             if (error)
    4125           0 :                 *error = 1;
    4126           0 :             if (conn)
    4127           0 :                 libpq_append_conn_error(conn, "incomplete multibyte character");
    4128           0 :             for (; i < len; i++)
    4129             :             {
    4130           0 :                 if (((size_t) (target - to)) / 2 >= length)
    4131           0 :                     break;
    4132           0 :                 *target++ = ' ';
    4133             :             }
    4134           0 :             break;
    4135             :         }
    4136             :     }
    4137             : 
    4138             :     /* Write the terminating NUL character. */
    4139        9822 :     *target = '\0';
    4140             : 
    4141        9822 :     return target - to;
    4142             : }
    4143             : 
    4144             : size_t
    4145        9822 : PQescapeStringConn(PGconn *conn,
    4146             :                    char *to, const char *from, size_t length,
    4147             :                    int *error)
    4148             : {
    4149        9822 :     if (!conn)
    4150             :     {
    4151             :         /* force empty-string result */
    4152           0 :         *to = '\0';
    4153           0 :         if (error)
    4154           0 :             *error = 1;
    4155           0 :         return 0;
    4156             :     }
    4157             : 
    4158        9822 :     if (conn->cmd_queue_head == NULL)
    4159        9822 :         pqClearConnErrorState(conn);
    4160             : 
    4161        9822 :     return PQescapeStringInternal(conn, to, from, length, error,
    4162             :                                   conn->client_encoding,
    4163        9822 :                                   conn->std_strings);
    4164             : }
    4165             : 
    4166             : size_t
    4167           0 : PQescapeString(char *to, const char *from, size_t length)
    4168             : {
    4169           0 :     return PQescapeStringInternal(NULL, to, from, length, NULL,
    4170             :                                   static_client_encoding,
    4171             :                                   static_std_strings);
    4172             : }
    4173             : 
    4174             : 
    4175             : /*
    4176             :  * Escape arbitrary strings.  If as_ident is true, we escape the result
    4177             :  * as an identifier; if false, as a literal.  The result is returned in
    4178             :  * a newly allocated buffer.  If we fail due to an encoding violation or out
    4179             :  * of memory condition, we return NULL, storing an error message into conn.
    4180             :  */
    4181             : static char *
    4182        2870 : PQescapeInternal(PGconn *conn, const char *str, size_t len, bool as_ident)
    4183             : {
    4184             :     const char *s;
    4185             :     char       *result;
    4186             :     char       *rp;
    4187        2870 :     int         num_quotes = 0; /* single or double, depending on as_ident */
    4188        2870 :     int         num_backslashes = 0;
    4189             :     int         input_len;
    4190             :     int         result_size;
    4191        2870 :     char        quote_char = as_ident ? '"' : '\'';
    4192             : 
    4193             :     /* We must have a connection, else fail immediately. */
    4194        2870 :     if (!conn)
    4195           0 :         return NULL;
    4196             : 
    4197        2870 :     if (conn->cmd_queue_head == NULL)
    4198        2870 :         pqClearConnErrorState(conn);
    4199             : 
    4200             :     /* Scan the string for characters that must be escaped. */
    4201       69954 :     for (s = str; (s - str) < len && *s != '\0'; ++s)
    4202             :     {
    4203       67084 :         if (*s == quote_char)
    4204          76 :             ++num_quotes;
    4205       67008 :         else if (*s == '\\')
    4206          12 :             ++num_backslashes;
    4207       66996 :         else if (IS_HIGHBIT_SET(*s))
    4208             :         {
    4209             :             int         charlen;
    4210             : 
    4211             :             /* Slow path for possible multibyte characters */
    4212           0 :             charlen = pg_encoding_mblen(conn->client_encoding, s);
    4213             : 
    4214             :             /* Multibyte character overruns allowable length. */
    4215           0 :             if ((s - str) + charlen > len || memchr(s, 0, charlen) != NULL)
    4216             :             {
    4217           0 :                 libpq_append_conn_error(conn, "incomplete multibyte character");
    4218           0 :                 return NULL;
    4219             :             }
    4220             : 
    4221             :             /* Adjust s, bearing in mind that for loop will increment it. */
    4222           0 :             s += charlen - 1;
    4223             :         }
    4224             :     }
    4225             : 
    4226             :     /* Allocate output buffer. */
    4227        2870 :     input_len = s - str;
    4228        2870 :     result_size = input_len + num_quotes + 3;   /* two quotes, plus a NUL */
    4229        2870 :     if (!as_ident && num_backslashes > 0)
    4230          12 :         result_size += num_backslashes + 2;
    4231        2870 :     result = rp = (char *) malloc(result_size);
    4232        2870 :     if (rp == NULL)
    4233             :     {
    4234           0 :         libpq_append_conn_error(conn, "out of memory");
    4235           0 :         return NULL;
    4236             :     }
    4237             : 
    4238             :     /*
    4239             :      * If we are escaping a literal that contains backslashes, we use the
    4240             :      * escape string syntax so that the result is correct under either value
    4241             :      * of standard_conforming_strings.  We also emit a leading space in this
    4242             :      * case, to guard against the possibility that the result might be
    4243             :      * interpolated immediately following an identifier.
    4244             :      */
    4245        2870 :     if (!as_ident && num_backslashes > 0)
    4246             :     {
    4247          12 :         *rp++ = ' ';
    4248          12 :         *rp++ = 'E';
    4249             :     }
    4250             : 
    4251             :     /* Opening quote. */
    4252        2870 :     *rp++ = quote_char;
    4253             : 
    4254             :     /*
    4255             :      * Use fast path if possible.
    4256             :      *
    4257             :      * We've already verified that the input string is well-formed in the
    4258             :      * current encoding.  If it contains no quotes and, in the case of
    4259             :      * literal-escaping, no backslashes, then we can just copy it directly to
    4260             :      * the output buffer, adding the necessary quotes.
    4261             :      *
    4262             :      * If not, we must rescan the input and process each character
    4263             :      * individually.
    4264             :      */
    4265        2870 :     if (num_quotes == 0 && (num_backslashes == 0 || as_ident))
    4266             :     {
    4267        2836 :         memcpy(rp, str, input_len);
    4268        2836 :         rp += input_len;
    4269             :     }
    4270             :     else
    4271             :     {
    4272        3208 :         for (s = str; s - str < input_len; ++s)
    4273             :         {
    4274        3174 :             if (*s == quote_char || (!as_ident && *s == '\\'))
    4275             :             {
    4276          88 :                 *rp++ = *s;
    4277          88 :                 *rp++ = *s;
    4278             :             }
    4279        3086 :             else if (!IS_HIGHBIT_SET(*s))
    4280        3086 :                 *rp++ = *s;
    4281             :             else
    4282             :             {
    4283           0 :                 int         i = pg_encoding_mblen(conn->client_encoding, s);
    4284             : 
    4285             :                 while (1)
    4286             :                 {
    4287           0 :                     *rp++ = *s;
    4288           0 :                     if (--i == 0)
    4289           0 :                         break;
    4290           0 :                     ++s;        /* for loop will provide the final increment */
    4291             :                 }
    4292             :             }
    4293             :         }
    4294             :     }
    4295             : 
    4296             :     /* Closing quote and terminating NUL. */
    4297        2870 :     *rp++ = quote_char;
    4298        2870 :     *rp = '\0';
    4299             : 
    4300        2870 :     return result;
    4301             : }
    4302             : 
    4303             : char *
    4304        1608 : PQescapeLiteral(PGconn *conn, const char *str, size_t len)
    4305             : {
    4306        1608 :     return PQescapeInternal(conn, str, len, false);
    4307             : }
    4308             : 
    4309             : char *
    4310        1262 : PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
    4311             : {
    4312        1262 :     return PQescapeInternal(conn, str, len, true);
    4313             : }
    4314             : 
    4315             : /* HEX encoding support for bytea */
    4316             : static const char hextbl[] = "0123456789abcdef";
    4317             : 
    4318             : static const int8 hexlookup[128] = {
    4319             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4320             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4321             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4322             :     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
    4323             :     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4324             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4325             :     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4326             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    4327             : };
    4328             : 
    4329             : static inline char
    4330           0 : get_hex(char c)
    4331             : {
    4332           0 :     int         res = -1;
    4333             : 
    4334           0 :     if (c > 0 && c < 127)
    4335           0 :         res = hexlookup[(unsigned char) c];
    4336             : 
    4337           0 :     return (char) res;
    4338             : }
    4339             : 
    4340             : 
    4341             : /*
    4342             :  *      PQescapeBytea   - converts from binary string to the
    4343             :  *      minimal encoding necessary to include the string in an SQL
    4344             :  *      INSERT statement with a bytea type column as the target.
    4345             :  *
    4346             :  *      We can use either hex or escape (traditional) encoding.
    4347             :  *      In escape mode, the following transformations are applied:
    4348             :  *      '\0' == ASCII  0 == \000
    4349             :  *      '\'' == ASCII 39 == ''
    4350             :  *      '\\' == ASCII 92 == \\
    4351             :  *      anything < 0x20, or > 0x7e ---> \ooo
    4352             :  *                                      (where ooo is an octal expression)
    4353             :  *
    4354             :  *      If not std_strings, all backslashes sent to the output are doubled.
    4355             :  */
    4356             : static unsigned char *
    4357           0 : PQescapeByteaInternal(PGconn *conn,
    4358             :                       const unsigned char *from, size_t from_length,
    4359             :                       size_t *to_length, bool std_strings, bool use_hex)
    4360             : {
    4361             :     const unsigned char *vp;
    4362             :     unsigned char *rp;
    4363             :     unsigned char *result;
    4364             :     size_t      i;
    4365             :     size_t      len;
    4366           0 :     size_t      bslash_len = (std_strings ? 1 : 2);
    4367             : 
    4368             :     /*
    4369             :      * empty string has 1 char ('\0')
    4370             :      */
    4371           0 :     len = 1;
    4372             : 
    4373           0 :     if (use_hex)
    4374             :     {
    4375           0 :         len += bslash_len + 1 + 2 * from_length;
    4376             :     }
    4377             :     else
    4378             :     {
    4379           0 :         vp = from;
    4380           0 :         for (i = from_length; i > 0; i--, vp++)
    4381             :         {
    4382           0 :             if (*vp < 0x20 || *vp > 0x7e)
    4383           0 :                 len += bslash_len + 3;
    4384           0 :             else if (*vp == '\'')
    4385           0 :                 len += 2;
    4386           0 :             else if (*vp == '\\')
    4387           0 :                 len += bslash_len + bslash_len;
    4388             :             else
    4389           0 :                 len++;
    4390             :         }
    4391             :     }
    4392             : 
    4393           0 :     *to_length = len;
    4394           0 :     rp = result = (unsigned char *) malloc(len);
    4395           0 :     if (rp == NULL)
    4396             :     {
    4397           0 :         if (conn)
    4398           0 :             libpq_append_conn_error(conn, "out of memory");
    4399           0 :         return NULL;
    4400             :     }
    4401             : 
    4402           0 :     if (use_hex)
    4403             :     {
    4404           0 :         if (!std_strings)
    4405           0 :             *rp++ = '\\';
    4406           0 :         *rp++ = '\\';
    4407           0 :         *rp++ = 'x';
    4408             :     }
    4409             : 
    4410           0 :     vp = from;
    4411           0 :     for (i = from_length; i > 0; i--, vp++)
    4412             :     {
    4413           0 :         unsigned char c = *vp;
    4414             : 
    4415           0 :         if (use_hex)
    4416             :         {
    4417           0 :             *rp++ = hextbl[(c >> 4) & 0xF];
    4418           0 :             *rp++ = hextbl[c & 0xF];
    4419             :         }
    4420           0 :         else if (c < 0x20 || c > 0x7e)
    4421             :         {
    4422           0 :             if (!std_strings)
    4423           0 :                 *rp++ = '\\';
    4424           0 :             *rp++ = '\\';
    4425           0 :             *rp++ = (c >> 6) + '0';
    4426           0 :             *rp++ = ((c >> 3) & 07) + '0';
    4427           0 :             *rp++ = (c & 07) + '0';
    4428             :         }
    4429           0 :         else if (c == '\'')
    4430             :         {
    4431           0 :             *rp++ = '\'';
    4432           0 :             *rp++ = '\'';
    4433             :         }
    4434           0 :         else if (c == '\\')
    4435             :         {
    4436           0 :             if (!std_strings)
    4437             :             {
    4438           0 :                 *rp++ = '\\';
    4439           0 :                 *rp++ = '\\';
    4440             :             }
    4441           0 :             *rp++ = '\\';
    4442           0 :             *rp++ = '\\';
    4443             :         }
    4444             :         else
    4445           0 :             *rp++ = c;
    4446             :     }
    4447           0 :     *rp = '\0';
    4448             : 
    4449           0 :     return result;
    4450             : }
    4451             : 
    4452             : unsigned char *
    4453           0 : PQescapeByteaConn(PGconn *conn,
    4454             :                   const unsigned char *from, size_t from_length,
    4455             :                   size_t *to_length)
    4456             : {
    4457           0 :     if (!conn)
    4458           0 :         return NULL;
    4459             : 
    4460           0 :     if (conn->cmd_queue_head == NULL)
    4461           0 :         pqClearConnErrorState(conn);
    4462             : 
    4463           0 :     return PQescapeByteaInternal(conn, from, from_length, to_length,
    4464           0 :                                  conn->std_strings,
    4465           0 :                                  (conn->sversion >= 90000));
    4466             : }
    4467             : 
    4468             : unsigned char *
    4469           0 : PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length)
    4470             : {
    4471           0 :     return PQescapeByteaInternal(NULL, from, from_length, to_length,
    4472             :                                  static_std_strings,
    4473             :                                  false /* can't use hex */ );
    4474             : }
    4475             : 
    4476             : 
    4477             : #define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3')
    4478             : #define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7')
    4479             : #define OCTVAL(CH) ((CH) - '0')
    4480             : 
    4481             : /*
    4482             :  *      PQunescapeBytea - converts the null terminated string representation
    4483             :  *      of a bytea, strtext, into binary, filling a buffer. It returns a
    4484             :  *      pointer to the buffer (or NULL on error), and the size of the
    4485             :  *      buffer in retbuflen. The pointer may subsequently be used as an
    4486             :  *      argument to the function PQfreemem.
    4487             :  *
    4488             :  *      The following transformations are made:
    4489             :  *      \\   == ASCII 92 == \
    4490             :  *      \ooo == a byte whose value = ooo (ooo is an octal number)
    4491             :  *      \x   == x (x is any character not matched by the above transformations)
    4492             :  */
    4493             : unsigned char *
    4494           0 : PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
    4495             : {
    4496             :     size_t      strtextlen,
    4497             :                 buflen;
    4498             :     unsigned char *buffer,
    4499             :                *tmpbuf;
    4500             :     size_t      i,
    4501             :                 j;
    4502             : 
    4503           0 :     if (strtext == NULL)
    4504           0 :         return NULL;
    4505             : 
    4506           0 :     strtextlen = strlen((const char *) strtext);
    4507             : 
    4508           0 :     if (strtext[0] == '\\' && strtext[1] == 'x')
    4509           0 :     {
    4510             :         const unsigned char *s;
    4511             :         unsigned char *p;
    4512             : 
    4513           0 :         buflen = (strtextlen - 2) / 2;
    4514             :         /* Avoid unportable malloc(0) */
    4515           0 :         buffer = (unsigned char *) malloc(buflen > 0 ? buflen : 1);
    4516           0 :         if (buffer == NULL)
    4517           0 :             return NULL;
    4518             : 
    4519           0 :         s = strtext + 2;
    4520           0 :         p = buffer;
    4521           0 :         while (*s)
    4522             :         {
    4523             :             char        v1,
    4524             :                         v2;
    4525             : 
    4526             :             /*
    4527             :              * Bad input is silently ignored.  Note that this includes
    4528             :              * whitespace between hex pairs, which is allowed by byteain.
    4529             :              */
    4530           0 :             v1 = get_hex(*s++);
    4531           0 :             if (!*s || v1 == (char) -1)
    4532           0 :                 continue;
    4533           0 :             v2 = get_hex(*s++);
    4534           0 :             if (v2 != (char) -1)
    4535           0 :                 *p++ = (v1 << 4) | v2;
    4536             :         }
    4537             : 
    4538           0 :         buflen = p - buffer;
    4539             :     }
    4540             :     else
    4541             :     {
    4542             :         /*
    4543             :          * Length of input is max length of output, but add one to avoid
    4544             :          * unportable malloc(0) if input is zero-length.
    4545             :          */
    4546           0 :         buffer = (unsigned char *) malloc(strtextlen + 1);
    4547           0 :         if (buffer == NULL)
    4548           0 :             return NULL;
    4549             : 
    4550           0 :         for (i = j = 0; i < strtextlen;)
    4551             :         {
    4552           0 :             switch (strtext[i])
    4553             :             {
    4554           0 :                 case '\\':
    4555           0 :                     i++;
    4556           0 :                     if (strtext[i] == '\\')
    4557           0 :                         buffer[j++] = strtext[i++];
    4558             :                     else
    4559             :                     {
    4560           0 :                         if ((ISFIRSTOCTDIGIT(strtext[i])) &&
    4561           0 :                             (ISOCTDIGIT(strtext[i + 1])) &&
    4562           0 :                             (ISOCTDIGIT(strtext[i + 2])))
    4563             :                         {
    4564             :                             int         byte;
    4565             : 
    4566           0 :                             byte = OCTVAL(strtext[i++]);
    4567           0 :                             byte = (byte << 3) + OCTVAL(strtext[i++]);
    4568           0 :                             byte = (byte << 3) + OCTVAL(strtext[i++]);
    4569           0 :                             buffer[j++] = byte;
    4570             :                         }
    4571             :                     }
    4572             : 
    4573             :                     /*
    4574             :                      * Note: if we see '\' followed by something that isn't a
    4575             :                      * recognized escape sequence, we loop around having done
    4576             :                      * nothing except advance i.  Therefore the something will
    4577             :                      * be emitted as ordinary data on the next cycle. Corner
    4578             :                      * case: '\' at end of string will just be discarded.
    4579             :                      */
    4580           0 :                     break;
    4581             : 
    4582           0 :                 default:
    4583           0 :                     buffer[j++] = strtext[i++];
    4584           0 :                     break;
    4585             :             }
    4586             :         }
    4587           0 :         buflen = j;             /* buflen is the length of the dequoted data */
    4588             :     }
    4589             : 
    4590             :     /* Shrink the buffer to be no larger than necessary */
    4591             :     /* +1 avoids unportable behavior when buflen==0 */
    4592           0 :     tmpbuf = realloc(buffer, buflen + 1);
    4593             : 
    4594             :     /* It would only be a very brain-dead realloc that could fail, but... */
    4595           0 :     if (!tmpbuf)
    4596             :     {
    4597           0 :         free(buffer);
    4598           0 :         return NULL;
    4599             :     }
    4600             : 
    4601           0 :     *retbuflen = buflen;
    4602           0 :     return tmpbuf;
    4603             : }

Generated by: LCOV version 1.14