如何确保postgres范围类型表完全覆盖一个范围?

k10s72fa  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(269)

我有一张博士后的table numrange 类型,我称之为 buckets . 每个桶上的范围可以是任意大小,但总的来说它们需要覆盖一定的范围(在我的例子中是[0到2160])。
目前,我有一个自定义聚合函数 + ,对于 numrange + numrange ( SUM 未对范围实现)。在聚合之前需要对行进行排序,以便在累积数据块时保持连续。博士后 CREATE AGGREGATE 语句允许 SORTOP 我提供 < 运算符,它是为范围实现的。
我的问题是,当我像下面的代码示例那样实现这个聚合器时,会出现以下错误: ERROR 42883 (undefined_function) operator does not exist: numrange < numrange 如果我移除 SORTOP ,此聚合器在普通情况下(两个并排的存储桶)确实可以工作,但是如果提供更多的存储桶,则无法预料: ERROR 22000 (data_exception) result of range union would not be contiguous 我知道,即使sort操作符可以工作,如果我的数据实际上不是连续的,我也可能得到这个错误,但是在这种情况下,我可以得到这个错误。
下面是我正在处理的第一个错误:

CREATE FUNCTION numrange_accum_sfunc(numrange, numrange)
RETURNS numrange AS
$$
        SELECT $1 + $2;
$$ LANGUAGE 'sql' STRICT;

CREATE AGGREGATE numrange_accum(numrange)
(
  STYPE = numrange,
  SFUNC = numrange_accum_sfunc,
  SORTOP = <
);

CREATE OR REPLACE FUNCTION enforce_bucket_coverage() RETURNS trigger AS $$
DECLARE
    bucket_range numrange := numrange(0,0);
BEGIN
    LOCK TABLE buckets IN EXCLUSIVE MODE;

    SELECT numrange_accum(range)
    FROM buckets
    INTO bucket_range;

    IF bucket_range <> numrange(0,1461501637330902918203684832716283019655932542977) THEN
        RAISE EXCEPTION 'Bucket ranges must completely cover the range from 0 to 2^160 (inclusive). Coverage after inserting was %', bucket_range;
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;
rnmwe5a2

rnmwe5a21#

事实证明,在调用聚合函数时可以指定顺序,如下所示:

SELECT numrange_accum(range order by lower(range))
FROM buckets
INTO bucket_range;

这将在输入传递到累加器之前对输入进行排序。

相关问题