PostgreSQL Source Code git master
Loading...
Searching...
No Matches
libpq-be-fe-helpers.h File Reference
#include "libpq/libpq-be-fe.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "storage/latch.h"
#include "utils/timestamp.h"
#include "utils/wait_event.h"
Include dependency graph for libpq-be-fe-helpers.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PGresult   libpqsrv_PGresult
 
#define PQresultErrorMessage   libpqsrv_PQresultErrorMessage
 

Functions

static void libpqsrv_connect_prepare (void)
 
static void libpqsrv_connect_complete (PGconn *conn, uint32 wait_event_info)
 
static PGresultlibpqsrv_get_result_last (PGconn *conn, uint32 wait_event_info)
 
static PGresultlibpqsrv_get_result (PGconn *conn, uint32 wait_event_info)
 
static PGconnlibpqsrv_connect_start (const char *conninfo)
 
static PGconnlibpqsrv_connect (const char *conninfo, uint32 wait_event_info)
 
static PGconnlibpqsrv_connect_params_start (const char *const *keywords, const char *const *values, int expand_dbname)
 
static PGconnlibpqsrv_connect_params (const char *const *keywords, const char *const *values, int expand_dbname, uint32 wait_event_info)
 
static void libpqsrv_disconnect (PGconn *conn)
 
static PGresultlibpqsrv_exec (PGconn *conn, const char *query, uint32 wait_event_info)
 
static PGresultlibpqsrv_exec_params (PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat, uint32 wait_event_info)
 
static const charlibpqsrv_cancel (PGconn *conn, TimestampTz endtime)
 
static void libpqsrv_notice_receiver (void *arg, const PGresult *res)
 

Macro Definition Documentation

◆ PGresult

Definition at line 505 of file libpq-be-fe-helpers.h.

◆ PQresultErrorMessage

#define PQresultErrorMessage   libpqsrv_PQresultErrorMessage

Definition at line 506 of file libpq-be-fe-helpers.h.

Function Documentation

◆ libpqsrv_cancel()

static const char * libpqsrv_cancel ( PGconn conn,
TimestampTz  endtime 
)
inlinestatic

Definition at line 396 of file libpq-be-fe-helpers.h.

397{
399 const char *error = NULL;
400
402 if (cancel_conn == NULL)
403 return "out of memory";
404
405 /* In what follows, do not leak any PGcancelConn on any errors. */
406
407 PG_TRY();
408 {
410 {
412 goto exit;
413 }
414
415 for (;;)
416 {
419 long cur_timeout;
421
424 break; /* success! */
425
426 /* If timeout has expired, give up, else get sleep time. */
429 if (cur_timeout <= 0)
430 {
431 error = "cancel request timed out";
432 break;
433 }
434
435 switch (pollres)
436 {
439 break;
442 break;
443 default:
445 goto exit;
446 }
447
448 /* Sleep until there's something to do */
451
453
455 }
456exit: ;
457 }
458 PG_FINALLY();
459 {
461 }
462 PG_END_TRY();
463
464 return error;
465}
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition timestamp.c:1765
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1613
int64 TimestampTz
Definition timestamp.h:39
#define PG_TRY(...)
Definition elog.h:374
#define PG_END_TRY(...)
Definition elog.h:399
#define PG_FINALLY(...)
Definition elog.h:391
PGcancelConn * PQcancelCreate(PGconn *conn)
Definition fe-cancel.c:68
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
Definition fe-cancel.c:226
void PQcancelFinish(PGcancelConn *cancelConn)
Definition fe-cancel.c:353
int PQcancelSocket(const PGcancelConn *cancelConn)
Definition fe-cancel.c:313
char * PQcancelErrorMessage(const PGcancelConn *cancelConn)
Definition fe-cancel.c:325
int PQcancelStart(PGcancelConn *cancelConn)
Definition fe-cancel.c:204
struct Latch * MyLatch
Definition globals.c:65
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition latch.c:223
void ResetLatch(Latch *latch)
Definition latch.c:374
PostgresPollingStatusType
Definition libpq-fe.h:120
@ PGRES_POLLING_OK
Definition libpq-fe.h:124
@ PGRES_POLLING_READING
Definition libpq-fe.h:122
@ PGRES_POLLING_WRITING
Definition libpq-fe.h:123
char * pchomp(const char *in)
Definition mcxt.c:1938
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
static int fb(int x)
static void error(void)
PGconn * conn
Definition streamutil.c:52
#define PG_WAIT_CLIENT
#define WL_SOCKET_READABLE
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET
#define WL_SOCKET_WRITEABLE

References CHECK_FOR_INTERRUPTS, conn, error(), fb(), GetCurrentTimestamp(), MyLatch, now(), pchomp(), PG_END_TRY, PG_FINALLY, PG_TRY, PG_WAIT_CLIENT, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQcancelCreate(), PQcancelErrorMessage(), PQcancelFinish(), PQcancelPoll(), PQcancelSocket(), PQcancelStart(), ResetLatch(), TimestampDifferenceMilliseconds(), WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_SOCKET_READABLE, WL_SOCKET_WRITEABLE, and WL_TIMEOUT.

Referenced by dblink_cancel_query(), pgfdw_cancel_query_begin(), and pgfdw_get_cleanup_result().

◆ libpqsrv_connect()

static PGconn * libpqsrv_connect ( const char conninfo,
uint32  wait_event_info 
)
inlinestatic

Definition at line 74 of file libpq-be-fe-helpers.h.

75{
76 PGconn *conn;
77
78 conn = libpqsrv_connect_start(conninfo);
79
80 libpqsrv_connect_complete(conn, wait_event_info);
81
82 return conn;
83}
static void libpqsrv_connect_complete(PGconn *conn, uint32 wait_event_info)
static PGconn * libpqsrv_connect_start(const char *conninfo)

References conn, libpqsrv_connect_complete(), and libpqsrv_connect_start().

◆ libpqsrv_connect_complete()

static void libpqsrv_connect_complete ( PGconn conn,
uint32  wait_event_info 
)
inlinestatic

Definition at line 181 of file libpq-be-fe-helpers.h.

182{
183 /*
184 * With conn == NULL libpqsrv_disconnect() wouldn't release the FD. So do
185 * that here.
186 */
187 if (conn == NULL)
188 {
190 return;
191 }
192
193 /*
194 * Can't wait without a socket. Note that we don't want to close the libpq
195 * connection yet, so callers can emit a useful error.
196 */
198 return;
199
200 /*
201 * WaitLatchOrSocket() can conceivably fail, handle that case here instead
202 * of requiring all callers to do so.
203 */
204 PG_TRY();
205 {
207
208 /*
209 * Poll connection until we have OK or FAILED status.
210 *
211 * Per spec for PQconnectPoll, first wait till socket is write-ready.
212 */
213 status = PGRES_POLLING_WRITING;
214 while (status != PGRES_POLLING_OK && status != PGRES_POLLING_FAILED)
215 {
216 int io_flag;
217 int rc;
218
219 if (status == PGRES_POLLING_READING)
221#ifdef WIN32
222
223 /*
224 * Windows needs a different test while waiting for
225 * connection-made
226 */
227 else if (PQstatus(conn) == CONNECTION_STARTED)
229#endif
230 else
232
235 PQsocket(conn),
236 0,
237 wait_event_info);
238
239 /* Interrupted? */
240 if (rc & WL_LATCH_SET)
241 {
244 }
245
246 /* If socket is ready, advance the libpq state machine */
247 if (rc & io_flag)
248 status = PQconnectPoll(conn);
249 }
250 }
251 PG_CATCH();
252 {
253 /*
254 * If an error is thrown here, the callers won't call
255 * libpqsrv_disconnect() with a conn, so release resources
256 * immediately.
257 */
259 PQfinish(conn);
260
261 PG_RE_THROW();
262 }
263 PG_END_TRY();
264}
#define PG_RE_THROW()
Definition elog.h:407
#define PG_CATCH(...)
Definition elog.h:384
void ReleaseExternalFD(void)
Definition fd.c:1225
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
int PQsocket(const PGconn *conn)
@ CONNECTION_STARTED
Definition libpq-fe.h:98
@ CONNECTION_BAD
Definition libpq-fe.h:91
@ PGRES_POLLING_FAILED
Definition libpq-fe.h:121
#define WL_SOCKET_CONNECTED

References CHECK_FOR_INTERRUPTS, conn, CONNECTION_BAD, CONNECTION_STARTED, fb(), MyLatch, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQconnectPoll(), PQfinish(), PQsocket(), PQstatus(), ReleaseExternalFD(), ResetLatch(), WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_SOCKET_CONNECTED, WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by connect_pg_server(), dblink_connect(), dblink_get_conn(), libpqrcv_connect(), libpqsrv_connect(), and libpqsrv_connect_params().

◆ libpqsrv_connect_params()

static PGconn * libpqsrv_connect_params ( const char *const keywords,
const char *const values,
int  expand_dbname,
uint32  wait_event_info 
)
inlinestatic

Definition at line 105 of file libpq-be-fe-helpers.h.

109{
110 PGconn *conn;
111
113
114 libpqsrv_connect_complete(conn, wait_event_info);
115
116 return conn;
117}
static Datum values[MAXATTR]
Definition bootstrap.c:190
static const JsonPathKeyword keywords[]
static PGconn * libpqsrv_connect_params_start(const char *const *keywords, const char *const *values, int expand_dbname)

References conn, fb(), keywords, libpqsrv_connect_complete(), libpqsrv_connect_params_start(), and values.

◆ libpqsrv_connect_params_start()

static PGconn * libpqsrv_connect_params_start ( const char *const keywords,
const char *const values,
int  expand_dbname 
)
inlinestatic

Definition at line 91 of file libpq-be-fe-helpers.h.

94{
96
98}
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition fe-connect.c:877
static void libpqsrv_connect_prepare(void)

References fb(), keywords, libpqsrv_connect_prepare(), PQconnectStartParams(), and values.

Referenced by connect_pg_server(), libpqrcv_connect(), and libpqsrv_connect_params().

◆ libpqsrv_connect_prepare()

static void libpqsrv_connect_prepare ( void  )
inlinestatic

Definition at line 151 of file libpq-be-fe-helpers.h.

152{
153 /*
154 * We must obey fd.c's limit on non-virtual file descriptors. Assume that
155 * a PGconn represents one long-lived FD. (Doing this here also ensures
156 * that VFDs are closed if needed to make room.)
157 */
158 if (!AcquireExternalFD())
159 {
160#ifndef WIN32 /* can't write #if within ereport() macro */
163 errmsg("could not establish connection"),
164 errdetail("There are too many open files on the local server."),
165 errhint("Raise the server's \"max_files_per_process\" and/or \"ulimit -n\" limits.")));
166#else
169 errmsg("could not establish connection"),
170 errdetail("There are too many open files on the local server."),
171 errhint("Raise the server's \"max_files_per_process\" setting.")));
172#endif
173 }
174}
int errcode(int sqlerrcode)
Definition elog.c:875
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
bool AcquireExternalFD(void)
Definition fd.c:1172
static char * errmsg

References AcquireExternalFD(), ereport, errcode(), errdetail(), errhint(), errmsg, ERROR, and fb().

Referenced by libpqsrv_connect_params_start(), and libpqsrv_connect_start().

◆ libpqsrv_connect_start()

static PGconn * libpqsrv_connect_start ( const char conninfo)
inlinestatic

Definition at line 58 of file libpq-be-fe-helpers.h.

59{
61
62 return PQconnectStart(conninfo);
63}
PGconn * PQconnectStart(const char *conninfo)
Definition fe-connect.c:958

References libpqsrv_connect_prepare(), and PQconnectStart().

Referenced by dblink_connect(), dblink_get_conn(), and libpqsrv_connect().

◆ libpqsrv_disconnect()

static void libpqsrv_disconnect ( PGconn conn)
inlinestatic

Definition at line 127 of file libpq-be-fe-helpers.h.

128{
129 /*
130 * If no connection was established, we haven't reserved an FD for it (or
131 * already released it). This rule makes it easier to write PG_CATCH()
132 * handlers for this facility's users.
133 *
134 * See also libpqsrv_connect_complete().
135 */
136 if (conn == NULL)
137 return;
138
140 PQfinish(conn);
141}

References conn, fb(), PQfinish(), and ReleaseExternalFD().

Referenced by connect_pg_server(), dblink_connect(), dblink_disconnect(), dblink_exec(), dblink_get_conn(), dblink_record_internal(), dblink_security_check(), disconnect_pg_server(), libpqrcv_connect(), and libpqrcv_disconnect().

◆ libpqsrv_exec()

static PGresult * libpqsrv_exec ( PGconn conn,
const char query,
uint32  wait_event_info 
)
inlinestatic

Definition at line 277 of file libpq-be-fe-helpers.h.

278{
279 if (!PQsendQuery(conn, query))
280 return NULL;
281 return libpqsrv_get_result_last(conn, wait_event_info);
282}
int PQsendQuery(PGconn *conn, const char *query)
Definition fe-exec.c:1433
static PGresult * libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)

References conn, fb(), libpqsrv_get_result_last(), and PQsendQuery().

Referenced by dblink_close(), dblink_exec(), dblink_fetch(), dblink_open(), libpqrcv_alter_slot(), libpqrcv_connect(), libpqrcv_create_slot(), libpqrcv_exec(), libpqrcv_identify_system(), libpqrcv_readtimelinehistoryfile(), and libpqrcv_startstreaming().

◆ libpqsrv_exec_params()

static PGresult * libpqsrv_exec_params ( PGconn conn,
const char command,
int  nParams,
const Oid paramTypes,
const char *const paramValues,
const int paramLengths,
const int paramFormats,
int  resultFormat,
uint32  wait_event_info 
)
inlinestatic

Definition at line 290 of file libpq-be-fe-helpers.h.

299{
300 if (!PQsendQueryParams(conn, command, nParams, paramTypes, paramValues,
302 return NULL;
303 return libpqsrv_get_result_last(conn, wait_event_info);
304}
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 fe-exec.c:1509

References conn, fb(), libpqsrv_get_result_last(), and PQsendQueryParams().

◆ libpqsrv_get_result()

static PGresult * libpqsrv_get_result ( PGconn conn,
uint32  wait_event_info 
)
inlinestatic

Definition at line 344 of file libpq-be-fe-helpers.h.

345{
346 /*
347 * Collect data until PQgetResult is ready to get the result without
348 * blocking.
349 */
350 while (PQisBusy(conn))
351 {
352 int rc;
353
357 PQsocket(conn),
358 0,
359 wait_event_info);
360
361 /* Interrupted? */
362 if (rc & WL_LATCH_SET)
363 {
366 }
367
368 /* Consume whatever data is available from the socket */
369 if (PQconsumeInput(conn) == 0)
370 {
371 /* trouble; expect PQgetResult() to return NULL */
372 break;
373 }
374 }
375
376 /* Now we can collect and return the next PGresult */
377 return PQgetResult(conn);
378}
int PQconsumeInput(PGconn *conn)
Definition fe-exec.c:2001
int PQisBusy(PGconn *conn)
Definition fe-exec.c:2048
#define PQgetResult

References CHECK_FOR_INTERRUPTS, conn, MyLatch, PQconsumeInput(), PQgetResult, PQisBusy(), PQsocket(), ResetLatch(), WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_SOCKET_READABLE.

Referenced by dblink_record_internal(), libpqrcv_endstreaming(), libpqrcv_receive(), libpqsrv_get_result_last(), materializeQueryResult(), and storeQueryResult().

◆ libpqsrv_get_result_last()

static PGresult * libpqsrv_get_result_last ( PGconn conn,
uint32  wait_event_info 
)
inlinestatic

Definition at line 311 of file libpq-be-fe-helpers.h.

312{
314
315 for (;;)
316 {
317 /* Wait for, and collect, the next PGresult. */
319
320 result = libpqsrv_get_result(conn, wait_event_info);
321 if (result == NULL)
322 break; /* query is complete, or failure */
323
324 /*
325 * Emulate PQexec()'s behavior of returning the last result when there
326 * are many.
327 */
330
335 break;
336 }
337 return lastResult;
338}
uint32 result
static PGresult * libpqsrv_get_result(PGconn *conn, uint32 wait_event_info)
#define PQclear
#define PQresultStatus
@ PGRES_COPY_IN
Definition libpq-fe.h:138
@ PGRES_COPY_BOTH
Definition libpq-fe.h:143
@ PGRES_COPY_OUT
Definition libpq-fe.h:137

References conn, CONNECTION_BAD, fb(), libpqsrv_get_result(), PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PQclear, PQresultStatus, PQstatus(), and result.

Referenced by libpqsrv_exec(), libpqsrv_exec_params(), and pgfdw_get_result().

◆ libpqsrv_notice_receiver()

static void libpqsrv_notice_receiver ( void arg,
const PGresult res 
)
inlinestatic

Definition at line 485 of file libpq-be-fe-helpers.h.

486{
487 const char *message;
488 int len;
489 const char *prefix = (const char *) arg;
490
491 /*
492 * Trim the trailing newline from the message text returned from
493 * PQresultErrorMessage(), as it always includes one, to produce cleaner
494 * log output.
495 */
496 message = PQresultErrorMessage(res);
497 len = strlen(message);
498 if (len > 0 && message[len - 1] == '\n')
499 len--;
500
501 ereport(LOG,
502 errmsg_internal("%s: %.*s", prefix, len, message));
503}
Datum arg
Definition elog.c:1323
#define LOG
Definition elog.h:32
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define PQresultErrorMessage
const void size_t len

References arg, ereport, errmsg_internal(), fb(), len, LOG, and PQresultErrorMessage.

Referenced by connect_pg_server(), dblink_connect(), dblink_get_conn(), and libpqrcv_connect().