original) (raw)
PostgreSQL Source Code: src/interfaces/libpq/fe-protocol3.c File Reference (#include "[postgres_fe.h](postgres%5F%5Ffe%5F8h%5Fsource.html)"
#include <ctype.h>
#include <fcntl.h>
#include <[unistd.h](unistd%5F8h%5Fsource.html)>
#include <[netinet/tcp.h](tcp%5F8h%5Fsource.html)>
#include "[libpq-fe.h](libpq-fe%5F8h%5Fsource.html)"
#include "[libpq-int.h](libpq-int%5F8h%5Fsource.html)"
#include "[mb/pg_wchar.h](pg%5F%5Fwchar%5F8h%5Fsource.html)"
#include "[port/pg_bswap.h](pg%5F%5Fbswap%5F8h%5Fsource.html)"
Go to the source code of this file.
Macros | |
---|---|
#define | VALID_LONG_MESSAGE_TYPE(id) |
#define | DISPLAY_SIZE 60 /* screen width limit, in screen cols */ |
#define | MIN_RIGHT_CUT 10 /* try to keep this far away from EOL */ |
#define | ADD_STARTUP_OPTION(optname, optval) |
◆ ADD_STARTUP_OPTION
| #define ADD_STARTUP_OPTION | ( | | optname, | | ---------------------------- | - | | -------- | | | optval | | | | | ) | | | |
Value:
do { \
if (packet) \
strcpy(packet + packet_len, optname); \
packet_len += strlen(optname) + 1; \
if (packet) \
strcpy(packet + packet_len, optval); \
packet_len += strlen(optval) + 1; \
} while(0)
◆ DISPLAY_SIZE
#define DISPLAY_SIZE 60 /* screen width limit, in screen cols */
◆ MIN_RIGHT_CUT
#define MIN_RIGHT_CUT 10 /* try to keep this far away from EOL */
◆ VALID_LONG_MESSAGE_TYPE
| #define VALID_LONG_MESSAGE_TYPE | ( | | id | ) | | ---------------------------------- | - | | -- | - |
Value:
#define PqMsg_NotificationResponse
#define PqMsg_FunctionCallResponse
#define PqMsg_RowDescription
#define PqMsg_ErrorResponse
#define PqMsg_NoticeResponse
Definition at line 36 of file fe-protocol3.c.
◆ build_startup_packet()
Definition at line 2336 of file fe-protocol3.c.
2338{
2339 int packet_len = 0;
2341 const char *val;
2342
2343
2344 if (packet)
2345 {
2347
2348 memcpy(packet + packet_len, &pv, sizeof(ProtocolVersion));
2349 }
2351
2352
2353
2354#define ADD_STARTUP_OPTION(optname, optval) \
2355 do { \
2356 if (packet) \
2357 strcpy(packet + packet_len, optname); \
2358 packet_len += strlen(optname) + 1; \
2359 if (packet) \
2360 strcpy(packet + packet_len, optval); \
2361 packet_len += strlen(optval) + 1; \
2362 } while(0)
2363
2373 {
2374
2378 }
2379
2382
2383
2384 for (next_eo = options; next_eo->envName; next_eo++)
2385 {
2386 if ((val = getenv(next_eo->envName)) != NULL)
2387 {
2390 }
2391 }
2392
2393
2394 if (packet)
2395 packet[packet_len] = '\0';
2396 packet_len++;
2397
2398 return packet_len;
2399}
#define ADD_STARTUP_OPTION(optname, optval)
int pg_strcasecmp(const char *s1, const char *s2)
char * client_encoding_initial
References ADD_STARTUP_OPTION, pg_conn::appname, pg_conn::client_encoding_initial, conn, pg_conn::dbName, PQEnvironmentOption::envName, pg_conn::fbappname, pg_hton32, pg_strcasecmp(), PQEnvironmentOption::pgName, pg_conn::pgoptions, pg_conn::pguser, pg_conn::pversion, pg_conn::replication, pg_conn::send_appname, and val.
Referenced by pqBuildStartupPacket3().
◆ getAnotherTuple()
static int getAnotherTuple ( PGconn * conn, int msgLength ) | static |
---|
Definition at line 757 of file fe-protocol3.c.
758{
763 int tupnfields;
764 int vlen;
765 int i;
766
767
769 {
770
772 goto advance_and_error;
773 }
774
775 if (tupnfields != nfields)
776 {
778 goto advance_and_error;
779 }
780
781
784 {
787 if (!rowbuf)
788 {
789 errmsg = NULL;
790 goto advance_and_error;
791 }
794 }
795
796
797 for (i = 0; i < nfields; i++)
798 {
799
801 {
802
804 goto advance_and_error;
805 }
807
808
809
810
811
812
814
815
816 if (vlen > 0)
817 {
819 {
820
822 goto advance_and_error;
823 }
824 }
825 }
826
827
830 return 0;
831
832
833
834advance_and_error:
835
836
837
838
839
841
842
843
844
845
846
847
850
853
854
855
856
857
859
860
861
862
863
864
865 return 0;
866}
int errmsg(const char *fmt,...)
void pqSaveErrorResult(PGconn *conn)
int pqRowProcessor(PGconn *conn, const char **errmsgp)
void pqClearAsyncResult(PGconn *conn)
int pqSkipnchar(size_t len, PGconn *conn)
int pqGetInt(int *result, size_t bytes, PGconn *conn)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
PQExpBufferData errorMessage
References appendPQExpBuffer(), conn, errmsg(), pg_conn::errorMessage, i, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inStart, pgDataValue::len, libpq_gettext, pg_result::numAttributes, pqClearAsyncResult(), pqGetInt(), pqRowProcessor(), pqSaveErrorResult(), pqSkipnchar(), realloc, pg_conn::result, pg_conn::rowBuf, pg_conn::rowBufLen, and pgDataValue::value.
Referenced by pqParseInput3().
◆ getBackendKeyData()
static int getBackendKeyData ( PGconn * conn, int msgLength ) | static |
---|
Definition at line 1533 of file fe-protocol3.c.
1534{
1535 int cancel_key_len;
1536
1538 {
1542 }
1543
1545 return EOF;
1546
1548
1551 {
1553
1554 return EOF;
1555 }
1557 {
1560 return EOF;
1561 }
1563 return 0;
1564}
int pqGetnchar(void *s, size_t len, PGconn *conn)
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
References pg_conn::be_cancel_key, pg_conn::be_cancel_key_len, pg_conn::be_pid, conn, free, pg_conn::inCursor, pg_conn::inStart, libpq_append_conn_error(), malloc, pqGetInt(), and pqGetnchar().
Referenced by pqParseInput3().
◆ getCopyDataMessage()
static int getCopyDataMessage ( PGconn * conn) | static |
---|
Definition at line 1720 of file fe-protocol3.c.
1721{
1722 char id;
1723 int msgLength;
1724 int avail;
1725
1726 for (;;)
1727 {
1728
1729
1730
1731
1732
1735 return 0;
1737 return 0;
1738 if (msgLength < 4)
1739 {
1741 return -2;
1742 }
1744 if (avail < msgLength - 4)
1745 {
1746
1747
1748
1749
1752 {
1753
1754
1755
1756
1757
1758
1760 return -2;
1761 }
1762 return 0;
1763 }
1764
1765
1766
1767
1768
1769
1770
1771 switch (id)
1772 {
1775 return 0;
1776 break;
1779 return 0;
1780 break;
1783 return 0;
1784 break;
1786 return msgLength;
1788
1789
1790
1791
1792
1793
1796 else
1798 return -1;
1799 default:
1800
1801
1802
1803
1804
1806 return -1;
1807 }
1808
1809
1811 }
1812}
void pqParseDone(PGconn *conn, int newInStart)
int pqGetc(char *result, PGconn *conn)
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
static int getNotify(PGconn *conn)
static int getParameterStatus(PGconn *conn)
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
int pqGetErrorNotice3(PGconn *conn, bool isError)
#define PqMsg_ParameterStatus
PGAsyncStatusType asyncStatus
References pg_conn::asyncStatus, conn, getNotify(), getParameterStatus(), handleSyncLoss(), pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, pqCheckInBufferSpace(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), PqMsg_CopyData, PqMsg_CopyDone, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterStatus, and pqParseDone().
Referenced by pqGetCopyData3(), and pqGetlineAsync3().
◆ getCopyStart()
Definition at line 1632 of file fe-protocol3.c.
1633{
1635 int nfields;
1636 int i;
1637
1639 if (!result)
1640 goto failure;
1641
1643 goto failure;
1645
1647 goto failure;
1649
1650
1651 if (nfields > 0)
1652 {
1656 goto failure;
1658 }
1659
1660 for (i = 0; i < nfields; i++)
1661 {
1663
1665 goto failure;
1666
1667
1668
1669
1670
1673 }
1674
1675
1677 return 0;
1678
1679failure:
1681 return EOF;
1682}
#define MemSet(start, val, len)
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
void PQclear(PGresult *res)
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
References pg_result::attDescs, pg_result::binary, conn, pg_conn::copy_is_binary, format, pgresAttDesc::format, i, MemSet, pg_result::numAttributes, PQclear(), pqGetc(), pqGetInt(), PQmakeEmptyPGresult(), pqResultAlloc(), and pg_conn::result.
Referenced by pqParseInput3().
◆ getNotify()
static int getNotify ( PGconn * conn) | static |
---|
Definition at line 1576 of file fe-protocol3.c.
1577{
1578 int be_pid;
1579 char *svname;
1580 int nmlen;
1581 int extralen;
1583
1585 return EOF;
1587 return EOF;
1588
1590 if (!svname)
1591 return EOF;
1593 {
1594 free(svname);
1595 return EOF;
1596 }
1597
1598
1599
1600
1601
1602
1603 nmlen = strlen(svname);
1606 if (newNotify)
1607 {
1608 newNotify->relname = (char *) newNotify + sizeof(PGnotify);
1609 strcpy(newNotify->relname, svname);
1610 newNotify->extra = newNotify->relname + nmlen + 1;
1612 newNotify->be_pid = be_pid;
1613 newNotify->next = NULL;
1616 else
1619 }
1620
1621 free(svname);
1622 return 0;
1623}
int pqGets(PQExpBuffer buf, PGconn *conn)
PQExpBufferData workBuffer
References pgNotify::be_pid, conn, PQExpBufferData::data, pgNotify::extra, free, malloc, pgNotify::next, pg_conn::notifyHead, pg_conn::notifyTail, pqGetInt(), pqGets(), pgNotify::relname, and pg_conn::workBuffer.
Referenced by getCopyDataMessage(), pqFunctionCall3(), and pqParseInput3().
◆ getParamDescriptions()
static int getParamDescriptions ( PGconn * conn, int msgLength ) | static |
---|
Definition at line 669 of file fe-protocol3.c.
670{
672 const char *errmsg = NULL;
673 int nparams;
674 int i;
675
677 if (!result)
678 goto advance_and_error;
679
680
681
683 goto not_enough_data;
685
686
687 if (nparams > 0)
688 {
692 goto advance_and_error;
694 }
695
696
697 for (i = 0; i < nparams; i++)
698 {
699 int typid;
700
702 goto not_enough_data;
704 }
705
706
708
709 return 0;
710
711not_enough_data:
713
714advance_and_error:
715
716 if (result && result != conn->result)
718
719
720
721
722
724
725
726
727
728
729
730
735
736
737
738
739
741
742
743
744
745
746
747 return 0;
748}
PGresParamDesc * paramDescs
References appendPQExpBuffer(), conn, errmsg(), pg_conn::errorMessage, i, pg_conn::inCursor, pg_conn::inStart, libpq_gettext, MemSet, pg_result::numParameters, pg_result::paramDescs, PGRES_COMMAND_OK, PQclear(), pqClearAsyncResult(), pqGetInt(), PQmakeEmptyPGresult(), pqResultAlloc(), pqSaveErrorResult(), pg_conn::result, and pgresParamDesc::typid.
Referenced by pqParseInput3().
◆ getParameterStatus()
static int getParameterStatus ( PGconn * conn) | static |
---|
Definition at line 1506 of file fe-protocol3.c.
1507{
1509
1510
1512 return EOF;
1513
1516 {
1518 return EOF;
1519 }
1520
1523 return 0;
1524}
void pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
void initPQExpBuffer(PQExpBuffer str)
void termPQExpBuffer(PQExpBuffer str)
References conn, PQExpBufferData::data, initPQExpBuffer(), pqGets(), pqSaveParameterStatus(), termPQExpBuffer(), and pg_conn::workBuffer.
Referenced by getCopyDataMessage(), pqFunctionCall3(), and pqParseInput3().
◆ getReadyForQuery()
static int getReadyForQuery ( PGconn * conn) | static |
---|
◆ getRowDescriptions()
static int getRowDescriptions ( PGconn * conn, int msgLength ) | static |
---|
Definition at line 498 of file fe-protocol3.c.
499{
501 int nfields;
503 int i;
504
505
506
507
508
509
513 {
516 else
518 }
519 else
521 if (!result)
522 {
523 errmsg = NULL;
524 goto advance_and_error;
525 }
526
527
528
530 {
531
533 goto advance_and_error;
534 }
536
537
538 if (nfields > 0)
539 {
543 {
544 errmsg = NULL;
545 goto advance_and_error;
546 }
548 }
549
550
551 result->binary = (nfields > 0) ? 1 : 0;
552
553
554 for (i = 0; i < nfields; i++)
555 {
556 int tableid;
557 int columnid;
558 int typid;
559 int typlen;
560 int atttypmod;
562
570 {
571
573 goto advance_and_error;
574 }
575
576
577
578
579
580 columnid = (int) ((int16) columnid);
581 typlen = (int) ((int16) typlen);
583
587 {
588 errmsg = NULL;
589 goto advance_and_error;
590 }
597
600 }
601
602
604
605
606
607
608
612 {
614 return 0;
615 }
616
617
618
619
620
621
622
623 return 0;
624
625advance_and_error:
626
627 if (result && result != conn->result)
629
630
631
632
633
635
636
637
638
639
640
641
644
647
648
649
650
651
653
654
655
656
657
658
659 return 0;
660}
char * pqResultStrdup(PGresult *res, const char *str)
PGcmdQueueEntry * cmd_queue_head
References appendPQExpBuffer(), pg_conn::asyncStatus, pg_result::attDescs, pgresAttDesc::atttypmod, pg_result::binary, pg_conn::cmd_queue_head, pgresAttDesc::columnid, conn, PQExpBufferData::data, errmsg(), pg_conn::errorMessage, format, pgresAttDesc::format, i, pg_conn::inCursor, pg_conn::inStart, libpq_gettext, MemSet, pgresAttDesc::name, pg_result::numAttributes, PGASYNC_READY, PGQUERY_DESCRIBE, PGRES_COMMAND_OK, PGRES_TUPLES_OK, PQclear(), pqClearAsyncResult(), pqGetInt(), pqGets(), PQmakeEmptyPGresult(), pqResultAlloc(), pqResultStrdup(), pqSaveErrorResult(), PGcmdQueueEntry::queryclass, pg_conn::result, pgresAttDesc::tableid, pgresAttDesc::typid, pgresAttDesc::typlen, and pg_conn::workBuffer.
Referenced by pqParseInput3().
◆ handleSyncLoss()
static void handleSyncLoss ( PGconn * conn, char id, int msgLength ) | static |
---|
Definition at line 478 of file fe-protocol3.c.
479{
481 id, msgLength);
482
485
488}
void pqDropConnection(PGconn *conn, bool flushInput)
References pg_conn::asyncStatus, conn, CONNECTION_BAD, libpq_append_conn_error(), PGASYNC_READY, pqDropConnection(), pqSaveErrorResult(), and pg_conn::status.
Referenced by getCopyDataMessage(), pqFunctionCall3(), and pqParseInput3().
◆ pqBuildErrorMessage3()
Definition at line 1010 of file fe-protocol3.c.
1012{
1013 const char *val;
1014 const char *querytext = NULL;
1015 int querypos = 0;
1016
1017
1018 if (res == NULL)
1019 {
1021 return;
1022 }
1023
1024
1025
1026
1027
1029 {
1032 else
1034 return;
1035 }
1036
1037
1039 if (val)
1041
1043 {
1044
1045
1046
1047
1048
1049
1051 if (val)
1052 {
1054 return;
1055 }
1057 }
1058
1060 {
1062 if (val)
1064 }
1066 if (val)
1069 if (val)
1070 {
1072 {
1073
1075 querypos = atoi(val);
1076 }
1077 else
1078 {
1079
1080
1083 }
1084 }
1085 else
1086 {
1088 if (val)
1089 {
1091 if (verbosity != PQERRORS_TERSE && querytext != NULL)
1092 {
1093
1094 querypos = atoi(val);
1095 }
1096 else
1097 {
1098
1099
1102 }
1103 }
1104 }
1107 {
1108 if (querytext && querypos > 0)
1112 if (val)
1115 if (val)
1118 if (val)
1123 {
1125 if (val)
1128 }
1129 }
1131 {
1133 if (val)
1137 if (val)
1141 if (val)
1145 if (val)
1149 if (val)
1152 }
1154 {
1155 const char *valf;
1156 const char *vall;
1157
1161 if (val || valf || vall)
1162 {
1164 if (val)
1166 if (valf && vall)
1168 valf, vall);
1170 }
1171 }
1172}
char * PQresultErrorField(const PGresult *res, int fieldcode)
static void reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
#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
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
PGMessageField * errFields
ExecStatusType resultStatus
References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), pg_result::client_encoding, pg_result::errFields, pg_result::errMsg, pg_result::errQuery, libpq_gettext, PG_DIAG_COLUMN_NAME, PG_DIAG_CONSTRAINT_NAME, PG_DIAG_CONTEXT, PG_DIAG_DATATYPE_NAME, PG_DIAG_INTERNAL_POSITION, PG_DIAG_INTERNAL_QUERY, PG_DIAG_MESSAGE_DETAIL, PG_DIAG_MESSAGE_HINT, PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SCHEMA_NAME, PG_DIAG_SEVERITY, PG_DIAG_SOURCE_FILE, PG_DIAG_SOURCE_FUNCTION, PG_DIAG_SOURCE_LINE, PG_DIAG_SQLSTATE, PG_DIAG_STATEMENT_POSITION, PG_DIAG_TABLE_NAME, PGRES_FATAL_ERROR, PQERRORS_SQLSTATE, PQERRORS_TERSE, PQERRORS_VERBOSE, PQresultErrorField(), PQSHOW_CONTEXT_ALWAYS, PQSHOW_CONTEXT_ERRORS, reportErrorPosition(), pg_result::resultStatus, and val.
Referenced by pqGetErrorNotice3(), and PQresultVerboseErrorMessage().
◆ pqBuildStartupPacket3()
Definition at line 2313 of file fe-protocol3.c.
2315{
2316 char *startpacket;
2317
2319 startpacket = (char *) malloc(*packetlen);
2320 if (!startpacket)
2321 return NULL;
2323 return startpacket;
2324}
static int build_startup_packet(const PGconn *conn, char *packet, const PQEnvironmentOption *options)
References build_startup_packet(), conn, and malloc.
Referenced by PQconnectPoll().
◆ pqEndcopy3()
int pqEndcopy3 | ( | PGconn * | conn | ) |
---|
Definition at line 1990 of file fe-protocol3.c.
1991{
1993
1997 {
1999 return 1;
2000 }
2001
2002
2005 {
2008 return 1;
2009
2010
2011
2012
2013
2016 {
2019 return 1;
2020 }
2021 }
2022
2023
2024
2025
2026
2028 return 1;
2029
2030
2032
2033
2034
2035
2036
2037
2038
2039
2041 return 1;
2042
2043
2045
2046
2048 {
2050 return 0;
2051 }
2052
2053
2054
2055
2056
2057
2058
2059
2061 {
2062
2064
2065 if (svLast == '\n')
2069 }
2070
2072
2073 return 1;
2074}
PGresult * PQgetResult(PGconn *conn)
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
int PQisBusy(PGconn *conn)
int pqFlush(PGconn *conn)
int pqPutMsgStart(char msg_type, PGconn *conn)
int pqPutMsgEnd(PGconn *conn)
#define pqIsnonblocking(conn)
PGNoticeHooks noticeHooks
References pg_conn::asyncStatus, pg_conn::cmd_queue_head, conn, PQExpBufferData::data, pg_conn::errorMessage, PQExpBufferData::len, libpq_append_conn_error(), pg_conn::noticeHooks, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGQUERY_SIMPLE, PGRES_COMMAND_OK, PQclear(), pqFlush(), PQgetResult(), pqInternalNotice(), PQisBusy(), pqIsnonblocking, PqMsg_CopyDone, PqMsg_Sync, pqPutMsgEnd(), pqPutMsgStart(), PGcmdQueueEntry::queryclass, and pg_result::resultStatus.
Referenced by PQendcopy().
◆ pqFunctionCall3()
PGresult * pqFunctionCall3 | ( | PGconn * | conn, |
---|---|---|---|
Oid | fnid, | ||
int * | result_buf, | ||
int * | actual_result_len, | ||
int | result_is_int, | ||
const PQArgBlock * | args, | ||
int | nargs | ||
) |
Definition at line 2083 of file fe-protocol3.c.
2087{
2088 bool needInput = false;
2090 char id;
2091 int msgLength;
2092 int avail;
2093 int i;
2094
2095
2097
2098
2099
2101 pqPutInt(fnid, 4, conn) < 0 ||
2102 pqPutInt(1, 2, conn) < 0 ||
2103 pqPutInt(1, 2, conn) < 0 ||
2104 pqPutInt(nargs, 2, conn) < 0)
2105 {
2106
2107 return NULL;
2108 }
2109
2110 for (i = 0; i < nargs; ++i)
2111 {
2113 return NULL;
2115 continue;
2116
2118 {
2120 return NULL;
2121 }
2122 else
2123 {
2125 return NULL;
2126 }
2127 }
2128
2129 if (pqPutInt(1, 2, conn) < 0)
2130 return NULL;
2131
2134 return NULL;
2135
2136 for (;;)
2137 {
2138 if (needInput)
2139 {
2140
2143 break;
2144 }
2145
2146
2147
2148
2149 needInput = true;
2150
2153 continue;
2155 continue;
2156
2157
2158
2159
2160
2161
2162 if (msgLength < 4)
2163 {
2165 break;
2166 }
2168 {
2170 break;
2171 }
2172
2173
2174
2175
2176 msgLength -= 4;
2178 if (avail < msgLength)
2179 {
2180
2181
2182
2183
2186 {
2187
2188
2189
2190
2191
2192
2194 break;
2195 }
2196 continue;
2197 }
2198
2199
2200
2201
2202
2203
2204 switch (id)
2205 {
2206 case 'V':
2208 continue;
2209 if (*actual_result_len != -1)
2210 {
2211 if (result_is_int)
2212 {
2213 if (pqGetInt(result_buf, *actual_result_len, conn))
2214 continue;
2215 }
2216 else
2217 {
2219 *actual_result_len,
2221 continue;
2222 }
2223 }
2224
2226 break;
2227 case 'E':
2229 continue;
2231 break;
2232 case 'A':
2233
2235 continue;
2236 break;
2237 case 'N':
2238
2240 continue;
2241 break;
2242 case 'Z':
2244 continue;
2245
2246
2248
2249
2250
2251
2252
2253
2254
2256 {
2258 {
2261 {
2264 }
2265 }
2266 else
2267 {
2270 }
2271 }
2272
2274 case 'S':
2276 continue;
2277 break;
2278 default:
2279
2282
2283
2284
2285
2286
2287
2290 }
2291
2292
2294 needInput = false;
2295 }
2296
2297
2298
2299
2300
2301
2304}
PGresult * pqPrepareAsyncResult(PGconn *conn)
int pqReadData(PGconn *conn)
int pqPutInt(int value, size_t bytes, PGconn *conn)
int pqWait(int forRead, int forWrite, PGconn *conn)
int pqPutnchar(const void *s, size_t len, PGconn *conn)
#define VALID_LONG_MESSAGE_TYPE(id)
static int getReadyForQuery(PGconn *conn)
Assert(PointerIsAligned(start, uint64))
#define pgHavePendingResult(conn)
#define PqMsg_FunctionCall
PGpipelineStatus pipelineStatus
References generate_unaccent_rules::args, Assert(), conn, getNotify(), getParameterStatus(), getReadyForQuery(), handleSyncLoss(), i, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, len, libpq_append_conn_error(), pgHavePendingResult, PGRES_COMMAND_OK, PGRES_FATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqCheckInBufferSpace(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), PQmakeEmptyPGresult(), PqMsg_FunctionCall, pqParseDone(), pqPrepareAsyncResult(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqReadData(), pqSaveErrorResult(), pqWait(), pg_conn::result, and VALID_LONG_MESSAGE_TYPE.
Referenced by PQfn().
◆ pqGetCopyData3()
int pqGetCopyData3 | ( | PGconn * | conn, |
---|---|---|---|
char ** | buffer, | ||
int | async | ||
) |
◆ pqGetErrorNotice3()
int pqGetErrorNotice3 | ( | PGconn * | conn, |
---|---|---|---|
bool | isError | ||
) |
Definition at line 878 of file fe-protocol3.c.
879{
881 bool have_position = false;
883 char id;
884
885
888
889
890
891
892
893
894 if (isError)
896
897
898
899
900
901
902
904
905
906
907
908
909
910
911
912
913
915 if (res)
917
918
919
920
921
922
923
924 for (;;)
925 {
927 goto fail;
928 if (id == '\0')
929 break;
931 goto fail;
937 have_position = true;
938 }
939
940
941
942
943
944
947
948
949
950
953
954
955
956
957 if (isError)
958 {
960 if (res)
961 {
964 }
965 else
966 {
967
969 }
970
973 else
975 }
976 else
977 {
978
979 if (res)
980 {
981
982
983
984
985
988 else
993 }
994 }
995
997 return 0;
998
999fail:
1002 return EOF;
1003}
void pqSaveMessageField(PGresult *res, char code, const char *value)
void pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset)
void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
size_t strlcpy(char *dst, const char *src, size_t siz)
void resetPQExpBuffer(PQExpBuffer str)
#define PQExpBufferDataBroken(buf)
PQnoticeReceiver noticeRec
PGContextVisibility show_context
PGNoticeHooks noticeHooks
References appendPQExpBufferStr(), pg_conn::cmd_queue_head, conn, PQExpBufferData::data, pg_result::errMsg, pg_conn::error_result, pg_conn::errorMessage, pg_result::errQuery, initPQExpBuffer(), pg_conn::last_sqlstate, libpq_append_conn_error(), libpq_gettext, pg_result::noticeHooks, PGNoticeHooks::noticeRec, PGNoticeHooks::noticeRecArg, PG_DIAG_SQLSTATE, PG_DIAG_STATEMENT_POSITION, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_ABORTED, PQ_PIPELINE_OFF, pqBuildErrorMessage3(), PQclear(), pqClearAsyncResult(), PQExpBufferDataBroken, pqGetc(), pqGets(), PQmakeEmptyPGresult(), pqResultStrdup(), pqSaveMessageField(), pqSetResultError(), PGcmdQueueEntry::query, resetPQExpBuffer(), pg_conn::result, pg_result::resultStatus, pg_conn::show_context, strlcpy(), termPQExpBuffer(), and pg_conn::verbosity.
Referenced by getCopyDataMessage(), PQconnectPoll(), pqFunctionCall3(), and pqParseInput3().
◆ pqGetline3()
int pqGetline3 | ( | PGconn * | conn, |
---|---|---|---|
char * | s, | ||
int | maxlen | ||
) |
Definition at line 1884 of file fe-protocol3.c.
1885{
1886 int status;
1887
1892 {
1894 *s = '\0';
1895 return EOF;
1896 }
1897
1899 {
1900
1903 {
1904 *s = '\0';
1905 return EOF;
1906 }
1907 }
1908
1909 if (status < 0)
1910 {
1911
1912 strcpy(s, "\\.");
1913 return 0;
1914 }
1915
1916
1917 if (s[status - 1] == '\n')
1918 {
1919 s[status - 1] = '\0';
1920 return 0;
1921 }
1922 else
1923 {
1924 s[status] = '\0';
1925 return 1;
1926 }
1927}
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
References pg_conn::asyncStatus, conn, pg_conn::copy_is_binary, libpq_append_conn_error(), PGASYNC_COPY_BOTH, PGASYNC_COPY_OUT, PGINVALID_SOCKET, PQgetlineAsync(), pqReadData(), pqWait(), and pg_conn::sock.
Referenced by PQgetline().
◆ pqGetlineAsync3()
int pqGetlineAsync3 | ( | PGconn * | conn, |
---|---|---|---|
char * | buffer, | ||
int | bufsize | ||
) |
◆ pqGetNegotiateProtocolVersion3()
int pqGetNegotiateProtocolVersion3 | ( | PGconn * | conn | ) |
---|
Definition at line 1410 of file fe-protocol3.c.
1411{
1412 int their_version;
1413 int num;
1414
1416 goto eof;
1417
1419 goto eof;
1420
1421
1423 {
1424 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version");
1425 goto failure;
1426 }
1427
1429 {
1430 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version");
1431 goto failure;
1432 }
1433
1434
1436 {
1437 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requests downgrade to non-existent 3.1 protocol version");
1438 goto failure;
1439 }
1440
1441 if (num < 0)
1442 {
1443 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported negative number of unsupported parameters");
1444 goto failure;
1445 }
1446
1447 if (their_version == conn->pversion && num == 0)
1448 {
1449 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server negotiated but asks for no changes");
1450 goto failure;
1451 }
1452
1453 if (their_version < conn->min_pversion)
1454 {
1455 libpq_append_conn_error(conn, "server only supports protocol version %d.%d, but min_protocol_version was set to %d.%d",
1460
1461 goto failure;
1462 }
1463
1464
1466
1467
1468
1469
1470
1471 for (int i = 0; i < num; i++)
1472 {
1474 {
1475 goto eof;
1476 }
1478 {
1479 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported unsupported parameter name without a _pq_. prefix (\"%s\")", conn->workBuffer.data);
1480 goto failure;
1481 }
1482 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported an unsupported parameter that was not requested (\"%s\")", conn->workBuffer.data);
1483 goto failure;
1484 }
1485
1486 return 0;
1487
1488eof:
1490failure:
1493 return 1;
1494}
#define PG_PROTOCOL_MAJOR(v)
#define PG_PROTOCOL(m, n)
#define PG_PROTOCOL_MINOR(v)
ProtocolVersion min_pversion
References pg_conn::asyncStatus, conn, PQExpBufferData::data, i, libpq_append_conn_error(), pg_conn::min_pversion, PG_PROTOCOL, PG_PROTOCOL_MAJOR, PG_PROTOCOL_MINOR, PGASYNC_READY, pqGetInt(), pqGets(), pqSaveErrorResult(), pg_conn::pversion, and pg_conn::workBuffer.
Referenced by PQconnectPoll().
◆ pqParseInput3()
void pqParseInput3 | ( | PGconn * | conn | ) |
---|
Definition at line 67 of file fe-protocol3.c.
68{
69 char id;
70 int msgLength;
71 int avail;
72
73
74
75
76 for (;;)
77 {
78
79
80
81
84 return;
86 return;
87
88
89
90
91
92
93 if (msgLength < 4)
94 {
96 return;
97 }
99 {
101 return;
102 }
103
104
105
106
107 msgLength -= 4;
109 if (avail < msgLength)
110 {
111
112
113
114
115
116
117
118
121 {
122
123
124
125
126
127
129 }
130 return;
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
150 {
152 return;
153 }
155 {
157 return;
158 }
160 {
161
163 return;
164
165
166
167
168
169
170
171
172
173
175 {
177 return;
178 }
180 {
182 return;
183 }
184 else
185 {
186
188 "message type 0x%02x arrived from server while idle",
189 id);
190
192 }
193 }
194 else
195 {
196
197
198
199 switch (id)
200 {
203 return;
205 {
209 {
212 }
213 }
218 break;
221 return;
223 break;
226 return;
228 {
232 {
235 }
236 else
237 {
240 }
241 }
242 else
243 {
244
247 }
248 break;
251 {
255 {
258 }
259 }
261 break;
263
266 {
268 {
272 {
275 }
276 }
278 }
279 break;
281
282 break;
284
287 {
289 {
293 {
296 }
297 }
299 }
300 break;
303 return;
304 break;
306
307
308
309
310
311
313 return;
314 break;
319 {
320
321
322
323
325 }
329 {
330
332 return;
333 }
334 else
335 {
336
337
338
339
340
341
342
344 return;
345 }
346 break;
348
349
350
351
352
353
354
355
356
357
358
361 {
363 {
367 {
370 }
371 }
373 }
374 break;
377 return;
378 break;
383 {
384
386 return;
387 }
391 {
392
393
394
395
397 }
398 else
399 {
400
401 libpq_append_conn_error(conn, "server sent data (\"D\" message) without prior row description (\"T\" message)");
403
405 }
406 break;
409 return;
411 break;
414 return;
417 break;
420 return;
423 break;
425
426
427
428
429
430
432 break;
434
435
436
437
438
439
440
441 break;
442 default:
443 libpq_append_conn_error(conn, "unexpected response from server; first received character was \"%c\"", id);
444
446
448
450 break;
451 }
452 }
453
455 {
456
458 }
459 else
460 {
461
463
466
468 }
469 }
470}
void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
static int getAnotherTuple(PGconn *conn, int msgLength)
static int getRowDescriptions(PGconn *conn, int msgLength)
static int getCopyStart(PGconn *conn, ExecStatusType copytype)
static int getBackendKeyData(PGconn *conn, int msgLength)
static int getParamDescriptions(PGconn *conn, int msgLength)
#define PqMsg_CloseComplete
#define PqMsg_BindComplete
#define PqMsg_ParameterDescription
#define PqMsg_ReadyForQuery
#define PqMsg_CopyInResponse
#define PqMsg_EmptyQueryResponse
#define PqMsg_CopyBothResponse
#define PqMsg_BackendKeyData
#define PqMsg_CommandComplete
#define PqMsg_CopyOutResponse
#define PqMsg_ParseComplete
char cmdStatus[CMDSTATUS_LEN]
References pg_conn::asyncStatus, pg_conn::cmd_queue_head, pg_result::cmdStatus, CMDSTATUS_LEN, conn, pg_conn::copy_already_done, PQExpBufferData::data, pg_conn::error_result, getAnotherTuple(), getBackendKeyData(), getCopyStart(), getNotify(), getParamDescriptions(), getParameterStatus(), getReadyForQuery(), getRowDescriptions(), handleSyncLoss(), pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_append_conn_error(), pg_conn::noticeHooks, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGASYNC_IDLE, PGASYNC_READY, pgHavePendingResult, PGQUERY_CLOSE, PGQUERY_DESCRIBE, PGQUERY_PREPARE, PGRES_COMMAND_OK, PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_PIPELINE_SYNC, PGRES_TUPLES_CHUNK, PGRES_TUPLES_OK, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, PQ_PIPELINE_ON, pqCheckInBufferSpace(), pqCommandQueueAdvance(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGets(), pqInternalNotice(), PQmakeEmptyPGresult(), PqMsg_BackendKeyData, PqMsg_BindComplete, PqMsg_CloseComplete, PqMsg_CommandComplete, PqMsg_CopyBothResponse, PqMsg_CopyData, PqMsg_CopyDone, PqMsg_CopyInResponse, PqMsg_CopyOutResponse, PqMsg_DataRow, PqMsg_EmptyQueryResponse, PqMsg_ErrorResponse, PqMsg_NoData, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterDescription, PqMsg_ParameterStatus, PqMsg_ParseComplete, PqMsg_ReadyForQuery, PqMsg_RowDescription, pqParseDone(), pqSaveErrorResult(), PGcmdQueueEntry::queryclass, pg_conn::result, pg_result::resultStatus, strlcpy(), VALID_LONG_MESSAGE_TYPE, and pg_conn::workBuffer.
Referenced by parseInput().
◆ reportErrorPosition()
static void reportErrorPosition ( PQExpBuffer msg, const char * query, int loc, int encoding ) | static |
---|
Definition at line 1181 of file fe-protocol3.c.
1182{
1183#define DISPLAY_SIZE 60
1184#define MIN_RIGHT_CUT 10
1185
1186 char *wquery;
1187 int slen,
1188 cno,
1189 i,
1190 *qidx,
1191 *scridx,
1192 qoffset,
1193 scroffset,
1194 ibeg,
1195 iend,
1196 loc_line;
1197 bool mb_encoding,
1198 beg_trunc,
1199 end_trunc;
1200
1201
1202 loc--;
1203 if (loc < 0)
1204 return;
1205
1206
1207 wquery = strdup(query);
1208 if (wquery == NULL)
1209 return;
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 slen = strlen(wquery) + 1;
1221
1222 qidx = (int *) malloc(slen * sizeof(int));
1223 if (qidx == NULL)
1224 {
1225 free(wquery);
1226 return;
1227 }
1228 scridx = (int *) malloc(slen * sizeof(int));
1229 if (scridx == NULL)
1230 {
1232 free(wquery);
1233 return;
1234 }
1235
1236
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248 qoffset = 0;
1249 scroffset = 0;
1250 loc_line = 1;
1251 ibeg = 0;
1252 iend = -1;
1253
1254 for (cno = 0; wquery[qoffset] != '\0'; cno++)
1255 {
1256 char ch = wquery[qoffset];
1257
1258 qidx[cno] = qoffset;
1259 scridx[cno] = scroffset;
1260
1261
1262
1263
1264
1265
1266 if (ch == '\t')
1267 wquery[qoffset] = ' ';
1268
1269
1270
1271
1272
1273 else if (ch == '\r' || ch == '\n')
1274 {
1275 if (cno < loc)
1276 {
1277 if (ch == '\r' ||
1278 cno == 0 ||
1279 wquery[qidx[cno - 1]] != '\r')
1280 loc_line++;
1281
1282 ibeg = cno + 1;
1283 }
1284 else
1285 {
1286
1287 iend = cno;
1288
1289 break;
1290 }
1291 }
1292
1293
1294 if (mb_encoding)
1295 {
1296 int w;
1297
1299
1300 if (w <= 0)
1301 w = 1;
1302 scroffset += w;
1304 }
1305 else
1306 {
1307
1308 scroffset++;
1309 qoffset++;
1310 }
1311 }
1312
1313 if (iend < 0)
1314 {
1315 iend = cno;
1316 qidx[iend] = qoffset;
1317 scridx[iend] = scroffset;
1318 }
1319
1320
1321 if (loc <= cno)
1322 {
1323
1324 beg_trunc = false;
1325 end_trunc = false;
1326 if (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1327 {
1328
1329
1330
1331
1332
1334 {
1335 while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1336 iend--;
1337 end_trunc = true;
1338 }
1339 else
1340 {
1341
1342 while (scridx[loc] + MIN_RIGHT_CUT < scridx[iend])
1343 {
1344 iend--;
1345 end_trunc = true;
1346 }
1347
1348
1349 while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1350 {
1351 ibeg++;
1352 beg_trunc = true;
1353 }
1354 }
1355 }
1356
1357
1358 wquery[qidx[iend]] = '\0';
1359
1360
1363 if (beg_trunc)
1365
1366
1367
1368
1369
1370 scroffset = 0;
1372 {
1374
1375 if (w <= 0)
1376 w = 1;
1377 scroffset += w;
1378 }
1379
1380
1382 if (end_trunc)
1385
1386
1387 scroffset += scridx[loc] - scridx[ibeg];
1388 for (i = 0; i < scroffset; i++)
1392 }
1393
1394
1395 free(scridx);
1397 free(wquery);
1398}
int PQmblenBounded(const char *s, int encoding)
int pg_encoding_dsplen(int encoding, const char *mbstr)
int pg_encoding_max_length(int encoding)
References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), PQExpBufferData::data, DISPLAY_SIZE, encoding, free, i, PQExpBufferData::len, libpq_gettext, malloc, MIN_RIGHT_CUT, pg_encoding_dsplen(), pg_encoding_max_length(), and PQmblenBounded().
Referenced by pqBuildErrorMessage3().