68.3. 规划器统计信息和安全性

对表pg_statistic的访问仅限于超级用户,因此普通用户无法从中了解其他用户的表内容。某些选择性估计功能将使用用户提供的运算符(出现在查询中的运算符或相关的运算符)来分析存储的统计信息。例如,为了确定所存储的最常用值是否适用,选择性估计器将必须运行适当的=运算符以将查询中的常数与所存储的值进行比较。因此,pg_statistic中的数据可能会传递给用户定义的运算符。经过适当设计的运算符可以有意泄漏所传递的操作数(例如,通过记录它们或将它们写入不同的表中),或通过在错误消息中显示它们的值来意外泄漏它们,在任何一种情况下都可能会将pg_statistic中的数据暴露给应该看不到它。

为了防止这种情况,以下内容适用于所有内置的选择性估计功能。在计划查询时,为了能够使用存储的统计信息,当前用户必须对表或所涉及的列具有SELECT特权,或者所使用的运算符必须为LEAKPROOF(更准确地说,该运算符所基于的功能)。如果没有,那么选择性估计器将表现为好像没有可用的统计信息一样,并且计划程序将使用默认或后备假设进行。

如果用户对表或列没有所需的特权,则在许多情况下,查询最终将收到权限拒绝的错误,在这种情况下,该机制实际上是不可见的。但是,如果用户正在从安全屏障视图中进行读取,则计划者可能希望检查用户否则无法访问的基础表的统计信息。在这种情况下,操作员应防泄漏,否则将不使用统计信息。没有任何直接的反馈,只是该计划可能不是最理想的。如果怀疑是这种情况,可以尝试以更具特权的用户身份运行查询,以查看是否得出了不同的计划。

此限制仅适用于计划者需要对pg_statistic中的一个或多个值执行用户定义的运算符的情况。因此,无论访问权限如何,都允许计划者使用常规统计信息,例如空值的分数或一列中不同值的数量。

第三方扩展中包含的选择性估计功能(可能使用用户定义的运算符对统计信息进行操作)应遵循相同的安全规则。请查阅 PostgreSQL 源代码以获取指导。