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