Line data Source code
1 : /*------------------------------------------------------------------------- 2 : * 3 : * pg_parameter_acl.c 4 : * routines to support manipulation of the pg_parameter_acl relation 5 : * 6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group 7 : * Portions Copyright (c) 1994, Regents of the University of California 8 : * 9 : * 10 : * IDENTIFICATION 11 : * src/backend/catalog/pg_parameter_acl.c 12 : * 13 : *------------------------------------------------------------------------- 14 : */ 15 : #include "postgres.h" 16 : 17 : #include "access/table.h" 18 : #include "catalog/catalog.h" 19 : #include "catalog/indexing.h" 20 : #include "catalog/objectaccess.h" 21 : #include "catalog/pg_namespace.h" 22 : #include "catalog/pg_parameter_acl.h" 23 : #include "utils/builtins.h" 24 : #include "utils/guc.h" 25 : #include "utils/pg_locale.h" 26 : #include "utils/rel.h" 27 : #include "utils/syscache.h" 28 : 29 : 30 : /* 31 : * ParameterAclLookup - Given a configuration parameter name, 32 : * look up the associated configuration parameter ACL's OID. 33 : * 34 : * If missing_ok is false, throw an error if ACL entry not found. If 35 : * true, just return InvalidOid. 36 : */ 37 : Oid 38 126 : ParameterAclLookup(const char *parameter, bool missing_ok) 39 : { 40 : Oid oid; 41 : char *parname; 42 : 43 : /* Convert name to the form it should have in pg_parameter_acl... */ 44 126 : parname = convert_GUC_name_for_parameter_acl(parameter); 45 : 46 : /* ... and look it up */ 47 126 : oid = GetSysCacheOid1(PARAMETERACLNAME, Anum_pg_parameter_acl_oid, 48 : PointerGetDatum(cstring_to_text(parname))); 49 : 50 126 : if (!OidIsValid(oid) && !missing_ok) 51 0 : ereport(ERROR, 52 : (errcode(ERRCODE_UNDEFINED_OBJECT), 53 : errmsg("parameter ACL \"%s\" does not exist", parameter))); 54 : 55 126 : pfree(parname); 56 : 57 126 : return oid; 58 : } 59 : 60 : /* 61 : * ParameterAclCreate 62 : * 63 : * Add a new tuple to pg_parameter_acl. 64 : * 65 : * parameter: the parameter name to create an entry for. 66 : * Caller should have verified that there's no such entry already. 67 : * 68 : * Returns the new entry's OID. 69 : */ 70 : Oid 71 68 : ParameterAclCreate(const char *parameter) 72 : { 73 : Oid parameterId; 74 : char *parname; 75 : Relation rel; 76 : TupleDesc tupDesc; 77 : HeapTuple tuple; 78 68 : Datum values[Natts_pg_parameter_acl] = {0}; 79 68 : bool nulls[Natts_pg_parameter_acl] = {0}; 80 : 81 : /* 82 : * To prevent cluttering pg_parameter_acl with useless entries, insist 83 : * that the name be valid. 84 : */ 85 68 : if (!check_GUC_name_for_parameter_acl(parameter)) 86 2 : ereport(ERROR, 87 : (errcode(ERRCODE_INVALID_NAME), 88 : errmsg("invalid parameter name \"%s\"", 89 : parameter))); 90 : 91 : /* Convert name to the form it should have in pg_parameter_acl. */ 92 66 : parname = convert_GUC_name_for_parameter_acl(parameter); 93 : 94 : /* 95 : * Create and insert a new record containing a null ACL. 96 : * 97 : * We don't take a strong enough lock to prevent concurrent insertions, 98 : * relying instead on the unique index. 99 : */ 100 66 : rel = table_open(ParameterAclRelationId, RowExclusiveLock); 101 66 : tupDesc = RelationGetDescr(rel); 102 66 : parameterId = GetNewOidWithIndex(rel, 103 : ParameterAclOidIndexId, 104 : Anum_pg_parameter_acl_oid); 105 66 : values[Anum_pg_parameter_acl_oid - 1] = ObjectIdGetDatum(parameterId); 106 66 : values[Anum_pg_parameter_acl_parname - 1] = 107 66 : PointerGetDatum(cstring_to_text(parname)); 108 66 : nulls[Anum_pg_parameter_acl_paracl - 1] = true; 109 66 : tuple = heap_form_tuple(tupDesc, values, nulls); 110 66 : CatalogTupleInsert(rel, tuple); 111 : 112 : /* Close pg_parameter_acl, but keep lock till commit. */ 113 66 : heap_freetuple(tuple); 114 66 : table_close(rel, NoLock); 115 : 116 66 : return parameterId; 117 : }