Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Enumerations | Functions

libpq-fe.h File Reference

#include <stdio.h>
#include "postgres_ext.h"
Include dependency graph for libpq-fe.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pgNotify
struct  _PQprintOpt
struct  _PQconninfoOption
struct  PQArgBlock
struct  pgresAttDesc

Defines

#define PG_COPYRES_ATTRS   0x01
#define PG_COPYRES_TUPLES   0x02
#define PG_COPYRES_EVENTS   0x04
#define PG_COPYRES_NOTICEHOOKS   0x08
#define PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME)   PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
#define PQfreeNotify(ptr)   PQfreemem(ptr)
#define PQnoPasswordSupplied   "fe_sendauth: no password supplied\n"

Typedefs

typedef struct pg_conn PGconn
typedef struct pg_result PGresult
typedef struct pg_cancel PGcancel
typedef struct pgNotify PGnotify
typedef void(* PQnoticeReceiver )(void *arg, const PGresult *res)
typedef void(* PQnoticeProcessor )(void *arg, const char *message)
typedef char pqbool
typedef struct _PQprintOpt PQprintOpt
typedef struct _PQconninfoOption PQconninfoOption
typedef struct pgresAttDesc PGresAttDesc
typedef void(* pgthreadlock_t )(int acquire)

Enumerations

enum  ConnStatusType {
  CONNECTION_OK, CONNECTION_BAD, CONNECTION_STARTED, CONNECTION_MADE,
  CONNECTION_AWAITING_RESPONSE, CONNECTION_AUTH_OK, CONNECTION_SETENV, CONNECTION_SSL_STARTUP,
  CONNECTION_NEEDED
}
enum  PostgresPollingStatusType {
  PGRES_POLLING_FAILED = 0, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PGRES_POLLING_OK,
  PGRES_POLLING_ACTIVE
}
enum  ExecStatusType {
  PGRES_EMPTY_QUERY = 0, PGRES_COMMAND_OK, PGRES_TUPLES_OK, PGRES_COPY_OUT,
  PGRES_COPY_IN, PGRES_BAD_RESPONSE, PGRES_NONFATAL_ERROR, PGRES_FATAL_ERROR,
  PGRES_COPY_BOTH, PGRES_SINGLE_TUPLE
}
enum  PGTransactionStatusType {
  PQTRANS_IDLE, PQTRANS_ACTIVE, PQTRANS_INTRANS, PQTRANS_INERROR,
  PQTRANS_UNKNOWN
}
enum  PGVerbosity { PQERRORS_TERSE, PQERRORS_DEFAULT, PQERRORS_VERBOSE }
enum  PGPing { PQPING_OK, PQPING_REJECT, PQPING_NO_RESPONSE, PQPING_NO_ATTEMPT }

Functions

PGconnPQconnectStart (const char *conninfo)
PGconnPQconnectStartParams (const char *const *keywords, const char *const *values, int expand_dbname)
PostgresPollingStatusType PQconnectPoll (PGconn *conn)
PGconnPQconnectdb (const char *conninfo)
PGconnPQconnectdbParams (const char *const *keywords, const char *const *values, int expand_dbname)
PGconnPQsetdbLogin (const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
void PQfinish (PGconn *conn)
PQconninfoOptionPQconndefaults (void)
PQconninfoOptionPQconninfoParse (const char *conninfo, char **errmsg)
PQconninfoOptionPQconninfo (PGconn *conn)
void PQconninfoFree (PQconninfoOption *connOptions)
int PQresetStart (PGconn *conn)
PostgresPollingStatusType PQresetPoll (PGconn *conn)
void PQreset (PGconn *conn)
PGcancelPQgetCancel (PGconn *conn)
void PQfreeCancel (PGcancel *cancel)
int PQcancel (PGcancel *cancel, char *errbuf, int errbufsize)
int PQrequestCancel (PGconn *conn)
char * PQdb (const PGconn *conn)
char * PQuser (const PGconn *conn)
char * PQpass (const PGconn *conn)
char * PQhost (const PGconn *conn)
char * PQport (const PGconn *conn)
char * PQtty (const PGconn *conn)
char * PQoptions (const PGconn *conn)
ConnStatusType PQstatus (const PGconn *conn)
PGTransactionStatusType PQtransactionStatus (const PGconn *conn)
const char * PQparameterStatus (const PGconn *conn, const char *paramName)
int PQprotocolVersion (const PGconn *conn)
int PQserverVersion (const PGconn *conn)
char * PQerrorMessage (const PGconn *conn)
int PQsocket (const PGconn *conn)
int PQbackendPID (const PGconn *conn)
int PQconnectionNeedsPassword (const PGconn *conn)
int PQconnectionUsedPassword (const PGconn *conn)
int PQclientEncoding (const PGconn *conn)
int PQsetClientEncoding (PGconn *conn, const char *encoding)
void * PQgetssl (PGconn *conn)
void PQinitSSL (int do_init)
void PQinitOpenSSL (int do_ssl, int do_crypto)
PGVerbosity PQsetErrorVerbosity (PGconn *conn, PGVerbosity verbosity)
void PQtrace (PGconn *conn, FILE *debug_port)
void PQuntrace (PGconn *conn)
PQnoticeReceiver PQsetNoticeReceiver (PGconn *conn, PQnoticeReceiver proc, void *arg)
PQnoticeProcessor PQsetNoticeProcessor (PGconn *conn, PQnoticeProcessor proc, void *arg)
pgthreadlock_t PQregisterThreadLock (pgthreadlock_t newhandler)
PGresultPQexec (PGconn *conn, const char *query)
PGresultPQexecParams (PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
PGresultPQprepare (PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
PGresultPQexecPrepared (PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQsendQuery (PGconn *conn, const char *query)
int PQsendQueryParams (PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQsendPrepare (PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
int PQsendQueryPrepared (PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQsetSingleRowMode (PGconn *conn)
PGresultPQgetResult (PGconn *conn)
int PQisBusy (PGconn *conn)
int PQconsumeInput (PGconn *conn)
PGnotifyPQnotifies (PGconn *conn)
int PQputCopyData (PGconn *conn, const char *buffer, int nbytes)
int PQputCopyEnd (PGconn *conn, const char *errormsg)
int PQgetCopyData (PGconn *conn, char **buffer, int async)
int PQgetline (PGconn *conn, char *string, int length)
int PQputline (PGconn *conn, const char *string)
int PQgetlineAsync (PGconn *conn, char *buffer, int bufsize)
int PQputnbytes (PGconn *conn, const char *buffer, int nbytes)
int PQendcopy (PGconn *conn)
int PQsetnonblocking (PGconn *conn, int arg)
int PQisnonblocking (const PGconn *conn)
int PQisthreadsafe (void)
PGPing PQping (const char *conninfo)
PGPing PQpingParams (const char *const *keywords, const char *const *values, int expand_dbname)
int PQflush (PGconn *conn)
PGresultPQfn (PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
ExecStatusType PQresultStatus (const PGresult *res)
char * PQresStatus (ExecStatusType status)
char * PQresultErrorMessage (const PGresult *res)
char * PQresultErrorField (const PGresult *res, int fieldcode)
int PQntuples (const PGresult *res)
int PQnfields (const PGresult *res)
int PQbinaryTuples (const PGresult *res)
char * PQfname (const PGresult *res, int field_num)
int PQfnumber (const PGresult *res, const char *field_name)
Oid PQftable (const PGresult *res, int field_num)
int PQftablecol (const PGresult *res, int field_num)
int PQfformat (const PGresult *res, int field_num)
Oid PQftype (const PGresult *res, int field_num)
int PQfsize (const PGresult *res, int field_num)
int PQfmod (const PGresult *res, int field_num)
char * PQcmdStatus (PGresult *res)
char * PQoidStatus (const PGresult *res)
Oid PQoidValue (const PGresult *res)
char * PQcmdTuples (PGresult *res)
char * PQgetvalue (const PGresult *res, int tup_num, int field_num)
int PQgetlength (const PGresult *res, int tup_num, int field_num)
int PQgetisnull (const PGresult *res, int tup_num, int field_num)
int PQnparams (const PGresult *res)
Oid PQparamtype (const PGresult *res, int param_num)
PGresultPQdescribePrepared (PGconn *conn, const char *stmt)
PGresultPQdescribePortal (PGconn *conn, const char *portal)
int PQsendDescribePrepared (PGconn *conn, const char *stmt)
int PQsendDescribePortal (PGconn *conn, const char *portal)
void PQclear (PGresult *res)
void PQfreemem (void *ptr)
PGresultPQmakeEmptyPGresult (PGconn *conn, ExecStatusType status)
PGresultPQcopyResult (const PGresult *src, int flags)
int PQsetResultAttrs (PGresult *res, int numAttributes, PGresAttDesc *attDescs)
void * PQresultAlloc (PGresult *res, size_t nBytes)
int PQsetvalue (PGresult *res, int tup_num, int field_num, char *value, int len)
size_t PQescapeStringConn (PGconn *conn, char *to, const char *from, size_t length, int *error)
char * PQescapeLiteral (PGconn *conn, const char *str, size_t len)
char * PQescapeIdentifier (PGconn *conn, const char *str, size_t len)
unsigned char * PQescapeByteaConn (PGconn *conn, const unsigned char *from, size_t from_length, size_t *to_length)
unsigned char * PQunescapeBytea (const unsigned char *strtext, size_t *retbuflen)
size_t PQescapeString (char *to, const char *from, size_t length)
unsigned char * PQescapeBytea (const unsigned char *from, size_t from_length, size_t *to_length)
void PQprint (FILE *fout, const PGresult *res, const PQprintOpt *ps)
void PQdisplayTuples (const PGresult *res, FILE *fp, int fillAlign, const char *fieldSep, int printHeader, int quiet)
void PQprintTuples (const PGresult *res, FILE *fout, int printAttName, int terseOutput, int width)
int lo_open (PGconn *conn, Oid lobjId, int mode)
int lo_close (PGconn *conn, int fd)
int lo_read (PGconn *conn, int fd, char *buf, size_t len)
int lo_write (PGconn *conn, int fd, const char *buf, size_t len)
int lo_lseek (PGconn *conn, int fd, int offset, int whence)
pg_int64 lo_lseek64 (PGconn *conn, int fd, pg_int64 offset, int whence)
Oid lo_creat (PGconn *conn, int mode)
Oid lo_create (PGconn *conn, Oid lobjId)
int lo_tell (PGconn *conn, int fd)
pg_int64 lo_tell64 (PGconn *conn, int fd)
int lo_truncate (PGconn *conn, int fd, size_t len)
int lo_truncate64 (PGconn *conn, int fd, pg_int64 len)
int lo_unlink (PGconn *conn, Oid lobjId)
Oid lo_import (PGconn *conn, const char *filename)
Oid lo_import_with_oid (PGconn *conn, const char *filename, Oid lobjId)
int lo_export (PGconn *conn, Oid lobjId, const char *filename)
int PQlibVersion (void)
int PQmblen (const char *s, int encoding)
int PQdsplen (const char *s, int encoding)
int PQenv2encoding (void)
char * PQencryptPassword (const char *passwd, const char *user)
int pg_char_to_encoding (const char *name)
const char * pg_encoding_to_char (int encoding)
int pg_valid_server_encoding_id (int encoding)

Define Documentation

#define PG_COPYRES_ATTRS   0x01

Definition at line 34 of file libpq-fe.h.

Referenced by PQcopyResult(), and pqRowProcessor().

#define PG_COPYRES_EVENTS   0x04

Definition at line 36 of file libpq-fe.h.

Referenced by PQcopyResult(), and pqRowProcessor().

#define PG_COPYRES_NOTICEHOOKS   0x08

Definition at line 37 of file libpq-fe.h.

Referenced by PQcopyResult(), and pqRowProcessor().

#define PG_COPYRES_TUPLES   0x02

Definition at line 35 of file libpq-fe.h.

Referenced by PQcopyResult().

#define PQfreeNotify (   ptr  )     PQfreemem(ptr)

Definition at line 484 of file libpq-fe.h.

#define PQnoPasswordSupplied   "fe_sendauth: no password supplied\n"

Definition at line 488 of file libpq-fe.h.

Referenced by pg_fe_sendauth().

#define PQsetdb (   M_PGHOST,
  M_PGPORT,
  M_PGOPT,
  M_PGTTY,
  M_DBNAME 
)    PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)

Definition at line 258 of file libpq-fe.h.

Referenced by main().


Typedef Documentation

typedef struct pg_cancel PGcancel

Definition at line 142 of file libpq-fe.h.

typedef struct pg_conn PGconn

Definition at line 129 of file libpq-fe.h.

typedef struct pgNotify PGnotify
typedef struct pgresAttDesc PGresAttDesc
typedef struct pg_result PGresult

Definition at line 136 of file libpq-fe.h.

typedef void(* pgthreadlock_t)(int acquire)

Definition at line 353 of file libpq-fe.h.

typedef char pqbool

Definition at line 164 of file libpq-fe.h.

typedef void(* PQnoticeProcessor)(void *arg, const char *message)

Definition at line 161 of file libpq-fe.h.

typedef void(* PQnoticeReceiver)(void *arg, const PGresult *res)

Definition at line 160 of file libpq-fe.h.

typedef struct _PQprintOpt PQprintOpt

Enumeration Type Documentation

Enumerator:
CONNECTION_OK 
CONNECTION_BAD 
CONNECTION_STARTED 
CONNECTION_MADE 
CONNECTION_AWAITING_RESPONSE 
CONNECTION_AUTH_OK 
CONNECTION_SETENV 
CONNECTION_SSL_STARTUP 
CONNECTION_NEEDED 

Definition at line 47 of file libpq-fe.h.

{
    CONNECTION_OK,
    CONNECTION_BAD,
    /* Non-blocking mode only below here */

    /*
     * The existence of these should never be relied upon - they should only
     * be used for user feedback or similar purposes.
     */
    CONNECTION_STARTED,         /* Waiting for connection to be made.  */
    CONNECTION_MADE,            /* Connection OK; waiting to send.     */
    CONNECTION_AWAITING_RESPONSE,       /* Waiting for a response from the
                                         * postmaster.        */
    CONNECTION_AUTH_OK,         /* Received authentication; waiting for
                                 * backend startup. */
    CONNECTION_SETENV,          /* Negotiating environment. */
    CONNECTION_SSL_STARTUP,     /* Negotiating SSL. */
    CONNECTION_NEEDED           /* Internal state: connect() needed */
} ConnStatusType;

Enumerator:
PGRES_EMPTY_QUERY 
PGRES_COMMAND_OK 
PGRES_TUPLES_OK 
PGRES_COPY_OUT 
PGRES_COPY_IN 
PGRES_BAD_RESPONSE 
PGRES_NONFATAL_ERROR 
PGRES_FATAL_ERROR 
PGRES_COPY_BOTH 
PGRES_SINGLE_TUPLE 

Definition at line 78 of file libpq-fe.h.

{
    PGRES_EMPTY_QUERY = 0,      /* empty query string was executed */
    PGRES_COMMAND_OK,           /* a query command that doesn't return
                                 * anything was executed properly by the
                                 * backend */
    PGRES_TUPLES_OK,            /* a query command that returns tuples was
                                 * executed properly by the backend, PGresult
                                 * contains the result tuples */
    PGRES_COPY_OUT,             /* Copy Out data transfer in progress */
    PGRES_COPY_IN,              /* Copy In data transfer in progress */
    PGRES_BAD_RESPONSE,         /* an unexpected response was recv'd from the
                                 * backend */
    PGRES_NONFATAL_ERROR,       /* notice or warning message */
    PGRES_FATAL_ERROR,          /* query failed */
    PGRES_COPY_BOTH,            /* Copy In/Out data transfer in progress */
    PGRES_SINGLE_TUPLE          /* single tuple from larger resultset */
} ExecStatusType;

enum PGPing
Enumerator:
PQPING_OK 
PQPING_REJECT 
PQPING_NO_RESPONSE 
PQPING_NO_ATTEMPT 

Definition at line 118 of file libpq-fe.h.

{
    PQPING_OK,                  /* server is accepting connections */
    PQPING_REJECT,              /* server is alive but rejecting connections */
    PQPING_NO_RESPONSE,         /* could not establish connection */
    PQPING_NO_ATTEMPT           /* connection not attempted (bad params) */
} PGPing;

Enumerator:
PQTRANS_IDLE 
PQTRANS_ACTIVE 
PQTRANS_INTRANS 
PQTRANS_INERROR 
PQTRANS_UNKNOWN 

Definition at line 97 of file libpq-fe.h.

{
    PQTRANS_IDLE,               /* connection idle */
    PQTRANS_ACTIVE,             /* command in progress */
    PQTRANS_INTRANS,            /* idle, within transaction block */
    PQTRANS_INERROR,            /* idle, within failed transaction */
    PQTRANS_UNKNOWN             /* cannot determine status */
} PGTransactionStatusType;

Enumerator:
PQERRORS_TERSE 
PQERRORS_DEFAULT 
PQERRORS_VERBOSE 

Definition at line 106 of file libpq-fe.h.

{
    PQERRORS_TERSE,             /* single-line error messages */
    PQERRORS_DEFAULT,           /* recommended style */
    PQERRORS_VERBOSE            /* all the facts, ma'am */
} PGVerbosity;

Enumerator:
PGRES_POLLING_FAILED 
PGRES_POLLING_READING 
PGRES_POLLING_WRITING 
PGRES_POLLING_OK 
PGRES_POLLING_ACTIVE 

Definition at line 68 of file libpq-fe.h.

{
    PGRES_POLLING_FAILED = 0,
    PGRES_POLLING_READING,      /* These two indicate that one may    */
    PGRES_POLLING_WRITING,      /* use select before polling again.   */
    PGRES_POLLING_OK,
    PGRES_POLLING_ACTIVE        /* unused; keep for awhile for backwards
                                 * compatibility */
} PostgresPollingStatusType;


Function Documentation

int lo_close ( PGconn conn,
int  fd 
)

Definition at line 100 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_close, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

{
    PQArgBlock  argv[1];
    PGresult   *res;
    int         retval;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;
    res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
               &retval, &result_len, 1, argv, 1);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return retval;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

Oid lo_creat ( PGconn conn,
int  mode 
)

Definition at line 466 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_creat, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

{
    PQArgBlock  argv[1];
    PGresult   *res;
    int         retval;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return InvalidOid;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = mode;
    res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
               &retval, &result_len, 1, argv, 1);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return (Oid) retval;
    }
    else
    {
        PQclear(res);
        return InvalidOid;
    }
}

Oid lo_create ( PGconn conn,
Oid  lobjId 
)

Definition at line 505 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_create, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

{
    PQArgBlock  argv[1];
    PGresult   *res;
    int         retval;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return InvalidOid;
    }

    /* Must check this on-the-fly because it's not there pre-8.1 */
    if (conn->lobjfuncs->fn_lo_create == 0)
    {
        printfPQExpBuffer(&conn->errorMessage,
              libpq_gettext("cannot determine OID of function lo_create\n"));
        return InvalidOid;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = lobjId;
    res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
               &retval, &result_len, 1, argv, 1);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return (Oid) retval;
    }
    else
    {
        PQclear(res);
        return InvalidOid;
    }
}

int lo_export ( PGconn conn,
Oid  lobjId,
const char *  filename 
)

Definition at line 785 of file fe-lobj.c.

References buf, close, pg_conn::errorMessage, INV_READ, libpq_gettext, LO_BUFSIZE, lo_close(), lo_open(), lo_read(), PG_BINARY, pqStrerror(), printfPQExpBuffer(), and write.

{
    int         result = 1;
    int         fd;
    int         nbytes,
                tmp;
    char        buf[LO_BUFSIZE];
    int         lobj;
    char        sebuf[256];

    /*
     * open the large object.
     */
    lobj = lo_open(conn, lobjId, INV_READ);
    if (lobj == -1)
    {
        /* we assume lo_open() already set a suitable error message */
        return -1;
    }

    /*
     * create the file to be written to
     */
    fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
    if (fd < 0)
    {
        /* We must do lo_close before setting the errorMessage */
        int         save_errno = errno;

        (void) lo_close(conn, lobj);
        printfPQExpBuffer(&conn->errorMessage,
                          libpq_gettext("could not open file \"%s\": %s\n"),
                          filename,
                          pqStrerror(save_errno, sebuf, sizeof(sebuf)));
        return -1;
    }

    /*
     * read in from the large object and write to the file
     */
    while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
    {
        tmp = write(fd, buf, nbytes);
        if (tmp != nbytes)
        {
            /* We must do lo_close before setting the errorMessage */
            int         save_errno = errno;

            (void) lo_close(conn, lobj);
            (void) close(fd);
            printfPQExpBuffer(&conn->errorMessage,
                       libpq_gettext("could not write to file \"%s\": %s\n"),
                              filename,
                              pqStrerror(save_errno, sebuf, sizeof(sebuf)));
            return -1;
        }
    }

    /*
     * If lo_read() failed, we are now in an aborted transaction so there's no
     * need for lo_close(); furthermore, if we tried it we'd overwrite the
     * useful error result with a useless one. So skip lo_close() if we got a
     * failure result.
     */
    if (nbytes < 0 ||
        lo_close(conn, lobj) != 0)
    {
        /* assume lo_read() or lo_close() left a suitable error message */
        result = -1;
    }

    /* if we already failed, don't overwrite that msg with a close error */
    if (close(fd) && result >= 0)
    {
        printfPQExpBuffer(&conn->errorMessage,
                       libpq_gettext("could not write to file \"%s\": %s\n"),
                          filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
        result = -1;
    }

    return result;
}

Oid lo_import ( PGconn conn,
const char *  filename 
)

Definition at line 669 of file fe-lobj.c.

References InvalidOid, and lo_import_internal().

Oid lo_import_with_oid ( PGconn conn,
const char *  filename,
Oid  lobjId 
)

Definition at line 684 of file fe-lobj.c.

References lo_import_internal().

{
    return lo_import_internal(conn, filename, lobjId);
}

int lo_lseek ( PGconn conn,
int  fd,
int  offset,
int  whence 
)

Definition at line 366 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_lseek, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

{
    PQArgBlock  argv[3];
    PGresult   *res;
    int         retval;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    argv[1].isint = 1;
    argv[1].len = 4;
    argv[1].u.integer = offset;

    argv[2].isint = 1;
    argv[2].len = 4;
    argv[2].u.integer = whence;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
               &retval, &result_len, 1, argv, 3);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return retval;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

pg_int64 lo_lseek64 ( PGconn conn,
int  fd,
pg_int64  offset,
int  whence 
)

Definition at line 410 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_lseek64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_hton64(), lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

{
    PQArgBlock  argv[3];
    PGresult   *res;
    pg_int64    retval;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    if (conn->lobjfuncs->fn_lo_lseek64 == 0)
    {
        printfPQExpBuffer(&conn->errorMessage,
             libpq_gettext("cannot determine OID of function lo_lseek64\n"));
        return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    offset = lo_hton64(offset);
    argv[1].isint = 0;
    argv[1].len = 8;
    argv[1].u.ptr = (int *) &offset;

    argv[2].isint = 1;
    argv[2].len = 4;
    argv[2].u.integer = whence;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
               (int *) &retval, &result_len, 0, argv, 3);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return lo_ntoh64(retval);
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int lo_open ( PGconn conn,
Oid  lobjId,
int  mode 
)

Definition at line 58 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_open, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

{
    int         fd;
    int         result_len;
    PQArgBlock  argv[2];
    PGresult   *res;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = lobjId;

    argv[1].isint = 1;
    argv[1].len = 4;
    argv[1].u.integer = mode;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return fd;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int lo_read ( PGconn conn,
int  fd,
char *  buf,
size_t  len 
)

Definition at line 259 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_read, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

{
    PQArgBlock  argv[2];
    PGresult   *res;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    /*
     * Long ago, somebody thought it'd be a good idea to declare this function
     * as taking size_t ... but the underlying backend function only accepts a
     * signed int32 length.  So throw error if the given value overflows
     * int32.
     */
    if (len > (size_t) INT_MAX)
    {
        printfPQExpBuffer(&conn->errorMessage,
               libpq_gettext("argument of lo_read exceeds integer range\n"));
        return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    argv[1].isint = 1;
    argv[1].len = 4;
    argv[1].u.integer = (int) len;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
               (int *) buf, &result_len, 0, argv, 2);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return result_len;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int lo_tell ( PGconn conn,
int  fd 
)

Definition at line 549 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_tell, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

{
    int         retval;
    PQArgBlock  argv[1];
    PGresult   *res;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
               &retval, &result_len, 1, argv, 1);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return retval;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

pg_int64 lo_tell64 ( PGconn conn,
int  fd 
)

Definition at line 585 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_tell64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

{
    pg_int64    retval;
    PQArgBlock  argv[1];
    PGresult   *res;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    if (conn->lobjfuncs->fn_lo_tell64 == 0)
    {
        printfPQExpBuffer(&conn->errorMessage,
              libpq_gettext("cannot determine OID of function lo_tell64\n"));
        return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
               (int *) &retval, &result_len, 0, argv, 1);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return lo_ntoh64(retval);
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int lo_truncate ( PGconn conn,
int  fd,
size_t  len 
)

Definition at line 138 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_truncate, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

{
    PQArgBlock  argv[2];
    PGresult   *res;
    int         retval;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    /* Must check this on-the-fly because it's not there pre-8.3 */
    if (conn->lobjfuncs->fn_lo_truncate == 0)
    {
        printfPQExpBuffer(&conn->errorMessage,
            libpq_gettext("cannot determine OID of function lo_truncate\n"));
        return -1;
    }

    /*
     * Long ago, somebody thought it'd be a good idea to declare this function
     * as taking size_t ... but the underlying backend function only accepts a
     * signed int32 length.  So throw error if the given value overflows
     * int32.  (A possible alternative is to automatically redirect the call
     * to lo_truncate64; but if the caller wanted to rely on that backend
     * function being available, he could have called lo_truncate64 for
     * himself.)
     */
    if (len > (size_t) INT_MAX)
    {
        printfPQExpBuffer(&conn->errorMessage,
           libpq_gettext("argument of lo_truncate exceeds integer range\n"));
        return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    argv[1].isint = 1;
    argv[1].len = 4;
    argv[1].u.integer = (int) len;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
               &retval, &result_len, 1, argv, 2);

    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return retval;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int lo_truncate64 ( PGconn conn,
int  fd,
pg_int64  len 
)

Definition at line 206 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_truncate64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_hton64(), lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

{
    PQArgBlock  argv[2];
    PGresult   *res;
    int         retval;
    int         result_len;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    if (conn->lobjfuncs->fn_lo_truncate64 == 0)
    {
        printfPQExpBuffer(&conn->errorMessage,
          libpq_gettext("cannot determine OID of function lo_truncate64\n"));
        return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    len = lo_hton64(len);
    argv[1].isint = 0;
    argv[1].len = 8;
    argv[1].u.ptr = (int *) &len;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
               &retval, &result_len, 1, argv, 2);

    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return retval;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int lo_unlink ( PGconn conn,
Oid  lobjId 
)

Definition at line 629 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_unlink, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

{
    PQArgBlock  argv[1];
    PGresult   *res;
    int         result_len;
    int         retval;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = lobjId;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
               &retval, &result_len, 1, argv, 1);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return retval;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int lo_write ( PGconn conn,
int  fd,
const char *  buf,
size_t  len 
)

Definition at line 313 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_write, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, NULL, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

{
    PQArgBlock  argv[2];
    PGresult   *res;
    int         result_len;
    int         retval;

    if (conn == NULL || conn->lobjfuncs == NULL)
    {
        if (lo_initialize(conn) < 0)
            return -1;
    }

    /*
     * Long ago, somebody thought it'd be a good idea to declare this function
     * as taking size_t ... but the underlying backend function only accepts a
     * signed int32 length.  So throw error if the given value overflows
     * int32.
     */
    if (len > (size_t) INT_MAX)
    {
        printfPQExpBuffer(&conn->errorMessage,
              libpq_gettext("argument of lo_write exceeds integer range\n"));
        return -1;
    }

    argv[0].isint = 1;
    argv[0].len = 4;
    argv[0].u.integer = fd;

    argv[1].isint = 0;
    argv[1].len = (int) len;
    argv[1].u.ptr = (int *) buf;

    res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
               &retval, &result_len, 1, argv, 2);
    if (PQresultStatus(res) == PGRES_COMMAND_OK)
    {
        PQclear(res);
        return retval;
    }
    else
    {
        PQclear(res);
        return -1;
    }
}

int pg_char_to_encoding ( const char *  name  ) 
const char* pg_encoding_to_char ( int  encoding  ) 
int pg_valid_server_encoding_id ( int  encoding  ) 

Definition at line 429 of file encnames.c.

References PG_VALID_BE_ENCODING.

Referenced by setup_locale_encoding().

int PQbackendPID ( const PGconn conn  ) 

Definition at line 5283 of file fe-connect.c.

References pg_conn::be_pid, CONNECTION_OK, and pg_conn::status.

{
    if (!conn || conn->status != CONNECTION_OK)
        return 0;
    return conn->be_pid;
}

int PQbinaryTuples ( const PGresult res  ) 

Definition at line 2609 of file fe-exec.c.

References pg_result::binary.

Referenced by ProcessResult().

{
    if (!res)
        return 0;
    return res->binary;
}

int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

Definition at line 3238 of file fe-connect.c.

References pg_cancel::be_key, pg_cancel::be_pid, internal_cancel(), pg_cancel::raddr, and strlcpy().

Referenced by dblink_cancel_query(), DisconnectDatabase(), handle_sigint(), and run_permutation().

{
    if (!cancel)
    {
        strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
        return FALSE;
    }

    return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
                           errbuf, errbufsize);
}

void PQclear ( PGresult res  ) 

Definition at line 648 of file fe-exec.c.

References pg_result::attDescs, pg_result::curBlock, pg_result::errFields, pg_result::events, free, i, PGEvent::name, pg_result::nEvents, pgresult_data::next, NULL, pg_result::paramDescs, PGEvent::passThrough, PGEVT_RESULTDESTROY, PGEvent::proc, PGEventResultDestroy::result, PGEvent::resultInitialized, and pg_result::tuples.

Referenced by _doSetSessionAuth(), _doSetWithOids(), _selectOutputSchema(), _selectTablespace(), add_tablespace_footer(), BaseBackup(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel_oid(), binary_upgrade_set_type_oids_by_type_oid(), buildMatViewRefreshDependencies(), buildShSecLabels(), check_for_isn_and_int8_passing_mismatch(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_is_super_user(), check_loadable_libraries(), close_cursor(), cluster_all_databases(), convertTSFunction(), create_cursor(), createViewAsClause(), dblink_close(), dblink_exec(), dblink_fetch(), dblink_open(), dblink_res_error(), deallocate_one(), describeAggregates(), describeFunctions(), describeOneTableDetails(), describeOneTSConfig(), describeOneTSParser(), describeOperators(), describeRoles(), describeTableDetails(), describeTablespaces(), describeTypes(), descriptor_free(), discard_response(), do_lo_import(), do_lo_list(), do_sql_command(), do_watch(), doCustom(), dropDBs(), dropRoles(), dropTablespaces(), dumpAgg(), dumpBaseType(), dumpBlobs(), dumpCollation(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConversion(), dumpCreateDB(), dumpDatabase(), dumpDatabaseConfig(), dumpDatabases(), dumpDbRoleConfig(), dumpDomain(), dumpEnumType(), dumpFunc(), dumpGroups(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpRangeType(), dumpRoleMembership(), dumpRoles(), dumpRule(), dumpSequence(), dumpSequenceData(), dumpTable(), dumpTableData_copy(), dumpTableData_insert(), dumpTableSchema(), dumpTablespaces(), dumpTSConfig(), dumpTSDictionary(), dumpUserConfig(), dumpUserMappings(), ecpg_check_PQresult(), ecpg_execute(), ecpg_is_type_an_array(), ECPGdescribe(), ECPGsetcommit(), ECPGtrans(), EndDBCopyMode(), exec_command(), ExecQueryUsingCursor(), executeCommand(), executeMaintenanceCommand(), executeQueryOrDie(), ExecuteSqlCommand(), ExecuteSqlStatement(), executeStatement(), expand_schema_name_patterns(), expand_table_name_patterns(), fail_lo_xact(), fetch_more_data(), findLastBuiltinOid_V70(), findLastBuiltinOid_V71(), finish_lo_xact(), get_create_function_cmd(), get_db_infos(), get_loadable_libraries(), get_pg_database_relfilenode(), get_rel_infos(), get_remote_estimate(), get_synchronized_snapshot(), get_tablespace_paths(), getAggregates(), getBlobs(), getCasts(), getCollations(), getConstraints(), getConversions(), getCopyStart(), getDefaultACLs(), getDependencies(), getDomainConstraints(), getEventTriggers(), getExtensionMembership(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFormattedTypeName(), getFuncs(), getIndexes(), getInherits(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getParamDescriptions(), getProcLangs(), getRowDescriptions(), getRules(), getTableAttrs(), getTables(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), handleCopyIn(), handleCopyOut(), init(), install_support_functions_in_new_db(), libpqrcv_endstreaming(), libpqrcv_identify_system(), libpqrcv_PQexec(), libpqrcv_readtimelinehistoryfile(), libpqrcv_receive(), libpqrcv_startstreaming(), listAllDbs(), listCasts(), listCollations(), listConversions(), listDbRoleSettings(), listDefaultACLs(), listDomains(), listEventTriggers(), listExtensionContents(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listLanguages(), listOneExtensionContents(), listSchemas(), listTables(), listTSConfigs(), listTSConfigsVerbose(), listTSDictionaries(), listTSParsers(), listTSParsersVerbose(), listTSTemplates(), listUserMappings(), lo_close(), lo_creat(), lo_create(), lo_initialize(), lo_lseek(), lo_lseek64(), lo_open(), lo_read(), lo_tell(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_unlink(), lo_write(), lockTableNoWait(), lookup_function_oid(), main(), materializeQueryResult(), materializeResult(), new_9_0_populate_pg_largeobject_metadata(), objectDescription(), old_8_3_check_for_name_data_type_usage(), old_8_3_check_for_tsquery_usage(), old_8_3_check_ltree_usage(), old_8_3_create_sequence_script(), old_8_3_invalidate_bpchar_pattern_ops_indexes(), old_8_3_invalidate_hash_gin_indexes(), old_8_3_rebuild_tsvector_tables(), permissionsList(), pgfdw_report_error(), pgfdw_subxact_callback(), pgfdw_xact_callback(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresEndForeignModify(), postgresExecForeignDelete(), postgresExecForeignInsert(), postgresExecForeignUpdate(), postgresReScanForeignScan(), pqClearAsyncResult(), PQconnectPoll(), PQcopyResult(), pqEndcopy2(), pqEndcopy3(), PQexecFinish(), PQexecStart(), pqGetErrorNotice2(), pqGetErrorNotice3(), pqInternalNotice(), PQmakeEmptyPGresult(), pqRowProcessor(), PQsetClientEncoding(), pqSetenvPoll(), prepare_common(), prepare_foreign_modify(), process_file(), ProcessResult(), PSQLexec(), ReceiveXlogStream(), reindex_all_databases(), run_permutation(), SendQuery(), set_frozenxids(), set_locale_and_encoding(), sql_exec(), start_lo_xact(), store_returning_result(), storeQueryResult(), StreamLog(), try_complete_step(), uninstall_support_functions_from_new_cluster(), vacuum_all_databases(), and vacuumlo().

{
    PGresult_data *block;
    int         i;

    if (!res)
        return;

    for (i = 0; i < res->nEvents; i++)
    {
        /* only send DESTROY to successfully-initialized event procs */
        if (res->events[i].resultInitialized)
        {
            PGEventResultDestroy evt;

            evt.result = res;
            (void) res->events[i].proc(PGEVT_RESULTDESTROY, &evt,
                                       res->events[i].passThrough);
        }
        free(res->events[i].name);
    }

    if (res->events)
        free(res->events);

    /* Free all the subsidiary blocks */
    while ((block = res->curBlock) != NULL)
    {
        res->curBlock = block->next;
        free(block);
    }

    /* Free the top-level tuple pointer array */
    if (res->tuples)
        free(res->tuples);

    /* zero out the pointer fields to catch programming errors */
    res->attDescs = NULL;
    res->tuples = NULL;
    res->paramDescs = NULL;
    res->errFields = NULL;
    res->events = NULL;
    res->nEvents = 0;
    /* res->curBlock was zeroed out earlier */

    /* Free the PGresult structure itself */
    free(res);
}

int PQclientEncoding ( const PGconn conn  ) 
char* PQcmdStatus ( PGresult res  ) 

Definition at line 2841 of file fe-exec.c.

References pg_result::cmdStatus.

Referenced by dblink_exec(), ecpg_execute(), materializeQueryResult(), materializeResult(), PrintQueryResults(), PrintQueryStatus(), and SendQuery().

{
    if (!res)
        return NULL;
    return res->cmdStatus;
}

char* PQcmdTuples ( PGresult res  ) 

Definition at line 2912 of file fe-exec.c.

References pg_result::cmdStatus, pg_result::noticeHooks, and pqInternalNotice().

Referenced by ecpg_execute(), postgresExecForeignDelete(), postgresExecForeignInsert(), and postgresExecForeignUpdate().

{
    char       *p,
               *c;

    if (!res)
        return "";

    if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
    {
        p = res->cmdStatus + 7;
        /* INSERT: skip oid and space */
        while (*p && *p != ' ')
            p++;
        if (*p == 0)
            goto interpret_error;       /* no space? */
        p++;
    }
    else if (strncmp(res->cmdStatus, "SELECT ", 7) == 0 ||
             strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
             strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
        p = res->cmdStatus + 7;
    else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)
        p = res->cmdStatus + 6;
    else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0 ||
             strncmp(res->cmdStatus, "COPY ", 5) == 0)
        p = res->cmdStatus + 5;
    else
        return "";

    /* check that we have an integer (at least one digit, nothing else) */
    for (c = p; *c; c++)
    {
        if (!isdigit((unsigned char) *c))
            goto interpret_error;
    }
    if (c == p)
        goto interpret_error;

    return p;

interpret_error:
    pqInternalNotice(&res->noticeHooks,
                     "could not interpret result from server: %s",
                     res->cmdStatus);
    return "";
}

PQconninfoOption* PQconndefaults ( void   ) 

Definition at line 865 of file fe-connect.c.

References conninfo_add_defaults(), conninfo_init(), initPQExpBuffer(), NULL, PQconninfoFree(), PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by check_pghost_envvar(), dblink_fdw_validator(), InitPgFdwOptions(), and main().

{
    PQExpBufferData errorBuf;
    PQconninfoOption *connOptions;

    /* We don't actually report any errors here, but callees want a buffer */
    initPQExpBuffer(&errorBuf);
    if (PQExpBufferDataBroken(errorBuf))
        return NULL;            /* out of memory already :-( */

    connOptions = conninfo_init(&errorBuf);
    if (connOptions != NULL)
    {
        if (!conninfo_add_defaults(connOptions, &errorBuf))
        {
            PQconninfoFree(connOptions);
            connOptions = NULL;
        }
    }

    termPQExpBuffer(&errorBuf);
    return connOptions;
}

PGconn* PQconnectdb ( const char *  conninfo  ) 

Definition at line 511 of file fe-connect.c.

References conn, connectDBComplete(), CONNECTION_BAD, PQconnectStart(), and pg_conn::status.

Referenced by dblink_connect(), get_db_conn(), libpqrcv_connect(), and main().

{
    PGconn     *conn = PQconnectStart(conninfo);

    if (conn && conn->status != CONNECTION_BAD)
        (void) connectDBComplete(conn);

    return conn;
}

PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)
int PQconnectionNeedsPassword ( const PGconn conn  ) 

Definition at line 5291 of file fe-connect.c.

References NULL, pg_conn::password_needed, and pg_conn::pgpass.

Referenced by _connectDB(), ConnectDatabase(), connectDatabase(), do_connect(), doConnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

{
    if (!conn)
        return false;
    if (conn->password_needed &&
        (conn->pgpass == NULL || conn->pgpass[0] == '\0'))
        return true;
    else
        return false;
}

int PQconnectionUsedPassword ( const PGconn conn  ) 

Definition at line 5303 of file fe-connect.c.

References pg_conn::password_needed.

Referenced by connect_pg_server(), and dblink_security_check().

{
    if (!conn)
        return false;
    if (conn->password_needed)
        return true;
    else
        return false;
}

PostgresPollingStatusType PQconnectPoll ( PGconn conn  ) 

Definition at line 1553 of file fe-connect.c.

References SockAddr::addr, pg_conn::addr_cur, pg_conn::addrlist, pg_conn::addrlist_family, addrinfo::ai_addr, addrinfo::ai_addrlen, addrinfo::ai_family, addrinfo::ai_next, appendPQExpBuffer(), appendPQExpBufferChar(), pg_conn::appname, pg_conn::asyncStatus, AUTH_REQ_GSS_CONT, AUTH_REQ_MD5, AUTH_REQ_OK, pg_conn::auth_req_received, connect, connectFailureMessage(), CONNECTION_AUTH_OK, CONNECTION_AWAITING_RESPONSE, CONNECTION_BAD, CONNECTION_MADE, CONNECTION_NEEDED, CONNECTION_OK, CONNECTION_SETENV, CONNECTION_SSL_STARTUP, CONNECTION_STARTED, connectNoDelay(), PQExpBufferData::data, dot_pg_pass_warning(), EINPROGRESS, EINTR, ERRCODE_APPNAME_UNKNOWN, pg_conn::errorMessage, EWOULDBLOCK, pg_conn::fbappname, free, getpeereid(), pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, IS_AF_UNIX, pg_conn::laddr, PQExpBufferData::len, libpq_gettext, malloc, pg_conn::md5Salt, NEGOTIATE_SSL_CODE, pg_conn::next_eo, NULL, PG_DIAG_SQLSTATE, pg_fe_sendauth(), pg_freeaddrinfo_all(), PG_PROTOCOL, PG_PROTOCOL_MAJOR, pg_set_noblock(), PGRES_FATAL_ERROR, PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, pqBuildStartupPacket2(), pqBuildStartupPacket3(), pqCheckInBufferSpace(), PQclear(), pqDropConnection(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), pqGetpwuid(), PQgetResult(), pqGets_append(), PQisBusy(), pqPacketSend(), pqReadData(), PQresultErrorField(), pqsecure_initialize(), pqsecure_open_client(), pqSetenvPoll(), pqStrerror(), printfPQExpBuffer(), pg_conn::pversion, pg_conn::raddr, pg_conn::requirepeer, pg_result::resultStatus, SockAddr::salen, pg_conn::send_appname, pg_conn::setenv_state, setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), pg_conn::sigpipe_flag, pg_conn::sigpipe_so, pg_conn::sock, SOCK_ERRNO, SOCK_STRERROR, socket, pg_conn::sslmode, pg_conn::status, STATUS_OK, and useKeepalives().

Referenced by connectDBComplete(), connectDBStart(), and PQresetPoll().

{
    PGresult   *res;
    char        sebuf[256];
    int         optval;

    if (conn == NULL)
        return PGRES_POLLING_FAILED;

    /* Get the new data */
    switch (conn->status)
    {
            /*
             * We really shouldn't have been polled in these two cases, but we
             * can handle it.
             */
        case CONNECTION_BAD:
            return PGRES_POLLING_FAILED;
        case CONNECTION_OK:
            return PGRES_POLLING_OK;

            /* These are reading states */
        case CONNECTION_AWAITING_RESPONSE:
        case CONNECTION_AUTH_OK:
            {
                /* Load waiting data */
                int         n = pqReadData(conn);

                if (n < 0)
                    goto error_return;
                if (n == 0)
                    return PGRES_POLLING_READING;

                break;
            }

            /* These are writing states, so we just proceed. */
        case CONNECTION_STARTED:
        case CONNECTION_MADE:
            break;

            /* We allow pqSetenvPoll to decide whether to proceed. */
        case CONNECTION_SETENV:
            break;

            /* Special cases: proceed without waiting. */
        case CONNECTION_SSL_STARTUP:
        case CONNECTION_NEEDED:
            break;

        default:
            appendPQExpBuffer(&conn->errorMessage,
                              libpq_gettext(
                                            "invalid connection state, "
                                 "probably indicative of memory corruption\n"
                                            ));
            goto error_return;
    }


keep_going:                     /* We will come back to here until there is
                                 * nothing left to do. */
    switch (conn->status)
    {
        case CONNECTION_NEEDED:
            {
                /*
                 * Try to initiate a connection to one of the addresses
                 * returned by pg_getaddrinfo_all().  conn->addr_cur is the
                 * next one to try. We fail when we run out of addresses.
                 */
                while (conn->addr_cur != NULL)
                {
                    struct addrinfo *addr_cur = conn->addr_cur;

                    /* Remember current address for possible error msg */
                    memcpy(&conn->raddr.addr, addr_cur->ai_addr,
                           addr_cur->ai_addrlen);
                    conn->raddr.salen = addr_cur->ai_addrlen;

                    /* Open a socket */
                    conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
                    if (conn->sock < 0)
                    {
                        /*
                         * ignore socket() failure if we have more addresses
                         * to try
                         */
                        if (addr_cur->ai_next != NULL)
                        {
                            conn->addr_cur = addr_cur->ai_next;
                            continue;
                        }
                        appendPQExpBuffer(&conn->errorMessage,
                              libpq_gettext("could not create socket: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                        break;
                    }

                    /*
                     * Select socket options: no delay of outgoing data for
                     * TCP sockets, nonblock mode, close-on-exec. Fail if any
                     * of this fails.
                     */
                    if (!IS_AF_UNIX(addr_cur->ai_family))
                    {
                        if (!connectNoDelay(conn))
                        {
                            pqDropConnection(conn);
                            conn->addr_cur = addr_cur->ai_next;
                            continue;
                        }
                    }
                    if (!pg_set_noblock(conn->sock))
                    {
                        appendPQExpBuffer(&conn->errorMessage,
                                          libpq_gettext("could not set socket to nonblocking mode: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                        pqDropConnection(conn);
                        conn->addr_cur = addr_cur->ai_next;
                        continue;
                    }

#ifdef F_SETFD
                    if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
                    {
                        appendPQExpBuffer(&conn->errorMessage,
                                          libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                        pqDropConnection(conn);
                        conn->addr_cur = addr_cur->ai_next;
                        continue;
                    }
#endif   /* F_SETFD */

                    if (!IS_AF_UNIX(addr_cur->ai_family))
                    {
#ifndef WIN32
                        int         on = 1;
#endif
                        int         usekeepalives = useKeepalives(conn);
                        int         err = 0;

                        if (usekeepalives < 0)
                        {
                            appendPQExpBuffer(&conn->errorMessage,
                                              libpq_gettext("keepalives parameter must be an integer\n"));
                            err = 1;
                        }
                        else if (usekeepalives == 0)
                        {
                            /* Do nothing */
                        }
#ifndef WIN32
                        else if (setsockopt(conn->sock,
                                            SOL_SOCKET, SO_KEEPALIVE,
                                            (char *) &on, sizeof(on)) < 0)
                        {
                            appendPQExpBuffer(&conn->errorMessage,
                                              libpq_gettext("setsockopt(SO_KEEPALIVE) failed: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                            err = 1;
                        }
                        else if (!setKeepalivesIdle(conn)
                                 || !setKeepalivesInterval(conn)
                                 || !setKeepalivesCount(conn))
                            err = 1;
#else                           /* WIN32 */
#ifdef SIO_KEEPALIVE_VALS
                        else if (!setKeepalivesWin32(conn))
                            err = 1;
#endif   /* SIO_KEEPALIVE_VALS */
#endif   /* WIN32 */

                        if (err)
                        {
                            pqDropConnection(conn);
                            conn->addr_cur = addr_cur->ai_next;
                            continue;
                        }
                    }

                    /*----------
                     * We have three methods of blocking SIGPIPE during
                     * send() calls to this socket:
                     *
                     *  - setsockopt(sock, SO_NOSIGPIPE)
                     *  - send(sock, ..., MSG_NOSIGNAL)
                     *  - setting the signal mask to SIG_IGN during send()
                     *
                     * The third method requires three syscalls per send,
                     * so we prefer either of the first two, but they are
                     * less portable.  The state is tracked in the following
                     * members of PGconn:
                     *
                     * conn->sigpipe_so     - we have set up SO_NOSIGPIPE
                     * conn->sigpipe_flag   - we're specifying MSG_NOSIGNAL
                     *
                     * If we can use SO_NOSIGPIPE, then set sigpipe_so here
                     * and we're done.  Otherwise, set sigpipe_flag so that
                     * we will try MSG_NOSIGNAL on sends.  If we get an error
                     * with MSG_NOSIGNAL, we'll clear that flag and revert to
                     * signal masking.
                     *----------
                     */
                    conn->sigpipe_so = false;
#ifdef MSG_NOSIGNAL
                    conn->sigpipe_flag = true;
#else
                    conn->sigpipe_flag = false;
#endif   /* MSG_NOSIGNAL */

#ifdef SO_NOSIGPIPE
                    optval = 1;
                    if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
                                   (char *) &optval, sizeof(optval)) == 0)
                    {
                        conn->sigpipe_so = true;
                        conn->sigpipe_flag = false;
                    }
#endif   /* SO_NOSIGPIPE */

                    /*
                     * Start/make connection.  This should not block, since we
                     * are in nonblock mode.  If it does, well, too bad.
                     */
                    if (connect(conn->sock, addr_cur->ai_addr,
                                addr_cur->ai_addrlen) < 0)
                    {
                        if (SOCK_ERRNO == EINPROGRESS ||
                            SOCK_ERRNO == EWOULDBLOCK ||
                            SOCK_ERRNO == EINTR ||
                            SOCK_ERRNO == 0)
                        {
                            /*
                             * This is fine - we're in non-blocking mode, and
                             * the connection is in progress.  Tell caller to
                             * wait for write-ready on socket.
                             */
                            conn->status = CONNECTION_STARTED;
                            return PGRES_POLLING_WRITING;
                        }
                        /* otherwise, trouble */
                    }
                    else
                    {
                        /*
                         * Hm, we're connected already --- seems the "nonblock
                         * connection" wasn't.  Advance the state machine and
                         * go do the next stuff.
                         */
                        conn->status = CONNECTION_STARTED;
                        goto keep_going;
                    }

                    /*
                     * This connection failed --- set up error report, then
                     * close socket (do it this way in case close() affects
                     * the value of errno...).  We will ignore the connect()
                     * failure and keep going if there are more addresses.
                     */
                    connectFailureMessage(conn, SOCK_ERRNO);
                    pqDropConnection(conn);

                    /*
                     * Try the next address, if any.
                     */
                    conn->addr_cur = addr_cur->ai_next;
                }               /* loop over addresses */

                /*
                 * Ooops, no more addresses.  An appropriate error message is
                 * already set up, so just set the right status.
                 */
                goto error_return;
            }

        case CONNECTION_STARTED:
            {
                ACCEPT_TYPE_ARG3 optlen = sizeof(optval);

                /*
                 * Write ready, since we've made it here, so the connection
                 * has been made ... or has failed.
                 */

                /*
                 * Now check (using getsockopt) that there is not an error
                 * state waiting for us on the socket.
                 */

                if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
                               (char *) &optval, &optlen) == -1)
                {
                    appendPQExpBuffer(&conn->errorMessage,
                    libpq_gettext("could not get socket error status: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                    goto error_return;
                }
                else if (optval != 0)
                {
                    /*
                     * When using a nonblocking connect, we will typically see
                     * connect failures at this point, so provide a friendly
                     * error message.
                     */
                    connectFailureMessage(conn, optval);
                    pqDropConnection(conn);

                    /*
                     * If more addresses remain, keep trying, just as in the
                     * case where connect() returned failure immediately.
                     */
                    if (conn->addr_cur->ai_next != NULL)
                    {
                        conn->addr_cur = conn->addr_cur->ai_next;
                        conn->status = CONNECTION_NEEDED;
                        goto keep_going;
                    }
                    goto error_return;
                }

                /* Fill in the client address */
                conn->laddr.salen = sizeof(conn->laddr.addr);
                if (getsockname(conn->sock,
                                (struct sockaddr *) & conn->laddr.addr,
                                &conn->laddr.salen) < 0)
                {
                    appendPQExpBuffer(&conn->errorMessage,
                                      libpq_gettext("could not get client address from socket: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                    goto error_return;
                }

                /*
                 * Make sure we can write before advancing to next step.
                 */
                conn->status = CONNECTION_MADE;
                return PGRES_POLLING_WRITING;
            }

        case CONNECTION_MADE:
            {
                char       *startpacket;
                int         packetlen;

#ifdef HAVE_UNIX_SOCKETS

                /*
                 * Implement requirepeer check, if requested and it's a
                 * Unix-domain socket.
                 */
                if (conn->requirepeer && conn->requirepeer[0] &&
                    IS_AF_UNIX(conn->raddr.addr.ss_family))
                {
                    char        pwdbuf[BUFSIZ];
                    struct passwd pass_buf;
                    struct passwd *pass;
                    uid_t       uid;
                    gid_t       gid;

                    errno = 0;
                    if (getpeereid(conn->sock, &uid, &gid) != 0)
                    {
                        /*
                         * Provide special error message if getpeereid is a
                         * stub
                         */
                        if (errno == ENOSYS)
                            appendPQExpBuffer(&conn->errorMessage,
                                              libpq_gettext("requirepeer parameter is not supported on this platform\n"));
                        else
                            appendPQExpBuffer(&conn->errorMessage,
                                              libpq_gettext("could not get peer credentials: %s\n"),
                                    pqStrerror(errno, sebuf, sizeof(sebuf)));
                        goto error_return;
                    }

                    pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);

                    if (pass == NULL)
                    {
                        appendPQExpBuffer(&conn->errorMessage,
                                          libpq_gettext("local user with ID %d does not exist\n"),
                                          (int) uid);
                        goto error_return;
                    }

                    if (strcmp(pass->pw_name, conn->requirepeer) != 0)
                    {
                        appendPQExpBuffer(&conn->errorMessage,
                                          libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
                                          conn->requirepeer, pass->pw_name);
                        goto error_return;
                    }
                }
#endif   /* HAVE_UNIX_SOCKETS */

#ifdef USE_SSL

                /*
                 * If SSL is enabled and we haven't already got it running,
                 * request it instead of sending the startup message.
                 */
                if (IS_AF_UNIX(conn->raddr.addr.ss_family))
                {
                    /* Don't bother requesting SSL over a Unix socket */
                    conn->allow_ssl_try = false;
                }
                if (conn->allow_ssl_try && !conn->wait_ssl_try &&
                    conn->ssl == NULL)
                {
                    ProtocolVersion pv;

                    /*
                     * Send the SSL request packet.
                     *
                     * Theoretically, this could block, but it really
                     * shouldn't since we only got here if the socket is
                     * write-ready.
                     */
                    pv = htonl(NEGOTIATE_SSL_CODE);
                    if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
                    {
                        appendPQExpBuffer(&conn->errorMessage,
                                          libpq_gettext("could not send SSL negotiation packet: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                        goto error_return;
                    }
                    /* Ok, wait for response */
                    conn->status = CONNECTION_SSL_STARTUP;
                    return PGRES_POLLING_READING;
                }
#endif   /* USE_SSL */

                /*
                 * Build the startup packet.
                 */
                if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
                    startpacket = pqBuildStartupPacket3(conn, &packetlen,
                                                        EnvironmentOptions);
                else
                    startpacket = pqBuildStartupPacket2(conn, &packetlen,
                                                        EnvironmentOptions);
                if (!startpacket)
                {
                    /*
                     * will not appendbuffer here, since it's likely to also
                     * run out of memory
                     */
                    printfPQExpBuffer(&conn->errorMessage,
                                      libpq_gettext("out of memory\n"));
                    goto error_return;
                }

                /*
                 * Send the startup packet.
                 *
                 * Theoretically, this could block, but it really shouldn't
                 * since we only got here if the socket is write-ready.
                 */
                if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
                {
                    appendPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("could not send startup packet: %s\n"),
                            SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
                    free(startpacket);
                    goto error_return;
                }

                free(startpacket);

                conn->status = CONNECTION_AWAITING_RESPONSE;
                return PGRES_POLLING_READING;
            }

            /*
             * Handle SSL negotiation: wait for postmaster messages and
             * respond as necessary.
             */
        case CONNECTION_SSL_STARTUP:
            {
#ifdef USE_SSL
                PostgresPollingStatusType pollres;

                /*
                 * On first time through, get the postmaster's response to our
                 * SSL negotiation packet.
                 */
                if (conn->ssl == NULL)
                {
                    /*
                     * We use pqReadData here since it has the logic to
                     * distinguish no-data-yet from connection closure. Since
                     * conn->ssl isn't set, a plain recv() will occur.
                     */
                    char        SSLok;
                    int         rdresult;

                    rdresult = pqReadData(conn);
                    if (rdresult < 0)
                    {
                        /* errorMessage is already filled in */
                        goto error_return;
                    }
                    if (rdresult == 0)
                    {
                        /* caller failed to wait for data */
                        return PGRES_POLLING_READING;
                    }
                    if (pqGetc(&SSLok, conn) < 0)
                    {
                        /* should not happen really */
                        return PGRES_POLLING_READING;
                    }
                    if (SSLok == 'S')
                    {
                        /* mark byte consumed */
                        conn->inStart = conn->inCursor;
                        /* Set up global SSL state if required */
                        if (pqsecure_initialize(conn) != 0)
                            goto error_return;
                    }
                    else if (SSLok == 'N')
                    {
                        /* mark byte consumed */
                        conn->inStart = conn->inCursor;
                        /* OK to do without SSL? */
                        if (conn->sslmode[0] == 'r' ||  /* "require" */
                            conn->sslmode[0] == 'v')    /* "verify-ca" or
                                                         * "verify-full" */
                        {
                            /* Require SSL, but server does not want it */
                            appendPQExpBuffer(&conn->errorMessage,
                                              libpq_gettext("server does not support SSL, but SSL was required\n"));
                            goto error_return;
                        }
                        /* Otherwise, proceed with normal startup */
                        conn->allow_ssl_try = false;
                        conn->status = CONNECTION_MADE;
                        return PGRES_POLLING_WRITING;
                    }
                    else if (SSLok == 'E')
                    {
                        /*
                         * Server failure of some sort, such as failure to
                         * fork a backend process.  We need to process and
                         * report the error message, which might be formatted
                         * according to either protocol 2 or protocol 3.
                         * Rather than duplicate the code for that, we flip
                         * into AWAITING_RESPONSE state and let the code there
                         * deal with it.  Note we have *not* consumed the "E"
                         * byte here.
                         */
                        conn->status = CONNECTION_AWAITING_RESPONSE;
                        goto keep_going;
                    }
                    else
                    {
                        appendPQExpBuffer(&conn->errorMessage,
                                          libpq_gettext("received invalid response to SSL negotiation: %c\n"),
                                          SSLok);
                        goto error_return;
                    }
                }

                /*
                 * Begin or continue the SSL negotiation process.
                 */
                pollres = pqsecure_open_client(conn);
                if (pollres == PGRES_POLLING_OK)
                {
                    /* SSL handshake done, ready to send startup packet */
                    conn->status = CONNECTION_MADE;
                    return PGRES_POLLING_WRITING;
                }
                if (pollres == PGRES_POLLING_FAILED)
                {
                    /*
                     * Failed ... if sslmode is "prefer" then do a non-SSL
                     * retry
                     */
                    if (conn->sslmode[0] == 'p' /* "prefer" */
                        && conn->allow_ssl_try  /* redundant? */
                        && !conn->wait_ssl_try) /* redundant? */
                    {
                        /* only retry once */
                        conn->allow_ssl_try = false;
                        /* Must drop the old connection */
                        pqDropConnection(conn);
                        conn->status = CONNECTION_NEEDED;
                        goto keep_going;
                    }
                }
                return pollres;
#else                           /* !USE_SSL */
                /* can't get here */
                goto error_return;
#endif   /* USE_SSL */
            }

            /*
             * Handle authentication exchange: wait for postmaster messages
             * and respond as necessary.
             */
        case CONNECTION_AWAITING_RESPONSE:
            {
                char        beresp;
                int         msgLength;
                int         avail;
                AuthRequest areq;

                /*
                 * Scan the message from current point (note that if we find
                 * the message is incomplete, we will return without advancing
                 * inStart, and resume here next time).
                 */
                conn->inCursor = conn->inStart;

                /* Read type byte */
                if (pqGetc(&beresp, conn))
                {
                    /* We'll come back when there is more data */
                    return PGRES_POLLING_READING;
                }

                /*
                 * Validate message type: we expect only an authentication
                 * request or an error here.  Anything else probably means
                 * it's not Postgres on the other end at all.
                 */
                if (!(beresp == 'R' || beresp == 'E'))
                {
                    appendPQExpBuffer(&conn->errorMessage,
                                      libpq_gettext(
                                      "expected authentication request from "
                                                "server, but received %c\n"),
                                      beresp);
                    goto error_return;
                }

                if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
                {
                    /* Read message length word */
                    if (pqGetInt(&msgLength, 4, conn))
                    {
                        /* We'll come back when there is more data */
                        return PGRES_POLLING_READING;
                    }
                }
                else
                {
                    /* Set phony message length to disable checks below */
                    msgLength = 8;
                }

                /*
                 * Try to validate message length before using it.
                 * Authentication requests can't be very large, although GSS
                 * auth requests may not be that small.  Errors can be a
                 * little larger, but not huge.  If we see a large apparent
                 * length in an error, it means we're really talking to a
                 * pre-3.0-protocol server; cope.
                 */
                if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
                {
                    appendPQExpBuffer(&conn->errorMessage,
                                      libpq_gettext(
                                      "expected authentication request from "
                                                "server, but received %c\n"),
                                      beresp);
                    goto error_return;
                }

                if (beresp == 'E' && (msgLength < 8 || msgLength > 30000))
                {
                    /* Handle error from a pre-3.0 server */
                    conn->inCursor = conn->inStart + 1; /* reread data */
                    if (pqGets_append(&conn->errorMessage, conn))
                    {
                        /* We'll come back when there is more data */
                        return PGRES_POLLING_READING;
                    }
                    /* OK, we read the message; mark data consumed */
                    conn->inStart = conn->inCursor;

                    /*
                     * The postmaster typically won't end its message with a
                     * newline, so add one to conform to libpq conventions.
                     */
                    appendPQExpBufferChar(&conn->errorMessage, '\n');

                    /*
                     * If we tried to open the connection in 3.0 protocol,
                     * fall back to 2.0 protocol.
                     */
                    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
                    {
                        conn->pversion = PG_PROTOCOL(2, 0);
                        /* Must drop the old connection */
                        pqDropConnection(conn);
                        conn->status = CONNECTION_NEEDED;
                        goto keep_going;
                    }

                    goto error_return;
                }

                /*
                 * Can't process if message body isn't all here yet.
                 *
                 * (In protocol 2.0 case, we are assuming messages carry at
                 * least 4 bytes of data.)
                 */
                msgLength -= 4;
                avail = conn->inEnd - conn->inCursor;
                if (avail < msgLength)
                {
                    /*
                     * Before returning, try to enlarge the input buffer if
                     * needed to hold the whole message; see notes in
                     * pqParseInput3.
                     */
                    if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
                                             conn))
                        goto error_return;
                    /* We'll come back when there is more data */
                    return PGRES_POLLING_READING;
                }

                /* Handle errors. */
                if (beresp == 'E')
                {
                    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
                    {
                        if (pqGetErrorNotice3(conn, true))
                        {
                            /* We'll come back when there is more data */
                            return PGRES_POLLING_READING;
                        }
                    }
                    else
                    {
                        if (pqGets_append(&conn->errorMessage, conn))
                        {
                            /* We'll come back when there is more data */
                            return PGRES_POLLING_READING;
                        }
                    }
                    /* OK, we read the message; mark data consumed */
                    conn->inStart = conn->inCursor;

#ifdef USE_SSL

                    /*
                     * if sslmode is "allow" and we haven't tried an SSL
                     * connection already, then retry with an SSL connection
                     */
                    if (conn->sslmode[0] == 'a' /* "allow" */
                        && conn->ssl == NULL
                        && conn->allow_ssl_try
                        && conn->wait_ssl_try)
                    {
                        /* only retry once */
                        conn->wait_ssl_try = false;
                        /* Must drop the old connection */
                        pqDropConnection(conn);
                        conn->status = CONNECTION_NEEDED;
                        goto keep_going;
                    }

                    /*
                     * if sslmode is "prefer" and we're in an SSL connection,
                     * then do a non-SSL retry
                     */
                    if (conn->sslmode[0] == 'p' /* "prefer" */
                        && conn->allow_ssl_try
                        && !conn->wait_ssl_try) /* redundant? */
                    {
                        /* only retry once */
                        conn->allow_ssl_try = false;
                        /* Must drop the old connection */
                        pqDropConnection(conn);
                        conn->status = CONNECTION_NEEDED;
                        goto keep_going;
                    }
#endif

                    goto error_return;
                }

                /* It is an authentication request. */
                conn->auth_req_received = true;

                /* Get the type of request. */
                if (pqGetInt((int *) &areq, 4, conn))
                {
                    /* We'll come back when there are more data */
                    return PGRES_POLLING_READING;
                }

                /* Get the password salt if there is one. */
                if (areq == AUTH_REQ_MD5)
                {
                    if (pqGetnchar(conn->md5Salt,
                                   sizeof(conn->md5Salt), conn))
                    {
                        /* We'll come back when there are more data */
                        return PGRES_POLLING_READING;
                    }
                }
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)

                /*
                 * Continue GSSAPI/SSPI authentication
                 */
                if (areq == AUTH_REQ_GSS_CONT)
                {
                    int         llen = msgLength - 4;

                    /*
                     * We can be called repeatedly for the same buffer. Avoid
                     * re-allocating the buffer in this case - just re-use the
                     * old buffer.
                     */
                    if (llen != conn->ginbuf.length)
                    {
                        if (conn->ginbuf.value)
                            free(conn->ginbuf.value);

                        conn->ginbuf.length = llen;
                        conn->ginbuf.value = malloc(llen);
                        if (!conn->ginbuf.value)
                        {
                            printfPQExpBuffer(&conn->errorMessage,
                                              libpq_gettext("out of memory allocating GSSAPI buffer (%d)"),
                                              llen);
                            goto error_return;
                        }
                    }

                    if (pqGetnchar(conn->ginbuf.value, llen, conn))
                    {
                        /* We'll come back when there is more data. */
                        return PGRES_POLLING_READING;
                    }
                }
#endif

                /*
                 * OK, we successfully read the message; mark data consumed
                 */
                conn->inStart = conn->inCursor;

                /* Respond to the request if necessary. */

                /*
                 * Note that conn->pghost must be non-NULL if we are going to
                 * avoid the Kerberos code doing a hostname look-up.
                 */

                if (pg_fe_sendauth(areq, conn) != STATUS_OK)
                {
                    conn->errorMessage.len = strlen(conn->errorMessage.data);
                    goto error_return;
                }
                conn->errorMessage.len = strlen(conn->errorMessage.data);

                /*
                 * Just make sure that any data sent by pg_fe_sendauth is
                 * flushed out.  Although this theoretically could block, it
                 * really shouldn't since we don't send large auth responses.
                 */
                if (pqFlush(conn))
                    goto error_return;

                if (areq == AUTH_REQ_OK)
                {
                    /* We are done with authentication exchange */
                    conn->status = CONNECTION_AUTH_OK;

                    /*
                     * Set asyncStatus so that PQgetResult will think that
                     * what comes back next is the result of a query.  See
                     * below.
                     */
                    conn->asyncStatus = PGASYNC_BUSY;
                }

                /* Look to see if we have more data yet. */
                goto keep_going;
            }

        case CONNECTION_AUTH_OK:
            {
                /*
                 * Now we expect to hear from the backend. A ReadyForQuery
                 * message indicates that startup is successful, but we might
                 * also get an Error message indicating failure. (Notice
                 * messages indicating nonfatal warnings are also allowed by
                 * the protocol, as are ParameterStatus and BackendKeyData
                 * messages.) Easiest way to handle this is to let
                 * PQgetResult() read the messages. We just have to fake it
                 * out about the state of the connection, by setting
                 * asyncStatus = PGASYNC_BUSY (done above).
                 */

                if (PQisBusy(conn))
                    return PGRES_POLLING_READING;

                res = PQgetResult(conn);

                /*
                 * NULL return indicating we have gone to IDLE state is
                 * expected
                 */
                if (res)
                {
                    if (res->resultStatus != PGRES_FATAL_ERROR)
                        appendPQExpBuffer(&conn->errorMessage,
                                          libpq_gettext("unexpected message from server during startup\n"));
                    else if (conn->send_appname &&
                             (conn->appname || conn->fbappname))
                    {
                        /*
                         * If we tried to send application_name, check to see
                         * if the error is about that --- pre-9.0 servers will
                         * reject it at this stage of the process.  If so,
                         * close the connection and retry without sending
                         * application_name.  We could possibly get a false
                         * SQLSTATE match here and retry uselessly, but there
                         * seems no great harm in that; we'll just get the
                         * same error again if it's unrelated.
                         */
                        const char *sqlstate;

                        sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
                        if (sqlstate &&
                            strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
                        {
                            PQclear(res);
                            conn->send_appname = false;
                            /* Must drop the old connection */
                            pqDropConnection(conn);
                            conn->status = CONNECTION_NEEDED;
                            goto keep_going;
                        }
                    }

                    /*
                     * if the resultStatus is FATAL, then conn->errorMessage
                     * already has a copy of the error; needn't copy it back.
                     * But add a newline if it's not there already, since
                     * postmaster error messages may not have one.
                     */
                    if (conn->errorMessage.len <= 0 ||
                        conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
                        appendPQExpBufferChar(&conn->errorMessage, '\n');
                    PQclear(res);
                    goto error_return;
                }

                /* We can release the address list now. */
                pg_freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
                conn->addrlist = NULL;
                conn->addr_cur = NULL;

                /* Fire up post-connection housekeeping if needed */
                if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
                {
                    conn->status = CONNECTION_SETENV;
                    conn->setenv_state = SETENV_STATE_CLIENT_ENCODING_SEND;
                    conn->next_eo = EnvironmentOptions;
                    return PGRES_POLLING_WRITING;
                }

                /* Otherwise, we are open for business! */
                conn->status = CONNECTION_OK;
                return PGRES_POLLING_OK;
            }

        case CONNECTION_SETENV:

            /*
             * Do post-connection housekeeping (only needed in protocol 2.0).
             *
             * We pretend that the connection is OK for the duration of these
             * queries.
             */
            conn->status = CONNECTION_OK;

            switch (pqSetenvPoll(conn))
            {
                case PGRES_POLLING_OK:  /* Success */
                    break;

                case PGRES_POLLING_READING:     /* Still going */
                    conn->status = CONNECTION_SETENV;
                    return PGRES_POLLING_READING;

                case PGRES_POLLING_WRITING:     /* Still going */
                    conn->status = CONNECTION_SETENV;
                    return PGRES_POLLING_WRITING;

                default:
                    goto error_return;
            }

            /* We are open for business! */
            conn->status = CONNECTION_OK;
            return PGRES_POLLING_OK;

        default:
            appendPQExpBuffer(&conn->errorMessage,
                              libpq_gettext("invalid connection state %d, "
                               "probably indicative of memory corruption\n"),
                              conn->status);
            goto error_return;
    }

    /* Unreachable */

error_return:

    dot_pg_pass_warning(conn);

    /*
     * We used to close the socket at this point, but that makes it awkward
     * for those above us if they wish to remove this socket from their own
     * records (an fd_set for example).  We'll just have this socket closed
     * when PQfinish is called (which is compulsory even after an error, since
     * the connection structure must be freed).
     */
    conn->status = CONNECTION_BAD;
    return PGRES_POLLING_FAILED;
}

PGconn* PQconnectStart ( const char *  conninfo  ) 

Definition at line 633 of file fe-connect.c.

References conn, connectDBStart(), connectOptions1(), connectOptions2(), makeEmptyPGconn(), NULL, and pg_conn::status.

Referenced by PQconnectdb(), and PQping().

{
    PGconn     *conn;

    /*
     * Allocate memory for the conn structure
     */
    conn = makeEmptyPGconn();
    if (conn == NULL)
        return NULL;

    /*
     * Parse the conninfo string
     */
    if (!connectOptions1(conn, conninfo))
        return conn;

    /*
     * Compute derived options
     */
    if (!connectOptions2(conn))
        return conn;

    /*
     * Connect to the database
     */
    if (!connectDBStart(conn))
    {
        /* Just in case we failed to set it in connectDBStart */
        conn->status = CONNECTION_BAD;
    }

    return conn;
}

PGconn* PQconnectStartParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

Definition at line 558 of file fe-connect.c.

References conn, connectDBStart(), connectOptions2(), conninfo_array_parse(), pg_conn::errorMessage, fillPGconn(), makeEmptyPGconn(), NULL, PQconninfoFree(), and pg_conn::status.

Referenced by PQconnectdbParams(), and PQpingParams().

{
    PGconn     *conn;
    PQconninfoOption *connOptions;

    /*
     * Allocate memory for the conn structure
     */
    conn = makeEmptyPGconn();
    if (conn == NULL)
        return NULL;

    /*
     * Parse the conninfo arrays
     */
    connOptions = conninfo_array_parse(keywords, values,
                                       &conn->errorMessage,
                                       true, expand_dbname);
    if (connOptions == NULL)
    {
        conn->status = CONNECTION_BAD;
        /* errorMessage is already set */
        return conn;
    }

    /*
     * Move option values into conn structure
     */
    fillPGconn(conn, connOptions);

    /*
     * Free the option info - all is in conn now
     */
    PQconninfoFree(connOptions);

    /*
     * Compute derived options
     */
    if (!connectOptions2(conn))
        return conn;

    /*
     * Connect to the database
     */
    if (!connectDBStart(conn))
    {
        /* Just in case we failed to set it in connectDBStart */
        conn->status = CONNECTION_BAD;
    }

    return conn;
}

PQconninfoOption* PQconninfo ( PGconn conn  ) 

Definition at line 5098 of file fe-connect.c.

References conninfo_init(), conninfo_storeval(), _internalPQconninfoOption::connofs, initPQExpBuffer(), _internalPQconninfoOption::keyword, NULL, PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by GenerateRecoveryConf().

{
    PQExpBufferData errorBuf;
    PQconninfoOption *connOptions;

    if (conn == NULL)
        return NULL;

    /* We don't actually report any errors here, but callees want a buffer */
    initPQExpBuffer(&errorBuf);
    if (PQExpBufferDataBroken(errorBuf))
        return NULL;            /* out of memory already :-( */

    connOptions = conninfo_init(&errorBuf);

    if (connOptions != NULL)
    {
        const internalPQconninfoOption *option;

        for (option = PQconninfoOptions; option->keyword; option++)
        {
            char      **connmember;

            if (option->connofs < 0)
                continue;

            connmember = (char **) ((char *) conn + option->connofs);

            if (*connmember)
                conninfo_storeval(connOptions, option->keyword, *connmember,
                                  &errorBuf, true, false);
        }
    }

    termPQExpBuffer(&errorBuf);

    return connOptions;
}

void PQconninfoFree ( PQconninfoOption connOptions  ) 

Definition at line 5139 of file fe-connect.c.

References free, _PQconninfoOption::keyword, NULL, and _PQconninfoOption::val.

Referenced by check_pghost_envvar(), connectDatabase(), connectOptions1(), conninfo_array_parse(), conninfo_parse(), conninfo_uri_parse(), dblink_connstr_check(), GenerateRecoveryConf(), GetConnection(), main(), PQconndefaults(), and PQconnectStartParams().

{
    PQconninfoOption *option;

    if (connOptions == NULL)
        return;

    for (option = connOptions; option->keyword != NULL; option++)
    {
        if (option->val != NULL)
            free(option->val);
    }
    free(connOptions);
}

PQconninfoOption* PQconninfoParse ( const char *  conninfo,
char **  errmsg 
)

Definition at line 3986 of file fe-connect.c.

References PQExpBufferData::data, initPQExpBuffer(), NULL, parse_connection_string(), PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by connectDatabase(), dblink_connstr_check(), GetConnection(), and main().

{
    PQExpBufferData errorBuf;
    PQconninfoOption *connOptions;

    if (errmsg)
        *errmsg = NULL;         /* default */
    initPQExpBuffer(&errorBuf);
    if (PQExpBufferDataBroken(errorBuf))
        return NULL;            /* out of memory already :-( */
    connOptions = parse_connection_string(conninfo, &errorBuf, false);
    if (connOptions == NULL && errmsg)
        *errmsg = errorBuf.data;
    else
        termPQExpBuffer(&errorBuf);
    return connOptions;
}

int PQconsumeInput ( PGconn conn  ) 

Definition at line 1608 of file fe-exec.c.

References pqFlush(), pqIsnonblocking, and pqReadData().

Referenced by dblink_get_notify(), dblink_is_busy(), doCustom(), HandleCopyStream(), libpqrcv_PQexec(), libpqrcv_receive(), main(), and try_complete_step().

{
    if (!conn)
        return 0;

    /*
     * for non-blocking connections try to flush the send-queue, otherwise we
     * may never get a response for something that may not have already been
     * sent because it's in our write buffer!
     */
    if (pqIsnonblocking(conn))
    {
        if (pqFlush(conn) < 0)
            return 0;
    }

    /*
     * Load more data, if available. We do this no matter what state we are
     * in, since we are probably getting called because the application wants
     * to get rid of a read-select condition. Note that we will NOT block
     * waiting for more input.
     */
    if (pqReadData(conn) < 0)
        return 0;

    /* Parsing of the data waits till later. */
    return 1;
}

PGresult* PQcopyResult ( const PGresult src,
int  flags 
)

Definition at line 289 of file fe-exec.c.

References pg_result::attDescs, pg_result::client_encoding, pg_result::cmdStatus, PGEventResultCopy::dest, dupEvents(), pg_result::events, i, pgresAttValue::len, pg_result::nEvents, pg_result::noticeHooks, pg_result::ntups, NULL, pg_result::numAttributes, PGEvent::passThrough, PG_COPYRES_ATTRS, PG_COPYRES_EVENTS, PG_COPYRES_NOTICEHOOKS, PG_COPYRES_TUPLES, PGEVT_RESULTCOPY, PGRES_TUPLES_OK, PQclear(), PQmakeEmptyPGresult(), PQsetResultAttrs(), PQsetvalue(), PGEvent::proc, PGEvent::resultInitialized, PGEventResultCopy::src, pg_result::tuples, and pgresAttValue::value.

Referenced by pqRowProcessor().

{
    PGresult   *dest;
    int         i;

    if (!src)
        return NULL;

    dest = PQmakeEmptyPGresult(NULL, PGRES_TUPLES_OK);
    if (!dest)
        return NULL;

    /* Always copy these over.  Is cmdStatus really useful here? */
    dest->client_encoding = src->client_encoding;
    strcpy(dest->cmdStatus, src->cmdStatus);

    /* Wants attrs? */
    if (flags & (PG_COPYRES_ATTRS | PG_COPYRES_TUPLES))
    {
        if (!PQsetResultAttrs(dest, src->numAttributes, src->attDescs))
        {
            PQclear(dest);
            return NULL;
        }
    }

    /* Wants to copy tuples? */
    if (flags & PG_COPYRES_TUPLES)
    {
        int         tup,
                    field;

        for (tup = 0; tup < src->ntups; tup++)
        {
            for (field = 0; field < src->numAttributes; field++)
            {
                if (!PQsetvalue(dest, tup, field,
                                src->tuples[tup][field].value,
                                src->tuples[tup][field].len))
                {
                    PQclear(dest);
                    return NULL;
                }
            }
        }
    }

    /* Wants to copy notice hooks? */
    if (flags & PG_COPYRES_NOTICEHOOKS)
        dest->noticeHooks = src->noticeHooks;

    /* Wants to copy PGEvents? */
    if ((flags & PG_COPYRES_EVENTS) && src->nEvents > 0)
    {
        dest->events = dupEvents(src->events, src->nEvents);
        if (!dest->events)
        {
            PQclear(dest);
            return NULL;
        }
        dest->nEvents = src->nEvents;
    }

    /* Okay, trigger PGEVT_RESULTCOPY event */
    for (i = 0; i < dest->nEvents; i++)
    {
        if (src->events[i].resultInitialized)
        {
            PGEventResultCopy evt;

            evt.src = src;
            evt.dest = dest;
            if (!dest->events[i].proc(PGEVT_RESULTCOPY, &evt,
                                      dest->events[i].passThrough))
            {
                PQclear(dest);
                return NULL;
            }
            dest->events[i].resultInitialized = TRUE;
        }
    }

    return dest;
}

char* PQdb ( const PGconn conn  ) 
PGresult* PQdescribePortal ( PGconn conn,
const char *  portal 
)

Definition at line 2038 of file fe-exec.c.

References PQexecFinish(), PQexecStart(), and PQsendDescribe().

{
    if (!PQexecStart(conn))
        return NULL;
    if (!PQsendDescribe(conn, 'P', portal))
        return NULL;
    return PQexecFinish(conn);
}

PGresult* PQdescribePrepared ( PGconn conn,
const char *  stmt 
)

Definition at line 2019 of file fe-exec.c.

References PQexecFinish(), PQexecStart(), and PQsendDescribe().

Referenced by ECPGdescribe().

{
    if (!PQexecStart(conn))
        return NULL;
    if (!PQsendDescribe(conn, 'S', stmt))
        return NULL;
    return PQexecFinish(conn);
}

void PQdisplayTuples ( const PGresult res,
FILE *  fp,
int  fillAlign,
const char *  fieldSep,
int  printHeader,
int  quiet 
)

Definition at line 573 of file fe-print.c.

References fill(), free, i, libpq_gettext, malloc, NULL, PQfname(), PQgetlength(), PQgetvalue(), PQnfields(), and PQntuples().

{
#define DEFAULT_FIELD_SEP " "

    int         i,
                j;
    int         nFields;
    int         nTuples;
    int        *fLength = NULL;

    if (fieldSep == NULL)
        fieldSep = DEFAULT_FIELD_SEP;

    /* Get some useful info about the results */
    nFields = PQnfields(res);
    nTuples = PQntuples(res);

    if (fp == NULL)
        fp = stdout;

    /* Figure the field lengths to align to */
    /* will be somewhat time consuming for very large results */
    if (fillAlign)
    {
        fLength = (int *) malloc(nFields * sizeof(int));
        if (!fLength)
        {
            fprintf(stderr, libpq_gettext("out of memory\n"));
            abort();
        }

        for (j = 0; j < nFields; j++)
        {
            fLength[j] = strlen(PQfname(res, j));
            for (i = 0; i < nTuples; i++)
            {
                int         flen = PQgetlength(res, i, j);

                if (flen > fLength[j])
                    fLength[j] = flen;
            }
        }
    }

    if (printHeader)
    {
        /* first, print out the attribute names */
        for (i = 0; i < nFields; i++)
        {
            fputs(PQfname(res, i), fp);
            if (fillAlign)
                fill(strlen(PQfname(res, i)), fLength[i], ' ', fp);
            fputs(fieldSep, fp);
        }
        fprintf(fp, "\n");

        /* Underline the attribute names */
        for (i = 0; i < nFields; i++)
        {
            if (fillAlign)
                fill(0, fLength[i], '-', fp);
            fputs(fieldSep, fp);
        }
        fprintf(fp, "\n");
    }

    /* next, print out the instances */
    for (i = 0; i < nTuples; i++)
    {
        for (j = 0; j < nFields; j++)
        {
            fprintf(fp, "%s", PQgetvalue(res, i, j));
            if (fillAlign)
                fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp);
            fputs(fieldSep, fp);
        }
        fprintf(fp, "\n");
    }

    if (!quiet)
        fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res),
                (PQntuples(res) == 1) ? "" : "s");

    fflush(fp);

    if (fLength)
        free(fLength);
}

int PQdsplen ( const char *  s,
int  encoding 
)

Definition at line 1151 of file fe-misc.c.

References pg_encoding_dsplen().

Referenced by pg_wcsformat(), pg_wcssize(), pg_wcswidth(), and strlen_max_width().

{
    return pg_encoding_dsplen(encoding, s);
}

char* PQencryptPassword ( const char *  passwd,
const char *  user 
)

Definition at line 1040 of file fe-auth.c.

References free, malloc, MD5_PASSWD_LEN, and pg_md5_encrypt().

Referenced by exec_command(), and main().

{
    char       *crypt_pwd;

    crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
    if (!crypt_pwd)
        return NULL;

    if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
    {
        free(crypt_pwd);
        return NULL;
    }

    return crypt_pwd;
}

int PQendcopy ( PGconn conn  ) 

Definition at line 2478 of file fe-exec.c.

References PG_PROTOCOL_MAJOR, pqEndcopy2(), pqEndcopy3(), and pg_conn::pversion.

Referenced by ecpg_check_PQresult(), and init().

{
    if (!conn)
        return 0;

    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
        return pqEndcopy3(conn);
    else
        return pqEndcopy2(conn);
}

int PQenv2encoding ( void   ) 

Definition at line 1160 of file fe-misc.c.

References encoding, and pg_char_to_encoding().

Referenced by main().

{
    char       *str;
    int         encoding = PG_SQL_ASCII;

    str = getenv("PGCLIENTENCODING");
    if (str && *str != '\0')
    {
        encoding = pg_char_to_encoding(str);
        if (encoding < 0)
            encoding = PG_SQL_ASCII;
    }
    return encoding;
}

char* PQerrorMessage ( const PGconn conn  ) 

Definition at line 5266 of file fe-connect.c.

References PQExpBufferData::data, pg_conn::errorMessage, and libpq_gettext.

Referenced by _connectDB(), _doSetSessionAuth(), _doSetWithOids(), _selectOutputSchema(), _selectTablespace(), AcceptResult(), BaseBackup(), check_conn(), check_loadable_libraries(), cluster_one_database(), connect_pg_server(), ConnectDatabase(), connectDatabase(), connectToServer(), dblink_connect(), dblink_error_message(), dblink_send_query(), die_on_query_failure(), do_connect(), do_lo_export(), do_lo_import(), do_lo_unlink(), doConnect(), doCustom(), dumpBlobs(), dumpTableData_copy(), ecpg_check_PQresult(), ecpg_raise_backend(), ECPGconnect(), EndDBCopyMode(), executeCommand(), executeQuery(), executeQueryOrDie(), ExecuteSqlCommand(), ExecuteSqlCommandBuf(), executeStatement(), GetConnection(), handleCopyIn(), handleCopyOut(), HandleCopyStream(), init(), libpqrcv_connect(), libpqrcv_endstreaming(), libpqrcv_identify_system(), libpqrcv_readtimelinehistoryfile(), libpqrcv_receive(), libpqrcv_send(), libpqrcv_startstreaming(), lockTableNoWait(), main(), my_truncate(), overwrite(), pickout(), PSQLexec(), ReceiveAndUnpackTarFile(), ReceiveTarFile(), ReceiveXlogStream(), reindex_one_database(), reindex_system_catalogs(), run_permutation(), sendFeedback(), SendQuery(), sql_conn(), sql_exec(), start_postmaster(), StartRestoreBlob(), storeQueryResult(), StreamLog(), try_complete_step(), vacuum_one_database(), and vacuumlo().

{
    if (!conn)
        return libpq_gettext("connection pointer is NULL\n");

    return conn->errorMessage.data;
}

unsigned char* PQescapeBytea ( const unsigned char *  from,
size_t  from_length,
size_t *  to_length 
)

Definition at line 3528 of file fe-exec.c.

References NULL, PQescapeByteaInternal(), and static_std_strings.

{
    return PQescapeByteaInternal(NULL, from, from_length, to_length,
                                 static_std_strings,
                                 false /* can't use hex */ );
}

unsigned char* PQescapeByteaConn ( PGconn conn,
const unsigned char *  from,
size_t  from_length,
size_t *  to_length 
)

Definition at line 3516 of file fe-exec.c.

References PQescapeByteaInternal(), pg_conn::std_strings, and pg_conn::sversion.

{
    if (!conn)
        return NULL;
    return PQescapeByteaInternal(conn, from, from_length, to_length,
                                 conn->std_strings,
                                 (conn->sversion >= 90000));
}

char* PQescapeIdentifier ( PGconn conn,
const char *  str,
size_t  len 
)

Definition at line 3372 of file fe-exec.c.

References PQescapeInternal().

Referenced by init(), and vacuumlo().

{
    return PQescapeInternal(conn, str, len, true);
}

char* PQescapeLiteral ( PGconn conn,
const char *  str,
size_t  len 
)

Definition at line 3366 of file fe-exec.c.

References PQescapeInternal().

{
    return PQescapeInternal(conn, str, len, false);
}

size_t PQescapeString ( char *  to,
const char *  from,
size_t  length 
)
size_t PQescapeStringConn ( PGconn conn,
char *  to,
const char *  from,
size_t  length,
int *  error 
)

Definition at line 3212 of file fe-exec.c.

References pg_conn::client_encoding, PQescapeStringInternal(), and pg_conn::std_strings.

Referenced by appendStringLiteralConn(), BaseBackup(), check_loadable_libraries(), and do_lo_import().

{
    if (!conn)
    {
        /* force empty-string result */
        *to = '\0';
        if (error)
            *error = 1;
        return 0;
    }
    return PQescapeStringInternal(conn, to, from, length, error,
                                  conn->client_encoding,
                                  conn->std_strings);
}

PGresult* PQexec ( PGconn conn,
const char *  query 
)
PGresult* PQexecParams ( PGconn conn,
const char *  command,
int  nParams,
const Oid paramTypes,
const char *const *  paramValues,
const int *  paramLengths,
const int *  paramFormats,
int  resultFormat 
)

Definition at line 1816 of file fe-exec.c.

References PQexecFinish(), PQexecStart(), and PQsendQueryParams().

Referenced by create_cursor(), ecpg_execute(), and main().

{
    if (!PQexecStart(conn))
        return NULL;
    if (!PQsendQueryParams(conn, command,
                           nParams, paramTypes, paramValues, paramLengths,
                           paramFormats, resultFormat))
        return NULL;
    return PQexecFinish(conn);
}

PGresult* PQexecPrepared ( PGconn conn,
const char *  stmtName,
int  nParams,
const char *const *  paramValues,
const int *  paramLengths,
const int *  paramFormats,
int  resultFormat 
)

Definition at line 1863 of file fe-exec.c.

References PQexecFinish(), PQexecStart(), and PQsendQueryPrepared().

Referenced by ecpg_execute(), postgresExecForeignDelete(), postgresExecForeignInsert(), postgresExecForeignUpdate(), and try_complete_step().

{
    if (!PQexecStart(conn))
        return NULL;
    if (!PQsendQueryPrepared(conn, stmtName,
                             nParams, paramValues, paramLengths,
                             paramFormats, resultFormat))
        return NULL;
    return PQexecFinish(conn);
}

int PQfformat ( const PGresult res,
int  field_num 
)

Definition at line 2797 of file fe-exec.c.

References pg_result::attDescs, check_field_number(), and pgresAttDesc::format.

Referenced by ecpg_get_data(), and ecpg_store_result().

{
    if (!check_field_number(res, field_num))
        return 0;
    if (res->attDescs)
        return res->attDescs[field_num].format;
    else
        return 0;
}

void PQfinish ( PGconn conn  ) 

Definition at line 2962 of file fe-connect.c.

References closePGconn(), and freePGconn().

Referenced by _connectDB(), BaseBackup(), check_for_isn_and_int8_passing_mismatch(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_is_super_user(), check_loadable_libraries(), CheckConnection(), clientDone(), cluster_all_databases(), cluster_one_database(), connect_pg_server(), ConnectDatabase(), connectDatabase(), connectToServer(), createNewConnection(), dblink_connect(), dblink_disconnect(), dblink_exec(), dblink_record_internal(), dblink_security_check(), disconnect_all(), DisconnectDatabase(), do_connect(), doConnect(), doCustom(), dumpCreateDB(), dumpTablespaces(), ecpg_finish(), executeCommand(), executeQuery(), executeQueryOrDie(), exit_nicely(), get_db_infos(), get_loadable_libraries(), get_pg_database_relfilenode(), get_rel_infos(), get_tablespace_paths(), GetConnection(), init(), install_support_functions_in_new_db(), libpqrcv_disconnect(), LogStreamerMain(), main(), new_9_0_populate_pg_largeobject_metadata(), old_8_3_check_for_name_data_type_usage(), old_8_3_check_for_tsquery_usage(), old_8_3_check_ltree_usage(), old_8_3_create_sequence_script(), old_8_3_invalidate_bpchar_pattern_ops_indexes(), old_8_3_invalidate_hash_gin_indexes(), old_8_3_rebuild_tsvector_tables(), pgfdw_xact_callback(), PQping(), PQpingParams(), ReconnectToServer(), reindex_all_databases(), reindex_one_database(), reindex_system_catalogs(), set_frozenxids(), set_locale_and_encoding(), sql_conn(), sql_exec(), start_postmaster(), StreamLog(), threadRun(), uninstall_support_functions_from_new_cluster(), vacuum_all_databases(), vacuum_one_database(), vacuumlo(), and WaitForCommands().

{
    if (conn)
    {
        closePGconn(conn);
        freePGconn(conn);
    }
}

int PQflush ( PGconn conn  ) 

Definition at line 3085 of file fe-exec.c.

References pqFlush().

Referenced by HandleCopyStream(), libpqrcv_endstreaming(), libpqrcv_send(), and sendFeedback().

{
    return pqFlush(conn);
}

int PQfmod ( const PGresult res,
int  field_num 
)

Definition at line 2830 of file fe-exec.c.

References pg_result::attDescs, pgresAttDesc::atttypmod, and check_field_number().

Referenced by ECPGget_desc().

{
    if (!check_field_number(res, field_num))
        return 0;
    if (res->attDescs)
        return res->attDescs[field_num].atttypmod;
    else
        return 0;
}

PGresult* PQfn ( PGconn conn,
int  fnid,
int *  result_buf,
int *  result_len,
int  result_is_int,
const PQArgBlock args,
int  nargs 
)

Definition at line 2514 of file fe-exec.c.

References pg_conn::asyncStatus, pg_conn::errorMessage, libpq_gettext, NULL, PG_PROTOCOL_MAJOR, PGASYNC_IDLE, pqFunctionCall2(), pqFunctionCall3(), printfPQExpBuffer(), pg_conn::pversion, resetPQExpBuffer(), pg_conn::result, and pg_conn::sock.

Referenced by lo_close(), lo_creat(), lo_create(), lo_lseek(), lo_lseek64(), lo_open(), lo_read(), lo_tell(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_unlink(), and lo_write().

{
    *actual_result_len = 0;

    if (!conn)
        return NULL;

    /* clear the error string */
    resetPQExpBuffer(&conn->errorMessage);

    if (conn->sock < 0 || conn->asyncStatus != PGASYNC_IDLE ||
        conn->result != NULL)
    {
        printfPQExpBuffer(&conn->errorMessage,
                          libpq_gettext("connection in wrong state\n"));
        return NULL;
    }

    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
        return pqFunctionCall3(conn, fnid,
                               result_buf, actual_result_len,
                               result_is_int,
                               args, nargs);
    else
        return pqFunctionCall2(conn, fnid,
                               result_buf, actual_result_len,
                               result_is_int,
                               args, nargs);
}

char* PQfname ( const PGresult res,
int  field_num 
)
int PQfnumber ( const PGresult res,
const char *  field_name 
)

Definition at line 2701 of file fe-exec.c.

References pg_result::attDescs, free, i, pgresAttDesc::name, NULL, pg_result::numAttributes, and pg_tolower().

Referenced by binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel_oid(), binary_upgrade_set_type_oids_by_type_oid(), buildMatViewRefreshDependencies(), check_for_isn_and_int8_passing_mismatch(), check_for_reg_data_type_usage(), collectComments(), collectSecLabels(), dropRoles(), dumpAgg(), dumpBaseType(), dumpCollation(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConversion(), dumpDatabase(), dumpDomain(), dumpEnumType(), dumpFunc(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpRangeType(), dumpRoles(), dumpTableSchema(), dumpTSConfig(), dumpUserMappings(), findLastBuiltinOid_V70(), findLastBuiltinOid_V71(), get_db_infos(), get_pg_database_relfilenode(), get_rel_infos(), get_tablespace_paths(), getAggregates(), getCasts(), getCollations(), getConstraints(), getConversions(), getDefaultACLs(), getDependencies(), getDomainConstraints(), getEventTriggers(), getExtensionMembership(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFuncs(), getIndexes(), getInherits(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getProcLangs(), getRules(), getTableAttrs(), getTables(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), new_9_0_populate_pg_largeobject_metadata(), old_8_3_check_for_name_data_type_usage(), old_8_3_check_for_tsquery_usage(), old_8_3_check_ltree_usage(), old_8_3_create_sequence_script(), old_8_3_invalidate_bpchar_pattern_ops_indexes(), old_8_3_invalidate_hash_gin_indexes(), old_8_3_rebuild_tsvector_tables(), set_frozenxids(), set_locale_and_encoding(), and show_binary_results().

{
    char       *field_case;
    bool        in_quotes;
    char       *iptr;
    char       *optr;
    int         i;

    if (!res)
        return -1;

    /*
     * Note: it is correct to reject a zero-length input string; the proper
     * input to match a zero-length field name would be "".
     */
    if (field_name == NULL ||
        field_name[0] == '\0' ||
        res->attDescs == NULL)
        return -1;

    /*
     * Note: this code will not reject partially quoted strings, eg
     * foo"BAR"foo will become fooBARfoo when it probably ought to be an error
     * condition.
     */
    field_case = strdup(field_name);
    if (field_case == NULL)
        return -1;              /* grotty */

    in_quotes = false;
    optr = field_case;
    for (iptr = field_case; *iptr; iptr++)
    {
        char        c = *iptr;

        if (in_quotes)
        {
            if (c == '"')
            {
                if (iptr[1] == '"')
                {
                    /* doubled quotes become a single quote */
                    *optr++ = '"';
                    iptr++;
                }
                else
                    in_quotes = false;
            }
            else
                *optr++ = c;
        }
        else if (c == '"')
            in_quotes = true;
        else
        {
            c = pg_tolower((unsigned char) c);
            *optr++ = c;
        }
    }
    *optr = '\0';

    for (i = 0; i < res->numAttributes; i++)
    {
        if (strcmp(field_case, res->attDescs[i].name) == 0)
        {
            free(field_case);
            return i;
        }
    }
    free(field_case);
    return -1;
}

void PQfreeCancel ( PGcancel cancel  ) 

Definition at line 3106 of file fe-connect.c.

References free.

Referenced by dblink_cancel_query(), DisconnectDatabase(), ResetCancelConn(), run_permutation(), and SetCancelConn().

{
    if (cancel)
        free(cancel);
}

void PQfreemem ( void *  ptr  ) 
int PQfsize ( const PGresult res,
int  field_num 
)

Definition at line 2819 of file fe-exec.c.

References pg_result::attDescs, check_field_number(), and pgresAttDesc::typlen.

Referenced by ecpg_build_compat_sqlda(), and ECPGget_desc().

{
    if (!check_field_number(res, field_num))
        return 0;
    if (res->attDescs)
        return res->attDescs[field_num].typlen;
    else
        return 0;
}

Oid PQftable ( const PGresult res,
int  field_num 
)

Definition at line 2775 of file fe-exec.c.

References pg_result::attDescs, check_field_number(), and pgresAttDesc::tableid.

{
    if (!check_field_number(res, field_num))
        return InvalidOid;
    if (res->attDescs)
        return res->attDescs[field_num].tableid;
    else
        return InvalidOid;
}

int PQftablecol ( const PGresult res,
int  field_num 
)

Definition at line 2786 of file fe-exec.c.

References pg_result::attDescs, check_field_number(), and pgresAttDesc::columnid.

{
    if (!check_field_number(res, field_num))
        return 0;
    if (res->attDescs)
        return res->attDescs[field_num].columnid;
    else
        return 0;
}

Oid PQftype ( const PGresult res,
int  field_num 
)

Definition at line 2808 of file fe-exec.c.

References pg_result::attDescs, check_field_number(), and pgresAttDesc::typid.

Referenced by dumpTableData_insert(), ecpg_build_compat_sqlda(), ecpg_build_native_sqlda(), ecpg_store_result(), ECPGget_desc(), printQuery(), and sqlda_common_total_size().

{
    if (!check_field_number(res, field_num))
        return InvalidOid;
    if (res->attDescs)
        return res->attDescs[field_num].typid;
    else
        return InvalidOid;
}

PGcancel* PQgetCancel ( PGconn conn  ) 

Definition at line 3083 of file fe-connect.c.

References pg_conn::be_key, pg_cancel::be_key, pg_conn::be_pid, pg_cancel::be_pid, malloc, NULL, pg_conn::raddr, pg_cancel::raddr, and pg_conn::sock.

Referenced by dblink_cancel_query(), DisconnectDatabase(), run_permutation(), and SetCancelConn().

{
    PGcancel   *cancel;

    if (!conn)
        return NULL;

    if (conn->sock < 0)
        return NULL;

    cancel = malloc(sizeof(PGcancel));
    if (cancel == NULL)
        return NULL;

    memcpy(&cancel->raddr, &conn->raddr, sizeof(SockAddr));
    cancel->be_pid = conn->be_pid;
    cancel->be_key = conn->be_key;

    return cancel;
}

int PQgetCopyData ( PGconn conn,
char **  buffer,
int  async 
)

Definition at line 2333 of file fe-exec.c.

References pg_conn::asyncStatus, pg_conn::errorMessage, libpq_gettext, PG_PROTOCOL_MAJOR, PGASYNC_COPY_BOTH, PGASYNC_COPY_OUT, pqGetCopyData2(), pqGetCopyData3(), printfPQExpBuffer(), and pg_conn::pversion.

Referenced by dumpTableData_copy(), ecpg_execute(), handleCopyOut(), HandleCopyStream(), libpqrcv_receive(), ReceiveAndUnpackTarFile(), and ReceiveTarFile().

{
    *buffer = NULL;             /* for all failure cases */
    if (!conn)
        return -2;
    if (conn->asyncStatus != PGASYNC_COPY_OUT &&
        conn->asyncStatus != PGASYNC_COPY_BOTH)
    {
        printfPQExpBuffer(&conn->errorMessage,
                          libpq_gettext("no COPY in progress\n"));
        return -2;
    }
    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
        return pqGetCopyData3(conn, buffer, async);
    else
        return pqGetCopyData2(conn, buffer, async);
}

int PQgetisnull ( const PGresult res,
int  tup_num,
int  field_num 
)
int PQgetlength ( const PGresult res,
int  tup_num,
int  field_num 
)

Definition at line 2976 of file fe-exec.c.

References check_tuple_field_number(), pgresAttValue::len, NULL_LEN, and pg_result::tuples.

Referenced by createViewAsClause(), do_field(), ecpg_get_data(), ecpg_store_result(), ECPGget_desc(), libpqrcv_readtimelinehistoryfile(), PQdisplayTuples(), and show_binary_results().

{
    if (!check_tuple_field_number(res, tup_num, field_num))
        return 0;
    if (res->tuples[tup_num][field_num].len != NULL_LEN)
        return res->tuples[tup_num][field_num].len;
    else
        return 0;
}

int PQgetline ( PGconn conn,
char *  string,
int  length 
)

Definition at line 2375 of file fe-exec.c.

References PG_PROTOCOL_MAJOR, pqGetline2(), pqGetline3(), and pg_conn::pversion.

{
    if (!s || maxlen <= 0)
        return EOF;
    *s = '\0';
    /* maxlen must be at least 3 to hold the \. terminator! */
    if (maxlen < 3)
        return EOF;

    if (!conn)
        return EOF;

    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
        return pqGetline3(conn, s, maxlen);
    else
        return pqGetline2(conn, s, maxlen);
}

int PQgetlineAsync ( PGconn conn,
char *  buffer,
int  bufsize 
)

Definition at line 2425 of file fe-exec.c.

References PG_PROTOCOL_MAJOR, pqGetlineAsync2(), pqGetlineAsync3(), and pg_conn::pversion.

Referenced by pqGetline3().

{
    if (!conn)
        return -1;

    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
        return pqGetlineAsync3(conn, buffer, bufsize);
    else
        return pqGetlineAsync2(conn, buffer, bufsize);
}

PGresult* PQgetResult ( PGconn conn  ) 

Definition at line 1679 of file fe-exec.c.

References pg_conn::asyncStatus, PGEventResultCreate::conn, PQExpBufferData::data, pg_conn::errorMessage, pg_result::events, FALSE, i, libpq_gettext, PGEvent::name, pg_result::nEvents, parseInput(), PGEvent::passThrough, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGASYNC_IDLE, PGASYNC_READY, PGEVT_RESULTCREATE, PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_FATAL_ERROR, pqFlush(), PQmakeEmptyPGresult(), pqPrepareAsyncResult(), pqReadData(), pqSaveErrorResult(), pqSetResultError(), pqWait(), printfPQExpBuffer(), PGEvent::proc, PGEventResultCreate::result, pg_conn::result, PGEvent::resultInitialized, pg_result::resultStatus, and TRUE.

Referenced by BaseBackup(), dblink_record_internal(), discard_response(), doCustom(), dumpTableData_copy(), ecpg_execute(), EndDBCopyMode(), handleCopyIn(), handleCopyOut(), HandleCopyStream(), libpqrcv_endstreaming(), libpqrcv_PQexec(), libpqrcv_receive(), materializeQueryResult(), PQconnectPoll(), pqEndcopy2(), pqEndcopy3(), PQexecFinish(), PQexecStart(), pqSetenvPoll(), ProcessResult(), ReceiveAndUnpackTarFile(), ReceiveTarFile(), ReceiveXlogStream(), run_permutation(), storeQueryResult(), and try_complete_step().

{
    PGresult   *res;

    if (!conn)
        return NULL;

    /* Parse any available data, if our state permits. */
    parseInput(conn);

    /* If not ready to return something, block until we are. */
    while (conn->asyncStatus == PGASYNC_BUSY)
    {
        int         flushResult;

        /*
         * If data remains unsent, send it.  Else we might be waiting for the
         * result of a command the backend hasn't even got yet.
         */
        while ((flushResult = pqFlush(conn)) > 0)
        {
            if (pqWait(FALSE, TRUE, conn))
            {
                flushResult = -1;
                break;
            }
        }

        /* Wait for some more data, and load it. */
        if (flushResult ||
            pqWait(TRUE, FALSE, conn) ||
            pqReadData(conn) < 0)
        {
            /*
             * conn->errorMessage has been set by pqWait or pqReadData. We
             * want to append it to any already-received error message.
             */
            pqSaveErrorResult(conn);
            conn->asyncStatus = PGASYNC_IDLE;
            return pqPrepareAsyncResult(conn);
        }

        /* Parse it. */
        parseInput(conn);
    }

    /* Return the appropriate thing. */
    switch (conn->asyncStatus)
    {
        case PGASYNC_IDLE:
            res = NULL;         /* query is complete */
            break;
        case PGASYNC_READY:
            res = pqPrepareAsyncResult(conn);
            /* Set the state back to BUSY, allowing parsing to proceed. */
            conn->asyncStatus = PGASYNC_BUSY;
            break;
        case PGASYNC_COPY_IN:
            if (conn->result && conn->result->resultStatus == PGRES_COPY_IN)
                res = pqPrepareAsyncResult(conn);
            else
                res = PQmakeEmptyPGresult(conn, PGRES_COPY_IN);
            break;
        case PGASYNC_COPY_OUT:
            if (conn->result && conn->result->resultStatus == PGRES_COPY_OUT)
                res = pqPrepareAsyncResult(conn);
            else
                res = PQmakeEmptyPGresult(conn, PGRES_COPY_OUT);
            break;
        case PGASYNC_COPY_BOTH:
            if (conn->result && conn->result->resultStatus == PGRES_COPY_BOTH)
                res = pqPrepareAsyncResult(conn);
            else
                res = PQmakeEmptyPGresult(conn, PGRES_COPY_BOTH);
            break;
        default:
            printfPQExpBuffer(&conn->errorMessage,
                              libpq_gettext("unexpected asyncStatus: %d\n"),
                              (int) conn->asyncStatus);
            res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
            break;
    }

    if (res)
    {
        int         i;

        for (i = 0; i < res->nEvents; i++)
        {
            PGEventResultCreate evt;

            evt.conn = conn;
            evt.result = res;
            if (!res->events[i].proc(PGEVT_RESULTCREATE, &evt,
                                     res->events[i].passThrough))
            {
                printfPQExpBuffer(&conn->errorMessage,
                                  libpq_gettext("PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n"),
                                  res->events[i].name);
                pqSetResultError(res, conn->errorMessage.data);
                res->resultStatus = PGRES_FATAL_ERROR;
                break;
            }
            res->events[i].resultInitialized = TRUE;
        }
    }

    return res;
}

void* PQgetssl ( PGconn conn  ) 

Definition at line 1547 of file fe-secure.c.

Referenced by printSSLInfo().

{
    return NULL;
}

char* PQgetvalue ( const PGresult res,
int  tup_num,
int  field_num 
)

Definition at line 2965 of file fe-exec.c.

References check_tuple_field_number(), pg_result::tuples, and pgresAttValue::value.

Referenced by add_tablespace_footer(), BaseBackup(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel_oid(), binary_upgrade_set_type_oids_by_type_oid(), buildMatViewRefreshDependencies(), check_for_isn_and_int8_passing_mismatch(), check_for_reg_data_type_usage(), check_is_super_user(), cluster_all_databases(), collectComments(), collectSecLabels(), convertTSFunction(), createViewAsClause(), describeOneTableDetails(), describeRoles(), describeTableDetails(), do_field(), dropDBs(), dropRoles(), dropTablespaces(), dumpAgg(), dumpBaseType(), dumpBlobs(), dumpCollation(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConversion(), dumpCreateDB(), dumpDatabase(), dumpDatabaseConfig(), dumpDatabases(), dumpDbRoleConfig(), dumpDomain(), dumpEnumType(), dumpForeignServer(), dumpFunc(), dumpGroups(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpRangeType(), dumpRoleMembership(), dumpRoles(), dumpRule(), dumpSequence(), dumpSequenceData(), dumpTable(), dumpTableData_insert(), dumpTableSchema(), dumpTablespaces(), dumpTSConfig(), dumpTSDictionary(), dumpUserConfig(), dumpUserMappings(), ecpg_get_data(), ecpg_is_type_an_array(), ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), ecpg_store_result(), emitShSecLabels(), expand_schema_name_patterns(), expand_table_name_patterns(), findLastBuiltinOid_V70(), findLastBuiltinOid_V71(), get_create_function_cmd(), get_db_infos(), get_loadable_libraries(), get_pg_database_relfilenode(), get_rel_infos(), get_remote_estimate(), get_synchronized_snapshot(), get_tablespace_paths(), getAggregates(), getBlobs(), getCasts(), getCollations(), getConstraints(), getConversions(), getDefaultACLs(), getDependencies(), getDomainConstraints(), getEventTriggers(), getExtensionMembership(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFormattedTypeName(), getFuncs(), getIndexes(), getInherits(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getProcLangs(), getRules(), getTableAttrs(), getTables(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), libpqrcv_endstreaming(), libpqrcv_identify_system(), libpqrcv_readtimelinehistoryfile(), listExtensionContents(), listTSConfigsVerbose(), listTSParsersVerbose(), lo_initialize(), lockTableNoWait(), lookup_function_oid(), main(), make_tuple_from_result_row(), materializeResult(), new_9_0_populate_pg_largeobject_metadata(), old_8_3_check_for_name_data_type_usage(), old_8_3_check_for_tsquery_usage(), old_8_3_check_ltree_usage(), old_8_3_create_sequence_script(), old_8_3_invalidate_bpchar_pattern_ops_indexes(), old_8_3_invalidate_hash_gin_indexes(), old_8_3_rebuild_tsvector_tables(), postgresAnalyzeForeignTable(), PQdisplayTuples(), PQprintTuples(), pqSetenvPoll(), printQuery(), printResultSet(), ReceiveAndUnpackTarFile(), ReceiveTarFile(), ReceiveXlogStream(), reindex_all_databases(), set_frozenxids(), set_locale_and_encoding(), show_binary_results(), sql_exec(), sqlda_common_total_size(), StoreQueryTuple(), storeRow(), StreamLog(), vacuum_all_databases(), and vacuumlo().

{
    if (!check_tuple_field_number(res, tup_num, field_num))
        return NULL;
    return res->tuples[tup_num][field_num].value;
}

char* PQhost ( const PGconn conn  ) 

Definition at line 5181 of file fe-connect.c.

References pg_conn::pghost, and pg_conn::pgunixsocket.

Referenced by _connectDB(), CloneArchive(), do_connect(), exec_command(), get_prompt(), and SyncVariables().

{
    if (!conn)
        return NULL;
    return conn->pghost ? conn->pghost : conn->pgunixsocket;
}

void PQinitOpenSSL ( int  do_ssl,
int  do_crypto 
)

Definition at line 199 of file fe-secure.c.

Referenced by PQinitSSL().

{
#ifdef USE_SSL
#ifdef ENABLE_THREAD_SAFETY

    /*
     * Disallow changing the flags while we have open connections, else we'd
     * get completely confused.
     */
    if (ssl_open_connections != 0)
        return;
#endif

    pq_init_ssl_lib = do_ssl;
    pq_init_crypto_lib = do_crypto;
#endif
}

void PQinitSSL ( int  do_init  ) 

Definition at line 189 of file fe-secure.c.

References PQinitOpenSSL().

int PQisBusy ( PGconn conn  ) 

Definition at line 1658 of file fe-exec.c.

References pg_conn::asyncStatus, and parseInput().

Referenced by dblink_is_busy(), doCustom(), libpqrcv_PQexec(), PQconnectPoll(), pqEndcopy2(), pqEndcopy3(), pqSetenvPoll(), and try_complete_step().

{
    if (!conn)
        return FALSE;

    /* Parse any available data, if our state permits. */
    parseInput(conn);

    /* PQgetResult will return immediately in all states except BUSY. */
    return conn->asyncStatus == PGASYNC_BUSY;
}

int PQisnonblocking ( const PGconn conn  ) 

Definition at line 3066 of file fe-exec.c.

References pqIsnonblocking.

{
    return pqIsnonblocking(conn);
}

int PQisthreadsafe ( void   ) 

Definition at line 3073 of file fe-exec.c.

{
#ifdef ENABLE_THREAD_SAFETY
    return true;
#else
    return false;
#endif
}

int PQlibVersion ( void   ) 

Definition at line 72 of file fe-misc.c.

{
    return PG_VERSION_NUM;
}

PGresult* PQmakeEmptyPGresult ( PGconn conn,
ExecStatusType  status 
)

Definition at line 139 of file fe-exec.c.

References pg_result::attDescs, pg_result::binary, pg_conn::client_encoding, pg_result::client_encoding, pg_result::cmdStatus, pg_result::curBlock, pg_result::curOffset, PQExpBufferData::data, dupEvents(), pg_result::errFields, pg_result::errMsg, pg_conn::errorMessage, pg_conn::events, pg_result::events, malloc, pg_conn::nEvents, pg_result::nEvents, pg_conn::noticeHooks, pg_result::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeProcArg, PGNoticeHooks::noticeRec, PGNoticeHooks::noticeRecArg, pg_result::ntups, pg_result::null_field, pg_result::numAttributes, pg_result::numParameters, pg_result::paramDescs, PGRES_COMMAND_OK, PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_SINGLE_TUPLE, PGRES_TUPLES_OK, PQclear(), pqSetResultError(), pg_result::resultStatus, pg_result::spaceLeft, pg_result::tupArrSize, and pg_result::tuples.

Referenced by ECPGallocate_desc(), getAnotherTuple(), getCopyStart(), getParamDescriptions(), getRowDescriptions(), PQcopyResult(), pqFunctionCall2(), pqFunctionCall3(), pqGetErrorNotice2(), pqGetErrorNotice3(), PQgetResult(), pqInternalNotice(), pqParseInput2(), pqParseInput3(), pqPrepareAsyncResult(), and pqSaveErrorResult().

{
    PGresult   *result;

    result = (PGresult *) malloc(sizeof(PGresult));
    if (!result)
        return NULL;

    result->ntups = 0;
    result->numAttributes = 0;
    result->attDescs = NULL;
    result->tuples = NULL;
    result->tupArrSize = 0;
    result->numParameters = 0;
    result->paramDescs = NULL;
    result->resultStatus = status;
    result->cmdStatus[0] = '\0';
    result->binary = 0;
    result->events = NULL;
    result->nEvents = 0;
    result->errMsg = NULL;
    result->errFields = NULL;
    result->null_field[0] = '\0';
    result->curBlock = NULL;
    result->curOffset = 0;
    result->spaceLeft = 0;

    if (conn)
    {
        /* copy connection data we might need for operations on PGresult */
        result->noticeHooks = conn->noticeHooks;
        result->client_encoding = conn->client_encoding;

        /* consider copying conn's errorMessage */
        switch (status)
        {
            case PGRES_EMPTY_QUERY:
            case PGRES_COMMAND_OK:
            case PGRES_TUPLES_OK:
            case PGRES_COPY_OUT:
            case PGRES_COPY_IN:
            case PGRES_COPY_BOTH:
            case PGRES_SINGLE_TUPLE:
                /* non-error cases */
                break;
            default:
                pqSetResultError(result, conn->errorMessage.data);
                break;
        }

        /* copy events last; result must be valid if we need to PQclear */
        if (conn->nEvents > 0)
        {
            result->events = dupEvents(conn->events, conn->nEvents);
            if (!result->events)
            {
                PQclear(result);
                return NULL;
            }
            result->nEvents = conn->nEvents;
        }
    }
    else
    {
        /* defaults... */
        result->noticeHooks.noticeRec = NULL;
        result->noticeHooks.noticeRecArg = NULL;
        result->noticeHooks.noticeProc = NULL;
        result->noticeHooks.noticeProcArg = NULL;
        result->client_encoding = PG_SQL_ASCII;
    }

    return result;
}

int PQmblen ( const char *  s,
int  encoding 
)
int PQnfields ( const PGresult res  ) 
PGnotify* PQnotifies ( PGconn conn  ) 

Definition at line 2149 of file fe-exec.c.

References pgNotify::next, pg_conn::notifyHead, pg_conn::notifyTail, and parseInput().

Referenced by dblink_get_notify(), ecpg_execute(), main(), and PrintNotifications().

{
    PGnotify   *event;

    if (!conn)
        return NULL;

    /* Parse any available data to see if we can extract NOTIFY messages. */
    parseInput(conn);

    event = conn->notifyHead;
    if (event)
    {
        conn->notifyHead = event->next;
        if (!conn->notifyHead)
            conn->notifyTail = NULL;
        event->next = NULL;     /* don't let app see the internal state */
    }
    return event;
}

int PQnparams ( const PGresult res  ) 

Definition at line 3004 of file fe-exec.c.

References pg_result::numParameters.

{
    if (!res)
        return 0;
    return res->numParameters;
}

int PQntuples ( const PGresult res  ) 

Definition at line 2593 of file fe-exec.c.

References pg_result::ntups.

Referenced by add_tablespace_footer(), BaseBackup(), buildMatViewRefreshDependencies(), check_for_isn_and_int8_passing_mismatch(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_is_super_user(), cluster_all_databases(), collectComments(), collectSecLabels(), createViewAsClause(), describeOneTableDetails(), describeRoles(), describeTableDetails(), dropDBs(), dropRoles(), dropTablespaces(), dumpBlobs(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpCreateDB(), dumpDatabaseConfig(), dumpDatabases(), dumpDbRoleConfig(), dumpEnumType(), dumpGroups(), dumpOpclass(), dumpOpfamily(), dumpRoleMembership(), dumpRoles(), dumpRule(), dumpSequence(), dumpSequenceData(), dumpTable(), dumpTableData_insert(), dumpTablespaces(), dumpTSConfig(), dumpUserConfig(), dumpUserMappings(), ecpg_execute(), ecpg_is_type_an_array(), ecpg_store_result(), ECPGget_desc(), emitShSecLabels(), ExecQueryUsingCursor(), ExecuteSqlQueryForSingleRow(), expand_schema_name_patterns(), expand_table_name_patterns(), fetch_more_data(), get_create_function_cmd(), get_db_infos(), get_loadable_libraries(), get_rel_infos(), get_tablespace_paths(), getAggregates(), getBlobs(), getCasts(), getCollations(), getConstraints(), getConversions(), getDefaultACLs(), getDependencies(), getDomainConstraints(), getEventTriggers(), getExtensionMembership(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFuncs(), getIndexes(), getInherits(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getProcLangs(), getRules(), getTableAttrs(), getTables(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), libpqrcv_endstreaming(), libpqrcv_identify_system(), libpqrcv_readtimelinehistoryfile(), listDbRoleSettings(), listExtensionContents(), listTables(), listTSConfigsVerbose(), listTSParsersVerbose(), lo_initialize(), lookup_function_oid(), main(), make_tuple_from_result_row(), materializeResult(), old_8_3_check_for_name_data_type_usage(), old_8_3_check_for_tsquery_usage(), old_8_3_check_ltree_usage(), old_8_3_create_sequence_script(), old_8_3_invalidate_bpchar_pattern_ops_indexes(), old_8_3_invalidate_hash_gin_indexes(), old_8_3_rebuild_tsvector_tables(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresExecForeignDelete(), postgresExecForeignInsert(), postgresExecForeignUpdate(), PQdisplayTuples(), PQprint(), PQprintTuples(), pqSetenvPoll(), printQuery(), printResultSet(), ReceiveXlogStream(), reindex_all_databases(), set_frozenxids(), set_locale_and_encoding(), show_binary_results(), sql_exec(), StoreQueryTuple(), storeRow(), StreamLog(), try_complete_step(), vacuum_all_databases(), and vacuumlo().

{
    if (!res)
        return 0;
    return res->ntups;
}

char* PQoidStatus ( const PGresult res  ) 

Definition at line 2854 of file fe-exec.c.

References buf, and pg_result::cmdStatus.

{
    /*
     * This must be enough to hold the result. Don't laugh, this is better
     * than what this function used to do.
     */
    static char buf[24];

    size_t      len;

    if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
        return "";

    len = strspn(res->cmdStatus + 7, "0123456789");
    if (len > 23)
        len = 23;
    strncpy(buf, res->cmdStatus + 7, len);
    buf[len] = '\0';

    return buf;
}

Oid PQoidValue ( const PGresult res  ) 

Definition at line 2882 of file fe-exec.c.

References pg_result::cmdStatus.

Referenced by ecpg_execute(), and PrintQueryStatus().

{
    char       *endptr = NULL;
    unsigned long result;

    if (!res ||
        !res->cmdStatus ||
        strncmp(res->cmdStatus, "INSERT ", 7) != 0 ||
        res->cmdStatus[7] < '0' ||
        res->cmdStatus[7] > '9')
        return InvalidOid;

    result = strtoul(res->cmdStatus + 7, &endptr, 10);

    if (!endptr || (*endptr != ' ' && *endptr != '\0'))
        return InvalidOid;
    else
        return (Oid) result;
}

char* PQoptions ( const PGconn conn  ) 

Definition at line 5205 of file fe-connect.c.

References pg_conn::pgoptions.

{
    if (!conn)
        return NULL;
    return conn->pgoptions;
}

const char* PQparameterStatus ( const PGconn conn,
const char *  paramName 
)

Definition at line 5231 of file fe-connect.c.

References pgParameterStatus::name, pgParameterStatus::next, NULL, pg_conn::pstatus, and pgParameterStatus::value.

Referenced by _check_database_version(), applyRemoteGucs(), BaseBackup(), CheckServerVersionForStreaming(), connectDatabase(), connection_warnings(), GetConnection(), is_superuser(), main(), session_username(), setup_connection(), and standard_strings().

{
    const pgParameterStatus *pstatus;

    if (!conn || !paramName)
        return NULL;
    for (pstatus = conn->pstatus; pstatus != NULL; pstatus = pstatus->next)
    {
        if (strcmp(pstatus->name, paramName) == 0)
            return pstatus->value;
    }
    return NULL;
}

Oid PQparamtype ( const PGresult res,
int  param_num 
)

Definition at line 3015 of file fe-exec.c.

References check_param_number(), pg_result::paramDescs, and pgresParamDesc::typid.

{
    if (!check_param_number(res, param_num))
        return InvalidOid;
    if (res->paramDescs)
        return res->paramDescs[param_num].typid;
    else
        return InvalidOid;
}

char* PQpass ( const PGconn conn  ) 

Definition at line 5173 of file fe-connect.c.

References pg_conn::pgpass.

Referenced by do_connect().

{
    if (!conn)
        return NULL;
    return conn->pgpass;
}

PGPing PQping ( const char *  conninfo  ) 

Definition at line 527 of file fe-connect.c.

References conn, internal_ping(), PQconnectStart(), and PQfinish().

Referenced by test_postmaster_connection().

{
    PGconn     *conn = PQconnectStart(conninfo);
    PGPing      ret;

    ret = internal_ping(conn);
    PQfinish(conn);

    return ret;
}

PGPing PQpingParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

Definition at line 474 of file fe-connect.c.

References conn, internal_ping(), PQconnectStartParams(), and PQfinish().

Referenced by main().

{
    PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
    PGPing      ret;

    ret = internal_ping(conn);
    PQfinish(conn);

    return ret;
}

char* PQport ( const PGconn conn  ) 

Definition at line 5189 of file fe-connect.c.

References pg_conn::pgport.

Referenced by _connectDB(), CloneArchive(), do_connect(), exec_command(), get_prompt(), and SyncVariables().

{
    if (!conn)
        return NULL;
    return conn->pgport;
}

PGresult* PQprepare ( PGconn conn,
const char *  stmtName,
const char *  query,
int  nParams,
const Oid paramTypes 
)

Definition at line 1846 of file fe-exec.c.

References PQexecFinish(), PQexecStart(), and PQsendPrepare().

Referenced by doCustom(), main(), prepare_common(), and prepare_foreign_modify().

{
    if (!PQexecStart(conn))
        return NULL;
    if (!PQsendPrepare(conn, stmtName, query, nParams, paramTypes))
        return NULL;
    return PQexecFinish(conn);
}

void PQprint ( FILE *  fout,
const PGresult res,
const PQprintOpt ps 
)

Definition at line 68 of file fe-print.c.

References _PQprintOpt::align, calloc, _PQprintOpt::caption, do_field(), do_header(), _PQprintOpt::expanded, _PQprintOpt::fieldName, _PQprintOpt::fieldSep, free, _PQprintOpt::header, _PQprintOpt::html3, i, libpq_gettext, NULL, output_row(), _PQprintOpt::pager, PQfname(), PQnfields(), PQntuples(), pqsignal(), SIG_IGN, SIGPIPE, _PQprintOpt::standard, and _PQprintOpt::tableOpt.

{
    int         nFields;

    nFields = PQnfields(res);

    if (nFields > 0)
    {                           /* only print rows with at least 1 field.  */
        int         i,
                    j;
        int         nTups;
        int        *fieldMax = NULL;    /* in case we don't use them */
        unsigned char *fieldNotNum = NULL;
        char       *border = NULL;
        char      **fields = NULL;
        const char **fieldNames;
        int         fieldMaxLen = 0;
        int         numFieldName;
        int         fs_len = strlen(po->fieldSep);
        int         total_line_length = 0;
        int         usePipe = 0;
        char       *pagerenv;

#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
        sigset_t    osigset;
        bool        sigpipe_masked = false;
        bool        sigpipe_pending;
#endif
#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
        pqsigfunc   oldsigpipehandler = NULL;
#endif

#ifdef TIOCGWINSZ
        struct winsize screen_size;
#else
        struct winsize
        {
            int         ws_row;
            int         ws_col;
        }           screen_size;
#endif

        nTups = PQntuples(res);
        if (!(fieldNames = (const char **) calloc(nFields, sizeof(char *))))
        {
            fprintf(stderr, libpq_gettext("out of memory\n"));
            abort();
        }
        if (!(fieldNotNum = (unsigned char *) calloc(nFields, 1)))
        {
            fprintf(stderr, libpq_gettext("out of memory\n"));
            abort();
        }
        if (!(fieldMax = (int *) calloc(nFields, sizeof(int))))
        {
            fprintf(stderr, libpq_gettext("out of memory\n"));
            abort();
        }
        for (numFieldName = 0;
             po->fieldName && po->fieldName[numFieldName];
             numFieldName++)
            ;
        for (j = 0; j < nFields; j++)
        {
            int         len;
            const char *s = (j < numFieldName && po->fieldName[j][0]) ?
            po->fieldName[j] : PQfname(res, j);

            fieldNames[j] = s;
            len = s ? strlen(s) : 0;
            fieldMax[j] = len;
            len += fs_len;
            if (len > fieldMaxLen)
                fieldMaxLen = len;
            total_line_length += len;
        }

        total_line_length += nFields * strlen(po->fieldSep) + 1;

        if (fout == NULL)
            fout = stdout;
        if (po->pager && fout == stdout && isatty(fileno(stdin)) &&
            isatty(fileno(stdout)))
        {
            /*
             * If we think there'll be more than one screen of output, try to
             * pipe to the pager program.
             */
#ifdef TIOCGWINSZ
            if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
                screen_size.ws_col == 0 ||
                screen_size.ws_row == 0)
            {
                screen_size.ws_row = 24;
                screen_size.ws_col = 80;
            }
#else
            screen_size.ws_row = 24;
            screen_size.ws_col = 80;
#endif
            pagerenv = getenv("PAGER");
            if (pagerenv != NULL &&
                pagerenv[0] != '\0' &&
                !po->html3 &&
                ((po->expanded &&
                  nTups * (nFields + 1) >= screen_size.ws_row) ||
                 (!po->expanded &&
                  nTups * (total_line_length / screen_size.ws_col + 1) *
                  (1 + (po->standard != 0)) >= screen_size.ws_row -
                  (po->header != 0) *
                  (total_line_length / screen_size.ws_col + 1) * 2
                  - (po->header != 0) * 2       /* row count and newline */
                  )))
            {
                fout = popen(pagerenv, "w");
                if (fout)
                {
                    usePipe = 1;
#ifndef WIN32
#ifdef ENABLE_THREAD_SAFETY
                    if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
                        sigpipe_masked = true;
#else
                    oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
#endif   /* ENABLE_THREAD_SAFETY */
#endif   /* WIN32 */
                }
                else
                    fout = stdout;
            }
        }

        if (!po->expanded && (po->align || po->html3))
        {
            if (!(fields = (char **) calloc(nFields * (nTups + 1), sizeof(char *))))
            {
                fprintf(stderr, libpq_gettext("out of memory\n"));
                abort();
            }
        }
        else if (po->header && !po->html3)
        {
            if (po->expanded)
            {
                if (po->align)
                    fprintf(fout, libpq_gettext("%-*s%s Value\n"),
                            fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep);
                else
                    fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep);
            }
            else
            {
                int         len = 0;

                for (j = 0; j < nFields; j++)
                {
                    const char *s = fieldNames[j];

                    fputs(s, fout);
                    len += strlen(s) + fs_len;
                    if ((j + 1) < nFields)
                        fputs(po->fieldSep, fout);
                }
                fputc('\n', fout);
                for (len -= fs_len; len--; fputc('-', fout));
                fputc('\n', fout);
            }
        }
        if (po->expanded && po->html3)
        {
            if (po->caption)
                fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption);
            else
                fprintf(fout,
                        "<center><h2>"
                        "Query retrieved %d rows * %d fields"
                        "</h2></center>\n",
                        nTups, nFields);
        }
        for (i = 0; i < nTups; i++)
        {
            if (po->expanded)
            {
                if (po->html3)
                    fprintf(fout,
                            "<table %s><caption align=\"top\">%d</caption>\n",
                            po->tableOpt ? po->tableOpt : "", i);
                else
                    fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);
            }
            for (j = 0; j < nFields; j++)
                do_field(po, res, i, j, fs_len, fields, nFields,
                         fieldNames, fieldNotNum,
                         fieldMax, fieldMaxLen, fout);
            if (po->html3 && po->expanded)
                fputs("</table>\n", fout);
        }
        if (!po->expanded && (po->align || po->html3))
        {
            if (po->html3)
            {
                if (po->header)
                {
                    if (po->caption)
                        fprintf(fout,
                           "<table %s><caption align=\"top\">%s</caption>\n",
                                po->tableOpt ? po->tableOpt : "",
                                po->caption);
                    else
                        fprintf(fout,
                                "<table %s><caption align=\"top\">"
                                "Retrieved %d rows * %d fields"
                                "</caption>\n",
                           po->tableOpt ? po->tableOpt : "", nTups, nFields);
                }
                else
                    fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
            }
            if (po->header)
                border = do_header(fout, po, nFields, fieldMax, fieldNames,
                                   fieldNotNum, fs_len, res);
            for (i = 0; i < nTups; i++)
                output_row(fout, po, nFields, fields,
                           fieldNotNum, fieldMax, border, i);
            free(fields);
            if (border)
                free(border);
        }
        if (po->header && !po->html3)
            fprintf(fout, "(%d row%s)\n\n", PQntuples(res),
                    (PQntuples(res) == 1) ? "" : "s");
        free(fieldMax);
        free(fieldNotNum);
        free((void *) fieldNames);
        if (usePipe)
        {
#ifdef WIN32
            _pclose(fout);
#else
            pclose(fout);

#ifdef ENABLE_THREAD_SAFETY
            /* we can't easily verify if EPIPE occurred, so say it did */
            if (sigpipe_masked)
                pq_reset_sigpipe(&osigset, sigpipe_pending, true);
#else
            pqsignal(SIGPIPE, oldsigpipehandler);
#endif   /* ENABLE_THREAD_SAFETY */
#endif   /* WIN32 */
        }
        if (po->html3 && !po->expanded)
            fputs("</table>\n", fout);
    }
}

void PQprintTuples ( const PGresult res,
FILE *  fout,
int  printAttName,
int  terseOutput,
int  width 
)

Definition at line 671 of file fe-print.c.

References free, i, libpq_gettext, malloc, PQfname(), PQgetvalue(), PQnfields(), and PQntuples().

{
    int         nFields;
    int         nTups;
    int         i,
                j;
    char        formatString[80];
    char       *tborder = NULL;

    nFields = PQnfields(res);
    nTups = PQntuples(res);

    if (colWidth > 0)
        sprintf(formatString, "%%s %%-%ds", colWidth);
    else
        sprintf(formatString, "%%s %%s");

    if (nFields > 0)
    {                           /* only print rows with at least 1 field.  */

        if (!TerseOutput)
        {
            int         width;

            width = nFields * 14;
            tborder = (char *) malloc(width + 1);
            if (!tborder)
            {
                fprintf(stderr, libpq_gettext("out of memory\n"));
                abort();
            }
            for (i = 0; i < width; i++)
                tborder[i] = '-';
            tborder[width] = '\0';
            fprintf(fout, "%s\n", tborder);
        }

        for (i = 0; i < nFields; i++)
        {
            if (PrintAttNames)
            {
                fprintf(fout, formatString,
                        TerseOutput ? "" : "|",
                        PQfname(res, i));
            }
        }

        if (PrintAttNames)
        {
            if (TerseOutput)
                fprintf(fout, "\n");
            else
                fprintf(fout, "|\n%s\n", tborder);
        }

        for (i = 0; i < nTups; i++)
        {
            for (j = 0; j < nFields; j++)
            {
                const char *pval = PQgetvalue(res, i, j);

                fprintf(fout, formatString,
                        TerseOutput ? "" : "|",
                        pval ? pval : "");
            }
            if (TerseOutput)
                fprintf(fout, "\n");
            else
                fprintf(fout, "|\n%s\n", tborder);
        }
    }

    if (tborder)
        free(tborder);
}

int PQprotocolVersion ( const PGconn conn  ) 

Definition at line 5246 of file fe-connect.c.

References CONNECTION_BAD, PG_PROTOCOL_MAJOR, pg_conn::pversion, and pg_conn::status.

{
    if (!conn)
        return 0;
    if (conn->status == CONNECTION_BAD)
        return 0;
    return PG_PROTOCOL_MAJOR(conn->pversion);
}

int PQputCopyData ( PGconn conn,
const char *  buffer,
int  nbytes 
)

Definition at line 2177 of file fe-exec.c.

References pg_conn::asyncStatus, pg_conn::errorMessage, libpq_gettext, pg_conn::outBufSize, pg_conn::outCount, parseInput(), PG_PROTOCOL_MAJOR, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, pqCheckOutBufferSpace(), pqFlush(), pqIsnonblocking, pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), printfPQExpBuffer(), and pg_conn::pversion.

Referenced by ExecuteSqlCommandBuf(), handleCopyIn(), libpqrcv_send(), PQputnbytes(), and sendFeedback().

{
    if (!conn)
        return -1;
    if (conn->asyncStatus != PGASYNC_COPY_IN &&
        conn->asyncStatus != PGASYNC_COPY_BOTH)
    {
        printfPQExpBuffer(&conn->errorMessage,
                          libpq_gettext("no COPY in progress\n"));
        return -1;
    }

    /*
     * Process any NOTICE or NOTIFY messages that might be pending in the
     * input buffer.  Since the server might generate many notices during the
     * COPY, we want to clean those out reasonably promptly to prevent
     * indefinite expansion of the input buffer.  (Note: the actual read of
     * input data into the input buffer happens down inside pqSendSome, but
     * it's not authorized to get rid of the data again.)
     */
    parseInput(conn);

    if (nbytes > 0)
    {
        /*
         * Try to flush any previously sent data in preference to growing the
         * output buffer.  If we can't enlarge the buffer enough to hold the
         * data, return 0 in the nonblock case, else hard error. (For
         * simplicity, always assume 5 bytes of overhead even in protocol 2.0
         * case.)
         */
        if ((conn->outBufSize - conn->outCount - 5) < nbytes)
        {
            if (pqFlush(conn) < 0)
                return -1;
            if (pqCheckOutBufferSpace(conn->outCount + 5 + (size_t) nbytes,
                                      conn))
                return pqIsnonblocking(conn) ? 0 : -1;
        }
        /* Send the data (too simple to delegate to fe-protocol files) */
        if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
        {
            if (pqPutMsgStart('d', false, conn) < 0 ||
                pqPutnchar(buffer, nbytes, conn) < 0 ||
                pqPutMsgEnd(conn) < 0)
                return -1;
        }
        else
        {
            if (pqPutMsgStart(0, false, conn) < 0 ||
                pqPutnchar(buffer, nbytes, conn) < 0 ||
                pqPutMsgEnd(conn) < 0)
                return -1;
        }
    }
    return 1;
}

int PQputCopyEnd ( PGconn conn,
const char *  errormsg 
)

Definition at line 2244 of file fe-exec.c.

References pg_conn::asyncStatus, pg_conn::errorMessage, libpq_gettext, PG_PROTOCOL_MAJOR, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGQUERY_SIMPLE, pqFlush(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqPuts(), printfPQExpBuffer(), pg_conn::pversion, pg_conn::queryclass, and resetPQExpBuffer().

Referenced by EndDBCopyMode(), handleCopyIn(), HandleCopyStream(), libpqrcv_endstreaming(), and PQexecStart().

{
    if (!conn)
        return -1;
    if (conn->asyncStatus != PGASYNC_COPY_IN &&
        conn->asyncStatus != PGASYNC_COPY_BOTH)
    {
        printfPQExpBuffer(&conn->errorMessage,
                          libpq_gettext("no COPY in progress\n"));
        return -1;
    }

    /*
     * Send the COPY END indicator.  This is simple enough that we don't
     * bother delegating it to the fe-protocol files.
     */
    if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
    {
        if (errormsg)
        {
            /* Send COPY FAIL */
            if (pqPutMsgStart('f', false, conn) < 0 ||
                pqPuts(errormsg, conn) < 0 ||
                pqPutMsgEnd(conn) < 0)
                return -1;
        }
        else
        {
            /* Send COPY DONE */
            if (pqPutMsgStart('c', false, conn) < 0 ||
                pqPutMsgEnd(conn) < 0)
                return -1;
        }

        /*
         * If we sent the COPY command in extended-query mode, we must issue a
         * Sync as well.
         */
        if (conn->queryclass != PGQUERY_SIMPLE)
        {
            if (pqPutMsgStart('S', false, conn) < 0 ||
                pqPutMsgEnd(conn) < 0)
                return -1;
        }
    }
    else
    {
        if (errormsg)
        {
            /* Ooops, no way to do this in 2.0 */
            printfPQExpBuffer(&conn->errorMessage,
                              libpq_gettext("function requires at least protocol version 3.0\n"));
            return -1;
        }
        else
        {
            /* Send old-style end-of-data marker */
            if (pqPutMsgStart(0, false, conn) < 0 ||
                pqPutnchar("\\.\n", 3, conn) < 0 ||
                pqPutMsgEnd(conn) < 0)
                return -1;
        }
    }

    /* Return to active duty */
    if (conn->asyncStatus == PGASYNC_COPY_BOTH)
        conn->asyncStatus = PGASYNC_COPY_OUT;
    else
        conn->asyncStatus = PGASYNC_BUSY;
    resetPQExpBuffer(&conn->errorMessage);

    /* Try to flush data */
    if (pqFlush(conn) < 0)
        return -1;

    return 1;
}

int PQputline ( PGconn conn,
const char *  string 
)

Definition at line 2445 of file fe-exec.c.

References PQputnbytes().

Referenced by init().

{
    return PQputnbytes(conn, s, strlen(s));
}

int PQputnbytes ( PGconn conn,
const char *  buffer,
int  nbytes 
)

Definition at line 2455 of file fe-exec.c.

References PQputCopyData().

Referenced by PQputline().

{
    if (PQputCopyData(conn, buffer, nbytes) > 0)
        return 0;
    else
        return EOF;
}

pgthreadlock_t PQregisterThreadLock ( pgthreadlock_t  newhandler  ) 

Definition at line 5735 of file fe-connect.c.

References pg_g_threadlock.

{
    pgthreadlock_t prev = pg_g_threadlock;

    if (newhandler)
        pg_g_threadlock = newhandler;
    else
        pg_g_threadlock = default_threadlock;

    return prev;
}

int PQrequestCancel ( PGconn conn  ) 

Definition at line 3263 of file fe-connect.c.

References pg_conn::be_key, pg_conn::be_pid, PQExpBufferData::data, pg_conn::errorMessage, internal_cancel(), PQExpBufferData::len, PQExpBufferData::maxlen, pg_conn::raddr, pg_conn::sock, and strlcpy().

{
    int         r;

    /* Check we have an open connection */
    if (!conn)
        return FALSE;

    if (conn->sock < 0)
    {
        strlcpy(conn->errorMessage.data,
                "PQrequestCancel() -- connection is not open\n",
                conn->errorMessage.maxlen);
        conn->errorMessage.len = strlen(conn->errorMessage.data);

        return FALSE;
    }

    r = internal_cancel(&conn->raddr, conn->be_pid, conn->be_key,
                        conn->errorMessage.data, conn->errorMessage.maxlen);

    if (!r)
        conn->errorMessage.len = strlen(conn->errorMessage.data);

    return r;
}

void PQreset ( PGconn conn  ) 

Definition at line 2976 of file fe-connect.c.

References closePGconn(), PGEventConnReset::conn, connectDBComplete(), connectDBStart(), pg_conn::errorMessage, pg_conn::events, i, libpq_gettext, PGEvent::name, pg_conn::nEvents, PGEvent::passThrough, PGEVT_CONNRESET, printfPQExpBuffer(), PGEvent::proc, and pg_conn::status.

Referenced by CheckConnection(), and pqEndcopy2().

{
    if (conn)
    {
        closePGconn(conn);

        if (connectDBStart(conn) && connectDBComplete(conn))
        {
            /*
             * Notify event procs of successful reset.  We treat an event proc
             * failure as disabling the connection ... good idea?
             */
            int         i;

            for (i = 0; i < conn->nEvents; i++)
            {
                PGEventConnReset evt;

                evt.conn = conn;
                if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
                                          conn->events[i].passThrough))
                {
                    conn->status = CONNECTION_BAD;
                    printfPQExpBuffer(&conn->errorMessage,
                                      libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
                                      conn->events[i].name);
                    break;
                }
            }
        }
    }
}

PostgresPollingStatusType PQresetPoll ( PGconn conn  ) 

Definition at line 3036 of file fe-connect.c.

References PGEventConnReset::conn, pg_conn::errorMessage, pg_conn::events, i, libpq_gettext, PGEvent::name, pg_conn::nEvents, PGEvent::passThrough, PGEVT_CONNRESET, PGRES_POLLING_OK, PQconnectPoll(), printfPQExpBuffer(), PGEvent::proc, pg_conn::status, and status().

{
    if (conn)
    {
        PostgresPollingStatusType status = PQconnectPoll(conn);

        if (status == PGRES_POLLING_OK)
        {
            /*
             * Notify event procs of successful reset.  We treat an event proc
             * failure as disabling the connection ... good idea?
             */
            int         i;

            for (i = 0; i < conn->nEvents; i++)
            {
                PGEventConnReset evt;

                evt.conn = conn;
                if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
                                          conn->events[i].passThrough))
                {
                    conn->status = CONNECTION_BAD;
                    printfPQExpBuffer(&conn->errorMessage,
                                      libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
                                      conn->events[i].name);
                    return PGRES_POLLING_FAILED;
                }
            }
        }

        return status;
    }

    return PGRES_POLLING_FAILED;
}

int PQresetStart ( PGconn conn  ) 

Definition at line 3017 of file fe-connect.c.

References closePGconn(), and connectDBStart().

Referenced by pqEndcopy2().

{
    if (conn)
    {
        closePGconn(conn);

        return connectDBStart(conn);
    }

    return 0;
}

char* PQresStatus ( ExecStatusType  status  ) 

Definition at line 2562 of file fe-exec.c.

References libpq_gettext, and pgresStatus.

Referenced by try_complete_step().

{
    if ((unsigned int) status >= sizeof pgresStatus / sizeof pgresStatus[0])
        return libpq_gettext("invalid ExecStatusType code");
    return pgresStatus[status];
}

void* PQresultAlloc ( PGresult res,
size_t  nBytes 
)

Definition at line 488 of file fe-exec.c.

References pqResultAlloc(), and TRUE.

Referenced by PQsetResultAttrs().

{
    return pqResultAlloc(res, nBytes, TRUE);
}

char* PQresultErrorField ( const PGresult res,
int  fieldcode 
)

Definition at line 2578 of file fe-exec.c.

References pgMessageField::code, pgMessageField::contents, pg_result::errFields, pgMessageField::next, and NULL.

Referenced by dblink_res_error(), dot_pg_pass_warning(), ecpg_raise_backend(), ECPGnoticeReceiver(), minimal_error_message(), pgfdw_report_error(), PQconnectPoll(), pqGetErrorNotice3(), and try_complete_step().

{
    PGMessageField *pfield;

    if (!res)
        return NULL;
    for (pfield = res->errFields; pfield != NULL; pfield = pfield->next)
    {
        if (pfield->code == fieldcode)
            return pfield->contents;
    }
    return NULL;
}

char* PQresultErrorMessage ( const PGresult res  ) 

Definition at line 2570 of file fe-exec.c.

References pg_result::errMsg.

Referenced by defaultNoticeReceiver(), ecpg_check_PQresult(), ecpg_execute(), pqPrepareAsyncResult(), ReceiveXlogStream(), and try_complete_step().

{
    if (!res || !res->errMsg)
        return "";
    return res->errMsg;
}

ExecStatusType PQresultStatus ( const PGresult res  ) 

Definition at line 2554 of file fe-exec.c.

References pg_result::resultStatus.

Referenced by _doSetSessionAuth(), _doSetWithOids(), _selectOutputSchema(), _selectTablespace(), AcceptResult(), BaseBackup(), check_loadable_libraries(), close_cursor(), create_cursor(), dblink_close(), dblink_exec(), dblink_fetch(), dblink_open(), dblink_record_internal(), do_sql_command(), do_watch(), doCustom(), dumpTableData_copy(), ecpg_check_PQresult(), ecpg_execute(), ecpg_is_type_an_array(), EndDBCopyMode(), ExecQueryUsingCursor(), executeCommand(), executeMaintenanceCommand(), executeQuery(), executeQueryOrDie(), ExecuteSqlCommand(), ExecuteSqlQuery(), ExecuteSqlStatement(), executeStatement(), fetch_more_data(), get_create_function_cmd(), get_remote_estimate(), handleCopyIn(), handleCopyOut(), HandleCopyStream(), init(), libpqrcv_endstreaming(), libpqrcv_identify_system(), libpqrcv_PQexec(), libpqrcv_readtimelinehistoryfile(), libpqrcv_receive(), libpqrcv_startstreaming(), lo_close(), lo_creat(), lo_create(), lo_lseek(), lo_lseek64(), lo_open(), lo_read(), lo_tell(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_unlink(), lo_write(), lockTableNoWait(), lookup_function_oid(), main(), materializeQueryResult(), materializeResult(), pgfdw_subxact_callback(), pgfdw_xact_callback(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresEndForeignModify(), postgresExecForeignDelete(), postgresExecForeignInsert(), postgresExecForeignUpdate(), postgresReScanForeignScan(), pqSetenvPoll(), prepare_foreign_modify(), PrintQueryResults(), ProcessResult(), PSQLexec(), ReceiveAndUnpackTarFile(), ReceiveTarFile(), ReceiveXlogStream(), run_permutation(), SendQuery(), sql_exec(), storeQueryResult(), StreamLog(), try_complete_step(), and vacuumlo().

{
    if (!res)
        return PGRES_FATAL_ERROR;
    return res->resultStatus;
}

int PQsendDescribePortal ( PGconn conn,
const char *  portal 
)

Definition at line 2068 of file fe-exec.c.

References PQsendDescribe().

{
    return PQsendDescribe(conn, 'P', portal);
}

int PQsendDescribePrepared ( PGconn conn,
const char *  stmt 
)

Definition at line 2055 of file fe-exec.c.

References PQsendDescribe().

{
    return PQsendDescribe(conn, 'S', stmt);
}

int PQsendPrepare ( PGconn conn,
const char *  stmtName,
const char *  query,
int  nParams,
const Oid paramTypes 
)

Definition at line 1207 of file fe-exec.c.

References pg_conn::asyncStatus, pg_conn::errorMessage, free, i, pg_conn::last_query, libpq_gettext, PG_PROTOCOL_MAJOR, pqFlush(), pqHandleSendFailure(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPuts(), PQsendQueryStart(), printfPQExpBuffer(), pg_conn::pversion, and pg_conn::queryclass.

Referenced by PQprepare().

{
    if (!PQsendQueryStart(conn))
        return 0;

    /* check the arguments */
    if (!stmtName)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("statement name is a null pointer\n"));
        return 0;
    }
    if (!query)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("command string is a null pointer\n"));
        return 0;
    }
    if (nParams < 0 || nParams > 65535)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("number of parameters must be between 0 and 65535\n"));
        return 0;
    }

    /* This isn't gonna work on a 2.0 server */
    if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
    {
        printfPQExpBuffer(&conn->errorMessage,
         libpq_gettext("function requires at least protocol version 3.0\n"));
        return 0;
    }

    /* construct the Parse message */
    if (pqPutMsgStart('P', false, conn) < 0 ||
        pqPuts(stmtName, conn) < 0 ||
        pqPuts(query, conn) < 0)
        goto sendFailed;

    if (nParams > 0 && paramTypes)
    {
        int         i;

        if (pqPutInt(nParams, 2, conn) < 0)
            goto sendFailed;
        for (i = 0; i < nParams; i++)
        {
            if (pqPutInt(paramTypes[i], 4, conn) < 0)
                goto sendFailed;
        }
    }
    else
    {
        if (pqPutInt(0, 2, conn) < 0)
            goto sendFailed;
    }
    if (pqPutMsgEnd(conn) < 0)
        goto sendFailed;

    /* construct the Sync message */
    if (pqPutMsgStart('S', false, conn) < 0 ||
        pqPutMsgEnd(conn) < 0)
        goto sendFailed;

    /* remember we are doing just a Parse */
    conn->queryclass = PGQUERY_PREPARE;

    /* and remember the query text too, if possible */
    /* if insufficient memory, last_query just winds up NULL */
    if (conn->last_query)
        free(conn->last_query);
    conn->last_query = strdup(query);

    /*
     * Give the data a push.  In nonblock mode, don't complain if we're unable
     * to send it all; PQgetResult() will do any additional flushing needed.
     */
    if (pqFlush(conn) < 0)
        goto sendFailed;

    /* OK, it's launched! */
    conn->asyncStatus = PGASYNC_BUSY;
    return 1;

sendFailed:
    pqHandleSendFailure(conn);
    return 0;
}

int PQsendQuery ( PGconn conn,
const char *  query 
)

Definition at line 1111 of file fe-exec.c.

References pg_conn::asyncStatus, pg_conn::errorMessage, free, pg_conn::last_query, libpq_gettext, pqFlush(), pqHandleSendFailure(), pqPutMsgEnd(), pqPutMsgStart(), pqPuts(), PQsendQueryStart(), printfPQExpBuffer(), and pg_conn::queryclass.

Referenced by BaseBackup(), dblink_send_query(), doCustom(), libpqrcv_PQexec(), PQexec(), pqSetenvPoll(), run_permutation(), and storeQueryResult().

{
    if (!PQsendQueryStart(conn))
        return 0;

    /* check the argument */
    if (!query)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("command string is a null pointer\n"));
        return 0;
    }

    /* construct the outgoing Query message */
    if (pqPutMsgStart('Q', false, conn) < 0 ||
        pqPuts(query, conn) < 0 ||
        pqPutMsgEnd(conn) < 0)
    {
        pqHandleSendFailure(conn);
        return 0;
    }

    /* remember we are using simple query protocol */
    conn->queryclass = PGQUERY_SIMPLE;

    /* and remember the query text too, if possible */
    /* if insufficient memory, last_query just winds up NULL */
    if (conn->last_query)
        free(conn->last_query);
    conn->last_query = strdup(query);

    /*
     * Give the data a push.  In nonblock mode, don't complain if we're unable
     * to send it all; PQgetResult() will do any additional flushing needed.
     */
    if (pqFlush(conn) < 0)
    {
        pqHandleSendFailure(conn);
        return 0;
    }

    /* OK, it's launched! */
    conn->asyncStatus = PGASYNC_BUSY;
    return 1;
}

int PQsendQueryParams ( PGconn conn,
const char *  command,
int  nParams,
const Oid paramTypes,
const char *const *  paramValues,
const int *  paramLengths,
const int *  paramFormats,
int  resultFormat 
)

Definition at line 1162 of file fe-exec.c.

References pg_conn::errorMessage, libpq_gettext, PQsendQueryGuts(), PQsendQueryStart(), and printfPQExpBuffer().

Referenced by doCustom(), and PQexecParams().

{
    if (!PQsendQueryStart(conn))
        return 0;

    /* check the arguments */
    if (!command)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("command string is a null pointer\n"));
        return 0;
    }
    if (nParams < 0 || nParams > 65535)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("number of parameters must be between 0 and 65535\n"));
        return 0;
    }

    return PQsendQueryGuts(conn,
                           command,
                           "",  /* use unnamed statement */
                           nParams,
                           paramTypes,
                           paramValues,
                           paramLengths,
                           paramFormats,
                           resultFormat);
}

int PQsendQueryPrepared ( PGconn conn,
const char *  stmtName,
int  nParams,
const char *const *  paramValues,
const int *  paramLengths,
const int *  paramFormats,
int  resultFormat 
)

Definition at line 1304 of file fe-exec.c.

References pg_conn::errorMessage, libpq_gettext, NULL, PQsendQueryGuts(), PQsendQueryStart(), and printfPQExpBuffer().

Referenced by doCustom(), and PQexecPrepared().

{
    if (!PQsendQueryStart(conn))
        return 0;

    /* check the arguments */
    if (!stmtName)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("statement name is a null pointer\n"));
        return 0;
    }
    if (nParams < 0 || nParams > 65535)
    {
        printfPQExpBuffer(&conn->errorMessage,
                        libpq_gettext("number of parameters must be between 0 and 65535\n"));
        return 0;
    }

    return PQsendQueryGuts(conn,
                           NULL,    /* no command to parse */
                           stmtName,
                           nParams,
                           NULL,    /* no param types */
                           paramValues,
                           paramLengths,
                           paramFormats,
                           resultFormat);
}

int PQserverVersion ( const PGconn conn  ) 
int PQsetClientEncoding ( PGconn conn,
const char *  encoding 
)

Definition at line 5322 of file fe-connect.c.

References CONNECTION_OK, NULL, pg_encoding_to_char(), pg_get_encoding_from_locale(), PG_PROTOCOL_MAJOR, PGRES_COMMAND_OK, PQclear(), PQexec(), pqSaveParameterStatus(), pg_conn::pversion, pg_result::resultStatus, and pg_conn::status.

Referenced by CloneArchive(), dblink_connect(), exec_command(), and setup_connection().

{
    char        qbuf[128];
    static const char query[] = "set client_encoding to '%s'";
    PGresult   *res;
    int         status;

    if (!conn || conn->status != CONNECTION_OK)
        return -1;

    if (!encoding)
        return -1;

    /* Resolve special "auto" value from the locale */
    if (strcmp(encoding, "auto") == 0)
        encoding = pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true));

    /* check query buffer overflow */
    if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
        return -1;

    /* ok, now send a query */
    sprintf(qbuf, query, encoding);
    res = PQexec(conn, qbuf);

    if (res == NULL)
        return -1;
    if (res->resultStatus != PGRES_COMMAND_OK)
        status = -1;
    else
    {
        /*
         * In protocol 2 we have to assume the setting will stick, and adjust
         * our state immediately.  In protocol 3 and up we can rely on the
         * backend to report the parameter value, and we'll change state at
         * that time.
         */
        if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
            pqSaveParameterStatus(conn, "client_encoding", encoding);
        status = 0;             /* everything is ok */
    }
    PQclear(res);
    return status;
}

PGconn* PQsetdbLogin ( const char *  pghost,
const char *  pgport,
const char *  pgoptions,
const char *  pgtty,
const char *  dbName,
const char *  login,
const char *  pwd 
)

Definition at line 902 of file fe-connect.c.

References conn, connectDBComplete(), connectDBStart(), connectOptions1(), connectOptions2(), pg_conn::dbName, free, makeEmptyPGconn(), NULL, pg_conn::pghost, pg_conn::pgoptions, pg_conn::pgpass, pg_conn::pgport, pg_conn::pgtty, pg_conn::pguser, and recognized_connection_string().

{
    PGconn     *conn;

    /*
     * Allocate memory for the conn structure
     */
    conn = makeEmptyPGconn();
    if (conn == NULL)
        return NULL;

    /*
     * If the dbName parameter contains what looks like a connection string,
     * parse it into conn struct using connectOptions1.
     */
    if (dbName && recognized_connection_string(dbName))
    {
        if (!connectOptions1(conn, dbName))
            return conn;
    }
    else
    {
        /*
         * Old-style path: first, parse an empty conninfo string in order to
         * set up the same defaults that PQconnectdb() would use.
         */
        if (!connectOptions1(conn, ""))
            return conn;

        /* Insert dbName parameter value into struct */
        if (dbName && dbName[0] != '\0')
        {
            if (conn->dbName)
                free(conn->dbName);
            conn->dbName = strdup(dbName);
        }
    }

    /*
     * Insert remaining parameters into struct, overriding defaults (as well
     * as any conflicting data from dbName taken as a conninfo).
     */
    if (pghost && pghost[0] != '\0')
    {
        if (conn->pghost)
            free(conn->pghost);
        conn->pghost = strdup(pghost);
    }

    if (pgport && pgport[0] != '\0')
    {
        if (conn->pgport)
            free(conn->pgport);
        conn->pgport = strdup(pgport);
    }

    if (pgoptions && pgoptions[0] != '\0')
    {
        if (conn->pgoptions)
            free(conn->pgoptions);
        conn->pgoptions = strdup(pgoptions);
    }

    if (pgtty && pgtty[0] != '\0')
    {
        if (conn->pgtty)
            free(conn->pgtty);
        conn->pgtty = strdup(pgtty);
    }

    if (login && login[0] != '\0')
    {
        if (conn->pguser)
            free(conn->pguser);
        conn->pguser = strdup(login);
    }

    if (pwd && pwd[0] != '\0')
    {
        if (conn->pgpass)
            free(conn->pgpass);
        conn->pgpass = strdup(pwd);
    }

    /*
     * Compute derived options
     */
    if (!connectOptions2(conn))
        return conn;

    /*
     * Connect to the database
     */
    if (connectDBStart(conn))
        (void) connectDBComplete(conn);

    return conn;
}

PGVerbosity PQsetErrorVerbosity ( PGconn conn,
PGVerbosity  verbosity 
)

Definition at line 5368 of file fe-connect.c.

References pg_conn::verbosity.

Referenced by SyncVariables(), and verbosity_hook().

{
    PGVerbosity old;

    if (!conn)
        return PQERRORS_DEFAULT;
    old = conn->verbosity;
    conn->verbosity = verbosity;
    return old;
}

int PQsetnonblocking ( PGconn conn,
int  arg 
)

Definition at line 3033 of file fe-exec.c.

References CONNECTION_BAD, pg_conn::nonblocking, pqFlush(), pg_conn::status, and TRUE.

{
    bool        barg;

    if (!conn || conn->status == CONNECTION_BAD)
        return -1;

    barg = (arg ? TRUE : FALSE);

    /* early out if the socket is already in the state requested */
    if (barg == conn->nonblocking)
        return 0;

    /*
     * to guarantee constancy for flushing/query/result-polling behavior we
     * need to flush the send queue at this point in order to guarantee proper
     * behavior. this is ok because either they are making a transition _from_
     * or _to_ blocking mode, either way we can block them.
     */
    /* if we are going from blocking to non-blocking flush here */
    if (pqFlush(conn))
        return -1;

    conn->nonblocking = barg;

    return 0;
}

PQnoticeProcessor PQsetNoticeProcessor ( PGconn conn,
PQnoticeProcessor  proc,
void *  arg 
)

Definition at line 5418 of file fe-connect.c.

References pg_conn::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeProcArg, and NULL.

Referenced by _connectDB(), ConnectDatabase(), do_connect(), and main().

{
    PQnoticeProcessor old;

    if (conn == NULL)
        return NULL;

    old = conn->noticeHooks.noticeProc;
    if (proc)
    {
        conn->noticeHooks.noticeProc = proc;
        conn->noticeHooks.noticeProcArg = arg;
    }
    return old;
}

PQnoticeReceiver PQsetNoticeReceiver ( PGconn conn,
PQnoticeReceiver  proc,
void *  arg 
)

Definition at line 5401 of file fe-connect.c.

References pg_conn::noticeHooks, PGNoticeHooks::noticeRec, PGNoticeHooks::noticeRecArg, and NULL.

Referenced by ECPGconnect().

{
    PQnoticeReceiver old;

    if (conn == NULL)
        return NULL;

    old = conn->noticeHooks.noticeRec;
    if (proc)
    {
        conn->noticeHooks.noticeRec = proc;
        conn->noticeHooks.noticeRecArg = arg;
    }
    return old;
}

int PQsetResultAttrs ( PGresult res,
int  numAttributes,
PGresAttDesc attDescs 
)

Definition at line 224 of file fe-exec.c.

References pg_result::attDescs, pg_result::binary, pgresAttDesc::format, i, pgresAttDesc::name, pg_result::null_field, pg_result::numAttributes, PQresultAlloc(), and pqResultStrdup().

Referenced by PQcopyResult().

{
    int         i;

    /* If attrs already exist, they cannot be overwritten. */
    if (!res || res->numAttributes > 0)
        return FALSE;

    /* ignore no-op request */
    if (numAttributes <= 0 || !attDescs)
        return TRUE;

    res->attDescs = (PGresAttDesc *)
        PQresultAlloc(res, numAttributes * sizeof(PGresAttDesc));

    if (!res->attDescs)
        return FALSE;

    res->numAttributes = numAttributes;
    memcpy(res->attDescs, attDescs, numAttributes * sizeof(PGresAttDesc));

    /* deep-copy the attribute names, and determine format */
    res->binary = 1;
    for (i = 0; i < res->numAttributes; i++)
    {
        if (res->attDescs[i].name)
            res->attDescs[i].name = pqResultStrdup(res, res->attDescs[i].name);
        else
            res->attDescs[i].name = res->null_field;

        if (!res->attDescs[i].name)
            return FALSE;

        if (res->attDescs[i].format == 0)
            res->binary = 0;
    }

    return TRUE;
}

int PQsetSingleRowMode ( PGconn conn  ) 

Definition at line 1581 of file fe-exec.c.

References pg_conn::asyncStatus, PGASYNC_BUSY, PGQUERY_EXTENDED, PGQUERY_SIMPLE, pg_conn::queryclass, pg_conn::result, and pg_conn::singleRowMode.

Referenced by storeQueryResult().

{
    /*
     * Only allow setting the flag when we have launched a query and not yet
     * received any results.
     */
    if (!conn)
        return 0;
    if (conn->asyncStatus != PGASYNC_BUSY)
        return 0;
    if (conn->queryclass != PGQUERY_SIMPLE &&
        conn->queryclass != PGQUERY_EXTENDED)
        return 0;
    if (conn->result)
        return 0;

    /* OK, set flag */
    conn->singleRowMode = true;
    return 1;
}

int PQsetvalue ( PGresult res,
int  tup_num,
int  field_num,
char *  value,
int  len 
)

Definition at line 419 of file fe-exec.c.

References check_field_number(), FALSE, i, pgresAttValue::len, pg_result::ntups, NULL, pg_result::null_field, NULL_LEN, pg_result::numAttributes, pqAddTuple(), pqResultAlloc(), TRUE, pg_result::tuples, and pgresAttValue::value.

Referenced by PQcopyResult().

{
    PGresAttValue *attval;

    if (!check_field_number(res, field_num))
        return FALSE;

    /* Invalid tup_num, must be <= ntups */
    if (tup_num < 0 || tup_num > res->ntups)
        return FALSE;

    /* need to allocate a new tuple? */
    if (tup_num == res->ntups)
    {
        PGresAttValue *tup;
        int         i;

        tup = (PGresAttValue *)
            pqResultAlloc(res, res->numAttributes * sizeof(PGresAttValue),
                          TRUE);

        if (!tup)
            return FALSE;

        /* initialize each column to NULL */
        for (i = 0; i < res->numAttributes; i++)
        {
            tup[i].len = NULL_LEN;
            tup[i].value = res->null_field;
        }

        /* add it to the array */
        if (!pqAddTuple(res, tup))
            return FALSE;
    }

    attval = &res->tuples[tup_num][field_num];

    /* treat either NULL_LEN or NULL value pointer as a NULL field */
    if (len == NULL_LEN || value == NULL)
    {
        attval->len = NULL_LEN;
        attval->value = res->null_field;
    }
    else if (len <= 0)
    {
        attval->len = 0;
        attval->value = res->null_field;
    }
    else
    {
        attval->value = (char *) pqResultAlloc(res, len + 1, TRUE);
        if (!attval->value)
            return FALSE;
        attval->len = len;
        memcpy(attval->value, value, len);
        attval->value[len] = '\0';
    }

    return TRUE;
}

int PQsocket ( const PGconn conn  ) 

Definition at line 5275 of file fe-connect.c.

References pg_conn::sock.

Referenced by HandleCopyStream(), libpq_select(), main(), threadRun(), and try_complete_step().

{
    if (!conn)
        return -1;
    return conn->sock;
}

ConnStatusType PQstatus ( const PGconn conn  ) 
void PQtrace ( PGconn conn,
FILE *  debug_port 
)

Definition at line 5380 of file fe-connect.c.

References NULL, pg_conn::Pfdebug, and PQuntrace().

{
    if (conn == NULL)
        return;
    PQuntrace(conn);
    conn->Pfdebug = debug_port;
}

PGTransactionStatusType PQtransactionStatus ( const PGconn conn  ) 
char* PQtty ( const PGconn conn  ) 

Definition at line 5197 of file fe-connect.c.

References pg_conn::pgtty.

{
    if (!conn)
        return NULL;
    return conn->pgtty;
}

unsigned char* PQunescapeBytea ( const unsigned char *  strtext,
size_t *  retbuflen 
)

Definition at line 3553 of file fe-exec.c.

References free, get_hex(), i, ISFIRSTOCTDIGIT, ISOCTDIGIT, malloc, NULL, OCTVAL, realloc, and tmpbuf.

Referenced by dumpTrigger().

{
    size_t      strtextlen,
                buflen;
    unsigned char *buffer,
               *tmpbuf;
    size_t      i,
                j;

    if (strtext == NULL)
        return NULL;

    strtextlen = strlen((const char *) strtext);

    if (strtext[0] == '\\' && strtext[1] == 'x')
    {
        const unsigned char *s;
        unsigned char *p;

        buflen = (strtextlen - 2) / 2;
        /* Avoid unportable malloc(0) */
        buffer = (unsigned char *) malloc(buflen > 0 ? buflen : 1);
        if (buffer == NULL)
            return NULL;

        s = strtext + 2;
        p = buffer;
        while (*s)
        {
            char        v1,
                        v2;

            /*
             * Bad input is silently ignored.  Note that this includes
             * whitespace between hex pairs, which is allowed by byteain.
             */
            v1 = get_hex(*s++);
            if (!*s || v1 == (char) -1)
                continue;
            v2 = get_hex(*s++);
            if (v2 != (char) -1)
                *p++ = (v1 << 4) | v2;
        }

        buflen = p - buffer;
    }
    else
    {
        /*
         * Length of input is max length of output, but add one to avoid
         * unportable malloc(0) if input is zero-length.
         */
        buffer = (unsigned char *) malloc(strtextlen + 1);
        if (buffer == NULL)
            return NULL;

        for (i = j = 0; i < strtextlen;)
        {
            switch (strtext[i])
            {
                case '\\':
                    i++;
                    if (strtext[i] == '\\')
                        buffer[j++] = strtext[i++];
                    else
                    {
                        if ((ISFIRSTOCTDIGIT(strtext[i])) &&
                            (ISOCTDIGIT(strtext[i + 1])) &&
                            (ISOCTDIGIT(strtext[i + 2])))
                        {
                            int         byte;

                            byte = OCTVAL(strtext[i++]);
                            byte = (byte << 3) + OCTVAL(strtext[i++]);
                            byte = (byte << 3) + OCTVAL(strtext[i++]);
                            buffer[j++] = byte;
                        }
                    }

                    /*
                     * Note: if we see '\' followed by something that isn't a
                     * recognized escape sequence, we loop around having done
                     * nothing except advance i.  Therefore the something will
                     * be emitted as ordinary data on the next cycle. Corner
                     * case: '\' at end of string will just be discarded.
                     */
                    break;

                default:
                    buffer[j++] = strtext[i++];
                    break;
            }
        }
        buflen = j;             /* buflen is the length of the dequoted data */
    }

    /* Shrink the buffer to be no larger than necessary */
    /* +1 avoids unportable behavior when buflen==0 */
    tmpbuf = realloc(buffer, buflen + 1);

    /* It would only be a very brain-dead realloc that could fail, but... */
    if (!tmpbuf)
    {
        free(buffer);
        return NULL;
    }

    *retbuflen = buflen;
    return tmpbuf;
}

void PQuntrace ( PGconn conn  ) 

Definition at line 5389 of file fe-connect.c.

References NULL, and pg_conn::Pfdebug.

Referenced by PQtrace().

{
    if (conn == NULL)
        return;
    if (conn->Pfdebug)
    {
        fflush(conn->Pfdebug);
        conn->Pfdebug = NULL;
    }
}

char* PQuser ( const PGconn conn  ) 

Definition at line 5165 of file fe-connect.c.

References pg_conn::pguser.

Referenced by _connectDB(), CloneArchive(), do_connect(), exec_command(), get_prompt(), ReconnectToServer(), session_username(), and SyncVariables().

{
    if (!conn)
        return NULL;
    return conn->pguser;
}