代码之家  ›  专栏  ›  技术社区  ›  Jan Wytze

postgresql 10日期范围限制

  •  0
  • Jan Wytze  · 技术社区  · 7 年前

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

    如何使此约束生效?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Pasi    7 年前

    这个 start_time end_time 列具有类型 TIMESTAMP ,而 tstzrange 期望 TIMESTAMPTZ (带时区)。显然,这种转换是自动发生的,但它并不被认为是“不变的”。

    文档位于 https://www.postgresql.org/docs/10/static/xfunc-volatility.html 表示

    普通的 错误是当函数的结果依赖于配置参数时,将其标记为不可变。例如,一个处理时间戳的函数很可能会产生取决于时区设置的结果。为安全起见,此类功能应标记为稳定。

    您可能应该使用 tsrange 相反,或者显式转换为带时区的时间戳(以不依赖于服务器设置的方式):

    tstzrange(start_time at time zone 'utc', COALESCE(end_time at time zone 'utc', 'infinity')) WITH &&
    

    不过,我不知道版本之间发生了什么变化(我在9.6.6中得到了相同的错误消息)。