3
* Routines to support manipulation of the pg_db_role_setting relation
5
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
6
* Portions Copyright (c) 1994, Regents of the University of California
9
* src/backend/catalog/pg_db_role_setting.c
13
#include "access/genam.h"
14
#include "access/heapam.h"
15
#include "access/htup.h"
16
#include "access/skey.h"
17
#include "catalog/indexing.h"
18
#include "catalog/pg_db_role_setting.h"
19
#include "utils/fmgroids.h"
20
#include "utils/rel.h"
21
#include "utils/tqual.h"
24
AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
29
ScanKeyData scankey[2];
32
valuestr = ExtractSetVariableArgs(setstmt);
34
/* Get the old tuple, if any. */
36
rel = heap_open(DbRoleSettingRelationId, RowExclusiveLock);
37
ScanKeyInit(&scankey[0],
38
Anum_pg_db_role_setting_setdatabase,
39
BTEqualStrategyNumber, F_OIDEQ,
40
ObjectIdGetDatum(databaseid));
41
ScanKeyInit(&scankey[1],
42
Anum_pg_db_role_setting_setrole,
43
BTEqualStrategyNumber, F_OIDEQ,
44
ObjectIdGetDatum(roleid));
45
scan = systable_beginscan(rel, DbRoleSettingDatidRolidIndexId, true,
46
SnapshotNow, 2, scankey);
47
tuple = systable_getnext(scan);
50
* There are three cases:
52
* - in RESET ALL, request GUC to reset the settings array and update the
53
* catalog if there's anything left, delete it otherwise
55
* - in other commands, if there's a tuple in pg_db_role_setting, update
56
* it; if it ends up empty, delete it
58
* - otherwise, insert a new pg_db_role_setting tuple, but only if the
59
* command is not RESET
61
if (setstmt->kind == VAR_RESET_ALL)
63
if (HeapTupleIsValid(tuple))
65
ArrayType *new = NULL;
69
datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
70
RelationGetDescr(rel), &isnull);
73
new = GUCArrayReset(DatumGetArrayTypeP(datum));
77
Datum repl_val[Natts_pg_db_role_setting];
78
bool repl_null[Natts_pg_db_role_setting];
79
bool repl_repl[Natts_pg_db_role_setting];
82
memset(repl_repl, false, sizeof(repl_repl));
84
repl_val[Anum_pg_db_role_setting_setconfig - 1] =
86
repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
87
repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
89
newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
90
repl_val, repl_null, repl_repl);
91
simple_heap_update(rel, &tuple->t_self, newtuple);
94
CatalogUpdateIndexes(rel, newtuple);
97
simple_heap_delete(rel, &tuple->t_self);
100
else if (HeapTupleIsValid(tuple))
102
Datum repl_val[Natts_pg_db_role_setting];
103
bool repl_null[Natts_pg_db_role_setting];
104
bool repl_repl[Natts_pg_db_role_setting];
110
memset(repl_repl, false, sizeof(repl_repl));
111
repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
112
repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
114
/* Extract old value of setconfig */
115
datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
116
RelationGetDescr(rel), &isnull);
117
a = isnull ? NULL : DatumGetArrayTypeP(datum);
119
/* Update (valuestr is NULL in RESET cases) */
121
a = GUCArrayAdd(a, setstmt->name, valuestr);
123
a = GUCArrayDelete(a, setstmt->name);
127
repl_val[Anum_pg_db_role_setting_setconfig - 1] =
130
newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
131
repl_val, repl_null, repl_repl);
132
simple_heap_update(rel, &tuple->t_self, newtuple);
135
CatalogUpdateIndexes(rel, newtuple);
138
simple_heap_delete(rel, &tuple->t_self);
142
/* non-null valuestr means it's not RESET, so insert a new tuple */
144
Datum values[Natts_pg_db_role_setting];
145
bool nulls[Natts_pg_db_role_setting];
148
memset(nulls, false, sizeof(nulls));
150
a = GUCArrayAdd(NULL, setstmt->name, valuestr);
152
values[Anum_pg_db_role_setting_setdatabase - 1] =
153
ObjectIdGetDatum(databaseid);
154
values[Anum_pg_db_role_setting_setrole - 1] = ObjectIdGetDatum(roleid);
155
values[Anum_pg_db_role_setting_setconfig - 1] = PointerGetDatum(a);
156
newtuple = heap_form_tuple(RelationGetDescr(rel), values, nulls);
158
simple_heap_insert(rel, newtuple);
161
CatalogUpdateIndexes(rel, newtuple);
164
systable_endscan(scan);
166
/* Close pg_db_role_setting, but keep lock till commit */
167
heap_close(rel, NoLock);
171
* Drop some settings from the catalog. These can be for a particular
172
* database, or for a particular role. (It is of course possible to do both
173
* too, but it doesn't make sense for current uses.)
176
DropSetting(Oid databaseid, Oid roleid)
184
relsetting = heap_open(DbRoleSettingRelationId, RowExclusiveLock);
186
if (OidIsValid(databaseid))
188
ScanKeyInit(&keys[numkeys],
189
Anum_pg_db_role_setting_setdatabase,
190
BTEqualStrategyNumber,
192
ObjectIdGetDatum(databaseid));
195
if (OidIsValid(roleid))
197
ScanKeyInit(&keys[numkeys],
198
Anum_pg_db_role_setting_setrole,
199
BTEqualStrategyNumber,
201
ObjectIdGetDatum(roleid));
205
scan = heap_beginscan(relsetting, SnapshotNow, numkeys, keys);
206
while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection)))
208
simple_heap_delete(relsetting, &tup->t_self);
212
heap_close(relsetting, RowExclusiveLock);
216
* Scan pg_db_role_setting looking for applicable settings, and load them on
217
* the current process.
219
* relsetting is pg_db_role_setting, already opened and locked.
221
* Note: we only consider setting for the exact databaseid/roleid combination.
222
* This probably needs to be called more than once, with InvalidOid passed as
226
ApplySetting(Oid databaseid, Oid roleid, Relation relsetting, GucSource source)
232
ScanKeyInit(&keys[0],
233
Anum_pg_db_role_setting_setdatabase,
234
BTEqualStrategyNumber,
236
ObjectIdGetDatum(databaseid));
237
ScanKeyInit(&keys[1],
238
Anum_pg_db_role_setting_setrole,
239
BTEqualStrategyNumber,
241
ObjectIdGetDatum(roleid));
243
scan = systable_beginscan(relsetting, DbRoleSettingDatidRolidIndexId, true,
244
SnapshotNow, 2, keys);
245
while (HeapTupleIsValid(tup = systable_getnext(scan)))
250
datum = heap_getattr(tup, Anum_pg_db_role_setting_setconfig,
251
RelationGetDescr(relsetting), &isnull);
254
ArrayType *a = DatumGetArrayTypeP(datum);
257
* We process all the options at SUSET level. We assume that the
258
* right to insert an option into pg_db_role_setting was checked
259
* when it was inserted.
261
ProcessGUCArray(a, PGC_SUSET, source, GUC_ACTION_SET);
265
systable_endscan(scan);