5

我在将值 32767 插入smallintPostgres 的列中时遇到问题,这会产生错误smallint out of range。这很奇怪,因为我可以这样做:

SELECT 32767::int2;

这会很好。在拉了一点头发之后,我终于找到了相关列的索引。首先,这是架构(嗯,不是真的,但我已将其简化为重现案例):

CREATE TABLE Test
(
  id uuid NOT NULL,
  cooktime smallint,
  preptime smallint,
  CONSTRAINT test_pkey PRIMARY KEY (id )
)
WITH (
  OIDS=FALSE
);

我现在创建以下索引:

CREATE INDEX idx_test_totaltime
  ON Test
  USING btree
  ((cooktime + preptime) );

接下来,我尝试创建以下行:

INSERT INTO Test (CookTime, PrepTime, Id)
VALUES (
  (32767)::int2,
  (10)::int2,
  (E'fd47dc1e-c3c6-42c1-b058-689e926a72a4')::uuid
);

我得到错误:

错误:smallint 超出范围 SQL 状态:22003

似乎idx_test_totaltime期望最大值为int2,即使该索引应用于两个 smallint 的总和。

这是 Postgres 错误,还是我遗漏了一些简单的东西?有没有办法解决这个限制,或者我需要制作这些列int4并使用 CHECK 约束将每个值限制为 32767?我正在使用 Postgres 9.0.0(是的,我需要升级!)但是我创建了一个SQL Fiddle,它在 9.1.4 上演示了这个错误。

4

2 回答 2

5

您的问题是int2 + int2另一个问题,int2因此您的索引中的表达式(cooktime + preptime), 溢出了(32767, 10). 您可以通过在索引表达式中进行一些强制转换来解决这个问题:

CREATE INDEX idx_test_totaltime
  ON Test
  USING btree
  ((cooktime::int4 + preptime::int4));

你只需要其中一个演员,但同时使用两者都不会受到伤害。

于 2012-08-05T05:37:29.093 回答
3

为什么不使用INTERVAL作为时间间隔?它是您问题的完美解决方案。

于 2012-08-05T10:27:49.017 回答