LP#1549505: Query literal interpolation casts incorrectly
authorMike Rylander <mrylander@gmail.com>
Thu, 26 May 2016 21:51:49 +0000 (17:51 -0400)
committerKathy Lussier <klussier@masslnc.org>
Fri, 29 Jul 2016 20:56:11 +0000 (16:56 -0400)
We need to be sure that all query values are of the same type in the same
columns because PLPGSQL functions are compiled and cached.  In this case,
the core query of the in-db search cannot have its shape change.  This
commit assures that browse and search uses of the SP provide core queries
that match on their SELECT lists.  Of particular importance is the type
of the "rel" output column, which was variously float8 or numeric, depending
on whether the search contained any terms (a "search") or not (a browse
link).

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
Open-ILS/src/sql/Pg/030.schema.metabib.sql
Open-ILS/src/sql/Pg/upgrade/YYYY.function.qp_search.sql

index 9265a88..4be8e93 100644 (file)
@@ -944,10 +944,10 @@ sub toSQL {
             # have an overage badge score of zero.
 
             my $adjusted_scale = ( $max_mult - 1.0 ) / 5.0;
-            $rank = "1.0/(( $rel ) * (1.0 + (AVG(COALESCE(pop_with.total_score::NUMERIC,0.0)) * $adjusted_scale)))::NUMERIC";
+            $rank = "1.0/(( $rel ) * (1.0 + (AVG(COALESCE(pop_with.total_score::NUMERIC,0.0::NUMERIC)) * ${adjusted_scale}::NUMERIC)))::NUMERIC";
         }
     } elsif ($sort_filter =~ /^pop/) {
-        $rank = '1.0/(AVG(COALESCE(pop_with.total_score::NUMERIC,0.0)) + 5.0)::NUMERIC';
+        $rank = '1.0/(AVG(COALESCE(pop_with.total_score::NUMERIC,0.0::NUMERIC)) + 5.0::NUMERIC)::NUMERIC';
         my $pop_desc = $desc eq 'ASC' ? 'DESC' : 'ASC';
         $pop_extra_sort = "3 $pop_desc $nullpos,";
     } else {
@@ -980,11 +980,11 @@ sub toSQL {
 $with
 SELECT  $key AS id,
         $agg_records,
-        $rel AS rel,
+        ${rel}::NUMERIC AS rel,
         $rank AS rank, 
         FIRST(pubdate_t.value) AS tie_break,
         STRING_AGG(ARRAY_TO_STRING(pop_with.badges,','),',') AS badges,
-        AVG(COALESCE(pop_with.total_score::NUMERIC,0.0))::NUMERIC(2,1) AS popularity
+        AVG(COALESCE(pop_with.total_score::NUMERIC,0.0::NUMERIC))::NUMERIC(2,1) AS popularity
   FROM  metabib.metarecord_source_map m
         $$flat_plan{from}
         $mra_join
index 40f0dfb..0d3fb00 100644 (file)
@@ -2192,8 +2192,8 @@ BEGIN
                 superpage_of_records := all_brecords[slice_start:slice_end];
                 qpfts_query :=
                     'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
-                    'NULL AS badges, NULL AS popularity, ' ||
-                    '1::INT AS rel FROM (SELECT UNNEST(' ||
+                    'NULL AS badges, NULL::NUMERIC AS popularity, ' ||
+                    '1::NUMERIC AS rel FROM (SELECT UNNEST(' ||
                     quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
 
                 -- We use search.query_parser_fts() for visibility testing.
@@ -2231,8 +2231,8 @@ BEGIN
                 superpage_of_records := all_arecords[slice_start:slice_end];
                 qpfts_query :=
                     'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
-                    'NULL AS badges, NULL AS popularity, ' ||
-                    '1::INT AS rel FROM (SELECT UNNEST(' ||
+                    'NULL AS badges, NULL::NUMERIC AS popularity, ' ||
+                    '1::NUMERIC AS rel FROM (SELECT UNNEST(' ||
                     quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
 
                 -- We use search.query_parser_fts() for visibility testing.
index a4ea53d..3cb1da6 100644 (file)
@@ -484,8 +484,8 @@ BEGIN
                 superpage_of_records := all_brecords[slice_start:slice_end];
                 qpfts_query :=
                     'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
-                    'NULL AS badges, NULL AS popularity, ' ||
-                    '1::INT AS rel FROM (SELECT UNNEST(' ||
+                    'NULL AS badges, NULL::NUMERIC AS popularity, ' ||
+                    '1::NUMERIC AS rel FROM (SELECT UNNEST(' ||
                     quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
 
                 -- We use search.query_parser_fts() for visibility testing.
@@ -523,8 +523,8 @@ BEGIN
                 superpage_of_records := all_arecords[slice_start:slice_end];
                 qpfts_query :=
                     'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
-                    'NULL AS badges, NULL AS popularity, ' ||
-                    '1::INT AS rel FROM (SELECT UNNEST(' ||
+                    'NULL AS badges, NULL::NUMERIC AS popularity, ' ||
+                    '1::NUMERIC AS rel FROM (SELECT UNNEST(' ||
                     quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
 
                 -- We use search.query_parser_fts() for visibility testing.