postgresql 10 日期范围约束
postgresql 10 date range contraint
我想在 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
我怎样才能让这个约束生效?
start_time
和 end_time
列的类型为 TIMESTAMP
,而 tstzrange
需要 TIMESTAMPTZ
(带时区)。显然这种转换是自动发生的,但它不被认为是 "IMMUTABLE".
文档位于
https://www.postgresql.org/docs/10/static/xfunc-volatility.html 说
A common
error is to label a function IMMUTABLE when its results depend on a configuration parameter. For example, a function that manipulates timestamps might well have results that depend on the TimeZone setting. For safety, such functions should be labeled STABLE instead.
您可能应该改用 tsrange
,或者显式转换为带时区的时间戳(以不依赖于服务器设置的方式):
tstzrange(start_time at time zone 'utc', COALESCE(end_time at time zone 'utc', 'infinity')) WITH &&
不过,我不知道版本之间发生了什么变化(我收到了与 9.6.6 相同的错误消息)。
我想在 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
我怎样才能让这个约束生效?
start_time
和 end_time
列的类型为 TIMESTAMP
,而 tstzrange
需要 TIMESTAMPTZ
(带时区)。显然这种转换是自动发生的,但它不被认为是 "IMMUTABLE".
文档位于 https://www.postgresql.org/docs/10/static/xfunc-volatility.html 说
A common error is to label a function IMMUTABLE when its results depend on a configuration parameter. For example, a function that manipulates timestamps might well have results that depend on the TimeZone setting. For safety, such functions should be labeled STABLE instead.
您可能应该改用 tsrange
,或者显式转换为带时区的时间戳(以不依赖于服务器设置的方式):
tstzrange(start_time at time zone 'utc', COALESCE(end_time at time zone 'utc', 'infinity')) WITH &&
不过,我不知道版本之间发生了什么变化(我收到了与 9.6.6 相同的错误消息)。