]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0740.schema.checkless_browse_fix.sql
LP#1947173: Clean up bad cataloging pot hole
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0740.schema.checkless_browse_fix.sql
1 BEGIN;
2
3 SELECT evergreen.upgrade_deps_block_check('0740', :eg_version);
4
5 CREATE OR REPLACE
6     FUNCTION metabib.suggest_browse_entries(
7         raw_query_text  TEXT,   -- actually typed by humans at the UI level
8         search_class    TEXT,   -- 'alias' or 'class' or 'class|field..', etc
9         headline_opts   TEXT,   -- markup options for ts_headline()
10         visibility_org  INTEGER,-- null if you don't want opac visibility test
11         query_limit     INTEGER,-- use in LIMIT clause of interal query
12         normalization   INTEGER -- argument to TS_RANK_CD()
13     ) RETURNS TABLE (
14         value                   TEXT,   -- plain
15         field                   INTEGER,
16         buoyant_and_class_match BOOL,
17         field_match             BOOL,
18         field_weight            INTEGER,
19         rank                    REAL,
20         buoyant                 BOOL,
21         match                   TEXT    -- marked up
22     ) AS $func$
23 DECLARE
24     prepared_query_texts    TEXT[];
25     query                   TSQUERY;
26     plain_query             TSQUERY;
27     opac_visibility_join    TEXT;
28     search_class_join       TEXT;
29     r_fields                RECORD;
30 BEGIN
31     prepared_query_texts := metabib.autosuggest_prepare_tsquery(raw_query_text);
32
33     query := TO_TSQUERY('keyword', prepared_query_texts[1]);
34     plain_query := TO_TSQUERY('keyword', prepared_query_texts[2]);
35
36     visibility_org := NULLIF(visibility_org,-1);
37     IF visibility_org IS NOT NULL THEN
38         opac_visibility_join := '
39     JOIN asset.opac_visible_copies aovc ON (
40         aovc.record = x.source AND
41         aovc.circ_lib IN (SELECT id FROM actor.org_unit_descendants($4))
42     )';
43     ELSE
44         opac_visibility_join := '';
45     END IF;
46
47     -- The following determines whether we only provide suggestsons matching
48     -- the user's selected search_class, or whether we show other suggestions
49     -- too. The reason for MIN() is that for search_classes like
50     -- 'title|proper|uniform' you would otherwise get multiple rows.  The
51     -- implication is that if title as a class doesn't have restrict,
52     -- nor does the proper field, but the uniform field does, you're going
53     -- to get 'false' for your overall evaluation of 'should we restrict?'
54     -- To invert that, change from MIN() to MAX().
55
56     SELECT
57         INTO r_fields
58             MIN(cmc.restrict::INT) AS restrict_class,
59             MIN(cmf.restrict::INT) AS restrict_field
60         FROM metabib.search_class_to_registered_components(search_class)
61             AS _registered (field_class TEXT, field INT)
62         JOIN
63             config.metabib_class cmc ON (cmc.name = _registered.field_class)
64         LEFT JOIN
65             config.metabib_field cmf ON (cmf.id = _registered.field);
66
67     -- evaluate 'should we restrict?'
68     IF r_fields.restrict_field::BOOL OR r_fields.restrict_class::BOOL THEN
69         search_class_join := '
70     JOIN
71         metabib.search_class_to_registered_components($2)
72         AS _registered (field_class TEXT, field INT) ON (
73             (_registered.field IS NULL AND
74                 _registered.field_class = cmf.field_class) OR
75             (_registered.field = cmf.id)
76         )
77     ';
78     ELSE
79         search_class_join := '
80     LEFT JOIN
81         metabib.search_class_to_registered_components($2)
82         AS _registered (field_class TEXT, field INT) ON (
83             _registered.field_class = cmc.name
84         )
85     ';
86     END IF;
87
88     RETURN QUERY EXECUTE '
89 SELECT  DISTINCT
90         x.value,
91         x.id,
92         x.push,
93         x.restrict,
94         x.weight,
95         x.ts_rank_cd,
96         x.buoyant,
97         TS_HEADLINE(value, $7, $3)
98   FROM  (SELECT DISTINCT
99                 mbe.value,
100                 cmf.id,
101                 cmc.buoyant AND _registered.field_class IS NOT NULL AS push,
102                 _registered.field = cmf.id AS restrict,
103                 cmf.weight,
104                 TS_RANK_CD(mbe.index_vector, $1, $6),
105                 cmc.buoyant,
106                 mbedm.source
107           FROM  metabib.browse_entry_def_map mbedm
108                 JOIN (SELECT * FROM metabib.browse_entry WHERE index_vector @@ $1 LIMIT 10000) mbe ON (mbe.id = mbedm.entry)
109                 JOIN config.metabib_field cmf ON (cmf.id = mbedm.def)
110                 JOIN config.metabib_class cmc ON (cmf.field_class = cmc.name)
111                 '  || search_class_join || '
112           ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
113           LIMIT 1000) AS x
114         ' || opac_visibility_join || '
115   ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
116   LIMIT $5
117 '   -- sic, repeat the order by clause in the outer select too
118     USING
119         query, search_class, headline_opts,
120         visibility_org, query_limit, normalization, plain_query
121         ;
122
123     -- sort order:
124     --  buoyant AND chosen class = match class
125     --  chosen field = match field
126     --  field weight
127     --  rank
128     --  buoyancy
129     --  value itself
130
131 END;
132 $func$ LANGUAGE PLPGSQL;
133
134 COMMIT;