Einschränkung definiert DEFERRABLE INITIALLY IMMEDIATE ist immer noch ZURÜCKGESTELLT?

In Verbindung mit die Antwort stieß ich auf ein Phänomen, das ich nicht erklären kann.

Version:
PostgreSQL 9.1.2 auf x86_64-unknown-linux-gnu, compiled by gcc-4.4.real (Debian 4.4.5-8) 4.4.5, 64-bit -

Betrachten Sie die folgende demo. Testbed:

CREATE TEMP TABLE t (
  id  integer
 ,txt text
 ,CONSTRAINT t_pkey PRIMARY KEY (id) DEFERRABLE INITIALLY IMMEDIATE
);

INSERT INTO t VALUES
 (1, 'one')
,(2, 'two');

1) UPDATE-Anweisung geändert wird, die mehrere Zeilen:

UPDATE t
SET    id = t_old.id
FROM   t t_old
WHERE (t.id, t_old.id) IN ((1,2), (2,1));

Scheint es einen bug in der aktuellen Implementierung? Die oben genannten UPDATE funktioniert, obwohl es sollte nicht. Die Einschränkung definiert INITIALLY IMMEDIATE und ich habe nicht mit SET CONSTRAINTS.

Bin ich etwas fehlt, oder ist dies ein (eher harmloser) bug?


2) Daten ändern CTE

Folglich ein Daten ändern CTE funktioniert, auch wenn es fehlschlägt, mit einem NOT DEFERRED pk:

WITH x AS (
    UPDATE t SET id = 1 WHERE id = 2
    )
UPDATE t SET id = 2 WHERE id = 1;

Ich zitiere die Handbuch auf Allgemeine Tabellenausdrücke:

Den sub-Anweisungen in MIT ausgeführt werden, die gleichzeitig miteinander
und mit der Haupt-Abfrage. Deshalb, wenn Sie Daten ändern
Aussagen, die Reihenfolge, in der die angegebenen updates eigentlich
geschehen ist unberechenbar. Alle Anweisungen ausgeführt, die mit der gleichen
Schnappschuss (siehe Kapitel 13), so dass Sie nicht "sehen" gegenseitig Ihre Wirkung
auf dem Ziel-Tabellen.


3) Mehrere UPDATE-Anweisungen in einer Transaktion

Ohne SET CONSTRAINTS dieses schlägt mit einem EINMALIGEN Verstoß - wie erwartet:

BEGIN;
-- SET CONSTRAINTS t_pkey DEFERRED;
UPDATE t SET id = 2 WHERE txt = 'one';
UPDATE t SET id = 1 WHERE txt = 'two';
COMMIT;
Gleiche mit 9.1.3 unter Windows. Sie sollten berichten, dass ein Fehler der PostgreSQL-team.
Die Art, wie ich Lesen Sie die Dokumentation, ich denke, das update fehlschlagen sollte. Würde ich es nennen, ein Fehler.
Können Sie der Dokumentation, die zeigt, warum "Die da oben UPDATE funktioniert, obwohl es nicht sein sollte." - warum das update nicht funktionieren sollte?
Betrachten Sie die Antworten unten. Auch Folgen den link in die Kommentare und prüfen, Peter Eisentraut ist die Antwort da.
was sagt "Der SQL-standard sagt, dass die Eindeutigkeit erzwungen werden soll, die nur am Ende der Anweisung ... Zu erhalten standard-konform Verhalten, erklären die constraint als DEFERRABLE aber nicht die latenten (d.h., ZUNÄCHST IMMEDIATE)" - das ist genau das, was Sie tun, damit das update erfolgreich sein sollte, weil am Ende der Anweisung werden alle IDs sind einzigartig.

InformationsquelleAutor Erwin Brandstetter | 2012-04-05

Schreibe einen Kommentar