1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * fe-protocol2.c |
4 | * functions that are specific to frontend/backend protocol version 2 |
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-protocol2.c |
12 | * |
13 | *------------------------------------------------------------------------- |
14 | */ |
15 | #include "postgres_fe.h" |
16 | |
17 | #include <ctype.h> |
18 | #include <fcntl.h> |
19 | |
20 | #include "libpq-fe.h" |
21 | #include "libpq-int.h" |
22 | #include "port/pg_bswap.h" |
23 | |
24 | |
25 | #ifdef WIN32 |
26 | #include "win32.h" |
27 | #else |
28 | #include <unistd.h> |
29 | #ifdef HAVE_NETINET_TCP_H |
30 | #include <netinet/tcp.h> |
31 | #endif |
32 | #endif |
33 | |
34 | |
35 | static int getRowDescriptions(PGconn *conn); |
36 | static int getAnotherTuple(PGconn *conn, bool binary); |
37 | static int pqGetErrorNotice2(PGconn *conn, bool isError); |
38 | static void checkXactStatus(PGconn *conn, const char *cmdTag); |
39 | static int getNotify(PGconn *conn); |
40 | |
41 | |
42 | /* |
43 | * pqSetenvPoll |
44 | * |
45 | * Polls the process of passing the values of a standard set of environment |
46 | * variables to the backend. |
47 | */ |
48 | PostgresPollingStatusType |
49 | pqSetenvPoll(PGconn *conn) |
50 | { |
51 | PGresult *res; |
52 | |
53 | if (conn == NULL || conn->status == CONNECTION_BAD) |
54 | return PGRES_POLLING_FAILED; |
55 | |
56 | /* Check whether there are any data for us */ |
57 | switch (conn->setenv_state) |
58 | { |
59 | /* These are reading states */ |
60 | case SETENV_STATE_CLIENT_ENCODING_WAIT: |
61 | case SETENV_STATE_OPTION_WAIT: |
62 | case SETENV_STATE_QUERY1_WAIT: |
63 | case SETENV_STATE_QUERY2_WAIT: |
64 | { |
65 | /* Load waiting data */ |
66 | int n = pqReadData(conn); |
67 | |
68 | if (n < 0) |
69 | goto error_return; |
70 | if (n == 0) |
71 | return PGRES_POLLING_READING; |
72 | |
73 | break; |
74 | } |
75 | |
76 | /* These are writing states, so we just proceed. */ |
77 | case SETENV_STATE_CLIENT_ENCODING_SEND: |
78 | case SETENV_STATE_OPTION_SEND: |
79 | case SETENV_STATE_QUERY1_SEND: |
80 | case SETENV_STATE_QUERY2_SEND: |
81 | break; |
82 | |
83 | /* Should we raise an error if called when not active? */ |
84 | case SETENV_STATE_IDLE: |
85 | return PGRES_POLLING_OK; |
86 | |
87 | default: |
88 | printfPQExpBuffer(&conn->errorMessage, |
89 | libpq_gettext( |
90 | "invalid setenv state %c, " |
91 | "probably indicative of memory corruption\n" |
92 | ), |
93 | conn->setenv_state); |
94 | goto error_return; |
95 | } |
96 | |
97 | /* We will loop here until there is nothing left to do in this call. */ |
98 | for (;;) |
99 | { |
100 | switch (conn->setenv_state) |
101 | { |
102 | /* |
103 | * The _CLIENT_ENCODING_SEND code is slightly different from |
104 | * _OPTION_SEND below (e.g., no getenv() call), which is why a |
105 | * different state is used. |
106 | */ |
107 | case SETENV_STATE_CLIENT_ENCODING_SEND: |
108 | { |
109 | char setQuery[100]; /* note length limit in |
110 | * sprintf below */ |
111 | const char *val = conn->client_encoding_initial; |
112 | |
113 | if (val) |
114 | { |
115 | if (pg_strcasecmp(val, "default" ) == 0) |
116 | sprintf(setQuery, "SET client_encoding = DEFAULT" ); |
117 | else |
118 | sprintf(setQuery, "SET client_encoding = '%.60s'" , |
119 | val); |
120 | #ifdef CONNECTDEBUG |
121 | fprintf(stderr, |
122 | "Sending client_encoding with %s\n" , |
123 | setQuery); |
124 | #endif |
125 | if (!PQsendQuery(conn, setQuery)) |
126 | goto error_return; |
127 | |
128 | conn->setenv_state = SETENV_STATE_CLIENT_ENCODING_WAIT; |
129 | } |
130 | else |
131 | conn->setenv_state = SETENV_STATE_OPTION_SEND; |
132 | break; |
133 | } |
134 | |
135 | case SETENV_STATE_OPTION_SEND: |
136 | { |
137 | /* |
138 | * Send SET commands for stuff directed by Environment |
139 | * Options. Note: we assume that SET commands won't start |
140 | * transaction blocks, even in a 7.3 server with |
141 | * autocommit off. |
142 | */ |
143 | char setQuery[100]; /* note length limit in |
144 | * sprintf below */ |
145 | |
146 | if (conn->next_eo->envName) |
147 | { |
148 | const char *val; |
149 | |
150 | if ((val = getenv(conn->next_eo->envName))) |
151 | { |
152 | if (pg_strcasecmp(val, "default" ) == 0) |
153 | sprintf(setQuery, "SET %s = DEFAULT" , |
154 | conn->next_eo->pgName); |
155 | else |
156 | sprintf(setQuery, "SET %s = '%.60s'" , |
157 | conn->next_eo->pgName, val); |
158 | #ifdef CONNECTDEBUG |
159 | fprintf(stderr, |
160 | "Use environment variable %s to send %s\n" , |
161 | conn->next_eo->envName, setQuery); |
162 | #endif |
163 | if (!PQsendQuery(conn, setQuery)) |
164 | goto error_return; |
165 | |
166 | conn->setenv_state = SETENV_STATE_OPTION_WAIT; |
167 | } |
168 | else |
169 | conn->next_eo++; |
170 | } |
171 | else |
172 | { |
173 | /* No more options to send, so move on to querying */ |
174 | conn->setenv_state = SETENV_STATE_QUERY1_SEND; |
175 | } |
176 | break; |
177 | } |
178 | |
179 | case SETENV_STATE_CLIENT_ENCODING_WAIT: |
180 | { |
181 | if (PQisBusy(conn)) |
182 | return PGRES_POLLING_READING; |
183 | |
184 | res = PQgetResult(conn); |
185 | |
186 | if (res) |
187 | { |
188 | if (PQresultStatus(res) != PGRES_COMMAND_OK) |
189 | { |
190 | PQclear(res); |
191 | goto error_return; |
192 | } |
193 | PQclear(res); |
194 | /* Keep reading until PQgetResult returns NULL */ |
195 | } |
196 | else |
197 | { |
198 | /* Query finished, so send the next option */ |
199 | conn->setenv_state = SETENV_STATE_OPTION_SEND; |
200 | } |
201 | break; |
202 | } |
203 | |
204 | case SETENV_STATE_OPTION_WAIT: |
205 | { |
206 | if (PQisBusy(conn)) |
207 | return PGRES_POLLING_READING; |
208 | |
209 | res = PQgetResult(conn); |
210 | |
211 | if (res) |
212 | { |
213 | if (PQresultStatus(res) != PGRES_COMMAND_OK) |
214 | { |
215 | PQclear(res); |
216 | goto error_return; |
217 | } |
218 | PQclear(res); |
219 | /* Keep reading until PQgetResult returns NULL */ |
220 | } |
221 | else |
222 | { |
223 | /* Query finished, so send the next option */ |
224 | conn->next_eo++; |
225 | conn->setenv_state = SETENV_STATE_OPTION_SEND; |
226 | } |
227 | break; |
228 | } |
229 | |
230 | case SETENV_STATE_QUERY1_SEND: |
231 | { |
232 | /* |
233 | * Issue query to get information we need. Here we must |
234 | * use begin/commit in case autocommit is off by default |
235 | * in a 7.3 server. |
236 | * |
237 | * Note: version() exists in all protocol-2.0-supporting |
238 | * backends. In 7.3 it would be safer to write |
239 | * pg_catalog.version(), but we can't do that without |
240 | * causing problems on older versions. |
241 | */ |
242 | if (!PQsendQuery(conn, "begin; select version(); end" )) |
243 | goto error_return; |
244 | |
245 | conn->setenv_state = SETENV_STATE_QUERY1_WAIT; |
246 | return PGRES_POLLING_READING; |
247 | } |
248 | |
249 | case SETENV_STATE_QUERY1_WAIT: |
250 | { |
251 | if (PQisBusy(conn)) |
252 | return PGRES_POLLING_READING; |
253 | |
254 | res = PQgetResult(conn); |
255 | |
256 | if (res) |
257 | { |
258 | char *val; |
259 | |
260 | if (PQresultStatus(res) == PGRES_COMMAND_OK) |
261 | { |
262 | /* ignore begin/commit command results */ |
263 | PQclear(res); |
264 | continue; |
265 | } |
266 | |
267 | if (PQresultStatus(res) != PGRES_TUPLES_OK || |
268 | PQntuples(res) != 1) |
269 | { |
270 | PQclear(res); |
271 | goto error_return; |
272 | } |
273 | |
274 | /* |
275 | * Extract server version and save as if |
276 | * ParameterStatus |
277 | */ |
278 | val = PQgetvalue(res, 0, 0); |
279 | if (val && strncmp(val, "PostgreSQL " , 11) == 0) |
280 | { |
281 | char *ptr; |
282 | |
283 | /* strip off PostgreSQL part */ |
284 | val += 11; |
285 | |
286 | /* |
287 | * strip off platform part (scribbles on result, |
288 | * naughty naughty) |
289 | */ |
290 | ptr = strchr(val, ' '); |
291 | if (ptr) |
292 | *ptr = '\0'; |
293 | |
294 | pqSaveParameterStatus(conn, "server_version" , |
295 | val); |
296 | } |
297 | |
298 | PQclear(res); |
299 | /* Keep reading until PQgetResult returns NULL */ |
300 | } |
301 | else |
302 | { |
303 | /* Query finished, move to next */ |
304 | conn->setenv_state = SETENV_STATE_QUERY2_SEND; |
305 | } |
306 | break; |
307 | } |
308 | |
309 | case SETENV_STATE_QUERY2_SEND: |
310 | { |
311 | const char *query; |
312 | |
313 | /* |
314 | * pg_client_encoding does not exist in pre-7.2 servers. |
315 | * So we need to be prepared for an error here. Do *not* |
316 | * start a transaction block, except in 7.3 servers where |
317 | * we need to prevent autocommit-off from starting a |
318 | * transaction anyway. |
319 | */ |
320 | if (conn->sversion >= 70300 && |
321 | conn->sversion < 70400) |
322 | query = "begin; select pg_catalog.pg_client_encoding(); end" ; |
323 | else |
324 | query = "select pg_client_encoding()" ; |
325 | if (!PQsendQuery(conn, query)) |
326 | goto error_return; |
327 | |
328 | conn->setenv_state = SETENV_STATE_QUERY2_WAIT; |
329 | return PGRES_POLLING_READING; |
330 | } |
331 | |
332 | case SETENV_STATE_QUERY2_WAIT: |
333 | { |
334 | if (PQisBusy(conn)) |
335 | return PGRES_POLLING_READING; |
336 | |
337 | res = PQgetResult(conn); |
338 | |
339 | if (res) |
340 | { |
341 | const char *val; |
342 | |
343 | if (PQresultStatus(res) == PGRES_COMMAND_OK) |
344 | { |
345 | /* ignore begin/commit command results */ |
346 | PQclear(res); |
347 | continue; |
348 | } |
349 | |
350 | if (PQresultStatus(res) == PGRES_TUPLES_OK && |
351 | PQntuples(res) == 1) |
352 | { |
353 | /* Extract client encoding and save it */ |
354 | val = PQgetvalue(res, 0, 0); |
355 | if (val && *val) /* null should not happen, but */ |
356 | pqSaveParameterStatus(conn, "client_encoding" , |
357 | val); |
358 | } |
359 | else |
360 | { |
361 | /* |
362 | * Error: presumably function not available, so |
363 | * use PGCLIENTENCODING or SQL_ASCII as the |
364 | * fallback. |
365 | */ |
366 | val = getenv("PGCLIENTENCODING" ); |
367 | if (val && *val) |
368 | pqSaveParameterStatus(conn, "client_encoding" , |
369 | val); |
370 | else |
371 | pqSaveParameterStatus(conn, "client_encoding" , |
372 | "SQL_ASCII" ); |
373 | } |
374 | |
375 | PQclear(res); |
376 | /* Keep reading until PQgetResult returns NULL */ |
377 | } |
378 | else |
379 | { |
380 | /* Query finished, so we're done */ |
381 | conn->setenv_state = SETENV_STATE_IDLE; |
382 | return PGRES_POLLING_OK; |
383 | } |
384 | break; |
385 | } |
386 | |
387 | default: |
388 | printfPQExpBuffer(&conn->errorMessage, |
389 | libpq_gettext("invalid state %c, " |
390 | "probably indicative of memory corruption\n" ), |
391 | conn->setenv_state); |
392 | goto error_return; |
393 | } |
394 | } |
395 | |
396 | /* Unreachable */ |
397 | |
398 | error_return: |
399 | conn->setenv_state = SETENV_STATE_IDLE; |
400 | return PGRES_POLLING_FAILED; |
401 | } |
402 | |
403 | |
404 | /* |
405 | * parseInput: if appropriate, parse input data from backend |
406 | * until input is exhausted or a stopping state is reached. |
407 | * Note that this function will NOT attempt to read more data from the backend. |
408 | */ |
409 | void |
410 | pqParseInput2(PGconn *conn) |
411 | { |
412 | char id; |
413 | |
414 | /* |
415 | * Loop to parse successive complete messages available in the buffer. |
416 | */ |
417 | for (;;) |
418 | { |
419 | /* |
420 | * Quit if in COPY_OUT state: we expect raw data from the server until |
421 | * PQendcopy is called. Don't try to parse it according to the normal |
422 | * protocol. (This is bogus. The data lines ought to be part of the |
423 | * protocol and have identifying leading characters.) |
424 | */ |
425 | if (conn->asyncStatus == PGASYNC_COPY_OUT) |
426 | return; |
427 | |
428 | /* |
429 | * OK to try to read a message type code. |
430 | */ |
431 | conn->inCursor = conn->inStart; |
432 | if (pqGetc(&id, conn)) |
433 | return; |
434 | |
435 | /* |
436 | * NOTIFY and NOTICE messages can happen in any state besides COPY |
437 | * OUT; always process them right away. |
438 | * |
439 | * Most other messages should only be processed while in BUSY state. |
440 | * (In particular, in READY state we hold off further parsing until |
441 | * the application collects the current PGresult.) |
442 | * |
443 | * However, if the state is IDLE then we got trouble; we need to deal |
444 | * with the unexpected message somehow. |
445 | */ |
446 | if (id == 'A') |
447 | { |
448 | if (getNotify(conn)) |
449 | return; |
450 | } |
451 | else if (id == 'N') |
452 | { |
453 | if (pqGetErrorNotice2(conn, false)) |
454 | return; |
455 | } |
456 | else if (conn->asyncStatus != PGASYNC_BUSY) |
457 | { |
458 | /* If not IDLE state, just wait ... */ |
459 | if (conn->asyncStatus != PGASYNC_IDLE) |
460 | return; |
461 | |
462 | /* |
463 | * Unexpected message in IDLE state; need to recover somehow. |
464 | * ERROR messages are displayed using the notice processor; |
465 | * anything else is just dropped on the floor after displaying a |
466 | * suitable warning notice. (An ERROR is very possibly the |
467 | * backend telling us why it is about to close the connection, so |
468 | * we don't want to just discard it...) |
469 | */ |
470 | if (id == 'E') |
471 | { |
472 | if (pqGetErrorNotice2(conn, false /* treat as notice */ )) |
473 | return; |
474 | } |
475 | else |
476 | { |
477 | pqInternalNotice(&conn->noticeHooks, |
478 | "message type 0x%02x arrived from server while idle" , |
479 | id); |
480 | /* Discard the unexpected message; good idea?? */ |
481 | conn->inStart = conn->inEnd; |
482 | break; |
483 | } |
484 | } |
485 | else |
486 | { |
487 | /* |
488 | * In BUSY state, we can process everything. |
489 | */ |
490 | switch (id) |
491 | { |
492 | case 'C': /* command complete */ |
493 | if (pqGets(&conn->workBuffer, conn)) |
494 | return; |
495 | if (conn->result == NULL) |
496 | { |
497 | conn->result = PQmakeEmptyPGresult(conn, |
498 | PGRES_COMMAND_OK); |
499 | if (!conn->result) |
500 | { |
501 | printfPQExpBuffer(&conn->errorMessage, |
502 | libpq_gettext("out of memory" )); |
503 | pqSaveErrorResult(conn); |
504 | } |
505 | } |
506 | if (conn->result) |
507 | { |
508 | strlcpy(conn->result->cmdStatus, conn->workBuffer.data, |
509 | CMDSTATUS_LEN); |
510 | } |
511 | checkXactStatus(conn, conn->workBuffer.data); |
512 | conn->asyncStatus = PGASYNC_READY; |
513 | break; |
514 | case 'E': /* error return */ |
515 | if (pqGetErrorNotice2(conn, true)) |
516 | return; |
517 | conn->asyncStatus = PGASYNC_READY; |
518 | break; |
519 | case 'Z': /* backend is ready for new query */ |
520 | conn->asyncStatus = PGASYNC_IDLE; |
521 | break; |
522 | case 'I': /* empty query */ |
523 | /* read and throw away the closing '\0' */ |
524 | if (pqGetc(&id, conn)) |
525 | return; |
526 | if (id != '\0') |
527 | pqInternalNotice(&conn->noticeHooks, |
528 | "unexpected character %c following empty query response (\"I\" message)" , |
529 | id); |
530 | if (conn->result == NULL) |
531 | { |
532 | conn->result = PQmakeEmptyPGresult(conn, |
533 | PGRES_EMPTY_QUERY); |
534 | if (!conn->result) |
535 | { |
536 | printfPQExpBuffer(&conn->errorMessage, |
537 | libpq_gettext("out of memory" )); |
538 | pqSaveErrorResult(conn); |
539 | } |
540 | } |
541 | conn->asyncStatus = PGASYNC_READY; |
542 | break; |
543 | case 'K': /* secret key data from the backend */ |
544 | |
545 | /* |
546 | * This is expected only during backend startup, but it's |
547 | * just as easy to handle it as part of the main loop. |
548 | * Save the data and continue processing. |
549 | */ |
550 | if (pqGetInt(&(conn->be_pid), 4, conn)) |
551 | return; |
552 | if (pqGetInt(&(conn->be_key), 4, conn)) |
553 | return; |
554 | break; |
555 | case 'P': /* synchronous (normal) portal */ |
556 | if (pqGets(&conn->workBuffer, conn)) |
557 | return; |
558 | /* We pretty much ignore this message type... */ |
559 | break; |
560 | case 'T': /* row descriptions (start of query results) */ |
561 | if (conn->result == NULL) |
562 | { |
563 | /* First 'T' in a query sequence */ |
564 | if (getRowDescriptions(conn)) |
565 | return; |
566 | /* getRowDescriptions() moves inStart itself */ |
567 | continue; |
568 | } |
569 | else |
570 | { |
571 | /* |
572 | * A new 'T' message is treated as the start of |
573 | * another PGresult. (It is not clear that this is |
574 | * really possible with the current backend.) We stop |
575 | * parsing until the application accepts the current |
576 | * result. |
577 | */ |
578 | conn->asyncStatus = PGASYNC_READY; |
579 | return; |
580 | } |
581 | break; |
582 | case 'D': /* ASCII data tuple */ |
583 | if (conn->result != NULL) |
584 | { |
585 | /* Read another tuple of a normal query response */ |
586 | if (getAnotherTuple(conn, false)) |
587 | return; |
588 | /* getAnotherTuple() moves inStart itself */ |
589 | continue; |
590 | } |
591 | else |
592 | { |
593 | pqInternalNotice(&conn->noticeHooks, |
594 | "server sent data (\"D\" message) without prior row description (\"T\" message)" ); |
595 | /* Discard the unexpected message; good idea?? */ |
596 | conn->inStart = conn->inEnd; |
597 | return; |
598 | } |
599 | break; |
600 | case 'B': /* Binary data tuple */ |
601 | if (conn->result != NULL) |
602 | { |
603 | /* Read another tuple of a normal query response */ |
604 | if (getAnotherTuple(conn, true)) |
605 | return; |
606 | /* getAnotherTuple() moves inStart itself */ |
607 | continue; |
608 | } |
609 | else |
610 | { |
611 | pqInternalNotice(&conn->noticeHooks, |
612 | "server sent binary data (\"B\" message) without prior row description (\"T\" message)" ); |
613 | /* Discard the unexpected message; good idea?? */ |
614 | conn->inStart = conn->inEnd; |
615 | return; |
616 | } |
617 | break; |
618 | case 'G': /* Start Copy In */ |
619 | conn->asyncStatus = PGASYNC_COPY_IN; |
620 | break; |
621 | case 'H': /* Start Copy Out */ |
622 | conn->asyncStatus = PGASYNC_COPY_OUT; |
623 | break; |
624 | |
625 | /* |
626 | * Don't need to process CopyBothResponse here because it |
627 | * never arrives from the server during protocol 2.0. |
628 | */ |
629 | default: |
630 | printfPQExpBuffer(&conn->errorMessage, |
631 | libpq_gettext( |
632 | "unexpected response from server; first received character was \"%c\"\n" ), |
633 | id); |
634 | /* build an error result holding the error message */ |
635 | pqSaveErrorResult(conn); |
636 | /* Discard the unexpected message; good idea?? */ |
637 | conn->inStart = conn->inEnd; |
638 | conn->asyncStatus = PGASYNC_READY; |
639 | return; |
640 | } /* switch on protocol character */ |
641 | } |
642 | /* Successfully consumed this message */ |
643 | conn->inStart = conn->inCursor; |
644 | } |
645 | } |
646 | |
647 | /* |
648 | * parseInput subroutine to read a 'T' (row descriptions) message. |
649 | * We build a PGresult structure containing the attribute data. |
650 | * Returns: 0 if completed message, EOF if error or not enough data |
651 | * received yet. |
652 | * |
653 | * Note that if we run out of data, we have to suspend and reprocess |
654 | * the message after more data is received. Otherwise, conn->inStart |
655 | * must get advanced past the processed data. |
656 | */ |
657 | static int |
658 | getRowDescriptions(PGconn *conn) |
659 | { |
660 | PGresult *result; |
661 | int nfields; |
662 | const char *errmsg; |
663 | int i; |
664 | |
665 | result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK); |
666 | if (!result) |
667 | { |
668 | errmsg = NULL; /* means "out of memory", see below */ |
669 | goto advance_and_error; |
670 | } |
671 | |
672 | /* parseInput already read the 'T' label. */ |
673 | /* the next two bytes are the number of fields */ |
674 | if (pqGetInt(&(result->numAttributes), 2, conn)) |
675 | goto EOFexit; |
676 | nfields = result->numAttributes; |
677 | |
678 | /* allocate space for the attribute descriptors */ |
679 | if (nfields > 0) |
680 | { |
681 | result->attDescs = (PGresAttDesc *) |
682 | pqResultAlloc(result, nfields * sizeof(PGresAttDesc), true); |
683 | if (!result->attDescs) |
684 | { |
685 | errmsg = NULL; /* means "out of memory", see below */ |
686 | goto advance_and_error; |
687 | } |
688 | MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc)); |
689 | } |
690 | |
691 | /* get type info */ |
692 | for (i = 0; i < nfields; i++) |
693 | { |
694 | int typid; |
695 | int typlen; |
696 | int atttypmod; |
697 | |
698 | if (pqGets(&conn->workBuffer, conn) || |
699 | pqGetInt(&typid, 4, conn) || |
700 | pqGetInt(&typlen, 2, conn) || |
701 | pqGetInt(&atttypmod, 4, conn)) |
702 | goto EOFexit; |
703 | |
704 | /* |
705 | * Since pqGetInt treats 2-byte integers as unsigned, we need to |
706 | * coerce the result to signed form. |
707 | */ |
708 | typlen = (int) ((int16) typlen); |
709 | |
710 | result->attDescs[i].name = pqResultStrdup(result, |
711 | conn->workBuffer.data); |
712 | if (!result->attDescs[i].name) |
713 | { |
714 | errmsg = NULL; /* means "out of memory", see below */ |
715 | goto advance_and_error; |
716 | } |
717 | result->attDescs[i].tableid = 0; |
718 | result->attDescs[i].columnid = 0; |
719 | result->attDescs[i].format = 0; |
720 | result->attDescs[i].typid = typid; |
721 | result->attDescs[i].typlen = typlen; |
722 | result->attDescs[i].atttypmod = atttypmod; |
723 | } |
724 | |
725 | /* Success! */ |
726 | conn->result = result; |
727 | |
728 | /* Advance inStart to show that the "T" message has been processed. */ |
729 | conn->inStart = conn->inCursor; |
730 | |
731 | /* |
732 | * We could perform additional setup for the new result set here, but for |
733 | * now there's nothing else to do. |
734 | */ |
735 | |
736 | /* And we're done. */ |
737 | return 0; |
738 | |
739 | advance_and_error: |
740 | |
741 | /* |
742 | * Discard the failed message. Unfortunately we don't know for sure where |
743 | * the end is, so just throw away everything in the input buffer. This is |
744 | * not very desirable but it's the best we can do in protocol v2. |
745 | */ |
746 | conn->inStart = conn->inEnd; |
747 | |
748 | /* |
749 | * Replace partially constructed result with an error result. First |
750 | * discard the old result to try to win back some memory. |
751 | */ |
752 | pqClearAsyncResult(conn); |
753 | |
754 | /* |
755 | * If preceding code didn't provide an error message, assume "out of |
756 | * memory" was meant. The advantage of having this special case is that |
757 | * freeing the old result first greatly improves the odds that gettext() |
758 | * will succeed in providing a translation. |
759 | */ |
760 | if (!errmsg) |
761 | errmsg = libpq_gettext("out of memory for query result" ); |
762 | |
763 | printfPQExpBuffer(&conn->errorMessage, "%s\n" , errmsg); |
764 | |
765 | /* |
766 | * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can |
767 | * do to recover... |
768 | */ |
769 | conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR); |
770 | conn->asyncStatus = PGASYNC_READY; |
771 | |
772 | EOFexit: |
773 | if (result && result != conn->result) |
774 | PQclear(result); |
775 | return EOF; |
776 | } |
777 | |
778 | /* |
779 | * parseInput subroutine to read a 'B' or 'D' (row data) message. |
780 | * We fill rowbuf with column pointers and then call the row processor. |
781 | * Returns: 0 if completed message, EOF if error or not enough data |
782 | * received yet. |
783 | * |
784 | * Note that if we run out of data, we have to suspend and reprocess |
785 | * the message after more data is received. Otherwise, conn->inStart |
786 | * must get advanced past the processed data. |
787 | */ |
788 | static int |
789 | getAnotherTuple(PGconn *conn, bool binary) |
790 | { |
791 | PGresult *result = conn->result; |
792 | int nfields = result->numAttributes; |
793 | const char *errmsg; |
794 | PGdataValue *rowbuf; |
795 | |
796 | /* the backend sends us a bitmap of which attributes are null */ |
797 | char std_bitmap[64]; /* used unless it doesn't fit */ |
798 | char *bitmap = std_bitmap; |
799 | int i; |
800 | size_t nbytes; /* the number of bytes in bitmap */ |
801 | char bmap; /* One byte of the bitmap */ |
802 | int bitmap_index; /* Its index */ |
803 | int bitcnt; /* number of bits examined in current byte */ |
804 | int vlen; /* length of the current field value */ |
805 | |
806 | /* Resize row buffer if needed */ |
807 | rowbuf = conn->rowBuf; |
808 | if (nfields > conn->rowBufLen) |
809 | { |
810 | rowbuf = (PGdataValue *) realloc(rowbuf, |
811 | nfields * sizeof(PGdataValue)); |
812 | if (!rowbuf) |
813 | { |
814 | errmsg = NULL; /* means "out of memory", see below */ |
815 | goto advance_and_error; |
816 | } |
817 | conn->rowBuf = rowbuf; |
818 | conn->rowBufLen = nfields; |
819 | } |
820 | |
821 | /* Save format specifier */ |
822 | result->binary = binary; |
823 | |
824 | /* |
825 | * If it's binary, fix the column format indicators. We assume the |
826 | * backend will consistently send either B or D, not a mix. |
827 | */ |
828 | if (binary) |
829 | { |
830 | for (i = 0; i < nfields; i++) |
831 | result->attDescs[i].format = 1; |
832 | } |
833 | |
834 | /* Get the null-value bitmap */ |
835 | nbytes = (nfields + BITS_PER_BYTE - 1) / BITS_PER_BYTE; |
836 | /* malloc() only for unusually large field counts... */ |
837 | if (nbytes > sizeof(std_bitmap)) |
838 | { |
839 | bitmap = (char *) malloc(nbytes); |
840 | if (!bitmap) |
841 | { |
842 | errmsg = NULL; /* means "out of memory", see below */ |
843 | goto advance_and_error; |
844 | } |
845 | } |
846 | |
847 | if (pqGetnchar(bitmap, nbytes, conn)) |
848 | goto EOFexit; |
849 | |
850 | /* Scan the fields */ |
851 | bitmap_index = 0; |
852 | bmap = bitmap[bitmap_index]; |
853 | bitcnt = 0; |
854 | |
855 | for (i = 0; i < nfields; i++) |
856 | { |
857 | /* get the value length */ |
858 | if (!(bmap & 0200)) |
859 | vlen = NULL_LEN; |
860 | else if (pqGetInt(&vlen, 4, conn)) |
861 | goto EOFexit; |
862 | else |
863 | { |
864 | if (!binary) |
865 | vlen = vlen - 4; |
866 | if (vlen < 0) |
867 | vlen = 0; |
868 | } |
869 | rowbuf[i].len = vlen; |
870 | |
871 | /* |
872 | * rowbuf[i].value always points to the next address in the data |
873 | * buffer even if the value is NULL. This allows row processors to |
874 | * estimate data sizes more easily. |
875 | */ |
876 | rowbuf[i].value = conn->inBuffer + conn->inCursor; |
877 | |
878 | /* Skip over the data value */ |
879 | if (vlen > 0) |
880 | { |
881 | if (pqSkipnchar(vlen, conn)) |
882 | goto EOFexit; |
883 | } |
884 | |
885 | /* advance the bitmap stuff */ |
886 | bitcnt++; |
887 | if (bitcnt == BITS_PER_BYTE) |
888 | { |
889 | bitmap_index++; |
890 | bmap = bitmap[bitmap_index]; |
891 | bitcnt = 0; |
892 | } |
893 | else |
894 | bmap <<= 1; |
895 | } |
896 | |
897 | /* Release bitmap now if we allocated it */ |
898 | if (bitmap != std_bitmap) |
899 | free(bitmap); |
900 | bitmap = NULL; |
901 | |
902 | /* Advance inStart to show that the "D" message has been processed. */ |
903 | conn->inStart = conn->inCursor; |
904 | |
905 | /* Process the collected row */ |
906 | errmsg = NULL; |
907 | if (pqRowProcessor(conn, &errmsg)) |
908 | return 0; /* normal, successful exit */ |
909 | |
910 | goto set_error_result; /* pqRowProcessor failed, report it */ |
911 | |
912 | advance_and_error: |
913 | |
914 | /* |
915 | * Discard the failed message. Unfortunately we don't know for sure where |
916 | * the end is, so just throw away everything in the input buffer. This is |
917 | * not very desirable but it's the best we can do in protocol v2. |
918 | */ |
919 | conn->inStart = conn->inEnd; |
920 | |
921 | set_error_result: |
922 | |
923 | /* |
924 | * Replace partially constructed result with an error result. First |
925 | * discard the old result to try to win back some memory. |
926 | */ |
927 | pqClearAsyncResult(conn); |
928 | |
929 | /* |
930 | * If preceding code didn't provide an error message, assume "out of |
931 | * memory" was meant. The advantage of having this special case is that |
932 | * freeing the old result first greatly improves the odds that gettext() |
933 | * will succeed in providing a translation. |
934 | */ |
935 | if (!errmsg) |
936 | errmsg = libpq_gettext("out of memory for query result" ); |
937 | |
938 | printfPQExpBuffer(&conn->errorMessage, "%s\n" , errmsg); |
939 | |
940 | /* |
941 | * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can |
942 | * do to recover... |
943 | */ |
944 | conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR); |
945 | conn->asyncStatus = PGASYNC_READY; |
946 | |
947 | EOFexit: |
948 | if (bitmap != NULL && bitmap != std_bitmap) |
949 | free(bitmap); |
950 | return EOF; |
951 | } |
952 | |
953 | |
954 | /* |
955 | * Attempt to read an Error or Notice response message. |
956 | * This is possible in several places, so we break it out as a subroutine. |
957 | * Entry: 'E' or 'N' message type has already been consumed. |
958 | * Exit: returns 0 if successfully consumed message. |
959 | * returns EOF if not enough data. |
960 | */ |
961 | static int |
962 | pqGetErrorNotice2(PGconn *conn, bool isError) |
963 | { |
964 | PGresult *res = NULL; |
965 | PQExpBufferData workBuf; |
966 | char *startp; |
967 | char *splitp; |
968 | |
969 | /* |
970 | * If this is an error message, pre-emptively clear any incomplete query |
971 | * result we may have. We'd just throw it away below anyway, and |
972 | * releasing it before collecting the error might avoid out-of-memory. |
973 | */ |
974 | if (isError) |
975 | pqClearAsyncResult(conn); |
976 | |
977 | /* |
978 | * Since the message might be pretty long, we create a temporary |
979 | * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended |
980 | * for stuff that is expected to be short. |
981 | */ |
982 | initPQExpBuffer(&workBuf); |
983 | if (pqGets(&workBuf, conn)) |
984 | goto failure; |
985 | |
986 | /* |
987 | * Make a PGresult to hold the message. We temporarily lie about the |
988 | * result status, so that PQmakeEmptyPGresult doesn't uselessly copy |
989 | * conn->errorMessage. |
990 | * |
991 | * NB: This allocation can fail, if you run out of memory. The rest of the |
992 | * function handles that gracefully, and we still try to set the error |
993 | * message as the connection's error message. |
994 | */ |
995 | res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY); |
996 | if (res) |
997 | { |
998 | res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR; |
999 | res->errMsg = pqResultStrdup(res, workBuf.data); |
1000 | } |
1001 | |
1002 | /* |
1003 | * Break the message into fields. We can't do very much here, but we can |
1004 | * split the severity code off, and remove trailing newlines. Also, we use |
1005 | * the heuristic that the primary message extends only to the first |
1006 | * newline --- anything after that is detail message. (In some cases it'd |
1007 | * be better classed as hint, but we can hardly be expected to guess that |
1008 | * here.) |
1009 | */ |
1010 | while (workBuf.len > 0 && workBuf.data[workBuf.len - 1] == '\n') |
1011 | workBuf.data[--workBuf.len] = '\0'; |
1012 | splitp = strstr(workBuf.data, ": " ); |
1013 | if (splitp) |
1014 | { |
1015 | /* what comes before the colon is severity */ |
1016 | *splitp = '\0'; |
1017 | pqSaveMessageField(res, PG_DIAG_SEVERITY, workBuf.data); |
1018 | startp = splitp + 3; |
1019 | } |
1020 | else |
1021 | { |
1022 | /* can't find a colon? oh well... */ |
1023 | startp = workBuf.data; |
1024 | } |
1025 | splitp = strchr(startp, '\n'); |
1026 | if (splitp) |
1027 | { |
1028 | /* what comes before the newline is primary message */ |
1029 | *splitp++ = '\0'; |
1030 | pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, startp); |
1031 | /* the rest is detail; strip any leading whitespace */ |
1032 | while (*splitp && isspace((unsigned char) *splitp)) |
1033 | splitp++; |
1034 | pqSaveMessageField(res, PG_DIAG_MESSAGE_DETAIL, splitp); |
1035 | } |
1036 | else |
1037 | { |
1038 | /* single-line message, so all primary */ |
1039 | pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, startp); |
1040 | } |
1041 | |
1042 | /* |
1043 | * Either save error as current async result, or just emit the notice. |
1044 | * Also, if it's an error and we were in a transaction block, assume the |
1045 | * server has now gone to error-in-transaction state. |
1046 | */ |
1047 | if (isError) |
1048 | { |
1049 | pqClearAsyncResult(conn); /* redundant, but be safe */ |
1050 | conn->result = res; |
1051 | resetPQExpBuffer(&conn->errorMessage); |
1052 | if (res && !PQExpBufferDataBroken(workBuf) && res->errMsg) |
1053 | appendPQExpBufferStr(&conn->errorMessage, res->errMsg); |
1054 | else |
1055 | printfPQExpBuffer(&conn->errorMessage, |
1056 | libpq_gettext("out of memory" )); |
1057 | if (conn->xactStatus == PQTRANS_INTRANS) |
1058 | conn->xactStatus = PQTRANS_INERROR; |
1059 | } |
1060 | else |
1061 | { |
1062 | if (res) |
1063 | { |
1064 | if (res->noticeHooks.noticeRec != NULL) |
1065 | res->noticeHooks.noticeRec(res->noticeHooks.noticeRecArg, res); |
1066 | PQclear(res); |
1067 | } |
1068 | } |
1069 | |
1070 | termPQExpBuffer(&workBuf); |
1071 | return 0; |
1072 | |
1073 | failure: |
1074 | if (res) |
1075 | PQclear(res); |
1076 | termPQExpBuffer(&workBuf); |
1077 | return EOF; |
1078 | } |
1079 | |
1080 | /* |
1081 | * checkXactStatus - attempt to track transaction-block status of server |
1082 | * |
1083 | * This is called each time we receive a command-complete message. By |
1084 | * watching for messages from BEGIN/COMMIT/ROLLBACK commands, we can do |
1085 | * a passable job of tracking the server's xact status. BUT: this does |
1086 | * not work at all on 7.3 servers with AUTOCOMMIT OFF. (Man, was that |
1087 | * feature ever a mistake.) Caveat user. |
1088 | * |
1089 | * The tags known here are all those used as far back as 7.0; is it worth |
1090 | * adding those from even-older servers? |
1091 | */ |
1092 | static void |
1093 | checkXactStatus(PGconn *conn, const char *cmdTag) |
1094 | { |
1095 | if (strcmp(cmdTag, "BEGIN" ) == 0) |
1096 | conn->xactStatus = PQTRANS_INTRANS; |
1097 | else if (strcmp(cmdTag, "COMMIT" ) == 0) |
1098 | conn->xactStatus = PQTRANS_IDLE; |
1099 | else if (strcmp(cmdTag, "ROLLBACK" ) == 0) |
1100 | conn->xactStatus = PQTRANS_IDLE; |
1101 | else if (strcmp(cmdTag, "START TRANSACTION" ) == 0) /* 7.3 only */ |
1102 | conn->xactStatus = PQTRANS_INTRANS; |
1103 | |
1104 | /* |
1105 | * Normally we get into INERROR state by detecting an Error message. |
1106 | * However, if we see one of these tags then we know for sure the server |
1107 | * is in abort state ... |
1108 | */ |
1109 | else if (strcmp(cmdTag, "*ABORT STATE*" ) == 0) /* pre-7.3 only */ |
1110 | conn->xactStatus = PQTRANS_INERROR; |
1111 | } |
1112 | |
1113 | /* |
1114 | * Attempt to read a Notify response message. |
1115 | * This is possible in several places, so we break it out as a subroutine. |
1116 | * Entry: 'A' message type and length have already been consumed. |
1117 | * Exit: returns 0 if successfully consumed Notify message. |
1118 | * returns EOF if not enough data. |
1119 | */ |
1120 | static int |
1121 | getNotify(PGconn *conn) |
1122 | { |
1123 | int be_pid; |
1124 | int nmlen; |
1125 | PGnotify *newNotify; |
1126 | |
1127 | if (pqGetInt(&be_pid, 4, conn)) |
1128 | return EOF; |
1129 | if (pqGets(&conn->workBuffer, conn)) |
1130 | return EOF; |
1131 | |
1132 | /* |
1133 | * Store the relation name right after the PQnotify structure so it can |
1134 | * all be freed at once. We don't use NAMEDATALEN because we don't want |
1135 | * to tie this interface to a specific server name length. |
1136 | */ |
1137 | nmlen = strlen(conn->workBuffer.data); |
1138 | newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + 1); |
1139 | if (newNotify) |
1140 | { |
1141 | newNotify->relname = (char *) newNotify + sizeof(PGnotify); |
1142 | strcpy(newNotify->relname, conn->workBuffer.data); |
1143 | /* fake up an empty-string extra field */ |
1144 | newNotify->extra = newNotify->relname + nmlen; |
1145 | newNotify->be_pid = be_pid; |
1146 | newNotify->next = NULL; |
1147 | if (conn->notifyTail) |
1148 | conn->notifyTail->next = newNotify; |
1149 | else |
1150 | conn->notifyHead = newNotify; |
1151 | conn->notifyTail = newNotify; |
1152 | } |
1153 | |
1154 | return 0; |
1155 | } |
1156 | |
1157 | |
1158 | /* |
1159 | * PQgetCopyData - read a row of data from the backend during COPY OUT |
1160 | * |
1161 | * If successful, sets *buffer to point to a malloc'd row of data, and |
1162 | * returns row length (always > 0) as result. |
1163 | * Returns 0 if no row available yet (only possible if async is true), |
1164 | * -1 if end of copy (consult PQgetResult), or -2 if error (consult |
1165 | * PQerrorMessage). |
1166 | */ |
1167 | int |
1168 | pqGetCopyData2(PGconn *conn, char **buffer, int async) |
1169 | { |
1170 | bool found; |
1171 | int msgLength; |
1172 | |
1173 | for (;;) |
1174 | { |
1175 | /* |
1176 | * Do we have a complete line of data? |
1177 | */ |
1178 | conn->inCursor = conn->inStart; |
1179 | found = false; |
1180 | while (conn->inCursor < conn->inEnd) |
1181 | { |
1182 | char c = conn->inBuffer[conn->inCursor++]; |
1183 | |
1184 | if (c == '\n') |
1185 | { |
1186 | found = true; |
1187 | break; |
1188 | } |
1189 | } |
1190 | if (!found) |
1191 | goto nodata; |
1192 | msgLength = conn->inCursor - conn->inStart; |
1193 | |
1194 | /* |
1195 | * If it's the end-of-data marker, consume it, exit COPY_OUT mode, and |
1196 | * let caller read status with PQgetResult(). |
1197 | */ |
1198 | if (msgLength == 3 && |
1199 | strncmp(&conn->inBuffer[conn->inStart], "\\.\n" , 3) == 0) |
1200 | { |
1201 | conn->inStart = conn->inCursor; |
1202 | conn->asyncStatus = PGASYNC_BUSY; |
1203 | return -1; |
1204 | } |
1205 | |
1206 | /* |
1207 | * Pass the line back to the caller. |
1208 | */ |
1209 | *buffer = (char *) malloc(msgLength + 1); |
1210 | if (*buffer == NULL) |
1211 | { |
1212 | printfPQExpBuffer(&conn->errorMessage, |
1213 | libpq_gettext("out of memory\n" )); |
1214 | return -2; |
1215 | } |
1216 | memcpy(*buffer, &conn->inBuffer[conn->inStart], msgLength); |
1217 | (*buffer)[msgLength] = '\0'; /* Add terminating null */ |
1218 | |
1219 | /* Mark message consumed */ |
1220 | conn->inStart = conn->inCursor; |
1221 | |
1222 | return msgLength; |
1223 | |
1224 | nodata: |
1225 | /* Don't block if async read requested */ |
1226 | if (async) |
1227 | return 0; |
1228 | /* Need to load more data */ |
1229 | if (pqWait(true, false, conn) || |
1230 | pqReadData(conn) < 0) |
1231 | return -2; |
1232 | } |
1233 | } |
1234 | |
1235 | |
1236 | /* |
1237 | * PQgetline - gets a newline-terminated string from the backend. |
1238 | * |
1239 | * See fe-exec.c for documentation. |
1240 | */ |
1241 | int |
1242 | pqGetline2(PGconn *conn, char *s, int maxlen) |
1243 | { |
1244 | int result = 1; /* return value if buffer overflows */ |
1245 | |
1246 | if (conn->sock == PGINVALID_SOCKET || |
1247 | conn->asyncStatus != PGASYNC_COPY_OUT) |
1248 | { |
1249 | *s = '\0'; |
1250 | return EOF; |
1251 | } |
1252 | |
1253 | /* |
1254 | * Since this is a purely synchronous routine, we don't bother to maintain |
1255 | * conn->inCursor; there is no need to back up. |
1256 | */ |
1257 | while (maxlen > 1) |
1258 | { |
1259 | if (conn->inStart < conn->inEnd) |
1260 | { |
1261 | char c = conn->inBuffer[conn->inStart++]; |
1262 | |
1263 | if (c == '\n') |
1264 | { |
1265 | result = 0; /* success exit */ |
1266 | break; |
1267 | } |
1268 | *s++ = c; |
1269 | maxlen--; |
1270 | } |
1271 | else |
1272 | { |
1273 | /* need to load more data */ |
1274 | if (pqWait(true, false, conn) || |
1275 | pqReadData(conn) < 0) |
1276 | { |
1277 | result = EOF; |
1278 | break; |
1279 | } |
1280 | } |
1281 | } |
1282 | *s = '\0'; |
1283 | |
1284 | return result; |
1285 | } |
1286 | |
1287 | /* |
1288 | * PQgetlineAsync - gets a COPY data row without blocking. |
1289 | * |
1290 | * See fe-exec.c for documentation. |
1291 | */ |
1292 | int |
1293 | pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize) |
1294 | { |
1295 | int avail; |
1296 | |
1297 | if (conn->asyncStatus != PGASYNC_COPY_OUT) |
1298 | return -1; /* we are not doing a copy... */ |
1299 | |
1300 | /* |
1301 | * Move data from libpq's buffer to the caller's. We want to accept data |
1302 | * only in units of whole lines, not partial lines. This ensures that we |
1303 | * can recognize the terminator line "\\.\n". (Otherwise, if it happened |
1304 | * to cross a packet/buffer boundary, we might hand the first one or two |
1305 | * characters off to the caller, which we shouldn't.) |
1306 | */ |
1307 | |
1308 | conn->inCursor = conn->inStart; |
1309 | |
1310 | avail = bufsize; |
1311 | while (avail > 0 && conn->inCursor < conn->inEnd) |
1312 | { |
1313 | char c = conn->inBuffer[conn->inCursor++]; |
1314 | |
1315 | *buffer++ = c; |
1316 | --avail; |
1317 | if (c == '\n') |
1318 | { |
1319 | /* Got a complete line; mark the data removed from libpq */ |
1320 | conn->inStart = conn->inCursor; |
1321 | /* Is it the endmarker line? */ |
1322 | if (bufsize - avail == 3 && buffer[-3] == '\\' && buffer[-2] == '.') |
1323 | return -1; |
1324 | /* No, return the data line to the caller */ |
1325 | return bufsize - avail; |
1326 | } |
1327 | } |
1328 | |
1329 | /* |
1330 | * We don't have a complete line. We'd prefer to leave it in libpq's |
1331 | * buffer until the rest arrives, but there is a special case: what if the |
1332 | * line is longer than the buffer the caller is offering us? In that case |
1333 | * we'd better hand over a partial line, else we'd get into an infinite |
1334 | * loop. Do this in a way that ensures we can't misrecognize a terminator |
1335 | * line later: leave last 3 characters in libpq buffer. |
1336 | */ |
1337 | if (avail == 0 && bufsize > 3) |
1338 | { |
1339 | conn->inStart = conn->inCursor - 3; |
1340 | return bufsize - 3; |
1341 | } |
1342 | return 0; |
1343 | } |
1344 | |
1345 | /* |
1346 | * PQendcopy |
1347 | * |
1348 | * See fe-exec.c for documentation. |
1349 | */ |
1350 | int |
1351 | pqEndcopy2(PGconn *conn) |
1352 | { |
1353 | PGresult *result; |
1354 | |
1355 | if (conn->asyncStatus != PGASYNC_COPY_IN && |
1356 | conn->asyncStatus != PGASYNC_COPY_OUT) |
1357 | { |
1358 | printfPQExpBuffer(&conn->errorMessage, |
1359 | libpq_gettext("no COPY in progress\n" )); |
1360 | return 1; |
1361 | } |
1362 | |
1363 | /* |
1364 | * make sure no data is waiting to be sent, abort if we are non-blocking |
1365 | * and the flush fails |
1366 | */ |
1367 | if (pqFlush(conn) && pqIsnonblocking(conn)) |
1368 | return 1; |
1369 | |
1370 | /* non blocking connections may have to abort at this point. */ |
1371 | if (pqIsnonblocking(conn) && PQisBusy(conn)) |
1372 | return 1; |
1373 | |
1374 | /* Return to active duty */ |
1375 | conn->asyncStatus = PGASYNC_BUSY; |
1376 | resetPQExpBuffer(&conn->errorMessage); |
1377 | |
1378 | /* Wait for the completion response */ |
1379 | result = PQgetResult(conn); |
1380 | |
1381 | /* Expecting a successful result */ |
1382 | if (result && result->resultStatus == PGRES_COMMAND_OK) |
1383 | { |
1384 | PQclear(result); |
1385 | return 0; |
1386 | } |
1387 | |
1388 | /* |
1389 | * Trouble. For backwards-compatibility reasons, we issue the error |
1390 | * message as if it were a notice (would be nice to get rid of this |
1391 | * silliness, but too many apps probably don't handle errors from |
1392 | * PQendcopy reasonably). Note that the app can still obtain the error |
1393 | * status from the PGconn object. |
1394 | */ |
1395 | if (conn->errorMessage.len > 0) |
1396 | { |
1397 | /* We have to strip the trailing newline ... pain in neck... */ |
1398 | char svLast = conn->errorMessage.data[conn->errorMessage.len - 1]; |
1399 | |
1400 | if (svLast == '\n') |
1401 | conn->errorMessage.data[conn->errorMessage.len - 1] = '\0'; |
1402 | pqInternalNotice(&conn->noticeHooks, "%s" , conn->errorMessage.data); |
1403 | conn->errorMessage.data[conn->errorMessage.len - 1] = svLast; |
1404 | } |
1405 | |
1406 | PQclear(result); |
1407 | |
1408 | /* |
1409 | * The worst case is that we've lost sync with the backend entirely due to |
1410 | * application screwup of the copy in/out protocol. To recover, reset the |
1411 | * connection (talk about using a sledgehammer...) |
1412 | */ |
1413 | pqInternalNotice(&conn->noticeHooks, |
1414 | "lost synchronization with server, resetting connection" ); |
1415 | |
1416 | /* |
1417 | * Users doing non-blocking connections need to handle the reset |
1418 | * themselves, they'll need to check the connection status if we return an |
1419 | * error. |
1420 | */ |
1421 | if (pqIsnonblocking(conn)) |
1422 | PQresetStart(conn); |
1423 | else |
1424 | PQreset(conn); |
1425 | |
1426 | return 1; |
1427 | } |
1428 | |
1429 | |
1430 | /* |
1431 | * PQfn - Send a function call to the POSTGRES backend. |
1432 | * |
1433 | * See fe-exec.c for documentation. |
1434 | */ |
1435 | PGresult * |
1436 | pqFunctionCall2(PGconn *conn, Oid fnid, |
1437 | int *result_buf, int *actual_result_len, |
1438 | int result_is_int, |
1439 | const PQArgBlock *args, int nargs) |
1440 | { |
1441 | bool needInput = false; |
1442 | ExecStatusType status = PGRES_FATAL_ERROR; |
1443 | char id; |
1444 | int i; |
1445 | |
1446 | /* PQfn already validated connection state */ |
1447 | |
1448 | if (pqPutMsgStart('F', false, conn) < 0 || /* function call msg */ |
1449 | pqPuts(" " , conn) < 0 || /* dummy string */ |
1450 | pqPutInt(fnid, 4, conn) != 0 || /* function id */ |
1451 | pqPutInt(nargs, 4, conn) != 0) /* # of args */ |
1452 | { |
1453 | /* error message should be set up already */ |
1454 | return NULL; |
1455 | } |
1456 | |
1457 | for (i = 0; i < nargs; ++i) |
1458 | { /* len.int4 + contents */ |
1459 | if (pqPutInt(args[i].len, 4, conn)) |
1460 | return NULL; |
1461 | |
1462 | if (args[i].isint) |
1463 | { |
1464 | if (pqPutInt(args[i].u.integer, 4, conn)) |
1465 | return NULL; |
1466 | } |
1467 | else |
1468 | { |
1469 | if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn)) |
1470 | return NULL; |
1471 | } |
1472 | } |
1473 | |
1474 | if (pqPutMsgEnd(conn) < 0 || |
1475 | pqFlush(conn)) |
1476 | return NULL; |
1477 | |
1478 | for (;;) |
1479 | { |
1480 | if (needInput) |
1481 | { |
1482 | /* Wait for some data to arrive (or for the channel to close) */ |
1483 | if (pqWait(true, false, conn) || |
1484 | pqReadData(conn) < 0) |
1485 | break; |
1486 | } |
1487 | |
1488 | /* |
1489 | * Scan the message. If we run out of data, loop around to try again. |
1490 | */ |
1491 | conn->inCursor = conn->inStart; |
1492 | needInput = true; |
1493 | |
1494 | if (pqGetc(&id, conn)) |
1495 | continue; |
1496 | |
1497 | /* |
1498 | * We should see V or E response to the command, but might get N |
1499 | * and/or A notices first. We also need to swallow the final Z before |
1500 | * returning. |
1501 | */ |
1502 | switch (id) |
1503 | { |
1504 | case 'V': /* function result */ |
1505 | if (pqGetc(&id, conn)) |
1506 | continue; |
1507 | if (id == 'G') |
1508 | { |
1509 | /* function returned nonempty value */ |
1510 | if (pqGetInt(actual_result_len, 4, conn)) |
1511 | continue; |
1512 | if (result_is_int) |
1513 | { |
1514 | if (pqGetInt(result_buf, 4, conn)) |
1515 | continue; |
1516 | } |
1517 | else |
1518 | { |
1519 | if (pqGetnchar((char *) result_buf, |
1520 | *actual_result_len, |
1521 | conn)) |
1522 | continue; |
1523 | } |
1524 | if (pqGetc(&id, conn)) /* get the last '0' */ |
1525 | continue; |
1526 | } |
1527 | if (id == '0') |
1528 | { |
1529 | /* correctly finished function result message */ |
1530 | status = PGRES_COMMAND_OK; |
1531 | } |
1532 | else |
1533 | { |
1534 | /* The backend violates the protocol. */ |
1535 | printfPQExpBuffer(&conn->errorMessage, |
1536 | libpq_gettext("protocol error: id=0x%x\n" ), |
1537 | id); |
1538 | pqSaveErrorResult(conn); |
1539 | conn->inStart = conn->inCursor; |
1540 | return pqPrepareAsyncResult(conn); |
1541 | } |
1542 | break; |
1543 | case 'E': /* error return */ |
1544 | if (pqGetErrorNotice2(conn, true)) |
1545 | continue; |
1546 | status = PGRES_FATAL_ERROR; |
1547 | break; |
1548 | case 'A': /* notify message */ |
1549 | /* handle notify and go back to processing return values */ |
1550 | if (getNotify(conn)) |
1551 | continue; |
1552 | break; |
1553 | case 'N': /* notice */ |
1554 | /* handle notice and go back to processing return values */ |
1555 | if (pqGetErrorNotice2(conn, false)) |
1556 | continue; |
1557 | break; |
1558 | case 'Z': /* backend is ready for new query */ |
1559 | /* consume the message and exit */ |
1560 | conn->inStart = conn->inCursor; |
1561 | /* if we saved a result object (probably an error), use it */ |
1562 | if (conn->result) |
1563 | return pqPrepareAsyncResult(conn); |
1564 | return PQmakeEmptyPGresult(conn, status); |
1565 | default: |
1566 | /* The backend violates the protocol. */ |
1567 | printfPQExpBuffer(&conn->errorMessage, |
1568 | libpq_gettext("protocol error: id=0x%x\n" ), |
1569 | id); |
1570 | pqSaveErrorResult(conn); |
1571 | conn->inStart = conn->inCursor; |
1572 | return pqPrepareAsyncResult(conn); |
1573 | } |
1574 | /* Completed this message, keep going */ |
1575 | conn->inStart = conn->inCursor; |
1576 | needInput = false; |
1577 | } |
1578 | |
1579 | /* |
1580 | * We fall out of the loop only upon failing to read data. |
1581 | * conn->errorMessage has been set by pqWait or pqReadData. We want to |
1582 | * append it to any already-received error message. |
1583 | */ |
1584 | pqSaveErrorResult(conn); |
1585 | return pqPrepareAsyncResult(conn); |
1586 | } |
1587 | |
1588 | |
1589 | /* |
1590 | * Construct startup packet |
1591 | * |
1592 | * Returns a malloc'd packet buffer, or NULL if out of memory |
1593 | */ |
1594 | char * |
1595 | pqBuildStartupPacket2(PGconn *conn, int *packetlen, |
1596 | const PQEnvironmentOption *options) |
1597 | { |
1598 | StartupPacket *startpacket; |
1599 | |
1600 | *packetlen = sizeof(StartupPacket); |
1601 | startpacket = (StartupPacket *) malloc(sizeof(StartupPacket)); |
1602 | if (!startpacket) |
1603 | return NULL; |
1604 | |
1605 | MemSet(startpacket, 0, sizeof(StartupPacket)); |
1606 | |
1607 | startpacket->protoVersion = pg_hton32(conn->pversion); |
1608 | |
1609 | /* strncpy is safe here: postmaster will handle full fields correctly */ |
1610 | strncpy(startpacket->user, conn->pguser, SM_USER); |
1611 | strncpy(startpacket->database, conn->dbName, SM_DATABASE); |
1612 | strncpy(startpacket->tty, conn->pgtty, SM_TTY); |
1613 | |
1614 | if (conn->pgoptions) |
1615 | strncpy(startpacket->options, conn->pgoptions, SM_OPTIONS); |
1616 | |
1617 | return (char *) startpacket; |
1618 | } |
1619 | |