#include #include #include #include "libpq-fe.h" #include "libpq-int.h" #include "mb/pg_wchar.h" #include "port/pg_bswap.h"">

PostgreSQL Source Code: src/interfaces/libpq/fe-protocol3.c File Reference (original) (raw)

#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)
Functions
static void handleSyncLoss (PGconn *conn, char id, int msgLength)
static int getRowDescriptions (PGconn *conn, int msgLength)
static int getParamDescriptions (PGconn *conn, int msgLength)
static int getAnotherTuple (PGconn *conn, int msgLength)
static int getParameterStatus (PGconn *conn)
static int getBackendKeyData (PGconn *conn, int msgLength)
static int getNotify (PGconn *conn)
static int getCopyStart (PGconn *conn, ExecStatusType copytype)
static int getReadyForQuery (PGconn *conn)
static void reportErrorPosition (PQExpBuffer msg, const char *query, int loc, int encoding)
static int build_startup_packet (const PGconn *conn, char *packet, const PQEnvironmentOption *options)
void pqParseInput3 (PGconn *conn)
int pqGetErrorNotice3 (PGconn *conn, bool isError)
void pqBuildErrorMessage3 (PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
int pqGetNegotiateProtocolVersion3 (PGconn *conn)
static int getCopyDataMessage (PGconn *conn)
int pqGetCopyData3 (PGconn *conn, char **buffer, int async)
int pqGetline3 (PGconn *conn, char *s, int maxlen)
int pqGetlineAsync3 (PGconn *conn, char *buffer, int bufsize)
int pqEndcopy3 (PGconn *conn)
PGresult * pqFunctionCall3 (PGconn *conn, Oid fnid, int *result_buf, int *actual_result_len, int result_is_int, const PQArgBlock *args, int nargs)
char * pqBuildStartupPacket3 (PGconn *conn, int *packetlen, const PQEnvironmentOption *options)

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 }

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}

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

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}

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

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}

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().