Si è verificato un problema durante l'inserimento del valore 32767 in una colonna smallint
in Postgres, che avrebbe restituito l'errore smallint nell'intervallo. Questo era strano perché potevo fare:PostgreSQL: overflow minimo durante la creazione dell'indice su più colonne. è un insetto?
SELECT 32767::int2;
Quale funzionerebbe bene. Dopo aver tirato un po 'di capelli, ho finalmente rintracciato questo in un indice sulla colonna in questione. In primo luogo, ecco lo schema (Beh, non proprio, ma ho semplificato questo fino a un caso repro):
CREATE TABLE Test
(
id uuid NOT NULL,
cooktime smallint,
preptime smallint,
CONSTRAINT test_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ora creare il seguente indice:
CREATE INDEX idx_test_totaltime
ON Test
USING btree
((cooktime + preptime));
Avanti, cerco di creare la seguente riga:
INSERT INTO Test (CookTime, PrepTime, Id)
VALUES (
(32767)::int2,
(10)::int2,
(E'fd47dc1e-c3c6-42c1-b058-689e926a72a4')::uuid
);
ottengo l'errore:
ERROR: smallint out of range SQL state: 22003
Sembra che idx_test_totaltime
si aspetti un valore massimo di int2
, anche se l'indice viene applicato sulla somma di due piccoli valori.
Si tratta di un bug Postgres o mi manca qualcosa di semplice? C'è un modo per ovviare a questa limitazione oppure dovrei rendere queste colonne int4
e utilizzare un vincolo CHECK per limitare ogni valore a 32767? Sto usando Postgres 9.0.0 (Sì, ho bisogno di aggiornamento!), Ma ho creato un SQL Fiddle che dimostra questo errore su 9.1.4.
Che funziona. Tuttavia, ho notato che se esegui 'SELECT * FROM Test WHERE CookTime + PrepTime> 100', non userà l'indice. Devi invece specificare 'WHERE CookTime :: Int4 + PrepTime :: Int4> 100'. Ora devo aggiornare il mio codice di ricerca :) –
@MikeChristensen: Questo è un buon punto sull'indice che non si abitua. Consiglierei di dimenticare tutto il business di 'int2' e di usare' int' per la colonna con i vincoli CHECK appropriati. –
Lancia il risultato del calcolo a INT2, non le colonne nell'indice. –