由于嵌套一个非不可变的函数会禁用函数内联,所以它基于 C 函数的一个副本,(假)也声明了 IMMUTABLE。它的 只有用途是在 SQL 函数包装器中使用。不应该单独使用。
这种复杂性是必要的,因为没有办法在 C 函数的声明中硬连接字典。(需要破解 C 代码本身。)SQL 包装函式可以做到这一点,并且允许这两个函数内联 还有表达式索引。
CREATE OR REPLACE FUNCTION public.immutable_unaccent(regdictionary, text)
RETURNS text
LANGUAGE c IMMUTABLE PARALLEL SAFE STRICT AS
'$libdir/unaccent', 'unaccent_dict';
然后:
CREATE OR REPLACE FUNCTION public.f_unaccent(text)
RETURNS text
LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
$func$
SELECT public.immutable_unaccent(regdictionary 'public.unaccent', $1)
$func$;
在 Postgres 14或更高版本中,SQL 标准函数稍微便宜一些,但是:
CREATE OR REPLACE FUNCTION public.f_unaccent(text)
RETURNS text
LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT
BEGIN ATOMIC
SELECT public.immutable_unaccent(regdictionary 'public.unaccent', $1);
END;
如果 您缺乏创建 C 函数所需的特权,那么您将回到第二个最佳实现: 模块提供的 STABLEunaccent()函数的 IMMUTABLE函数包装器:
CREATE OR REPLACE FUNCTION public.f_unaccent(text)
RETURNS text
LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
$func$
SELECT public.unaccent('public.unaccent', $1) -- schema-qualify function and dictionary
$func$;
最后,表达式索引表达式索引进行查询 很快:
CREATE INDEX users_unaccent_name_idx ON users(public.f_unaccent(name));
CREATE EXTENSION unaccent;
CREATE TEXT SEARCH CONFIGURATION mydict ( COPY = simple );
ALTER TEXT SEARCH CONFIGURATION mydict
ALTER MAPPING FOR hword, hword_part, word
WITH unaccent, simple;
然后您可以使用函数索引对其进行索引,
-- Just some sample data...
CREATE TABLE myTable ( myCol )
AS VALUES ('fóó bar baz'),('qux quz');
-- No index required, but feel free to create one
CREATE INDEX ON myTable
USING GIST (to_tsvector('mydict', myCol));
您现在可以非常简单地查询它
SELECT *
FROM myTable
WHERE to_tsvector('mydict', myCol) @@ 'foo & bar'
mycol
-------------
fóó bar baz
(1 row)