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 }

806 rowbuf[i].len = vlen;

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

1361 i = msg->len;

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

2117 if (args[i].isint)

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)