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