#define ATT_COMPOSITE_TYPE 0x0010
#define ATT_FOREIGN_TABLE 0x0020
-static void truncate_check_rel(Oid relid, Form_pg_class reltuple);
-static void truncate_check_perms(Oid relid, Form_pg_class reltuple);
-static void truncate_check_activity(Relation rel);
+static void truncate_check_rel(Relation rel);
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
List **supOids, List **supconstr, int *supOidCount);
static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
heap_close(rel, lockmode);
continue;
}
-
- truncate_check_rel(myrelid, rel->rd_rel);
- truncate_check_perms(myrelid, rel->rd_rel);
- truncate_check_activity(rel);
-
+ truncate_check_rel(rel);
rels = lappend(rels, rel);
relids = lappend_oid(relids, myrelid);
continue;
}
- /*
- * Inherited TRUNCATE commands perform access
- * permission checks on the parent table only.
- * So we skip checking the children's permissions
- * and don't call truncate_check_perms() here.
- */
- truncate_check_rel(RelationGetRelid(rel), rel->rd_rel);
- truncate_check_activity(rel);
-
+ truncate_check_rel(rel);
rels = lappend(rels, rel);
relids = lappend_oid(relids, childrelid);
}
ereport(NOTICE,
(errmsg("truncate cascades to table \"%s\"",
RelationGetRelationName(rel))));
- truncate_check_rel(relid, rel->rd_rel);
- truncate_check_perms(relid, rel->rd_rel);
- truncate_check_activity(rel);
+ truncate_check_rel(rel);
rels = lappend(rels, rel);
relids = lappend_oid(relids, relid);
}
* Check that a given rel is safe to truncate. Subroutine for ExecuteTruncate
*/
static void
-truncate_check_rel(Oid relid, Form_pg_class reltuple)
+truncate_check_rel(Relation rel)
{
- char *relname = NameStr(reltuple->relname);
+ AclResult aclresult;
/* Only allow truncate on regular tables */
- if (reltuple->relkind != RELKIND_RELATION)
+ if (rel->rd_rel->relkind != RELKIND_RELATION)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table", relname)));
+ errmsg("\"%s\" is not a table",
+ RelationGetRelationName(rel))));
- if (!allowSystemTableMods && IsSystemClass(relid, reltuple))
+ /* Permissions checks */
+ aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
+ ACL_TRUNCATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_CLASS,
+ RelationGetRelationName(rel));
+
+ if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied: \"%s\" is a system catalog",
- relname)));
-}
-
-/*
- * Check that current user has the permission to truncate given relation.
- */
-static void
-truncate_check_perms(Oid relid, Form_pg_class reltuple)
-{
- char *relname = NameStr(reltuple->relname);
- AclResult aclresult;
-
- /* Permissions checks */
- aclresult = pg_class_aclcheck(relid, GetUserId(), ACL_TRUNCATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_CLASS, relname);
-}
+ RelationGetRelationName(rel))));
-/*
- * Set of extra sanity checks to check if a given relation is safe to
- * truncate.
- */
-static void
-truncate_check_activity(Relation rel)
-{
/*
* Don't allow truncate on temp tables of other backends ... their local
* buffer manager is not going to cope.
-----
(0 rows)
--- child's permissions do not apply when operating on parent
-SET SESSION AUTHORIZATION regressuser1;
-REVOKE ALL ON atestc FROM regressuser2;
-GRANT ALL ON atestp1 TO regressuser2;
-SET SESSION AUTHORIZATION regressuser2;
-SELECT f2 FROM atestp1; -- ok
- f2
-----
-(0 rows)
-
-SELECT f2 FROM atestc; -- fail
-ERROR: permission denied for relation atestc
-DELETE FROM atestp1; -- ok
-DELETE FROM atestc; -- fail
-ERROR: permission denied for relation atestc
-UPDATE atestp1 SET f1 = 1; -- ok
-UPDATE atestc SET f1 = 1; -- fail
-ERROR: permission denied for relation atestc
-TRUNCATE atestp1; -- ok
-TRUNCATE atestc; -- fail
-ERROR: permission denied for relation atestc
-- privileges on functions, languages
-- switch to superuser
\c -