summaryrefslogtreecommitdiffstats
path: root/src/backend/catalog/pg_parameter_acl.c
blob: 2decee909b36619cd33f9ead7e6a3f8cbe41b697 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*-------------------------------------------------------------------------
 *
 * pg_parameter_acl.c
 *	  routines to support manipulation of the pg_parameter_acl relation
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/catalog/pg_parameter_acl.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_parameter_acl.h"
#include "utils/builtins.h"
#include "utils/pg_locale.h"
#include "utils/rel.h"
#include "utils/syscache.h"


/*
 * ParameterAclLookup - Given a configuration parameter name,
 * look up the associated configuration parameter ACL's OID.
 *
 * If missing_ok is false, throw an error if ACL entry not found.  If
 * true, just return InvalidOid.
 */
Oid
ParameterAclLookup(const char *parameter, bool missing_ok)
{
	Oid			oid;
	char	   *parname;

	/* Convert name to the form it should have in pg_parameter_acl... */
	parname = convert_GUC_name_for_parameter_acl(parameter);

	/* ... and look it up */
	oid = GetSysCacheOid1(PARAMETERACLNAME, Anum_pg_parameter_acl_oid,
						  PointerGetDatum(cstring_to_text(parname)));

	if (!OidIsValid(oid) && !missing_ok)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("parameter ACL \"%s\" does not exist", parameter)));

	pfree(parname);

	return oid;
}

/*
 * ParameterAclCreate
 *
 * Add a new tuple to pg_parameter_acl.
 *
 * parameter: the parameter name to create an entry for.
 * Caller should have verified that there's no such entry already.
 *
 * Returns the new entry's OID.
 */
Oid
ParameterAclCreate(const char *parameter)
{
	Oid			parameterId;
	char	   *parname;
	Relation	rel;
	TupleDesc	tupDesc;
	HeapTuple	tuple;
	Datum		values[Natts_pg_parameter_acl];
	bool		nulls[Natts_pg_parameter_acl];

	/*
	 * To prevent cluttering pg_parameter_acl with useless entries, insist
	 * that the name be valid.
	 */
	if (!check_GUC_name_for_parameter_acl(parameter))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_NAME),
				 errmsg("invalid parameter name \"%s\"",
						parameter)));

	/* Convert name to the form it should have in pg_parameter_acl. */
	parname = convert_GUC_name_for_parameter_acl(parameter);

	/*
	 * Create and insert a new record containing a null ACL.
	 *
	 * We don't take a strong enough lock to prevent concurrent insertions,
	 * relying instead on the unique index.
	 */
	rel = table_open(ParameterAclRelationId, RowExclusiveLock);
	tupDesc = RelationGetDescr(rel);
	MemSet(values, 0, sizeof(values));
	MemSet(nulls, false, sizeof(nulls));
	parameterId = GetNewOidWithIndex(rel,
									 ParameterAclOidIndexId,
									 Anum_pg_parameter_acl_oid);
	values[Anum_pg_parameter_acl_oid - 1] = ObjectIdGetDatum(parameterId);
	values[Anum_pg_parameter_acl_parname - 1] =
		PointerGetDatum(cstring_to_text(parname));
	nulls[Anum_pg_parameter_acl_paracl - 1] = true;
	tuple = heap_form_tuple(tupDesc, values, nulls);
	CatalogTupleInsert(rel, tuple);

	/* Close pg_parameter_acl, but keep lock till commit. */
	heap_freetuple(tuple);
	table_close(rel, NoLock);

	return parameterId;
}