1/*-------------------------------------------------------------------------
4 * functions that are specific to frontend/backend protocol version 3
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/interfaces/libpq/fe-protocol3.c
13 *-------------------------------------------------------------------------
33 * This macro lists the backend message types that could be "long" (more
34 * than a couple of kilobytes).
36 #define VALID_LONG_MESSAGE_TYPE(id) \
37 ((id) == PqMsg_CopyData || \
38 (id) == PqMsg_DataRow || \
39 (id) == PqMsg_ErrorResponse || \
40 (id) == PqMsg_FunctionCallResponse || \
41 (id) == PqMsg_NoticeResponse || \
42 (id) == PqMsg_NotificationResponse || \
43 (id) == PqMsg_RowDescription)
63 * parseInput: if appropriate, parse input data from backend
64 * until input is exhausted or a stopping state is reached.
65 * Note that this function will NOT attempt to read more data from the backend.
75 * Loop to parse successive complete messages available in the buffer.
80 * Try to read a message. First get the type code and length. Return
90 * Try to validate message type/length here. A length less than 4 is
91 * definitely broken. Large lengths should only be believed for a few
106 * Can't process if message body isn't all here yet.
110 if (avail < msgLength)
113 * Before returning, enlarge the input buffer if needed to hold
114 * the whole message. This is better than leaving it to
115 * pqReadData because we can avoid multiple cycles of realloc()
116 * when the message is large; also, we can implement a reasonable
117 * recovery strategy if we are unable to make the buffer big
124 * Abandon the connection. There's not much else we can
125 * safely do; we can't just ignore the message or we could
126 * miss important changes to the connection state.
127 * pqCheckInBufferSpace() already reported the error.
135 * NOTIFY and NOTICE messages can happen in any state; always process
138 * Most other messages should only be processed while in BUSY state.
139 * (In particular, in READY state we hold off further parsing until
140 * the application collects the current PGresult.)
142 * However, if the state is IDLE then we got trouble; we need to deal
143 * with the unexpected message somehow.
145 * ParameterStatus ('S') messages are a special case: in IDLE state we
146 * must process 'em (this case could happen if a new value was adopted
147 * from config file due to SIGHUP), but otherwise we hold off until
162 /* If not IDLE state, just wait ... */
167 * Unexpected message in IDLE state; need to recover somehow.
168 * ERROR messages are handled using the notice processor;
169 * ParameterStatus is handled normally; anything else is just
170 * dropped on the floor after displaying a suitable warning
171 * notice. (An ERROR is very possibly the backend telling us why
172 * it is about to close the connection, so we don't want to just
187 /* Any other case is unexpected and we summarily skip it */
189 "message type 0x%02x arrived from server while idle",
191 /* Discard the unexpected message */
198 * In BUSY state, we can process everything.
245 /* Advance the command queue and set us idle */
264 /* If we're doing PQprepare, we're done; else ignore */
282 /* Nothing to do for this message type */
285 /* If we're doing PQsendClose, we're done; else ignore */
309 * This is expected only during backend startup, but it's
310 * just as easy to handle it as part of the main loop.
311 * Save the data and continue processing.
322 * We've already choked for some reason. Just discard
323 * the data till we get to the end of the query.
331 /* First 'T' in a query sequence */
338 * A new 'T' message is treated as the start of
339 * another PGresult. (It is not clear that this is
340 * really possible with the current backend.) We stop
341 * parsing until the application accepts the current
351 * NoData indicates that we will not be seeing a
352 * RowDescription message because the statement or portal
353 * inquired about doesn't return rows.
355 * If we're doing a Describe, we have to pass something
356 * back to the client, so set up a COMMAND_OK result,
357 * instead of PGRES_TUPLES_OK. Otherwise we can just
358 * ignore this message.
385 /* Read another tuple of a normal query response */
394 * We've already choked for some reason. Just discard
395 * tuples till we get to the end of the query.
401 /* Set up to report error at end of query */
404 /* Discard the unexpected message */
428 * If we see Copy Data, just silently drop it. This would
429 * only occur if application exits COPY OUT mode too
437 * If we see Copy Done, just silently drop it. This is
438 * the normal case during PQendcopy. We will keep
439 * swallowing data, expecting to see command-complete for
445 /* build an error result holding the error message */
447 /* not sure if we will see more, so go to ready state */
449 /* Discard the unexpected message */
452 }
/* switch on protocol character */
454 /* Successfully consumed this message */
457 /* Normal case: parsing agrees with specified length */
462 /* The connection was abandoned and we already reported it */
467 /* Trouble --- report it */
469 /* build an error result holding the error message */
472 /* trust the specified message length as what to skip */
479 * handleFatalError: clean up after a nonrecoverable error
481 * This is for errors where we need to abandon the connection. The caller has
482 * already saved the error message in conn->errorMessage.
487 /* build an error result holding the error message */
490 /* flush input data since we're giving up on processing it */
496 * handleSyncLoss: clean up after loss of message-boundary sync
498 * There isn't really a lot we can do here except abandon the connection.
509 * parseInput subroutine to read a 'T' (row descriptions) message.
510 * We'll build a new PGresult structure (unless called for a Describe
511 * command for a prepared statement) containing the attribute data.
512 * Returns: 0 if processed message successfully, EOF to suspend parsing
513 * (the latter case is not actually used currently).
524 * When doing Describe for a prepared statement, there'll already be a
525 * PGresult created by getParamDescriptions, and we should fill data into
526 * that. Otherwise, create a new, empty PGresult.
541 errmsg = NULL;
/* means "out of memory", see below */
542 goto advance_and_error;
545 /* parseInput already read the 'T' label and message length. */
546 /* the next two bytes are the number of fields */
549 /* We should not run out of data here, so complain */
551 goto advance_and_error;
555 /* allocate space for the attribute descriptors */
562 errmsg = NULL;
/* means "out of memory", see below */
563 goto advance_and_error;
568 /* result->binary is true only if ALL columns are binary */
569 result->
binary = (nfields > 0) ? 1 : 0;
572 for (
i = 0;
i < nfields;
i++)
589 /* We should not run out of data here, so complain */
591 goto advance_and_error;
595 * Since pqGetInt treats 2-byte integers as unsigned, we need to
596 * coerce these results to signed form.
598 columnid = (int) ((
int16) columnid);
599 typlen = (int) ((
int16) typlen);
606 errmsg = NULL;
/* means "out of memory", see below */
607 goto advance_and_error;
624 * If we're doing a Describe, we're done, and ready to pass the result
625 * back to the client.
636 * We could perform additional setup for the new result set here, but for
637 * now there's nothing else to do.
640 /* And we're done. */
644 /* Discard unsaved result, if any */
649 * Replace partially constructed result with an error result. First
650 * discard the old result to try to win back some memory.
655 * If preceding code didn't provide an error message, assume "out of
656 * memory" was meant. The advantage of having this special case is that
657 * freeing the old result first greatly improves the odds that gettext()
658 * will succeed in providing a translation.
667 * Show the message as fully consumed, else pqParseInput3 will overwrite
668 * our error with a complaint about that.
673 * Return zero to allow input parsing to continue. Subsequent "D"
674 * messages will be ignored until we get to end of data, since an error
675 * result is already set up.
681 * parseInput subroutine to read a 't' (ParameterDescription) message.
682 * We'll build a new PGresult structure containing the parameter data.
683 * Returns: 0 if processed message successfully, EOF to suspend parsing
684 * (the latter case is not actually used currently).
690 const char *
errmsg = NULL;
/* means "out of memory", see below */
696 goto advance_and_error;
698 /* parseInput already read the 't' label and message length. */
699 /* the next two bytes are the number of parameters */
701 goto not_enough_data;
704 /* allocate space for the parameter descriptors */
710 goto advance_and_error;
714 /* get parameter info */
715 for (
i = 0;
i < nparams;
i++)
720 goto not_enough_data;
733 /* Discard unsaved result, if any */
738 * Replace partially constructed result with an error result. First
739 * discard the old result to try to win back some memory.
744 * If preceding code didn't provide an error message, assume "out of
745 * memory" was meant. The advantage of having this special case is that
746 * freeing the old result first greatly improves the odds that gettext()
747 * will succeed in providing a translation.
755 * Show the message as fully consumed, else pqParseInput3 will overwrite
756 * our error with a complaint about that.
761 * Return zero to allow input parsing to continue. Essentially, we've
762 * replaced the COMMAND_OK result with an error result, but since this
763 * doesn't affect the protocol state, it's fine.
769 * parseInput subroutine to read a 'D' (row data) message.
770 * We fill rowbuf with column pointers and then call the row processor.
771 * Returns: 0 if processed message successfully, EOF to suspend parsing
772 * (the latter case is not actually used currently).
781 int tupnfields;
/* # fields from tuple */
782 int vlen;
/* length of the current field value */
785 /* Get the field count and make sure it's what we expect */
788 /* We should not run out of data here, so complain */
790 goto advance_and_error;
793 if (tupnfields != nfields)
796 goto advance_and_error;
799 /* Resize row buffer if needed */
807 errmsg = NULL;
/* means "out of memory", see below */
808 goto advance_and_error;
814 /* Scan the fields */
815 for (
i = 0;
i < nfields;
i++)
817 /* get the value length */
820 /* We should not run out of data here, so complain */
822 goto advance_and_error;
824 rowbuf[
i].
len = vlen;
827 * rowbuf[i].value always points to the next address in the data
828 * buffer even if the value is NULL. This allows row processors to
829 * estimate data sizes more easily.
833 /* Skip over the data value */
838 /* We should not run out of data here, so complain */
840 goto advance_and_error;
845 /* Process the collected row */
848 return 0;
/* normal, successful exit */
850 /* pqRowProcessor failed, fall through to report it */
855 * Replace partially constructed result with an error result. First
856 * discard the old result to try to win back some memory.
861 * If preceding code didn't provide an error message, assume "out of
862 * memory" was meant. The advantage of having this special case is that
863 * freeing the old result first greatly improves the odds that gettext()
864 * will succeed in providing a translation.
873 * Show the message as fully consumed, else pqParseInput3 will overwrite
874 * our error with a complaint about that.
879 * Return zero to allow input parsing to continue. Subsequent "D"
880 * messages will be ignored until we get to end of data, since an error
881 * result is already set up.
888 * Attempt to read an Error or Notice response message.
889 * This is possible in several places, so we break it out as a subroutine.
891 * Entry: 'E' or 'N' message type and length have already been consumed.
892 * Exit: returns 0 if successfully consumed message.
893 * returns EOF if not enough data.
899 bool have_position =
false;
903 /* If in pipeline mode, set error indicator for it */
908 * If this is an error message, pre-emptively clear any incomplete query
909 * result we may have. We'd just throw it away below anyway, and
910 * releasing it before collecting the error might avoid out-of-memory.
916 * Since the fields might be pretty long, we create a temporary
917 * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
918 * for stuff that is expected to be short. We shouldn't use
919 * conn->errorMessage either, since this might be only a notice.
924 * Make a PGresult to hold the accumulated fields. We temporarily lie
925 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
926 * copy conn->errorMessage.
928 * NB: This allocation can fail, if you run out of memory. The rest of the
929 * function handles that gracefully, and we still try to set the error
930 * message as the connection's error message.
937 * Read the fields and save into res.
939 * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
940 * we saw a PG_DIAG_STATEMENT_POSITION field.
947 break;
/* terminator found */
955 have_position =
true;
959 * Save the active query text, if any, into res as well; but only if we
960 * might need it for an error cursor display, which is only true if there
961 * is a PG_DIAG_STATEMENT_POSITION field.
967 * Now build the "overall" error message for PQresultErrorMessage.
973 * Either save error as current async result, or just emit the notice.
985 /* Fall back to using the internal-error processing paths */
996 /* if we couldn't allocate the result set, just discard the NOTICE */
1000 * We can cheat a little here and not copy the message. But if we
1001 * were unlucky enough to run out of memory while filling workBuf,
1002 * insert "out of memory", as in pqSetResultError.
1024 * Construct an error message from the fields in the given PGresult,
1025 * appending it to the contents of "msg".
1032 const char *querytext = NULL;
1035 /* If we couldn't allocate a PGresult, just say "out of memory" */
1043 * If we don't have any broken-down fields, just return the base message.
1044 * This mainly applies if we're given a libpq-generated error result.
1055 /* Else build error message from relevant fields */
1063 * If we have a SQLSTATE, print that and nothing else. If not (which
1064 * shouldn't happen for server-generated errors, but might possibly
1065 * happen for libpq-generated ones), fall back to TERSE format, as
1066 * that seems better than printing nothing at all.
1091 /* emit position as a syntax cursor display */
1093 querypos = atoi(
val);
1097 /* emit position as text addition to primary message */
1098 /* translator: %s represents a digit string */
1111 /* emit position as a syntax cursor display */
1112 querypos = atoi(
val);
1116 /* emit position as text addition to primary message */
1117 /* translator: %s represents a digit string */
1126 if (querytext && querypos > 0)
1179 if (
val || valf || vall)
1184 if (valf && vall)
/* unlikely we'd have just one */
1193 * Add an error-location display to the error message under construction.
1195 * The cursor location is measured in logical characters; the query string
1196 * is presumed to be in the specified encoding.
1201#define DISPLAY_SIZE 60 /* screen width limit, in screen cols */
1202#define MIN_RIGHT_CUT 10 /* try to keep this far away from EOL */
1219 /* Convert loc from 1-based to 0-based; no-op if out of range */
1224 /* Need a writable copy of the query */
1225 wquery = strdup(query);
1227 return;
/* fail silently if out of memory */
1230 * Each character might occupy multiple physical bytes in the string, and
1231 * in some Far Eastern character sets it might take more than one screen
1232 * column as well. We compute the starting byte offset and starting
1233 * screen column of each logical character, and store these in qidx[] and
1234 * scridx[] respectively.
1237 /* we need a safe allocation size... */
1238 slen = strlen(wquery) + 1;
1240 qidx = (
int *)
malloc(slen *
sizeof(
int));
1246 scridx = (
int *)
malloc(slen *
sizeof(
int));
1254 /* We can optimize a bit if it's a single-byte encoding */
1258 * Within the scanning loop, cno is the current character's logical
1259 * number, qoffset is its offset in wquery, and scroffset is its starting
1260 * logical screen column (all indexed from 0). "loc" is the logical
1261 * character number of the error location. We scan to determine loc_line
1262 * (the 1-based line number containing loc) and ibeg/iend (first character
1263 * number and last+1 character number of the line containing loc). Note
1264 * that qidx[] and scridx[] are filled only as far as iend.
1270 iend = -1;
/* -1 means not set yet */
1272 for (cno = 0; wquery[qoffset] !=
'0円'; cno++)
1274 char ch = wquery[qoffset];
1276 qidx[cno] = qoffset;
1277 scridx[cno] = scroffset;
1280 * Replace tabs with spaces in the writable copy. (Later we might
1281 * want to think about coping with their variable screen width, but
1285 wquery[qoffset] =
' ';
1288 * If end-of-line, count lines and mark positions. Each \r or \n
1289 * counts as a line except when \r \n appear together.
1291 else if (ch ==
'\r' || ch ==
'\n')
1297 wquery[qidx[cno - 1]] !=
'\r')
1299 /* extract beginning = last line start before loc. */
1304 /* set extract end. */
1306 /* done scanning. */
1317 /* treat any non-tab control chars as width 1 */
1325 /* We assume wide chars only exist in multibyte encodings */
1330 /* Fix up if we didn't find an end-of-line after loc */
1333 iend = cno;
/* query length in chars, +1 */
1334 qidx[iend] = qoffset;
1335 scridx[iend] = scroffset;
1338 /* Print only if loc is within computed query length */
1341 /* If the line extracted is too long, we truncate it. */
1347 * We first truncate right if it is enough. This code might be
1348 * off a space or so on enforcing MIN_RIGHT_CUT if there's a wide
1349 * character right there, but that should be okay.
1359 /* Truncate right if not too close to loc. */
1366 /* Truncate left if still too long. */
1375 /* truncate working copy at desired endpoint */
1376 wquery[qidx[iend]] =
'0円';
1378 /* Begin building the finished message. */
1385 * While we have the prefix in the msg buffer, compute its screen
1398 /* Finish up the LINE message line. */
1404 /* Now emit the cursor marker line. */
1405 scroffset += scridx[loc] - scridx[ibeg];
1406 for (
i = 0;
i < scroffset;
i++)
1420 * Attempt to read a NegotiateProtocolVersion message. Sets conn->pversion
1421 * to the version that's negotiated by the server.
1423 * Entry: 'v' message type and length have already been consumed.
1424 * Exit: returns 0 if successfully consumed message.
1425 * returns 1 on failure. The error message is filled in.
1439 /* Check the protocol version */
1442 libpq_append_conn_error(
conn,
"received invalid protocol negotiation message: server requested downgrade to a higher-numbered version");
1448 libpq_append_conn_error(
conn,
"received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version");
1452 /* 3.1 never existed, we went straight from 3.0 to 3.2 */
1455 libpq_append_conn_error(
conn,
"received invalid protocol negotiation message: server requested downgrade to non-existent 3.1 protocol version");
1461 libpq_append_conn_error(
conn,
"received invalid protocol negotiation message: server reported negative number of unsupported parameters");
1471 if (their_version < conn->min_pversion)
1476 "min_protocol_version",
1483 /* the version is acceptable */
1487 * We don't currently request any protocol extensions, so we don't expect
1488 * the server to reply with any either.
1490 for (
int i = 0;
i < num;
i++)
1517 * Attempt to read a ParameterStatus message.
1518 * This is possible in several places, so we break it out as a subroutine.
1520 * Entry: 'S' message type and length have already been consumed.
1521 * Exit: returns 0 if successfully consumed message.
1522 * returns EOF if not enough data.
1529 /* Get the parameter name */
1532 /* Get the parameter value (could be large) */
1550 * parseInput subroutine to read a BackendKeyData message.
1551 * Entry: 'v' message type and length have already been consumed.
1552 * Exit: returns 0 if successfully consumed message.
1553 * returns EOF if not enough data.
1574 libpq_append_conn_error(
conn,
"received invalid BackendKeyData message: cancel key with length %d not allowed in protocol version 3.0 (must be 4 bytes)", cancel_key_len);
1579 if (cancel_key_len < 4)
1581 libpq_append_conn_error(
conn,
"received invalid BackendKeyData message: cancel key with length %d is too short (minimum 4 bytes)", cancel_key_len);
1586 if (cancel_key_len > 256)
1588 libpq_append_conn_error(
conn,
"received invalid BackendKeyData message: cancel key with length %d is too long (maximum 256 bytes)", cancel_key_len);
1612 * Attempt to read a Notify response message.
1613 * This is possible in several places, so we break it out as a subroutine.
1615 * Entry: 'A' message type and length have already been consumed.
1616 * Exit: returns 0 if successfully consumed Notify message.
1617 * returns EOF if not enough data.
1632 /* must save name while getting extra string */
1637 * Notify messages can arrive at any state, so we cannot associate the
1638 * error with any particular query. There's no way to return back an
1639 * "async error", so the best we can do is drop the connection. That
1640 * seems better than silently ignoring the notification.
1653 * Store the strings right after the PGnotify structure so it can all be
1654 * freed at once. We don't use NAMEDATALEN because we don't want to tie
1655 * this interface to a specific server name length.
1657 nmlen = strlen(svname);
1669 strcpy(newNotify->
relname, svname);
1672 newNotify->
be_pid = be_pid;
1673 newNotify->
next = NULL;
1685 * getCopyStart - process CopyInResponse, CopyOutResponse or
1686 * CopyBothResponse message
1688 * parseInput already read the message type and length.
1704 /* the next two bytes are the number of fields */
1709 /* allocate space for the attribute descriptors */
1719 for (
i = 0;
i < nfields;
i++)
1727 * Since pqGetInt treats 2-byte integers as unsigned, we need to
1728 * coerce these results to signed form.
1744 * getReadyForQuery - process ReadyForQuery message
1753 switch (xact_status)
1773 * getCopyDataMessage - fetch next CopyData message, process async messages
1775 * Returns length word of CopyData message (> 0), or 0 if no complete
1776 * message available, -1 if end of copy, -2 if error.
1788 * Do we have the next input message? To make life simpler for async
1789 * callers, we keep returning 0 until the next message is fully
1790 * available, even if it is not Copy Data.
1803 if (avail < msgLength - 4)
1806 * Before returning, enlarge the input buffer if needed to hold
1807 * the whole message. See notes in parseInput.
1813 * Abandon the connection. There's not much else we can
1814 * safely do; we can't just ignore the message or we could
1815 * miss important changes to the connection state.
1816 * pqCheckInBufferSpace() already reported the error.
1825 * If it's a legitimate async message type, process it. (NOTIFY
1826 * messages are not currently possible here, but we handle them for
1827 * completeness.) Otherwise, if it's anything except Copy Data,
1828 * report end-of-copy.
1849 * If this is a CopyDone message, exit COPY_OUT mode and let
1850 * caller read status with PQgetResult(). If we're in
1851 * COPY_BOTH mode, return to COPY_IN mode.
1858 default:
/* treat as end of copy */
1861 * Any other message terminates either COPY_IN or COPY_BOTH
1868 /* Drop the processed message and loop around for another */
1874 * PQgetCopyData - read a row of data from the backend during COPY OUT
1877 * If successful, sets *buffer to point to a malloc'd row of data, and
1878 * returns row length (always > 0) as result.
1879 * Returns 0 if no row available yet (only possible if async is true),
1880 * -1 if end of copy (consult PQgetResult), or -2 if error (consult
1891 * Collect the next input message. To make life simpler for async
1892 * callers, we keep returning 0 until the next message is fully
1893 * available, even if it is not Copy Data.
1897 return msgLength;
/* end-of-copy or error */
1900 /* Don't block if async read requested */
1903 /* Need to load more data */
1911 * Drop zero-length messages (shouldn't happen anyway). Otherwise
1912 * pass the data back to the caller.
1917 *buffer = (
char *)
malloc(msgLength + 1);
1918 if (*buffer == NULL)
1924 (*buffer)[msgLength] =
'0円';
/* Add terminating null */
1926 /* Mark message consumed */
1932 /* Empty, so drop it and loop around for another */
1938 * PQgetline - gets a newline-terminated string from the backend.
1940 * See fe-exec.c for documentation.
1959 /* need to load more data */
1970 /* End of copy detected; gin up old-style terminator */
1975 /* Add null terminator, and strip trailing \n if present */
1976 if (s[status - 1] ==
'\n')
1978 s[status - 1] =
'0円';
1989 * PQgetlineAsync - gets a COPY data row without blocking.
1991 * See fe-exec.c for documentation.
2001 return -1;
/* we are not doing a copy... */
2004 * Recognize the next input message. To make life simpler for async
2005 * callers, we keep returning 0 until the next message is fully available
2006 * even if it is not Copy Data. This should keep PQendcopy from blocking.
2007 * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
2011 return -1;
/* end-of-copy or error */
2013 return 0;
/* no data yet */
2016 * Move data from libpq's buffer to the caller's. In the case where a
2017 * prior call found the caller's buffer too small, we use
2018 * conn->copy_already_done to remember how much of the row was already
2019 * returned to the caller.
2025 /* Able to consume the whole message */
2027 /* Mark message consumed */
2029 /* Reset state for next time */
2035 /* We must return a partial message */
2037 /* The message is NOT consumed from libpq's buffer */
2046 * See fe-exec.c for documentation.
2061 /* Send the CopyDone message if needed */
2070 * If we sent the COPY command in extended-query mode, we must issue a
2083 * make sure no data is waiting to be sent, abort if we are non-blocking
2084 * and the flush fails
2089 /* Return to active duty */
2093 * Non blocking connections may have to abort at this point. If everyone
2094 * played the game there should be no problem, but in error scenarios the
2095 * expected messages may not have arrived yet. (We are assuming that the
2096 * backend's packetizing will ensure that CommandComplete arrives along
2097 * with the CopyDone; are there corner cases where that doesn't happen?)
2102 /* Wait for the completion response */
2105 /* Expecting a successful result */
2113 * Trouble. For backwards-compatibility reasons, we issue the error
2114 * message as if it were a notice (would be nice to get rid of this
2115 * silliness, but too many apps probably don't handle errors from
2116 * PQendcopy reasonably). Note that the app can still obtain the error
2117 * status from the PGconn object.
2121 /* We have to strip the trailing newline ... pain in neck... */
2137 * PQfn - Send a function call to the POSTGRES backend.
2139 * See fe-exec.c for documentation.
2143 int *result_buf,
int *actual_result_len,
2147 bool needInput =
false;
2154 /* already validated by PQfn */
2157 /* PQfn already validated connection state */
2165 /* error message should be set up already */
2169 for (
i = 0;
i < nargs; ++
i)
2170 {
/* len.int4 + contents */
2174 continue;
/* it's NULL */
2188 if (
pqPutInt(1, 2,
conn) < 0)
/* result format code: BINARY */
2199 /* Wait for some data to arrive (or for the channel to close) */
2206 * Scan the message. If we run out of data, loop around to try again.
2217 * Try to validate message type/length here. A length less than 4 is
2218 * definitely broken. Large lengths should only be believed for a few
2233 * Can't process if message body isn't all here yet.
2237 if (avail < msgLength)
2240 * Before looping, enlarge the input buffer if needed to hold the
2241 * whole message. See notes in parseInput.
2247 * Abandon the connection. There's not much else we can
2248 * safely do; we can't just ignore the message or we could
2249 * miss important changes to the connection state.
2250 * pqCheckInBufferSpace() already reported the error.
2259 * We should see V or E response to the command, but might get N
2260 * and/or A notices first. We also need to swallow the final Z before
2268 if (*actual_result_len != -1)
2283 /* correctly finished function result message */
2292 /* handle notify and go back to processing return values */
2297 /* handle notice and go back to processing return values */
2305 /* consume the message */
2309 * If we already have a result object (probably an error), use
2310 * that. Otherwise, if we saw a function result message,
2311 * report COMMAND_OK. Otherwise, the backend violated the
2312 * protocol, so complain.
2338 /* The backend violates the protocol. */
2343 * We can't call parsing done due to the protocol violation
2344 * (so message tracing wouldn't work), but trust the specified
2345 * message length as what to skip.
2351 /* Completed parsing this message, keep going */
2357 * We fall out of the loop only upon failing to read data.
2358 * conn->errorMessage has been set by pqWait or pqReadData. We want to
2359 * append it to any already-received error message.
2367 * Construct startup packet
2369 * Returns a malloc'd packet buffer, or NULL if out of memory
2378 startpacket = (
char *)
malloc(*packetlen);
2386 * Build a startup packet given a filled-in PGconn structure.
2388 * We need to figure out how much space is needed, then fill it in.
2389 * To avoid duplicate logic, this routine is called twice: the first time
2390 * (with packet == NULL) just counts the space needed, the second time
2391 * (with packet == allocated space) fills it in. Return value is the number
2402 /* Protocol version comes first. */
2411 /* Add user name, database name, options */
2413#define ADD_STARTUP_OPTION(optname, optval) \
2416 strcpy(packet + packet_len, optname); \
2417 packet_len += strlen(optname) + 1; \
2419 strcpy(packet + packet_len, optval); \
2420 packet_len += strlen(optval) + 1; \
2433 /* Use appname if present, otherwise use fallback */
2442 /* Add any environment-driven GUC settings needed */
2445 if ((
val = getenv(next_eo->
envName)) != NULL)
2452 /* Add trailing terminator */
2454 packet[packet_len] =
'0円';
#define MemSet(start, val, len)
int errmsg(const char *fmt,...)
void pqDropConnection(PGconn *conn, bool flushInput)
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
void pqSaveMessageField(PGresult *res, char code, const char *value)
PGresult * pqPrepareAsyncResult(PGconn *conn)
void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
void pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset)
void pqSaveErrorResult(PGconn *conn)
int pqRowProcessor(PGconn *conn, const char **errmsgp)
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
void pqClearAsyncResult(PGconn *conn)
int PQisBusy(PGconn *conn)
int pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
char * pqResultStrdup(PGresult *res, const char *str)
int pqReadData(PGconn *conn)
int pqPutInt(int value, size_t bytes, PGconn *conn)
int pqFlush(PGconn *conn)
void pqParseDone(PGconn *conn, int newInStart)
int pqPutMsgStart(char msg_type, PGconn *conn)
int pqSkipnchar(size_t len, PGconn *conn)
int pqGetc(char *result, PGconn *conn)
int pqGetInt(int *result, size_t bytes, PGconn *conn)
int pqWait(int forRead, int forWrite, PGconn *conn)
int pqGets(PQExpBuffer buf, PGconn *conn)
int pqPutnchar(const void *s, size_t len, PGconn *conn)
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
int pqGetnchar(void *s, size_t len, PGconn *conn)
int PQmblenBounded(const char *s, int encoding)
int pqPutMsgEnd(PGconn *conn)
void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
void pqParseInput3(PGconn *conn)
char * pqBuildStartupPacket3(PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
static int build_startup_packet(const PGconn *conn, char *packet, const PQEnvironmentOption *options)
int pqEndcopy3(PGconn *conn)
static int getNotify(PGconn *conn)
static int getAnotherTuple(PGconn *conn, int msgLength)
static int getRowDescriptions(PGconn *conn, int msgLength)
static void reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
PGresult * pqFunctionCall3(PGconn *conn, Oid fnid, int *result_buf, int *actual_result_len, int result_is_int, const PQArgBlock *args, int nargs)
int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize)
int pqGetCopyData3(PGconn *conn, char **buffer, int async)
int pqGetNegotiateProtocolVersion3(PGconn *conn)
static int getParameterStatus(PGconn *conn)
static void handleFatalError(PGconn *conn)
#define VALID_LONG_MESSAGE_TYPE(id)
static int getCopyStart(PGconn *conn, ExecStatusType copytype)
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
static int getReadyForQuery(PGconn *conn)
#define ADD_STARTUP_OPTION(optname, optval)
static int getBackendKeyData(PGconn *conn, int msgLength)
static int getCopyDataMessage(PGconn *conn)
static int getParamDescriptions(PGconn *conn, int msgLength)
int pqGetline3(PGconn *conn, char *s, int maxlen)
int pqGetErrorNotice3(PGconn *conn, bool isError)
Assert(PointerIsAligned(start, uint64))
#define PQresultErrorField
#define pqIsnonblocking(conn)
#define pgHavePendingResult(conn)
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
int pg_strcasecmp(const char *s1, const char *s2)
size_t strlcpy(char *dst, const char *src, size_t siz)
#define PG_DIAG_INTERNAL_QUERY
#define PG_DIAG_SCHEMA_NAME
#define PG_DIAG_CONSTRAINT_NAME
#define PG_DIAG_DATATYPE_NAME
#define PG_DIAG_SOURCE_LINE
#define PG_DIAG_STATEMENT_POSITION
#define PG_DIAG_SOURCE_FILE
#define PG_DIAG_MESSAGE_HINT
#define PG_DIAG_TABLE_NAME
#define PG_DIAG_MESSAGE_PRIMARY
#define PG_DIAG_COLUMN_NAME
#define PG_DIAG_MESSAGE_DETAIL
#define PG_DIAG_SOURCE_FUNCTION
#define PG_DIAG_INTERNAL_POSITION
#define PG_PROTOCOL_MAJOR(v)
#define PG_PROTOCOL(m, n)
#define PG_PROTOCOL_MINOR(v)
void initPQExpBuffer(PQExpBuffer str)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
#define PQExpBufferDataBroken(buf)
#define PqMsg_CloseComplete
#define PqMsg_NotificationResponse
#define PqMsg_BindComplete
#define PqMsg_ParameterDescription
#define PqMsg_FunctionCall
#define PqMsg_FunctionCallResponse
#define PqMsg_ReadyForQuery
#define PqMsg_CopyInResponse
#define PqMsg_EmptyQueryResponse
#define PqMsg_RowDescription
#define PqMsg_CopyBothResponse
#define PqMsg_ParameterStatus
#define PqMsg_BackendKeyData
#define PqMsg_CommandComplete
#define PqMsg_ErrorResponse
#define PqMsg_NoticeResponse
#define PqMsg_CopyOutResponse
#define PqMsg_ParseComplete
PQnoticeReceiver noticeRec
PGTransactionStatusType xactStatus
ProtocolVersion min_pversion
PQExpBufferData workBuffer
char * client_encoding_initial
PQExpBufferData errorMessage
PGAsyncStatusType asyncStatus
PGpipelineStatus pipelineStatus
PGNoticeHooks noticeHooks
PGcmdQueueEntry * cmd_queue_head
PGContextVisibility show_context
PGNoticeHooks noticeHooks
char cmdStatus[CMDSTATUS_LEN]
PGMessageField * errFields
PGresParamDesc * paramDescs
ExecStatusType resultStatus
int pg_encoding_dsplen(int encoding, const char *mbstr)
int pg_encoding_max_length(int encoding)