LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-exec.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 735 1370 53.6 %
Date: 2019-11-13 21:06:57 Functions: 72 99 72.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13