1 /*-------------------------------------------------------------------------
4 * PostgreSQL statistics manipulation utilities.
6 * Code supporting the direct manipulation of statistics.
8 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/backend/statistics/stat_utils.c
14 *-------------------------------------------------------------------------
19 #include "access/relation.h"
20 #include "catalog/pg_database.h"
21 #include "miscadmin.h"
22 #include "statistics/stat_utils.h"
23 #include "utils/acl.h"
24 #include "utils/array.h"
25 #include "utils/builtins.h"
26 #include "utils/rel.h"
29 * Ensure that a given argument is not null.
32 stats_check_required_arg(FunctionCallInfo fcinfo
,
33 struct StatsArgInfo
*arginfo
,
36 if (PG_ARGISNULL(argnum
))
38 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
39 errmsg("\"%s\" cannot be NULL",
40 arginfo
[argnum
].argname
)));
44 * Lock relation in ShareUpdateExclusive mode, check privileges, and close the
45 * relation (but retain the lock).
47 * A role has privileges to set statistics on the relation if any of the
49 * - the role owns the current database and the relation is not shared
50 * - the role has the MAINTAIN privilege on the relation
53 stats_lock_check_privileges(Oid reloid
)
55 Relation rel
= relation_open(reloid
, ShareUpdateExclusiveLock
);
56 const char relkind
= rel
->rd_rel
->relkind
;
58 /* All of the types that can be used with ANALYZE, plus indexes */
61 case RELKIND_RELATION
:
64 case RELKIND_FOREIGN_TABLE
:
65 case RELKIND_PARTITIONED_TABLE
:
66 case RELKIND_PARTITIONED_INDEX
:
70 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
71 errmsg("cannot modify statistics for relation \"%s\"",
72 RelationGetRelationName(rel
)),
73 errdetail_relkind_not_supported(rel
->rd_rel
->relkind
)));
76 if (rel
->rd_rel
->relisshared
)
78 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
79 errmsg("cannot modify statistics for shared relation")));
81 if (!object_ownercheck(DatabaseRelationId
, MyDatabaseId
, GetUserId()))
83 AclResult aclresult
= pg_class_aclcheck(RelationGetRelid(rel
),
87 if (aclresult
!= ACLCHECK_OK
)
88 aclcheck_error(aclresult
,
89 get_relkind_objtype(rel
->rd_rel
->relkind
),
90 NameStr(rel
->rd_rel
->relname
));
93 relation_close(rel
, NoLock
);