3

我想有一个等价的:

create table t (
    fromts timestamptz, 
    tots timestamptz,
    exclude using gist ((fromts, tots) with overlaps)
);
ERROR:  syntax error at or near ","
LINE 4:         exclude using gist ((fromts, tots) with overlaps)

我猜除了语法错误之外,还有不可交换运算符的问题。

使它工作的最简单方法是什么?

4

2 回答 2

4

起初这似乎是做作的,但它是开箱即用的(不是双关语):

正如@Quassnoi 帮助我发现的那样,这仅适用于timestamp,不适用于timestamptz

CREATE TABLE t (
    fromts timestamp, 
    tots   timestamp,
    exclude using GIST (box(point(EXTRACT(EPOCH FROM fromts), 0)
                          , point(EXTRACT(EPOCH FROM tots),   0)) WITH &&)
);

我的测试是timestamp- 在你澄清类型之前。EXTRACTIMMUTABLEtimestamp但不是timestamptz。@Quassnoi 在下面的评论中发布了一个关于为什么会这样的假设。

因此,对于timestamp with time zone,您必须IMMUTABLE使用 @Quassnoi 在他的回答中演示的辅助函数进行转换。

在 Postgres 9.2 或更高版本中

...对于这种特殊情况,您可以使用新引入的范围类型。该手册提供了带有排除约束的完整代码示例。tstzrange

于 2012-05-25T19:05:58.987 回答
3

PostgreSQL需要一个命名类型和一个运算符类才能使排除约束起作用。在9.1RANGE尚未实施。

您可以定义自己的,但这需要超级权限(即不适用于托管数据库等)

您可以尝试将时间戳转换为框并使用相交运算符 ( &&) 定义约束:

CREATE FUNCTION ts_to_box(TIMESTAMPTZ, TIMESTAMPTZ)
RETURNS BOX
AS
$$
    SELECT  BOX(POINT(DATE_PART('epoch', $1), -1), POINT(DATE_PART('epoch', $2), 1))
$$
LANGUAGE 'sql'
IMMUTABLE;

CREATE TABLE t (
    fromts timestamptz, 
    tots timestamptz,
    EXCLUDE USING GIST (ts_to_box(fromts, tots) WITH &&)
);
于 2012-05-25T19:03:22.277 回答