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

Generated by: LCOV version 1.11