今天在创建函数索引时遇到报错,报错信息即为标题,弄了很久,百思不得其解,后来向德哥咨询了下,很快就搞定了,下面是详细信息。
1 表定义
1 |
skytf=> /d test_39; |
现在需要在字段 “skyid”, “create_time” 上创建联合索引。
2 创建索引
1 |
skytf=> create index CONCURRENTLY idx_test_skyid_ctime on test_39 using btree (skyid, to_char(create_time, 'YYYY-MM-DD') ); |
创建函数索引报错,”functions in index expression must be marked IMMUTABLE” ,意思为建立函数索引时 函数必须标识为 “IMMUTABLE”。
3 查看 to_char 函数
1 |
skytf=> /df to_char(); |
4 以 postgres 超级用户连接,修改 to_char 函数属性
1 |
skytf=# alter function to_char(timestamp with time zone, text) IMMUTABLE; |
备注:由于表 test_39 上的列 create_time 类型为 “timestamp with time zone” , 所以修改函数时应该修改函数 to_char(timestamp with time zone, text),为了安全己见,不要直接修改 to_char 函数,建议新建一个 IMMUTABLE 属性的 to_char_immutable 函数。
5 验证是否生效
1 |
skytf=> /ef to_char(timestamp with time zone, text) |
从“IMMUTABLE STRICT” 中可以看出,函数已经修改成 “IMMUTABLE”属性。
6 以 skytf 连接, 再次创建索引
1 |
skytf=> create index CONCURRENTLY idx_test_skyid_ctime on test_39 using btree (skyid, to_char(create_time, 'YYYY-MM-DD') ); |
备注:在修改函数 to_char(timestamp with time zone, text) 属性后,创建索引就成功了。
1 |
skytf=> /d test_39 |
7 手册上关于 “IMMUTABLE” 属性解释
IMMUTABLE indicates that the function cannot modify the database and always returns the same result when given the same argument values; that is, it does not do database lookups or otherwise use information not directly present in its argument list. If this option is given, any call of the function with all-constant arguments can be immediately replaced with the function value.
8 总结
函数的默认属性为 “VOLATILE”, 即可变的,在创建函数索引时,需要将引用函数的属性改为”IMMUTABLE”, 即稳定的,函数索引才能创建成功。也就是说,只有属性为稳定的函数,才能用来创建函数索引。
原创文章,作者:1402239773,如若转载,请注明出处:https://blog.ytso.com/tech/database/236396.html