权限未更新问题:执行GRANT后仍无法删除触发器
先给你吃个定心丸:那个WARNING: no privileges were granted for "pg_stat_statements"完全不会影响你的权限生效,别纠结它。pg_stat_statements是PostgreSQL的系统扩展表,不属于你指定的public schema(它一般在pg_catalog或者单独的扩展专属schema里),所以你执行的GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public语句会自动跳过它,这个警告只是系统在告诉你“我跳过了一个不在目标schema里的表而已”,和你操作tablex的权限半毛钱关系都没有。
接下来看你遇到的核心问题:执行DROP TRIGGER时报错must be owner of relation tablex。这是因为删除触发器需要的不是普通的表读写权限,而是表的TRIGGER权限,或者你是该表的所有者——哪怕你有表的所有读写权限,没有TRIGGER权限也删不了触发器。
你已经执行了一堆权限操作,但还是踩坑了,可能的遗漏点有这几个:
ALL PRIVILEGES是否真的覆盖到了tablex?
在PostgreSQL里,ALL PRIVILEGES对于表对象来说默认是包含TRIGGER权限的,但有可能你的GRANT语句没正确应用到tablex上。你可以先验证一下userx对tablex的权限:
在psql终端里执行:\dp tablex或者用标准SQL查询:
SELECT privilege_type FROM information_schema.table_privileges WHERE table_name = 'tablex' AND grantee = 'userx';如果结果里没有
TRIGGER,那说明权限确实没加上。权限是否只对现有表生效?
GRANT ALL PRIVILEGES ON ALL TABLES只会授予执行该语句时已经存在的表的权限。如果tablex是你执行这条GRANT之后才创建的,那你设置的ALTER DEFAULT PRIVILEGES应该自动给新表授权,但如果执行ALTER DEFAULT的角色和创建tablex的角色不一致(比如用超级用户设了默认权限,但tablex是用另一个普通角色创建的),那默认权限可能不会生效。直接补授TRIGGER权限最稳妥
不管是哪种情况,直接给userx单独授予tablex的TRIGGER权限,都能快速解决问题:GRANT TRIGGER ON TABLE tablex TO userx;如果需要完全控制权,转表所有权更彻底
如果你希望userx能完全掌控这个表(包括删触发器、改表结构、加索引等所有操作),直接把表的所有权转给他就行:ALTER TABLE tablex OWNER TO userx;
总结一下:别管那个pg_stat_statements的警告,重点检查userx对tablex的TRIGGER权限,要么单独补授TRIGGER权限,要么转表所有权,就能解决删除触发器的权限问题了。
内容的提问来源于stack exchange,提问作者IAddBugsToCodebases

