zer*_*dge 4 postgresql performance datatypes array postgresql-performance
我正在尝试执行这个简单的查询,以检查某个值(1000)是否属于 Postgres 查询优化器使用的 MCV 列表:
SELECT array_position(most_common_vals, 1000)
FROM pg_stats
WHERE tablename = 'tenk1'
AND attname = 'unique1';
Run Code Online (Sandbox Code Playgroud)
但收到以下错误消息:
Run Code Online (Sandbox Code Playgroud)ERROR: function array_position(anyarray, integer) does not exist
如何解决?
array_position()是此处描述的标准函数,以下语句按预期返回2:
SELECT array_position('{1,2,3}', 2);
Run Code Online (Sandbox Code Playgroud)
假设您的列的数据类型tenk1.unique1是integer:
SELECT array_position(most_common_vals::text::int[], 1000)
FROM pg_stats
WHERE tablename = 'tenk1'
AND attname = 'unique1';
Run Code Online (Sandbox Code Playgroud)
使用您的实际列类型和相应的数组类型。
您将获取位置,如果该值不在 MCV 列表中,则获取 NULL。
解决方案很短 - 不像......
该函数array_position()被定义为采取(anyarray, anyelement)(或(anyarray, anyelement, integer)第二个变体)。
该列pg_stats.most_common_vals具有多态数据类型,anyarray能够保存任何数据类型的数组 - 原因显而易见。
anyarray且anyelement不允许作为用户创建表的数据类型。对于用户来说,两者都是多态伪类型。(但是 Postgres 可以在系统表中使用它们。)
同一函数中的多个多态变量必须解析为相同(或相应)的数据类型。手册:
此外,如果有位置声明
anyarray和其他位置声明anyelement,则位置中的实际数组类型anyarray必须是其元素与任意元素位置中出现的类型相同的数组。
和:
因此,当使用多态类型声明多个参数位置时,最终效果是只允许实际参数类型的某些组合。
大胆强调我的。
您发现了一个极端情况,其中多态与第二位置的- 或任何非多态类型的组合的函数类型解析失败。anyarrayinteger
1000在你的表达式中array_position(most_common_vals, 1000)是一个解析为 的数字常量integer。这些都会以类似的方式失败:
array_position(most_common_vals, '1000') -- untyped string literal
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)ERROR: function array_position(anyarray, unknown) does not exist
array_position(most_common_vals, '1000'::text)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)ERROR: function array_position(anyarray, text) does not exist
此外,没有为 定义强制转换anyarray,它是用户空间中的伪类型:
SELECT * FROM pg_cast WHERE castsource = 'anyarray'::regtype; -- nothing found
Run Code Online (Sandbox Code Playgroud)
解决方法是将 totext作为垫脚石,因为任何类型都可以转换为text。然后投射到integer[],得到上面的解。
最后,我认为这是函数类型解析中的一个缺点,可以解决(很容易?)。但由于数据类型anyarray不应该在用户域中这样使用,我怀疑任何开发人员都会花时间在它上面......
| 归档时间: |
|
| 查看次数: |
9412 次 |
| 最近记录: |