and*_*abs 9 postgresql index datatypes functions postgresql-9.4
我面临以下错误:
Run Code Online (Sandbox Code Playgroud)ERROR: functions in index expression must be marked IMMUTABLE
尝试创建这样的索引时:
CREATE INDEX full_phone_number ON orders_clientphone (concat(area_code, phone));
Run Code Online (Sandbox Code Playgroud)
另一方面,当使用替代语法进行连接时:
CREATE INDEX full_phone_number ON orders_clientphone ((area_code || phone));
Run Code Online (Sandbox Code Playgroud)
Postgres 对此非常满意。
两列都定义为character varying(256)。
Postgres的决定因素是函数concat()的定义稳定并没有一成不变的系统目录pg_proc:
SELECT proname, provolatile, proargtypes, proargtypes[0]::regtype AS argtype, prosrc
FROM pg_proc
WHERE proname = 'concat';
proname | provolatile | proargtypes| argtype | prosrc
--------+-------------+------------+---------+-----------
concat | s | 2276 | "any" | text_concat
Run Code Online (Sandbox Code Playgroud)
provolatile告诉函数的结果是仅取决于其输入参数,还是受外部因素的影响。它适用i于“不可变”函数,对于相同的输入,它总是提供相同的结果。它s用于“稳定”功能,其结果(对于固定输入)在扫描内不会改变。
我还添加了函数 ( "any")的参数类型以连接到 @dezso 和 @jjanes 的答案,这提供了使此函数稳定的决定背后的基本原理。以及内部函数的名称 ( text_concat)。
这是一个相关的问题,用于说明为什么索引表达式的不变性是必要条件:
至于使用运算符||:
SELECT o.oprname, o.oprleft::regtype, o.oprright::regtype, o.oprcode, p.provolatile
FROM pg_operator o
JOIN pg_proc p ON p.oid = o.oprcode
WHERE oprname = '||';
oprname | oprleft | oprright | oprcode | provolatile
---------+-------------+-------------+-----------------+-------------
|| | anyarray | anyelement | array_append | i
|| | anyelement | anyarray | array_prepend | i
|| | anyarray | anyarray | array_cat | i
|| | text | text | textcat | i
|| | bit varying | bit varying | bitcat | i
|| | bytea | bytea | byteacat | i
|| | text | anynonarray | textanycat | s
|| | anynonarray | text | anytextcat | s
|| | tsvector | tsvector | tsvector_concat | i
|| | tsquery | tsquery | tsquery_or | i
|| | jsonb | jsonb | jsonb_concat | i
Run Code Online (Sandbox Code Playgroud)
内部使用的函数取决于操作数的实际数据类型。运算符的定义包括 Postgres 中操作数的数据类型。所有的功能都不同,也与text_concat上面不同。||当其中一个运算符为 时,也同样稳定anynonarray。幕后的事情并不是那么简单。
character varying(256)(像任何varchar变体一样)是二进制强制的,text因此函数类型解析默认为text.
| 归档时间: |
|
| 查看次数: |
4979 次 |
| 最近记录: |