Wystąpił problem z wstawieniem wartości 32767 do kolumny smallint
w Postgresie, co spowodowałoby błąd o numerze smallint poza zakresem. To było dziwne, ponieważ mogłem zrobić:PostgreSQL - Smallint przepełnia się podczas tworzenia indeksu na wielu kolumnach. Czy to błąd?
SELECT 32767::int2;
Który działałby dobrze. Po przeciągnięciu trochę włosów, w końcu śledziłem to do indeksu na kolumnie, o której mowa. Po pierwsze, oto schemat (dobrze, nie bardzo, ale mam uproszczona to w dół do repro przypadku):
CREATE TABLE Test
(
id uuid NOT NULL,
cooktime smallint,
preptime smallint,
CONSTRAINT test_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
teraz utworzyć następujący wskaźnik:
CREATE INDEX idx_test_totaltime
ON Test
USING btree
((cooktime + preptime));
Następnie staram się tworzyć się następujący wiersz:
INSERT INTO Test (CookTime, PrepTime, Id)
VALUES (
(32767)::int2,
(10)::int2,
(E'fd47dc1e-c3c6-42c1-b058-689e926a72a4')::uuid
);
pojawia się błąd:
ERROR: smallint out of range SQL state: 22003
Wygląda na to, że idx_test_totaltime
spodziewa się maksymalnej wartości int2
, mimo że indeks jest stosowany do sumy dwóch małych znaków.
Czy jest to błąd PostgreSzu, czy też brakuje mi czegoś prostego? Czy istnieje sposób obejścia tego ograniczenia , czy musiałbym utworzyć te kolumny int4
i użyć ograniczenia CHECK, aby ograniczyć każdą wartość do 32767? Używam PostgreSQL 9.0.0 (tak, potrzebuję aktualizacji!), Ale utworzyłem kod SQL Fiddle, który demonstruje ten błąd w wersji 9.1.4.
To działa. Zauważyłem jednak, że jeśli wybierzesz 'SELECT * FROM Test WHERE CookTime + PrepTime> 100', to nie użyje on indeksu. Musisz zamiast tego podać "WHERE CookTime :: Int4 + PrepTime :: Int4> 100". Teraz muszę zaktualizować mój kod wyszukiwania :) –
@MikeChristensen: To nie jest dobre miejsce na indeksie. Polecam po prostu zapomnieć o wszystkim biznesie "int2" i użyć 'int' dla kolumny z odpowiednimi ograniczeniami CHECK. –
Prześlij wynik obliczeń do INT2, a nie do kolumn w indeksie. –