PostgreSQL Source Code: src/interfaces/libpq/fe-protocol3.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
17#include <ctype.h>
18#include <fcntl.h>
19
20#ifdef WIN32
21#include "win32.h"
22#else
25#endif
26
31
32
33
34
35
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)
44
45
59
60
61
62
63
64
65
66void
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}
471
472
473
474
475
476
477static void
479{
481 id, msgLength);
482
485
488}
489
490
491
492
493
494
495
496
497static int
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}
661
662
663
664
665
666
667
668static int
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}
749
750
751
752
753
754
755
756static int
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}
867
868
869
870
871
872
873
874
875
876
877int
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}
1004
1005
1006
1007
1008
1009void
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}
1173
1174
1175
1176
1177
1178
1179
1180static void
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}
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409int
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}
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505static int
1507{
1509
1510
1512 return EOF;
1513
1516 {
1518 return EOF;
1519 }
1520
1523 return 0;
1524}
1525
1526
1527
1528
1529
1530
1531
1532static int
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}
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575static int
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}
1624
1625
1626
1627
1628
1629
1630
1631static int
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}
1683
1684
1685
1686
1687static int
1689{
1690 char xact_status;
1691
1693 return EOF;
1694 switch (xact_status)
1695 {
1696 case 'I':
1698 break;
1699 case 'T':
1701 break;
1702 case 'E':
1704 break;
1705 default:
1707 break;
1708 }
1709
1710 return 0;
1711}
1712
1713
1714
1715
1716
1717
1718
1719static int
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}
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824int
1826{
1827 int msgLength;
1828
1829 for (;;)
1830 {
1831
1832
1833
1834
1835
1837 if (msgLength < 0)
1838 return msgLength;
1839 if (msgLength == 0)
1840 {
1841
1842 if (async)
1843 return 0;
1844
1847 return -2;
1848 continue;
1849 }
1850
1851
1852
1853
1854
1855 msgLength -= 4;
1856 if (msgLength > 0)
1857 {
1858 *buffer = (char *) malloc(msgLength + 1);
1859 if (*buffer == NULL)
1860 {
1862 return -2;
1863 }
1865 (*buffer)[msgLength] = '\0';
1866
1867
1869
1870 return msgLength;
1871 }
1872
1873
1875 }
1876}
1877
1878
1879
1880
1881
1882
1883int
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}
1928
1929
1930
1931
1932
1933
1934int
1936{
1937 int msgLength;
1938 int avail;
1939
1942 return -1;
1943
1944
1945
1946
1947
1948
1949
1951 if (msgLength < 0)
1952 return -1;
1953 if (msgLength == 0)
1954 return 0;
1955
1956
1957
1958
1959
1960
1961
1965 {
1966
1968
1970
1972 return avail;
1973 }
1974 else
1975 {
1976
1978
1981 }
1982}
1983
1984
1985
1986
1987
1988
1989int
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}
2075
2076
2077
2078
2079
2080
2081
2084 int *result_buf, int *actual_result_len,
2085 int result_is_int,
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}
2305
2306
2307
2308
2309
2310
2311
2312char *
2315{
2316 char *startpacket;
2317
2319 startpacket = (char *) malloc(*packetlen);
2320 if (!startpacket)
2321 return NULL;
2323 return startpacket;
2324}
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335static int
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 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)
PGresult * PQgetResult(PGconn *conn)
int pqRowProcessor(PGconn *conn, const char **errmsgp)
void PQclear(PGresult *res)
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
void pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
void pqClearAsyncResult(PGconn *conn)
char * PQresultErrorField(const PGresult *res, int fieldcode)
int PQisBusy(PGconn *conn)
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)
#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 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_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)