我在将问题32767插入Postgres的smallint
列时遇到问题,这会导致错误 smallint超出范围。这很奇怪,因为我能做到:
SELECT 32767::int2;
哪种方法可以正常使用。在拉了一下头发后,我终于将其追踪到了相关列的索引。首先,这是架构(嗯,不是真的,但我把它简化为一个repro案例):
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
,即使索引应用于两个小点的总和。
这是一个Postgres错误,还是我错过了一些简单的东西?有没有办法解决这个限制,或者我需要创建这些列int4
并使用CHECK约束将每个值限制为32767?我正在使用Postgres 9.0.0(是的,我需要升级!)但是我创建了一个SQL Fiddle,它在9.1.4上演示了这个错误。
答案 0 :(得分:4)
您的问题是int2 + int2
是另一个int2
,因此索引中的表达式(cooktime + preptime)
会溢出(32767, 10)
。您可以通过在索引表达式中进行一些转换来解决此问题:
CREATE INDEX idx_test_totaltime
ON Test
USING btree
((cooktime::int4 + preptime::int4));
你只需要其中一个演员,但两者都没有受伤。
答案 1 :(得分:3)
为什么不在一段时间内使用INTERVAL?这是解决问题的完美解决方案。