ERROR: Functions in index expression must be marked IMMUTABLE


在創建函數索引時遇到報錯,報錯信息即為標題,下面是詳細信息。

1 表定義

1
2
3
4
5
6
7
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 創建索引

1
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 函數

1
2
3
4
5
6
7
8
9
10
11
12
13
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 函數屬性

1
2
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 驗證是否生效

1
2
3
4
5
6
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 連接, 再次創建索引

1
2
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) 屬性后,創建索引就成功了。

1
2
3
4
5
6
7
8
9
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”, 即穩定的,函數索引才能創建成功。也就是說,只有屬性為穩定的函數,才能用來創建函數索引。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM