如何使用 jooq (postgresql) 批量执行处理 anyarray 参数化存储函数?

How to handle anyarray parameterized stored function in batch execution with jooq (postgresql)?

我有如下的数据库模式:

CREATE FUNCTION public.some_fun(anyarray) RETURNS anyarray AS $$
  SELECT ;
$$ LANGUAGE sql;

CREATE TABLE some_table (some_col int[]);

我在 java 中调用以下代码:

DSLContext ctx = ... // retrieve DSLcontext
Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
ctx.batch(query).execute();

代码产生异常:

org.postgresql.util.PSQLException: ERROR: could not determine polymorphic type because input has type "unknown"

生成的查询是:

insert into "public"."some_table" ("some_col") values ("public"."some_fun"('{"1"}'))

事实证明 jooq 没有显式地类型转换 {1} 数组并且 postgres 无法推断数组类型。

有趣的是,以下代码生成相同的查询并且确实有效:

Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
query.execute();

我想这个问题与 jdbc 如何处理批量查询有关,除非 jooq 将不同的查询记录到它真正执行的内容。我使用以下代码找到了该问题的 hackish 解决方法:

Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values(
        (Field) someFun(
            DSL.field(DSL.array(new Integer[]{1}).toString() + "::int[]")
        )
    );
ctx.batch(query).execute();

我还尝试通过将转换模式设置为 ALWAYS 让 jooq 始终明确地键入转换值,但它似乎不起作用:

ctx.renderContext().castMode(RenderContext.CastMode.ALWAYS);
Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
ctx.batch(query).execute();

我真的需要以丑陋的手动方式进行类型转换,还是有更好的方法来处理这个问题?


更新

可以通过像这样生成类型转换字符串来减少转换的麻烦:

String.format("::%s[]", DefaultDataType.getDataType(SQLDialect.POSTGRES, Integer[].class).getCastTypeName())

不过,这只是一种解决方法。

截至jOOQ 3.8,还不支持PostgreSQL的anyanyarray等多态数据类型。有一个待处理的功能请求: https://github.com/jOOQ/jOOQ/issues/5479

您的变通办法可能和现在一样好。