我想有一个相同的:
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)
我想除了语法错误之外,还存在非交换运算符的问题。
使它运作的最简单方法是什么?
答案 0 :(得分: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
。 EXTRACT
IMMUTABLE
为timestamp
,timestamptz
为timestamp with time zone
。 @Quassnoi在下面的评论中发布了一个假设,为什么会这样。
因此,对于IMMUTABLE
,您必须使用@Quassnoi等辅助函数在其答案中进行转换tstzrange
。
...您可以针对此特定情况使用新引入的range types,{{1}} The manual provides a full code example with an exclusion constraint.
答案 1 :(得分:3)
PostgreSQL
需要命名类型和运算符类才能使排除约束起作用。在9.1
中,RANGE
尚未实施。
您可以定义自己的权限,但这需要超级权限(即,不会对托管数据库等有效)。
您可以尝试将时间戳转换为框并使用intersects运算符(&&
)定义约束:
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 &&)
);