LCOV - differential code coverage report
Current view: top level - src/interfaces/libpq - fe-exec.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 61.5 % 1544 949 38 72 288 197 108 507 13 321 281 535 9 21
Current Date: 2023-04-08 17:13:01 Functions: 80.9 % 110 89 1 17 3 80 2 7 18 81
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 100.0 % 2 2 2
Legend: Lines: hit not hit (120,180] days: 13.2 % 38 5 33 4 1 1
(180,240] days: 56.5 % 23 13 5 3 2 3 7 2 1 2
(240..) days: 62.7 % 1481 929 69 286 197 105 500 5 319 281 532
Function coverage date bins:
(180,240] days: 50.0 % 2 1 1 1
(240..) days: 42.5 % 207 88 17 3 80 1 7 18 81

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

Generated by: LCOV version v1.16-55-g56c0a2a