PostgreSQL Source Code
git master
Loading...
Searching...
No Matches
test_resowner_basic.c
Go to the documentation of this file.
1
/*--------------------------------------------------------------------------
2
*
3
* test_resowner_basic.c
4
* Test basic ResourceOwner functionality
5
*
6
* Copyright (c) 2022-2026, PostgreSQL Global Development Group
7
*
8
* IDENTIFICATION
9
* src/test/modules/test_resowner/test_resowner_basic.c
10
*
11
* -------------------------------------------------------------------------
12
*/
13
#include "
postgres.h
"
14
15
#include "
fmgr.h
"
16
#include "
utils/resowner.h
"
17
18
PG_MODULE_MAGIC
;
19
20
static
void
ReleaseString
(
Datum
res);
21
static
char
*
PrintString
(
Datum
res);
22
23
/*
24
* A resource that tracks strings and prints the string when it's released.
25
* This makes the order that the resources are released visible.
26
*/
27
static
const
ResourceOwnerDesc
string_desc
= {
28
.
name
=
"test resource"
,
29
.release_phase =
RESOURCE_RELEASE_AFTER_LOCKS
,
30
.release_priority =
RELEASE_PRIO_FIRST
,
31
.ReleaseResource =
ReleaseString
,
32
.DebugPrint =
PrintString
33
};
34
35
static
void
36
ReleaseString
(
Datum
res)
37
{
38
elog
(
NOTICE
,
"releasing string: %s"
,
DatumGetCString
(res));
39
}
40
41
static
char
*
42
PrintString
(
Datum
res)
43
{
44
return
psprintf
(
"test string \"%s\""
,
DatumGetCString
(res));
45
}
46
47
/* demonstrates phases and priorities between a parent and child context */
48
PG_FUNCTION_INFO_V1
(
test_resowner_priorities
);
49
Datum
50
test_resowner_priorities
(
PG_FUNCTION_ARGS
)
51
{
52
int32
nkinds
=
PG_GETARG_INT32
(0);
53
int32
nresources
=
PG_GETARG_INT32
(1);
54
ResourceOwner
parent,
55
child;
56
ResourceOwnerDesc
*
before_desc
;
57
ResourceOwnerDesc
*
after_desc
;
58
59
if
(
nkinds
<= 0)
60
elog
(
ERROR
,
"nkinds must be greater than zero"
);
61
if
(
nresources
<= 0)
62
elog
(
ERROR
,
"nresources must be greater than zero"
);
63
64
parent =
ResourceOwnerCreate
(
CurrentResourceOwner
,
"test parent"
);
65
child =
ResourceOwnerCreate
(parent,
"test child"
);
66
67
before_desc
=
palloc
(
nkinds
*
sizeof
(
ResourceOwnerDesc
));
68
for
(
int
i
= 0;
i
<
nkinds
;
i
++)
69
{
70
before_desc
[
i
].name =
psprintf
(
"test resource before locks %d"
,
i
);
71
before_desc
[
i
].release_phase =
RESOURCE_RELEASE_BEFORE_LOCKS
;
72
before_desc
[
i
].release_priority =
RELEASE_PRIO_FIRST
+
i
;
73
before_desc
[
i
].ReleaseResource =
ReleaseString
;
74
before_desc
[
i
].DebugPrint =
PrintString
;
75
}
76
after_desc
=
palloc
(
nkinds
*
sizeof
(
ResourceOwnerDesc
));
77
for
(
int
i
= 0;
i
<
nkinds
;
i
++)
78
{
79
after_desc
[
i
].name =
psprintf
(
"test resource after locks %d"
,
i
);
80
after_desc
[
i
].release_phase =
RESOURCE_RELEASE_AFTER_LOCKS
;
81
after_desc
[
i
].release_priority =
RELEASE_PRIO_FIRST
+
i
;
82
after_desc
[
i
].ReleaseResource =
ReleaseString
;
83
after_desc
[
i
].DebugPrint =
PrintString
;
84
}
85
86
/* Add a bunch of resources to child, with different priorities */
87
for
(
int
i
= 0;
i
<
nresources
;
i
++)
88
{
89
ResourceOwnerDesc
*kind = &
before_desc
[
i
%
nkinds
];
90
91
ResourceOwnerEnlarge
(child);
92
ResourceOwnerRemember
(child,
93
CStringGetDatum
(
psprintf
(
"child before locks priority %d"
, kind->
release_priority
)),
94
kind);
95
}
96
for
(
int
i
= 0;
i
<
nresources
;
i
++)
97
{
98
ResourceOwnerDesc
*kind = &
after_desc
[
i
%
nkinds
];
99
100
ResourceOwnerEnlarge
(child);
101
ResourceOwnerRemember
(child,
102
CStringGetDatum
(
psprintf
(
"child after locks priority %d"
, kind->
release_priority
)),
103
kind);
104
}
105
106
/* And also to the parent */
107
for
(
int
i
= 0;
i
<
nresources
;
i
++)
108
{
109
ResourceOwnerDesc
*kind = &
after_desc
[
i
%
nkinds
];
110
111
ResourceOwnerEnlarge
(parent);
112
ResourceOwnerRemember
(parent,
113
CStringGetDatum
(
psprintf
(
"parent after locks priority %d"
, kind->
release_priority
)),
114
kind);
115
}
116
for
(
int
i
= 0;
i
<
nresources
;
i
++)
117
{
118
ResourceOwnerDesc
*kind = &
before_desc
[
i
%
nkinds
];
119
120
ResourceOwnerEnlarge
(parent);
121
ResourceOwnerRemember
(parent,
122
CStringGetDatum
(
psprintf
(
"parent before locks priority %d"
, kind->
release_priority
)),
123
kind);
124
}
125
126
elog
(
NOTICE
,
"releasing resources before locks"
);
127
ResourceOwnerRelease
(parent,
RESOURCE_RELEASE_BEFORE_LOCKS
,
false
,
false
);
128
elog
(
NOTICE
,
"releasing locks"
);
129
ResourceOwnerRelease
(parent,
RESOURCE_RELEASE_LOCKS
,
false
,
false
);
130
elog
(
NOTICE
,
"releasing resources after locks"
);
131
ResourceOwnerRelease
(parent,
RESOURCE_RELEASE_AFTER_LOCKS
,
false
,
false
);
132
133
ResourceOwnerDelete
(parent);
134
135
PG_RETURN_VOID
();
136
}
137
138
PG_FUNCTION_INFO_V1
(
test_resowner_leak
);
139
Datum
140
test_resowner_leak
(
PG_FUNCTION_ARGS
)
141
{
142
ResourceOwner
resowner;
143
144
resowner =
ResourceOwnerCreate
(
CurrentResourceOwner
,
"TestOwner"
);
145
146
ResourceOwnerEnlarge
(resowner);
147
148
ResourceOwnerRemember
(resowner,
CStringGetDatum
(
"my string"
), &
string_desc
);
149
150
/* don't call ResourceOwnerForget, so that it is leaked */
151
152
ResourceOwnerRelease
(resowner,
RESOURCE_RELEASE_BEFORE_LOCKS
,
true
,
false
);
153
ResourceOwnerRelease
(resowner,
RESOURCE_RELEASE_LOCKS
,
true
,
false
);
154
ResourceOwnerRelease
(resowner,
RESOURCE_RELEASE_AFTER_LOCKS
,
true
,
false
);
155
156
ResourceOwnerDelete
(resowner);
157
158
PG_RETURN_VOID
();
159
}
160
161
PG_FUNCTION_INFO_V1
(
test_resowner_remember_between_phases
);
162
Datum
163
test_resowner_remember_between_phases
(
PG_FUNCTION_ARGS
)
164
{
165
ResourceOwner
resowner;
166
167
resowner =
ResourceOwnerCreate
(
CurrentResourceOwner
,
"TestOwner"
);
168
169
ResourceOwnerRelease
(resowner,
RESOURCE_RELEASE_BEFORE_LOCKS
,
true
,
false
);
170
171
/*
172
* Try to remember a new resource. Fails because we already called
173
* ResourceOwnerRelease.
174
*/
175
ResourceOwnerEnlarge
(resowner);
176
ResourceOwnerRemember
(resowner,
CStringGetDatum
(
"my string"
), &
string_desc
);
177
178
/* unreachable */
179
elog
(
ERROR
,
"ResourceOwnerEnlarge should have errored out"
);
180
181
PG_RETURN_VOID
();
182
}
183
184
PG_FUNCTION_INFO_V1
(
test_resowner_forget_between_phases
);
185
Datum
186
test_resowner_forget_between_phases
(
PG_FUNCTION_ARGS
)
187
{
188
ResourceOwner
resowner;
189
Datum
str_resource
;
190
191
resowner =
ResourceOwnerCreate
(
CurrentResourceOwner
,
"TestOwner"
);
192
193
ResourceOwnerEnlarge
(resowner);
194
str_resource
=
CStringGetDatum
(
"my string"
);
195
ResourceOwnerRemember
(resowner,
str_resource
, &
string_desc
);
196
197
ResourceOwnerRelease
(resowner,
RESOURCE_RELEASE_BEFORE_LOCKS
,
true
,
false
);
198
199
/*
200
* Try to forget the resource that was remembered earlier. Fails because
201
* we already called ResourceOwnerRelease.
202
*/
203
ResourceOwnerForget
(resowner,
str_resource
, &
string_desc
);
204
205
/* unreachable */
206
elog
(
ERROR
,
"ResourceOwnerForget should have errored out"
);
207
208
PG_RETURN_VOID
();
209
}
int32
int32_t int32
Definition
c.h:542
ERROR
#define ERROR
Definition
elog.h:39
elog
#define elog(elevel,...)
Definition
elog.h:226
NOTICE
#define NOTICE
Definition
elog.h:35
fmgr.h
PG_RETURN_VOID
#define PG_RETURN_VOID()
Definition
fmgr.h:350
PG_FUNCTION_INFO_V1
#define PG_FUNCTION_INFO_V1(funcname)
Definition
fmgr.h:417
PG_GETARG_INT32
#define PG_GETARG_INT32(n)
Definition
fmgr.h:269
PG_FUNCTION_ARGS
#define PG_FUNCTION_ARGS
Definition
fmgr.h:193
i
int i
Definition
isn.c:77
palloc
void * palloc(Size size)
Definition
mcxt.c:1387
postgres.h
DatumGetCString
static char * DatumGetCString(Datum X)
Definition
postgres.h:365
Datum
uint64_t Datum
Definition
postgres.h:70
CStringGetDatum
static Datum CStringGetDatum(const char *X)
Definition
postgres.h:380
fb
static int fb(int x)
Definition
preproc-init.c:92
psprintf
char * psprintf(const char *fmt,...)
Definition
psprintf.c:43
ResourceOwnerCreate
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition
resowner.c:418
CurrentResourceOwner
ResourceOwner CurrentResourceOwner
Definition
resowner.c:173
ResourceOwnerRelease
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition
resowner.c:655
ResourceOwnerForget
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition
resowner.c:561
ResourceOwnerDelete
void ResourceOwnerDelete(ResourceOwner owner)
Definition
resowner.c:868
ResourceOwnerRemember
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition
resowner.c:521
ResourceOwnerEnlarge
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition
resowner.c:449
resowner.h
RESOURCE_RELEASE_LOCKS
@ RESOURCE_RELEASE_LOCKS
Definition
resowner.h:55
RESOURCE_RELEASE_BEFORE_LOCKS
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition
resowner.h:54
RESOURCE_RELEASE_AFTER_LOCKS
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition
resowner.h:56
RELEASE_PRIO_FIRST
#define RELEASE_PRIO_FIRST
Definition
resowner.h:80
ResourceOwnerData
Definition
resowner.c:113
ResourceOwnerDesc
Definition
resowner.h:92
ResourceOwnerDesc::release_priority
ResourceReleasePriority release_priority
Definition
resowner.h:97
ResourceOwnerDesc::name
const char * name
Definition
resowner.h:93
ReleaseString
static void ReleaseString(Datum res)
Definition
test_resowner_basic.c:36
test_resowner_forget_between_phases
Datum test_resowner_forget_between_phases(PG_FUNCTION_ARGS)
Definition
test_resowner_basic.c:186
PG_MODULE_MAGIC
PG_MODULE_MAGIC
Definition
test_resowner_basic.c:18
string_desc
static const ResourceOwnerDesc string_desc
Definition
test_resowner_basic.c:27
test_resowner_remember_between_phases
Datum test_resowner_remember_between_phases(PG_FUNCTION_ARGS)
Definition
test_resowner_basic.c:163
test_resowner_leak
Datum test_resowner_leak(PG_FUNCTION_ARGS)
Definition
test_resowner_basic.c:140
PrintString
static char * PrintString(Datum res)
Definition
test_resowner_basic.c:42
test_resowner_priorities
Datum test_resowner_priorities(PG_FUNCTION_ARGS)
Definition
test_resowner_basic.c:50
src
test
modules
test_resowner
test_resowner_basic.c
Generated on Tue Jan 27 2026 06:13:18 for PostgreSQL Source Code by
1.9.8