0

我想在 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

我怎样才能使这个约束起作用?

4

1 回答 1

0

和列具有类型,而start_time期望(带时区)。显然这种转换是自动发生的,但它不被认为是“IMMUTABLE”。end_timeTIMESTAMPtstzrangeTIMESTAMPTZ

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 相同的错误消息)。

于 2018-03-19T21:35:14.557 回答