假设我们有这个 postgresql 模式:
CREATE TABLE "temp" (id int, fields text[]);
INSERT INTO "temp" VALUES
(1, array['abc', 'def']),
(2, array['abc', 'def', 'jkl']),
(3, array['abd', 'def']),
(4, '{"1{c}1", a}');
以下在纯 SQL 中工作,返回第 1 行和第 2 行(@>
是 pg 中的“包含”运算符):
SELECT id, fields FROM temp WHERE "fields" @> '{def, abc}';
但在Doobie中也是如此(带有 postgresql 扩展):
import doobie._
import doobie.implicits._
import doobie.postgres.implicits._
val searchTerms = List("def", "abc")
fr"SELECT id, fields FROM temp WHERE fields @> $searchTerms"
失败:
org.postgresql.util.PSQLException: ERROR: operator does not exist: text[] @> character varying[]
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
将插值searchTerms
转换为text[]
似乎可以解决问题:
val searchTerms = List("def", "abc")
fr"SELECT id, fields FROM temp WHERE fields @> CAST($searchTerms AS text[])"
同样,我可以在数据库模式中将fields
列的类型从更改为text[]
tovarchar[]
以避免强制转换,这也将编译并返回正确的行。
我的主要问题是我不知道为什么 Doobie 会这样。对于自定义类型,我可能会再次遇到同样的问题,所以我需要了解为什么$searchTerms
解码成varying[]
而不是text[]
,以及我可以做些什么来改变这种行为,以便我可以保留text[]
列类型并避免强制转换。我猜想某处可能有一个隐式实例控制它,但我无法弄清楚它是什么。