3.6 KiB
3.6 KiB
IMMUTABLE函数错误最终解决方案
🔧 问题解决
错误: ERROR: 42P17: functions in index predicate must be marked IMMUTABLE
最终解决方案: 使用简单的表达式索引,完全避免自定义IMMUTABLE函数的复杂性。
✅ 修复内容
移除了复杂的IMMUTABLE函数
之前 (复杂方案):
-- 创建自定义IMMUTABLE函数
CREATE FUNCTION content_title_to_tsvector(title TEXT)
RETURNS tsvector LANGUAGE sql IMMUTABLE STRICT...
-- 使用自定义函数的索引
CREATE INDEX ... USING gin(content_title_to_tsvector(title));
现在 (简化方案):
-- 直接使用表达式索引
CREATE INDEX IF NOT EXISTS idx_contents_title_gin
ON public.ak_contents USING gin((to_tsvector('simple'::regconfig, title)));
CREATE INDEX IF NOT EXISTS idx_contents_content_gin
ON public.ak_contents USING gin((to_tsvector('simple'::regconfig, content)));
🎯 优势
- 简单可靠: 避免自定义函数的复杂性
- 兼容性强: 适用于所有PostgreSQL版本
- 性能良好: 表达式索引同样高效
- 维护简单: 不需要管理额外的函数
📋 使用方法
全文搜索查询
-- 搜索标题
SELECT id, title, published_at
FROM ak_contents
WHERE to_tsvector('simple', title) @@ to_tsquery('simple', 'AI');
-- 搜索内容
SELECT id, title, LEFT(content, 200) as preview
FROM ak_contents
WHERE to_tsvector('simple', content) @@ to_tsquery('simple', 'technology');
-- 组合搜索
SELECT id, title, published_at
FROM ak_contents
WHERE to_tsvector('simple', title) @@ to_tsquery('simple', 'AI | machine')
OR to_tsvector('simple', content) @@ to_tsquery('simple', 'AI | machine')
ORDER BY published_at DESC;
-- 相关性排序
SELECT id, title,
ts_rank(to_tsvector('simple', title), query) +
ts_rank(to_tsvector('simple', content), query) as rank
FROM ak_contents, to_tsquery('simple', 'artificial & intelligence') query
WHERE to_tsvector('simple', title) @@ query
OR to_tsvector('simple', content) @@ query
ORDER BY rank DESC;
高级搜索功能
-- 短语搜索
SELECT * FROM ak_contents
WHERE to_tsvector('simple', title) @@ phraseto_tsquery('simple', 'artificial intelligence');
-- 自然语言搜索
SELECT * FROM ak_contents
WHERE to_tsvector('simple', content) @@ plainto_tsquery('simple', 'machine learning algorithms');
-- 搜索高亮
SELECT id, title,
ts_headline('simple', content, to_tsquery('simple', 'AI'),
'MaxWords=35, MinWords=15, ShortWord=3, HighlightAll=FALSE') as highlight
FROM ak_contents
WHERE to_tsvector('simple', content) @@ to_tsquery('simple', 'AI');
🚀 部署状态
状态: ✅ 问题完全解决
- ✅ 移除了有问题的IMMUTABLE函数
- ✅ 使用简单可靠的表达式索引
- ✅ 保持高性能全文搜索功能
- ✅ 支持所有PostgreSQL/Supabase版本
📝 升级说明
如果您之前部署过有IMMUTABLE函数的版本:
- 自动清理: 新版本会自动删除旧的索引
- 重新创建: 自动创建新的简化索引
- 查询兼容: 查询方式略有变化,请参考上面的示例
🎉 结论
通过使用简单的表达式索引而不是自定义IMMUTABLE函数,我们彻底解决了 ERROR: 42P17 错误,同时保持了优秀的全文搜索性能。
这个解决方案更加:
- 🔧 简单: 无需维护自定义函数
- 🛡️ 可靠: 避免版本兼容性问题
- ⚡ 高效: 查询性能依然优秀
- 🌐 通用: 适用于所有环境
修复时间: 2025年6月18日
问题状态: ✅ 已完全解决
兼容性: 全版本PostgreSQL/Supabase