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