我想在postgresql 10中制作一个日期范围约束。在postgresql 9.6中,这有效:
CREATE TABLE project_lines (
id SERIAL PRIMARY KEY,
project_id INTEGER NOT NULL REFERENCES projects(id),
description VARCHAR(200) NOT NULL,
start_time TIMESTAMP NOT NULL,
end_time TIMESTAMP CHECK(end_time > start_time),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
CONSTRAINT overlapping_times EXCLUDE USING GIST(
project_id WITH =,
tstzrange(start_time, COALESCE(end_time, 'infinity')) WITH &&
)
);
但是在postgresql 10中我收到了这个错误:
functions in index expression must be marked IMMUTABLE
如何使此约束有效?
答案 0 :(得分:0)
start_time
和end_time
列的类型为TIMESTAMP
,而tstzrange
期望TIMESTAMPTZ
(带时区)。显然,这种转换会自动发生,但不会被视为“无法修改”。
文件在 https://www.postgresql.org/docs/10/static/xfunc-volatility.html说
一个常见的 错误是在结果取决于配置参数时标记函数IMMUTABLE。例如,操作时间戳的函数可能具有取决于TimeZone设置的结果。为安全起见,此类功能应标记为STABLE。
您应该使用tsrange
代替,或者显式转换为带时区的时间戳(以不依赖于服务器设置的方式):
tstzrange(start_time at time zone 'utc', COALESCE(end_time at time zone 'utc', 'infinity')) WITH &&
我不知道版本之间有什么变化(并且我得到了与9.6.6相同的错误消息)。