注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

PostgreSQL 中文网

 
 
 

日志

 
 

ERROR: functions in index expression must be marked IMMUTABLE  

2011-05-12 16:48:48|  分类: PG案例分析 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

                      
          今天在创建函数索引时遇到报错,报错信息即为标题,弄了很久,百思不得其解,
后来向德哥咨询了下,很快就搞定了,下面是详细信息。      
          
--1 表定义
skytf=> \d test_39;
               Table "skytf.test_39"
   Column    |           Type           | Modifiers
-------------+--------------------------+-----------
 skyid       | integer                  |
 create_time | timestamp with time zone |
 name        | character varying(32)    |
 
       现在需要在字段 "skyid", "create_time" 上创建联合索引。
 
--2 创建索引
skytf=> create index CONCURRENTLY idx_test_skyid_ctime on  test_39 using btree (skyid, to_char(create_time, 'YYYY-MM-DD') );
ERROR:  functions in index expression must be marked IMMUTABLE

       创建函数索引报错,"functions in index expression must be marked IMMUTABLE" ,意思为
  建立函数索引时 函数必须标识为 "IMMUTABLE"。


--3 查看 to_char 函数
skytf=> \df to_char();
                                  List of functions
   Schema   |  Name   | Result data type |        Argument data types        |  Type 
------------+---------+------------------+-----------------------------------+--------
 pg_catalog | to_char | text             | bigint, text                      | normal
 pg_catalog | to_char | text             | double precision, text            | normal
 pg_catalog | to_char | text             | integer, text                     | normal
 pg_catalog | to_char | text             | interval, text                    | normal
 pg_catalog | to_char | text             | numeric, text                     | normal
 pg_catalog | to_char | text             | real, text                        | normal
 pg_catalog | to_char | text             | timestamp with time zone, text    | normal
 pg_catalog | to_char | text             | timestamp without time zone, text | normal
(8 rows)


--4 以 postgres 超级用户连接,修改 to_char 函数属性
skytf=# alter function to_char(timestamp with time zone, text) IMMUTABLE;
ALTER FUNCTION

    备注:由于表 test_39 上的列 create_time 类型为 "timestamp with time zone" , 所以修改函数时

     应该修改函数 to_char(timestamp with time zone, text),为了安全己见,不要直接修改 to_char 函数,

     建议新建一个 IMMUTABLE 属性的 to_char_immutable 函数。


--5 验证是否生效
skytf=> \ef to_char(timestamp with time zone, text)

CREATE OR REPLACE FUNCTION pg_catalog.to_char(timestamp with time zone, text)
 RETURNS text
 LANGUAGE internal
 IMMUTABLE STRICT
AS $function$timestamptz_to_char$function$

   从“IMMUTABLE STRICT” 中可以看出,函数已经修改成 "IMMUTABLE"属性。

--6 以 skytf 连接, 再次创建索引
skytf=> create index CONCURRENTLY idx_test_skyid_ctime on  test_39 using btree (skyid, to_char(create_time, 'YYYY-MM-DD') );
CREATE INDEX

     备注:在修改函数 to_char(timestamp with time zone, text) 属性后,创建索引就成功了。

skytf=> \d test_39
               Table "skytf.test_39"
   Column    |           Type           | Modifiers
-------------+--------------------------+-----------
 skyid       | integer                  |
 create_time | timestamp with time zone |
 name        | character varying(32)    |
Indexes:
    "idx_test_skyid_ctime" btree (skyid, to_char(create_time, 'YYYY-MM-DD'::text))


--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", 即稳定的,函数索引才能创建成功。也就是说,只有属性为稳定的函数,才能用
   来创建函数索引。

  评论这张
 
阅读(26277)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016