VHITEK Maker

Vì sao tìm kiếm tiếng Việt ở VCMS phải dùng cột sinh ra

Bởi Ban biên tập VHITEK Maker|

Yêu cầu nghe đơn giản: gõ 'may giat' phải ra 'Máy giặt', và ngược lại. Postgres có `unaccent`, có `tsvector`, tưởng là xong trong một buổi chiều.

Chỗ nó gãy

sql
ALTER TABLE posts ADD COLUMN search_tsv tsvector
  GENERATED ALWAYS AS (to_tsvector('vietnamese', unaccent(title))) STORED;
-- ERROR:  generation expression is not immutable

`unaccent()` là VOLATILE, vì nó đọc một từ điển có thể đổi trong lúc chạy. Cột generated bắt buộc IMMUTABLE. Postgres không đoán, nó từ chối.

Cách đi vòng

sql
CREATE OR REPLACE FUNCTION public.f_unaccent(text)
RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS $$
  SELECT public.unaccent('public.unaccent', $1)
$$;

Dạng hai tham số chỉ đích danh từ điển, nên kết quả không phụ thuộc `search_path` — đó là điều kiện để tuyên bố IMMUTABLE mà không nói dối. Cũng phải dùng `to_tsvector(regconfig, text)` hai tham số: dạng một tham số chỉ STABLE và cũng bị từ chối.

Thứ đáng nhớ

Khi Postgres nói 'not immutable', nó không bắt bẻ vặt. Nó đang nói: nếu cho phép, index sẽ trỏ vào dữ liệu không còn đúng nữa, và bạn sẽ mất hàng trong kết quả tìm kiếm mà không có lỗi nào báo.

Bình luận

Chưa có bình luận nào. Nếu bài này sai ở đâu, nói giúp.

Bình luận được duyệt trước khi hiện. Chúng tôi lưu địa chỉ IP và trình duyệt của bạn trong 90 ngày để chống spam, và không lưu email ở dạng đọc được. Chi tiết ở quy tắc bình luận.