Ich hatte ein Problem beim Einfügen des Werts 32767 in eine smallint
Spalte in Postgres, die den Fehler smallint außerhalb des Bereichs ergeben würde. Das war seltsam, weil ich tun konnte:PostgreSQL - Smallint überfüllt, wenn Index für mehrere Spalten erstellt wird. Ist das ein Fehler?
SELECT 32767::int2;
Was würde gut funktionieren. Nach ein wenig Haarziehen habe ich das schließlich auf einen Index der fraglichen Spalte zurückverfolgt. Erstens ist hier das Schema (Na ja, nicht wirklich, aber ich habe diese bis zu einem repro Fall vereinfacht):
CREATE TABLE Test
(
id uuid NOT NULL,
cooktime smallint,
preptime smallint,
CONSTRAINT test_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ich nun folgende Index erstellen:
CREATE INDEX idx_test_totaltime
ON Test
USING btree
((cooktime + preptime));
Als nächstes versuche ich zu erstellen die folgende Zeile:
INSERT INTO Test (CookTime, PrepTime, Id)
VALUES (
(32767)::int2,
(10)::int2,
(E'fd47dc1e-c3c6-42c1-b058-689e926a72a4')::uuid
);
ich den Fehler:
ERROR: smallint out of range SQL state: 22003
Es scheint, dass idx_test_totaltime
einen maximalen Wert von int2
erwartet, obwohl der Index auf die Summe von zwei Smallints angewendet wird.
Ist das ein Postgres-Bug, oder fehlt mir etwas Einfaches? Gibt es eine Möglichkeit, um diese Einschränkung zu umgehen, oder müsste ich diese Spalten int4
machen und eine CHECK-Einschränkung verwenden, um jeden Wert auf 32767 zu begrenzen? Ich benutze Postgres 9.0.0 (Ja, ich muss upgraden!), Aber ich habe eine SQL Fiddle erstellt, die diesen Fehler am 9.1.4 zeigt.
Das funktioniert. Allerdings habe ich bemerkt, wenn Sie 'SELECT * FROM Test WHERE CookTime + PrepTime> 100 'dann wird es nicht den Index verwenden. Sie müssen stattdessen 'WHERE CookTime :: Int4 + PrepTime :: Int4> 100 angeben. Jetzt muss ich meinen Suchcode aktualisieren :) –
@MikeChristensen: Das ist ein guter Platz auf dem Index nicht gewöhnungsbedürftig. Ich würde empfehlen, einfach das gesamte Geschäft "int2" zu vergessen und "int" für die Spalte mit entsprechenden CHECK-Einschränkungen zu verwenden. –
Übergeben Sie das Ergebnis der Berechnung an ein INT2, nicht an die Spalten im Index. –