Best hold selection: fix a checkin-busting bug affecting Holds-go-home
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Tue, 19 Mar 2013 20:13:35 +0000 (16:13 -0400)
committerMike Rylander <mrylander@gmail.com>
Tue, 2 Apr 2013 01:27:40 +0000 (21:27 -0400)
Several subselects within SQL auxiliary queries can possibly return
multiple rows in situations where outer code requires that they return
only one or zero rows.

When you're using a best-hold order that includes htime or shtime, (such
as those with Holds-go-home) and if there are mutiple circs or transits
related to the copy in hand with certain characteristics, you can
trigger this bug.  The end user at the staff client gets one of those
nasty "Network error" dialogs, and the error in the SQL logs is:

> ERROR:  more than one row returned by a subquery used as an expression

Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm

index 9e09d19..baa7098 100644 (file)
@@ -394,7 +394,7 @@ sub build_hold_sort_clause {
 , copy_has_not_been_home AS (
     SELECT (
         -- part 1
-        SELECT circ.id FROM action.circulation circ
+        SELECT MIN(circ.id) FROM action.circulation circ
         JOIN go_home_interval ON (true)
         WHERE
             circ.target_copy = %d AND
@@ -433,7 +433,7 @@ sub build_hold_sort_clause {
     SELECT
         copy_has_not_been_home.response AND (
             -- part 1
-            SELECT atc.id FROM action.transit_copy atc
+            SELECT MIN(atc.id) FROM action.transit_copy atc
             JOIN go_home_interval ON (true)
             WHERE
                 atc.target_copy = %d AND
@@ -441,7 +441,7 @@ sub build_hold_sort_clause {
                 atc.dest_recv_time >= NOW() - go_home_interval.value
         ) IS NULL AND (
             -- part 2
-            SELECT circ.id FROM action.circulation circ
+            SELECT MIN(circ.id) FROM action.circulation circ
             JOIN go_home_interval ON (true)
             WHERE
                 circ.target_copy = %d AND