【问题标题】:How to wrap existing functions (including aggregates) into a new one in Postgres?如何将现有函数(包括聚合)包装到 Postgres 中的新函数中?
【发布时间】:2014-06-04 19:51:03
【问题描述】:

我正在使用 Postgres 9.2 生成一些 JSON 数据。对于每个嵌套表,我都在做这组嵌套函数:

SELECT array_to_json(
  coalesce(
    array_agg(
      row_to_json(foo)),
    ARRAY[]::json[])
)
FROM foo

效果是创建一个json数组,每一行都是该行的json集合。如果表为空,则合并确保我得到一个空数组而不是 nil。在大多数情况下, foo 实际上是一个子查询,但我认为这与问题无关。

我想创建一个函数table_to_json_array(expression),这样就和上面的效果一样:

SELECT table_to_json_array(foo) FROM foo

我需要使用这个批次,所以我打算创建一个 Postgres 函数来组合这些调用来清理我的查询。查看文档似乎我需要创建一个聚合而不是一个函数来获取表参数,但那些看起来我需要自己重新实现 array_agg

我是否遗漏了什么(可能只是函数需要采用的类型)?有什么建议吗?

【问题讨论】:

    标签: json function postgresql aggregate plpgsql


    【解决方案1】:

    在大多数情况下 foo 实际上是一个子查询,但我不认为那是 与问题相关。

    不幸的是,它是。您可以使用 regclass 参数创建函数:

    create or replace function table_to_json(source regclass)
    returns json language plpgsql
    as $$
    declare
        t json;
    begin
        execute format ('
            SELECT
                array_to_json(
                    coalesce(array_agg(row_to_json(%s)),
                    ARRAY[]::json[]))
            FROM %s', source, source)
            into t;
        return t;
    end $$;
    
    select table_to_json('my_table');
    select table_to_json('my_schema.my_view');
    

    但在上下文中:

    select table_to_json_rec(arg)
    from (select * from my_table) arg
    

    参数 arg 的类型是 record。 PL/pgSQL 函数不能接受类型记录。获得这个的唯一方法是 C 函数,我猜这不是一个选项。聚合也是如此(您必须具有定义聚合的函数)。

    【讨论】:

    • regclass 值的文本表示会在需要时自动引用,因此它必须是 format('.. %s ..', source)%I 将是错误的,并且对于必须引用的标识符会失败。 Details here.
    • 谢谢,来源是第一版中的文字。
    • 从你的回答来看,你知道细节。我将评论留给公众,因为这是一个常见的错误。
    【解决方案2】:

    Postgres 9.3 添加了一个 json_agg 函数,它简化了我需要的特定查询,尽管这不是聚合函数问题的一般解决方案。它仍然需要一个 coalesce 函数来确保正确返回空集。

    SELECT coalesce( json_agg(foo), json'[]')
    FROM foo
    

    即使 foo 是子查询,它也可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-05
      • 2014-11-09
      相关资源
      最近更新 更多