PostgreSQL Source Code git master
Macros | Functions
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
 
 

Functions

static void  libpqsrv_connect_prepare (void)
 
static void  libpqsrv_connect_internal (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 (const char *conninfo, uint32 wait_event_info)
 
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 char *  libpqsrv_cancel (PGconn *conn, TimestampTz endtime)
 
static void  libpqsrv_notice_receiver (void *arg, const PGresult *res)
 

Macro Definition Documentation

PGresult

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

PQresultErrorMessage

#define PQresultErrorMessage   libpqsrv_PQresultErrorMessage

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

Function Documentation

libpqsrv_cancel()

static const char * libpqsrv_cancel ( PGconnconn,
TimestampTz  endtime 
)
inlinestatic

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

366{
367 PGcancelConn *cancel_conn;
368 const char *error = NULL;
369
370 cancel_conn = PQcancelCreate(conn);
371 if (cancel_conn == NULL)
372 return "out of memory";
373
374 /* In what follows, do not leak any PGcancelConn on any errors. */
375
376 PG_TRY();
377 {
378 if (!PQcancelStart(cancel_conn))
379 {
380 error = pchomp(PQcancelErrorMessage(cancel_conn));
381 goto exit;
382 }
383
384 for (;;)
385 {
388 long cur_timeout;
389 int waitEvents = WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH;
390
391 pollres = PQcancelPoll(cancel_conn);
392 if (pollres == PGRES_POLLING_OK)
393 break; /* success! */
394
395 /* If timeout has expired, give up, else get sleep time. */
397 cur_timeout = TimestampDifferenceMilliseconds(now, endtime);
398 if (cur_timeout <= 0)
399 {
400 error = "cancel request timed out";
401 break;
402 }
403
404 switch (pollres)
405 {
407 waitEvents |= WL_SOCKET_READABLE;
408 break;
410 waitEvents |= WL_SOCKET_WRITEABLE;
411 break;
412 default:
413 error = pchomp(PQcancelErrorMessage(cancel_conn));
414 goto exit;
415 }
416
417 /* Sleep until there's something to do */
418 WaitLatchOrSocket(MyLatch, waitEvents, PQcancelSocket(cancel_conn),
419 cur_timeout, PG_WAIT_CLIENT);
420
422
424 }
425exit: ;
426 }
427 PG_FINALLY();
428 {
429 PQcancelFinish(cancel_conn);
430 }
431 PG_END_TRY();
432
433 return error;
434}
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition: timestamp.c:1757
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1609
int64 TimestampTz
Definition: timestamp.h:39
#define PG_TRY(...)
Definition: elog.h:372
#define PG_END_TRY(...)
Definition: elog.h:397
#define PG_FINALLY(...)
Definition: elog.h:389
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:63
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:114
@ PGRES_POLLING_OK
Definition: libpq-fe.h:118
@ PGRES_POLLING_READING
Definition: libpq-fe.h:116
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:117
char * pchomp(const char *in)
Definition: mcxt.c:1787
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
static void error(void)
Definition: sql-dyntest.c:147
PGconn * conn
Definition: streamutil.c:52
#define PG_WAIT_CLIENT
Definition: wait_classes.h:22
#define WL_SOCKET_READABLE
Definition: waiteventset.h:35
#define WL_TIMEOUT
Definition: waiteventset.h:37
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
#define WL_LATCH_SET
Definition: waiteventset.h:34
#define WL_SOCKET_WRITEABLE
Definition: waiteventset.h:36

References CHECK_FOR_INTERRUPTS, conn, error(), 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 56 of file libpq-be-fe-helpers.h.

57{
58 PGconn *conn = NULL;
59
61
62 conn = PQconnectStart(conninfo);
63
64 libpqsrv_connect_internal(conn, wait_event_info);
65
66 return conn;
67}
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:951
static void libpqsrv_connect_prepare(void)
static void libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info)

References conn, libpqsrv_connect_internal(), libpqsrv_connect_prepare(), and PQconnectStart().

Referenced by dblink_connect(), and dblink_get_conn().

libpqsrv_connect_internal()

static void libpqsrv_connect_internal ( PGconnconn,
uint32  wait_event_info 
)
inlinestatic

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

151{
152 /*
153 * With conn == NULL libpqsrv_disconnect() wouldn't release the FD. So do
154 * that here.
155 */
156 if (conn == NULL)
157 {
159 return;
160 }
161
162 /*
163 * Can't wait without a socket. Note that we don't want to close the libpq
164 * connection yet, so callers can emit a useful error.
165 */
167 return;
168
169 /*
170 * WaitLatchOrSocket() can conceivably fail, handle that case here instead
171 * of requiring all callers to do so.
172 */
173 PG_TRY();
174 {
176
177 /*
178 * Poll connection until we have OK or FAILED status.
179 *
180 * Per spec for PQconnectPoll, first wait till socket is write-ready.
181 */
182 status = PGRES_POLLING_WRITING;
183 while (status != PGRES_POLLING_OK && status != PGRES_POLLING_FAILED)
184 {
185 int io_flag;
186 int rc;
187
188 if (status == PGRES_POLLING_READING)
189 io_flag = WL_SOCKET_READABLE;
190#ifdef WIN32
191
192 /*
193 * Windows needs a different test while waiting for
194 * connection-made
195 */
196 else if (PQstatus(conn) == CONNECTION_STARTED)
197 io_flag = WL_SOCKET_CONNECTED;
198#endif
199 else
200 io_flag = WL_SOCKET_WRITEABLE;
201
204 PQsocket(conn),
205 0,
206 wait_event_info);
207
208 /* Interrupted? */
209 if (rc & WL_LATCH_SET)
210 {
213 }
214
215 /* If socket is ready, advance the libpq state machine */
216 if (rc & io_flag)
217 status = PQconnectPoll(conn);
218 }
219 }
220 PG_CATCH();
221 {
222 /*
223 * If an error is thrown here, the callers won't call
224 * libpqsrv_disconnect() with a conn, so release resources
225 * immediately.
226 */
228 PQfinish(conn);
229
230 PG_RE_THROW();
231 }
232 PG_END_TRY();
233}
#define PG_RE_THROW()
Definition: elog.h:405
#define PG_CATCH(...)
Definition: elog.h:382
void ReleaseExternalFD(void)
Definition: fd.c:1238
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2911
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7616
void PQfinish(PGconn *conn)
Definition: fe-connect.c:5305
int PQsocket(const PGconn *conn)
Definition: fe-connect.c:7705
@ CONNECTION_STARTED
Definition: libpq-fe.h:92
@ CONNECTION_BAD
Definition: libpq-fe.h:85
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:115
#define WL_SOCKET_CONNECTED
Definition: waiteventset.h:44

References CHECK_FOR_INTERRUPTS, conn, CONNECTION_BAD, CONNECTION_STARTED, 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 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 74 of file libpq-be-fe-helpers.h.

78{
79 PGconn *conn = NULL;
80
82
83 conn = PQconnectStartParams(keywords, values, expand_dbname);
84
85 libpqsrv_connect_internal(conn, wait_event_info);
86
87 return conn;
88}
static Datum values[MAXATTR]
Definition: bootstrap.c:153
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:870
static const JsonPathKeyword keywords[]
Definition: jsonpath_scan.l:402

References conn, keywords, libpqsrv_connect_internal(), libpqsrv_connect_prepare(), PQconnectStartParams(), and values.

Referenced by connect_pg_server(), and libpqrcv_connect().

libpqsrv_connect_prepare()

static void libpqsrv_connect_prepare ( void  )
inlinestatic

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

122{
123 /*
124 * We must obey fd.c's limit on non-virtual file descriptors. Assume that
125 * a PGconn represents one long-lived FD. (Doing this here also ensures
126 * that VFDs are closed if needed to make room.)
127 */
128 if (!AcquireExternalFD())
129 {
130#ifndef WIN32 /* can't write #if within ereport() macro */
132 (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
133 errmsg("could not establish connection"),
134 errdetail("There are too many open files on the local server."),
135 errhint("Raise the server's \"max_files_per_process\" and/or \"ulimit -n\" limits.")));
136#else
138 (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
139 errmsg("could not establish connection"),
140 errdetail("There are too many open files on the local server."),
141 errhint("Raise the server's \"max_files_per_process\" setting.")));
142#endif
143 }
144}
int errdetail(const char *fmt,...)
Definition: elog.c:1207
int errhint(const char *fmt,...)
Definition: elog.c:1321
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
bool AcquireExternalFD(void)
Definition: fd.c:1185

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

Referenced by libpqsrv_connect(), and libpqsrv_connect_params().

libpqsrv_disconnect()

static void libpqsrv_disconnect ( PGconnconn )
inlinestatic

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

98{
99 /*
100 * If no connection was established, we haven't reserved an FD for it (or
101 * already released it). This rule makes it easier to write PG_CATCH()
102 * handlers for this facility's users.
103 *
104 * See also libpqsrv_connect_internal().
105 */
106 if (conn == NULL)
107 return;
108
110 PQfinish(conn);
111}

References conn, 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 ( PGconnconn,
const char *  query,
uint32  wait_event_info 
)
inlinestatic

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

247{
248 if (!PQsendQuery(conn, query))
249 return NULL;
250 return libpqsrv_get_result_last(conn, wait_event_info);
251}
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1427
static PGresult * libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)

References conn, 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 ( PGconnconn,
const char *  command,
int  nParams,
const OidparamTypes,
const char *const *  paramValues,
const int *  paramLengths,
const int *  paramFormats,
int  resultFormat,
uint32  wait_event_info 
)
inlinestatic

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

268{
269 if (!PQsendQueryParams(conn, command, nParams, paramTypes, paramValues,
270 paramLengths, paramFormats, resultFormat))
271 return NULL;
272 return libpqsrv_get_result_last(conn, wait_event_info);
273}
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:1503

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

libpqsrv_get_result()

static PGresult * libpqsrv_get_result ( PGconnconn,
uint32  wait_event_info 
)
inlinestatic

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

314{
315 /*
316 * Collect data until PQgetResult is ready to get the result without
317 * blocking.
318 */
319 while (PQisBusy(conn))
320 {
321 int rc;
322
326 PQsocket(conn),
327 0,
328 wait_event_info);
329
330 /* Interrupted? */
331 if (rc & WL_LATCH_SET)
332 {
335 }
336
337 /* Consume whatever data is available from the socket */
338 if (PQconsumeInput(conn) == 0)
339 {
340 /* trouble; expect PQgetResult() to return NULL */
341 break;
342 }
343 }
344
345 /* Now we can collect and return the next PGresult */
346 return PQgetResult(conn);
347}
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1995
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:2042
#define PQgetResult
Definition: libpq-be-fe.h:246

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 ( PGconnconn,
uint32  wait_event_info 
)
inlinestatic

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

281{
282 PGresult *lastResult = NULL;
283
284 for (;;)
285 {
286 /* Wait for, and collect, the next PGresult. */
287 PGresult *result;
288
289 result = libpqsrv_get_result(conn, wait_event_info);
290 if (result == NULL)
291 break; /* query is complete, or failure */
292
293 /*
294 * Emulate PQexec()'s behavior of returning the last result when there
295 * are many.
296 */
297 PQclear(lastResult);
298 lastResult = result;
299
300 if (PQresultStatus(lastResult) == PGRES_COPY_IN ||
301 PQresultStatus(lastResult) == PGRES_COPY_OUT ||
302 PQresultStatus(lastResult) == PGRES_COPY_BOTH ||
304 break;
305 }
306 return lastResult;
307}
static PGresult * libpqsrv_get_result(PGconn *conn, uint32 wait_event_info)
#define PQclear
Definition: libpq-be-fe.h:245
#define PQresultStatus
Definition: libpq-be-fe.h:247
@ PGRES_COPY_IN
Definition: libpq-fe.h:132
@ PGRES_COPY_BOTH
Definition: libpq-fe.h:137
@ PGRES_COPY_OUT
Definition: libpq-fe.h:131

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

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

libpqsrv_notice_receiver()

static void libpqsrv_notice_receiver ( void *  arg,
const PGresultres 
)
inlinestatic

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

455{
456 const char *message;
457 int len;
458 const char *prefix = (const char *) arg;
459
460 /*
461 * Trim the trailing newline from the message text returned from
462 * PQresultErrorMessage(), as it always includes one, to produce cleaner
463 * log output.
464 */
465 message = PQresultErrorMessage(res);
466 len = strlen(message);
467 if (len > 0 && message[len - 1] == '\n')
468 len--;
469
470 ereport(LOG,
471 errmsg_internal("%s: %.*s", prefix, len, message));
472}
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1161
#define LOG
Definition: elog.h:31
#define PQresultErrorMessage
void * arg
const void size_t len

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

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

AltStyle によって変換されたページ (->オリジナル) /