我有一张博士后的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;
1条答案
按热度按时间rnmwe5a21#
事实证明,在调用聚合函数时可以指定顺序,如下所示:
这将在输入传递到累加器之前对输入进行排序。