LP#1657237: Properly constrain matview trigger function
authorMike Rylander <mrylander@gmail.com>
Tue, 17 Jan 2017 19:46:36 +0000 (14:46 -0500)
committerBill Erickson <berickxx@gmail.com>
Tue, 17 Jan 2017 20:12:18 +0000 (15:12 -0500)
The function maintaining the reporter.hold_request_record table
was performing an unconstrained update when a hold was moved.  This
fixes that.

To test:

[1] Apply the patch, the perform an asset merge that would
    change the target of a hold request.  Verify that
    reporter.hold_request_record is properly update.

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/sql/Pg/reporter-schema.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.function.hold-move-trigger-bug.sql [new file with mode: 0644]

index dce3603..985ca6f 100644 (file)
@@ -284,7 +284,7 @@ CREATE INDEX reporter_hold_request_record_bib_record_idx ON reporter.hold_reques
 
 ALTER TABLE reporter.hold_request_record ADD PRIMARY KEY USING INDEX reporter_hold_request_record_pkey_idx;
 
-CREATE FUNCTION reporter.hold_request_record_mapper () RETURNS TRIGGER AS $$
+CREATE OR REPLACE FUNCTION reporter.hold_request_record_mapper () RETURNS TRIGGER AS $$
 BEGIN
     IF TG_OP = 'INSERT' THEN
         INSERT INTO reporter.hold_request_record (id, target, hold_type, bib_record)
@@ -322,7 +322,8 @@ BEGIN
                         THEN (SELECT mr.master_record FROM metabib.metarecord mr WHERE mr.id = NEW.target)
                     WHEN NEW.hold_type = 'P'
                         THEN (SELECT bmp.record FROM biblio.monograph_part bmp WHERE bmp.id = NEW.target)
-                END;
+                END
+         WHERE  id = NEW.id;
     END IF;
     RETURN NEW;
 END;
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.hold-move-trigger-bug.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.hold-move-trigger-bug.sql
new file mode 100644 (file)
index 0000000..9192836
--- /dev/null
@@ -0,0 +1,49 @@
+BEGIN;
+
+CREATE OR REPLACE FUNCTION reporter.hold_request_record_mapper () RETURNS TRIGGER AS $$
+BEGIN
+    IF TG_OP = 'INSERT' THEN
+        INSERT INTO reporter.hold_request_record (id, target, hold_type, bib_record)
+        SELECT  NEW.id,
+                NEW.target,
+                NEW.hold_type,
+                CASE
+                    WHEN NEW.hold_type = 'T'
+                        THEN NEW.target
+                    WHEN NEW.hold_type = 'I'
+                        THEN (SELECT ssub.record_entry FROM serial.subscription ssub JOIN serial.issuance si ON (si.subscription = ssub.id) WHERE si.id = NEW.target)
+                    WHEN NEW.hold_type = 'V'
+                        THEN (SELECT cn.record FROM asset.call_number cn WHERE cn.id = NEW.target)
+                    WHEN NEW.hold_type IN ('C','R','F')
+                        THEN (SELECT cn.record FROM asset.call_number cn JOIN asset.copy cp ON (cn.id = cp.call_number) WHERE cp.id = NEW.target)
+                    WHEN NEW.hold_type = 'M'
+                        THEN (SELECT mr.master_record FROM metabib.metarecord mr WHERE mr.id = NEW.target)
+                    WHEN NEW.hold_type = 'P'
+                        THEN (SELECT bmp.record FROM biblio.monograph_part bmp WHERE bmp.id = NEW.target)
+                END AS bib_record;
+    ELSIF TG_OP = 'UPDATE' AND (OLD.target <> NEW.target OR OLD.hold_type <> NEW.hold_type) THEN
+        UPDATE  reporter.hold_request_record
+          SET   target = NEW.target,
+                hold_type = NEW.hold_type,
+                bib_record = CASE
+                    WHEN NEW.hold_type = 'T'
+                        THEN NEW.target
+                    WHEN NEW.hold_type = 'I'
+                        THEN (SELECT ssub.record_entry FROM serial.subscription ssub JOIN serial.issuance si ON (si.subscription = ssub.id) WHERE si.id = NEW.target)
+                    WHEN NEW.hold_type = 'V'
+                        THEN (SELECT cn.record FROM asset.call_number cn WHERE cn.id = NEW.target)
+                    WHEN NEW.hold_type IN ('C','R','F')
+                        THEN (SELECT cn.record FROM asset.call_number cn JOIN asset.copy cp ON (cn.id = cp.call_number) WHERE cp.id = NEW.target)
+                    WHEN NEW.hold_type = 'M'
+                        THEN (SELECT mr.master_record FROM metabib.metarecord mr WHERE mr.id = NEW.target)
+                    WHEN NEW.hold_type = 'P'
+                        THEN (SELECT bmp.record FROM biblio.monograph_part bmp WHERE bmp.id = NEW.target)
+                END
+         WHERE  id = NEW.id;
+    END IF;
+    RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+
+COMMIT;
+