Postgresql 具有重叠时间戳范围的排除约束

Postgresql 具有重叠时间戳范围的排除约束,postgresql,postgresql-9.1,Postgresql,Postgresql 9.1,我想要一个类似的: 创建表t( 弗洛姆茨, 托茨, 使用gist((fromts,tots)排除重叠) ); 错误:在“,”处或附近出现语法错误 第4行:使用gist((fromts,tots)排除重叠) 我想除了语法错误之外,还有非交换算子的问题 最简单的方法是什么?PostgreSQL需要一个命名类型和一个运算符类,排除约束才能工作。在9.1中,范围尚未实现 您可以定义自己的,但这需要一个超级权限(即不适用于托管数据库等) 您可以尝试将时间戳强制转换为框,并使用相交运算符(&&)定义约束:

我想要一个类似的:

创建表t(
弗洛姆茨,
托茨,
使用gist((fromts,tots)排除重叠)
);
错误:在“,”处或附近出现语法错误
第4行:使用gist((fromts,tots)排除重叠)
我想除了语法错误之外,还有非交换算子的问题


最简单的方法是什么?

PostgreSQL
需要一个命名类型和一个运算符类,排除约束才能工作。在
9.1
中,
范围
尚未实现

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

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


起初,这似乎是人为的,但它是开箱即用的(没有双关语):

正如@Quassnoi帮助我发现的,这只适用于
时间戳
,而不适用于
时间戳

CREATE TABLE t (
    fromts timestamp, 
    tots   timestamp,
    exclude using GIST (box(point(EXTRACT(EPOCH FROM fromts), 0)
                          , point(EXTRACT(EPOCH FROM tots),   0)) WITH &&)
);
我的测试是使用
时间戳
——在您澄清类型之前<代码>提取对于时间戳是不可变的,但对于时间戳则不可变@卡西尼在下面的评论中提出了一个假设

因此,对于带有时区的
时间戳
,您必须使用@Quassnoi在其答案中演示的辅助函数,使转换
不可变

在9.2或更高版本中 。。。对于这种特殊情况,您可以使用新引入的,
tstzrange


timestampz
?你是说
timestamtz
?@ErwinBrandstetter是的。已编辑。
错误:索引表达式中的函数必须标记为不可变
@Quassnoi:它是。在发布之前,我用Postgres9.1测试了这个解决方案。我也有一个与它一起工作的实现。Simplifeid一点。@ErwinBrandstetter:它在我的安装和sqlfiddle上都不起作用。@ErwinBrandstetter:
TZ
函数取决于会话区域参数,这就是我相信它的原因。我想也许<代码>摘录在<代码> EXCH < /C>中有一些神奇之处,这将使它不可变,但似乎没有。考虑一下这个。如果更改为
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 &&)
);