Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

PostgreSQL Source Code git master
libpq-be-fe.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * libpq-be-fe.h
4 * Wrapper functions for using libpq in extensions
5 *
6 * Code built directly into the backend is not allowed to link to libpq
7 * directly. Extension code is allowed to use libpq however. One of the
8 * main risks in doing so is leaking the malloc-allocated structures
9 * returned by libpq, causing a process-lifespan memory leak.
10 *
11 * This file provides wrapper objects to help in building memory-safe code.
12 * A PGresult object wrapped this way acts much as if it were palloc'd:
13 * it will go away when the specified context is reset or deleted.
14 * We might later extend the concept to other objects such as PGconns.
15 *
16 * See also the libpq-be-fe-helpers.h file, which provides additional
17 * facilities built on top of this one.
18 *
19 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
20 * Portions Copyright (c) 1994, Regents of the University of California
21 *
22 * src/include/libpq/libpq-be-fe.h
23 *
24 *-------------------------------------------------------------------------
25 */
26#ifndef LIBPQ_BE_FE_H
27#define LIBPQ_BE_FE_H
28
29/*
30 * Despite the name, BUILDING_DLL is set only when building code directly part
31 * of the backend. Which also is where libpq isn't allowed to be
32 * used. Obviously this doesn't protect against libpq-fe.h getting included
33 * otherwise, but perhaps still protects against a few mistakes...
34 */
35#ifdef BUILDING_DLL
36#error "libpq may not be used in code directly built into the backend"
37#endif
38
39#include "libpq-fe.h"
40
41/*
42 * Memory-context-safe wrapper object for a PGresult.
43 */
44typedef struct libpqsrv_PGresult
45{
46 PGresult *res; /* the wrapped PGresult */
47 MemoryContext ctx; /* the MemoryContext it's attached to */
48 MemoryContextCallback cb; /* the callback that implements freeing */
50
51
52/*
53 * Wrap the given PGresult in a libpqsrv_PGresult object, so that it will
54 * go away automatically if the current memory context is reset or deleted.
55 *
56 * To avoid potential memory leaks, backend code must always apply this
57 * immediately to the output of any PGresult-yielding libpq function.
58 */
59static inline libpqsrv_PGresult *
61{
64
65 /* We pass through a NULL result as-is, since there's nothing to free */
66 if (res == NULL)
67 return NULL;
68 /* Attempt to allocate the wrapper ... this had better not throw error */
69 bres = (libpqsrv_PGresult *)
71 sizeof(libpqsrv_PGresult),
73 /* If we failed to allocate a wrapper, free the PGresult before failing */
74 if (bres == NULL)
75 {
76 PQclear(res);
78 (errcode(ERRCODE_OUT_OF_MEMORY),
79 errmsg("out of memory")));
80 }
81 /* Okay, set up the wrapper */
82 bres->res = res;
83 bres->ctx = ctx;
85 bres->cb.arg = res;
87 return bres;
88}
89
90/*
91 * Free a wrapped PGresult, after detaching it from the memory context.
92 * Like PQclear(), allow the argument to be NULL.
93 */
94static inline void
96{
97 if (bres)
98 {
100 PQclear(bres->res);
101 pfree(bres);
102 }
103}
104
105/*
106 * Move a wrapped PGresult to have a different parent context.
107 */
108static inline libpqsrv_PGresult *
110{
111 libpqsrv_PGresult *newres;
112
113 /* We pass through a NULL result as-is */
114 if (bres == NULL)
115 return NULL;
116 /* Make a new wrapper in the target context, raising error on OOM */
117 newres = (libpqsrv_PGresult *)
119 /* Okay, set up the new wrapper */
120 newres->res = bres->res;
121 newres->ctx = ctx;
123 newres->cb.arg = bres->res;
125 /* Disarm and delete the old wrapper */
127 pfree(bres);
128 return newres;
129}
130
131/*
132 * Convenience wrapper for PQgetResult.
133 *
134 * We could supply wrappers for other PGresult-returning functions too,
135 * but at present there's no need.
136 */
137static inline libpqsrv_PGresult *
139{
141}
142
143/*
144 * Accessor functions for libpqsrv_PGresult. While it's not necessary to use
145 * these, they emulate the behavior of the underlying libpq functions when
146 * passed a NULL pointer. This is particularly important for PQresultStatus,
147 * which is often the first check on a result.
148 */
149
150static inline ExecStatusType
152{
153 if (!res)
154 return PGRES_FATAL_ERROR;
155 return PQresultStatus(res->res);
156}
157
158static inline const char *
160{
161 if (!res)
162 return "";
163 return PQresultErrorMessage(res->res);
164}
165
166static inline char *
168{
169 if (!res)
170 return NULL;
171 return PQresultErrorField(res->res, fieldcode);
172}
173
174static inline char *
176{
177 if (!res)
178 return NULL;
179 return PQcmdStatus(res->res);
180}
181
182static inline int
184{
185 if (!res)
186 return 0;
187 return PQntuples(res->res);
188}
189
190static inline int
192{
193 if (!res)
194 return 0;
195 return PQnfields(res->res);
196}
197
198static inline char *
199libpqsrv_PQgetvalue(const libpqsrv_PGresult *res, int tup_num, int field_num)
200{
201 if (!res)
202 return NULL;
203 return PQgetvalue(res->res, tup_num, field_num);
204}
205
206static inline int
207libpqsrv_PQgetlength(const libpqsrv_PGresult *res, int tup_num, int field_num)
208{
209 if (!res)
210 return 0;
211 return PQgetlength(res->res, tup_num, field_num);
212}
213
214static inline int
215libpqsrv_PQgetisnull(const libpqsrv_PGresult *res, int tup_num, int field_num)
216{
217 if (!res)
218 return 1; /* pretend it is null */
219 return PQgetisnull(res->res, tup_num, field_num);
220}
221
222static inline char *
223libpqsrv_PQfname(const libpqsrv_PGresult *res, int field_num)
224{
225 if (!res)
226 return NULL;
227 return PQfname(res->res, field_num);
228}
229
230static inline const char *
232{
233 if (!res)
234 return "";
235 return PQcmdTuples(res->res);
236}
237
238/*
239 * Redefine these libpq entry point names concerned with PGresults so that
240 * they will operate on libpqsrv_PGresults instead. This avoids needing to
241 * convert a lot of pre-existing code, and reduces the notational differences
242 * between frontend and backend libpq-using code.
243 */
244#define PGresult libpqsrv_PGresult
245#define PQclear libpqsrv_PQclear
246#define PQgetResult libpqsrv_PQgetResult
247#define PQresultStatus libpqsrv_PQresultStatus
248#define PQresultErrorMessage libpqsrv_PQresultErrorMessage
249#define PQresultErrorField libpqsrv_PQresultErrorField
250#define PQcmdStatus libpqsrv_PQcmdStatus
251#define PQntuples libpqsrv_PQntuples
252#define PQnfields libpqsrv_PQnfields
253#define PQgetvalue libpqsrv_PQgetvalue
254#define PQgetlength libpqsrv_PQgetlength
255#define PQgetisnull libpqsrv_PQgetisnull
256#define PQfname libpqsrv_PQfname
257#define PQcmdTuples libpqsrv_PQcmdTuples
258
259#endif /* LIBPQ_BE_FE_H */
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
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:29
#define PQgetvalue
Definition: libpq-be-fe.h:253
#define PQgetResult
Definition: libpq-be-fe.h:246
#define PQcmdStatus
Definition: libpq-be-fe.h:250
static libpqsrv_PGresult * libpqsrv_PQgetResult(PGconn *conn)
Definition: libpq-be-fe.h:138
static void libpqsrv_PQclear(libpqsrv_PGresult *bres)
Definition: libpq-be-fe.h:95
#define PQgetlength
Definition: libpq-be-fe.h:254
static char * libpqsrv_PQfname(const libpqsrv_PGresult *res, int field_num)
Definition: libpq-be-fe.h:223
static ExecStatusType libpqsrv_PQresultStatus(const libpqsrv_PGresult *res)
Definition: libpq-be-fe.h:151
static int libpqsrv_PQgetlength(const libpqsrv_PGresult *res, int tup_num, int field_num)
Definition: libpq-be-fe.h:207
#define PQclear
Definition: libpq-be-fe.h:245
static libpqsrv_PGresult * libpqsrv_PGresultSetParent(libpqsrv_PGresult *bres, MemoryContext ctx)
Definition: libpq-be-fe.h:109
#define PQresultErrorField
Definition: libpq-be-fe.h:249
#define PQcmdTuples
Definition: libpq-be-fe.h:257
static int libpqsrv_PQgetisnull(const libpqsrv_PGresult *res, int tup_num, int field_num)
Definition: libpq-be-fe.h:215
struct libpqsrv_PGresult libpqsrv_PGresult
static char * libpqsrv_PQcmdStatus(const libpqsrv_PGresult *res)
Definition: libpq-be-fe.h:175
static const char * libpqsrv_PQresultErrorMessage(const libpqsrv_PGresult *res)
Definition: libpq-be-fe.h:159
#define PQnfields
Definition: libpq-be-fe.h:252
#define PQresultStatus
Definition: libpq-be-fe.h:247
#define PQresultErrorMessage
Definition: libpq-be-fe.h:248
static libpqsrv_PGresult * libpqsrv_PQwrap(PGresult *res)
Definition: libpq-be-fe.h:60
static int libpqsrv_PQnfields(const libpqsrv_PGresult *res)
Definition: libpq-be-fe.h:191
#define PQgetisnull
Definition: libpq-be-fe.h:255
static char * libpqsrv_PQresultErrorField(const libpqsrv_PGresult *res, int fieldcode)
Definition: libpq-be-fe.h:167
static char * libpqsrv_PQgetvalue(const libpqsrv_PGresult *res, int tup_num, int field_num)
Definition: libpq-be-fe.h:199
static int libpqsrv_PQntuples(const libpqsrv_PGresult *res)
Definition: libpq-be-fe.h:183
#define PQfname
Definition: libpq-be-fe.h:256
static const char * libpqsrv_PQcmdTuples(const libpqsrv_PGresult *res)
Definition: libpq-be-fe.h:231
#define PQntuples
Definition: libpq-be-fe.h:251
ExecStatusType
Definition: libpq-fe.h:123
@ PGRES_FATAL_ERROR
Definition: libpq-fe.h:136
void MemoryContextUnregisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
Definition: mcxt.c:604
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1229
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
Definition: mcxt.c:579
void pfree(void *pointer)
Definition: mcxt.c:1594
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
Definition: mcxt.c:1286
void(* MemoryContextCallbackFunction)(void *arg)
Definition: palloc.h:45
PGconn * conn
Definition: streamutil.c:52
MemoryContextCallbackFunction func
Definition: palloc.h:49
MemoryContextCallback cb
Definition: libpq-be-fe.h:48
MemoryContext ctx
Definition: libpq-be-fe.h:47
PGresult * res
Definition: libpq-be-fe.h:46