1

假设我们有这个 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[]列类型并避免强制转换。我猜想某处可能有一个隐式实例控制它,但我无法弄清楚它是什么。

4

0 回答 0