Bring back #deleted modifier post-revive-qp-fts
[working/Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / XXXX.schema.deleted-search-fts.sql
1 BEGIN;
2
3 --Check if we can apply the upgrade.
4 SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
5
6
7 CREATE TYPE search.search_result AS ( id BIGINT, rel NUMERIC, record INT, total INT, checked INT, visible INT, deleted INT, excluded INT );
8 CREATE TYPE search.search_args AS ( id INT, field_class TEXT, field_name TEXT, table_alias TEXT, term TEXT, term_type TEXT );
9
10 CREATE OR REPLACE FUNCTION search.query_parser_fts (
11
12     param_search_ou INT,
13     param_depth     INT,
14     param_query     TEXT,
15     param_statuses  INT[],
16     param_locations INT[],
17     param_offset    INT,
18     param_check     INT,
19     param_limit     INT,
20     metarecord      BOOL,
21     staff           BOOL,
22     deleted_search  BOOL,
23     param_pref_ou   INT DEFAULT NULL
24 ) RETURNS SETOF search.search_result AS $func$
25 DECLARE
26
27     current_res         search.search_result%ROWTYPE;
28     search_org_list     INT[];
29     luri_org_list       INT[];
30     tmp_int_list        INT[];
31
32     check_limit         INT;
33     core_limit          INT;
34     core_offset         INT;
35     tmp_int             INT;
36
37     core_result         RECORD;
38     core_cursor         REFCURSOR;
39     core_rel_query      TEXT;
40
41     total_count         INT := 0;
42     check_count         INT := 0;
43     deleted_count       INT := 0;
44     visible_count       INT := 0;
45     excluded_count      INT := 0;
46
47 BEGIN
48
49     check_limit := COALESCE( param_check, 1000 );
50     core_limit  := COALESCE( param_limit, 25000 );
51     core_offset := COALESCE( param_offset, 0 );
52
53     -- core_skip_chk := COALESCE( param_skip_chk, 1 );
54
55     IF param_search_ou > 0 THEN
56         IF param_depth IS NOT NULL THEN
57             SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou, param_depth );
58         ELSE
59             SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou );
60         END IF;
61
62         SELECT array_accum(distinct id) INTO luri_org_list FROM actor.org_unit_ancestors( param_search_ou );
63
64     ELSIF param_search_ou < 0 THEN
65         SELECT array_accum(distinct org_unit) INTO search_org_list FROM actor.org_lasso_map WHERE lasso = -param_search_ou;
66
67         FOR tmp_int IN SELECT * FROM UNNEST(search_org_list) LOOP
68             SELECT array_accum(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors( tmp_int );
69             luri_org_list := luri_org_list || tmp_int_list;
70         END LOOP;
71
72         SELECT array_accum(DISTINCT x.id) INTO luri_org_list FROM UNNEST(luri_org_list) x(id);
73
74     ELSIF param_search_ou = 0 THEN
75         -- reserved for user lassos (ou_buckets/type='lasso') with ID passed in depth ... hack? sure.
76     END IF;
77
78     IF param_pref_ou IS NOT NULL THEN
79         SELECT array_accum(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors(param_pref_ou);
80         luri_org_list := luri_org_list || tmp_int_list;
81     END IF;
82
83     OPEN core_cursor FOR EXECUTE param_query;
84
85     LOOP
86
87         FETCH core_cursor INTO core_result;
88         EXIT WHEN NOT FOUND;
89         EXIT WHEN total_count >= core_limit;
90
91         total_count := total_count + 1;
92
93         CONTINUE WHEN total_count NOT BETWEEN  core_offset + 1 AND check_limit + core_offset;
94
95         check_count := check_count + 1;
96
97         IF NOT deleted_search THEN
98
99             PERFORM 1 FROM biblio.record_entry b WHERE NOT b.deleted AND b.id IN ( SELECT * FROM unnest( core_result.records ) );
100             IF NOT FOUND THEN
101                 -- RAISE NOTICE ' % were all deleted ... ', core_result.records;
102                 deleted_count := deleted_count + 1;
103                 CONTINUE;
104             END IF;
105
106             PERFORM 1
107               FROM  biblio.record_entry b
108                     JOIN config.bib_source s ON (b.source = s.id)
109               WHERE s.transcendant
110                     AND b.id IN ( SELECT * FROM unnest( core_result.records ) );
111
112             IF FOUND THEN
113                 -- RAISE NOTICE ' % were all transcendant ... ', core_result.records;
114                 visible_count := visible_count + 1;
115
116                 current_res.id = core_result.id;
117                 current_res.rel = core_result.rel;
118
119                 tmp_int := 1;
120                 IF metarecord THEN
121                     SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
122                 END IF;
123
124                 IF tmp_int = 1 THEN
125                     current_res.record = core_result.records[1];
126                 ELSE
127                     current_res.record = NULL;
128                 END IF;
129
130                 RETURN NEXT current_res;
131
132                 CONTINUE;
133             END IF;
134
135             PERFORM 1
136               FROM  asset.call_number cn
137                     JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
138                     JOIN asset.uri uri ON (map.uri = uri.id)
139               WHERE NOT cn.deleted
140                     AND cn.label = '##URI##'
141                     AND uri.active
142                     AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
143                     AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
144                     AND cn.owning_lib IN ( SELECT * FROM unnest( luri_org_list ) )
145               LIMIT 1;
146
147             IF FOUND THEN
148                 -- RAISE NOTICE ' % have at least one URI ... ', core_result.records;
149                 visible_count := visible_count + 1;
150
151                 current_res.id = core_result.id;
152                 current_res.rel = core_result.rel;
153
154                 tmp_int := 1;
155                 IF metarecord THEN
156                     SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
157                 END IF;
158
159                 IF tmp_int = 1 THEN
160                     current_res.record = core_result.records[1];
161                 ELSE
162                     current_res.record = NULL;
163                 END IF;
164
165                 RETURN NEXT current_res;
166
167                 CONTINUE;
168             END IF;
169
170             IF param_statuses IS NOT NULL AND array_upper(param_statuses, 1) > 0 THEN
171
172                 PERFORM 1
173                   FROM  asset.call_number cn
174                         JOIN asset.copy cp ON (cp.call_number = cn.id)
175                   WHERE NOT cn.deleted
176                         AND NOT cp.deleted
177                         AND cp.status IN ( SELECT * FROM unnest( param_statuses ) )
178                         AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
179                         AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
180                   LIMIT 1;
181
182                 IF NOT FOUND THEN
183                     PERFORM 1
184                       FROM  biblio.peer_bib_copy_map pr
185                             JOIN asset.copy cp ON (cp.id = pr.target_copy)
186                       WHERE NOT cp.deleted
187                             AND cp.status IN ( SELECT * FROM unnest( param_statuses ) )
188                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
189                             AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
190                       LIMIT 1;
191
192                     IF NOT FOUND THEN
193                     -- RAISE NOTICE ' % and multi-home linked records were all status-excluded ... ', core_result.records;
194                         excluded_count := excluded_count + 1;
195                         CONTINUE;
196                     END IF;
197                 END IF;
198
199             END IF;
200
201             IF param_locations IS NOT NULL AND array_upper(param_locations, 1) > 0 THEN
202
203                 PERFORM 1
204                   FROM  asset.call_number cn
205                         JOIN asset.copy cp ON (cp.call_number = cn.id)
206                   WHERE NOT cn.deleted
207                         AND NOT cp.deleted
208                         AND cp.location IN ( SELECT * FROM unnest( param_locations ) )
209                         AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
210                         AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
211                   LIMIT 1;
212
213                 IF NOT FOUND THEN
214                     PERFORM 1
215                       FROM  biblio.peer_bib_copy_map pr
216                             JOIN asset.copy cp ON (cp.id = pr.target_copy)
217                       WHERE NOT cp.deleted
218                             AND cp.location IN ( SELECT * FROM unnest( param_locations ) )
219                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
220                             AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
221                       LIMIT 1;
222
223                     IF NOT FOUND THEN
224                         -- RAISE NOTICE ' % and multi-home linked records were all copy_location-excluded ... ', core_result.records;
225                         excluded_count := excluded_count + 1;
226                         CONTINUE;
227                     END IF;
228                 END IF;
229
230             END IF;
231
232             IF staff IS NULL OR NOT staff THEN
233
234                 PERFORM 1
235                   FROM  asset.opac_visible_copies
236                   WHERE circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
237                         AND record IN ( SELECT * FROM unnest( core_result.records ) )
238                   LIMIT 1;
239
240                 IF NOT FOUND THEN
241                     PERFORM 1
242                       FROM  biblio.peer_bib_copy_map pr
243                             JOIN asset.opac_visible_copies cp ON (cp.copy_id = pr.target_copy)
244                       WHERE cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
245                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
246                       LIMIT 1;
247
248                     IF NOT FOUND THEN
249
250                         -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
251                         excluded_count := excluded_count + 1;
252                         CONTINUE;
253                     END IF;
254                 END IF;
255
256             ELSE
257
258                 PERFORM 1
259                   FROM  asset.call_number cn
260                         JOIN asset.copy cp ON (cp.call_number = cn.id)
261                   WHERE NOT cn.deleted
262                         AND NOT cp.deleted
263                         AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
264                         AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
265                   LIMIT 1;
266
267                 IF NOT FOUND THEN
268
269                     PERFORM 1
270                       FROM  biblio.peer_bib_copy_map pr
271                             JOIN asset.copy cp ON (cp.id = pr.target_copy)
272                       WHERE NOT cp.deleted
273                             AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
274                             AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
275                       LIMIT 1;
276
277                     IF NOT FOUND THEN
278
279                         PERFORM 1
280                           FROM  asset.call_number cn
281                                 JOIN asset.copy cp ON (cp.call_number = cn.id)
282                           WHERE cn.record IN ( SELECT * FROM unnest( core_result.records ) )
283                                 AND NOT cp.deleted
284                           LIMIT 1;
285
286                         IF FOUND THEN
287                             -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
288                             excluded_count := excluded_count + 1;
289                             CONTINUE;
290                         END IF;
291                     END IF;
292
293                 END IF;
294
295             END IF;
296
297         END IF;
298
299         visible_count := visible_count + 1;
300
301         current_res.id = core_result.id;
302         current_res.rel = core_result.rel;
303
304         tmp_int := 1;
305         IF metarecord THEN
306             SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
307         END IF;
308
309         IF tmp_int = 1 THEN
310             current_res.record = core_result.records[1];
311         ELSE
312             current_res.record = NULL;
313         END IF;
314
315         RETURN NEXT current_res;
316
317         IF visible_count % 1000 = 0 THEN
318             -- RAISE NOTICE ' % visible so far ... ', visible_count;
319         END IF;
320
321     END LOOP;
322
323     current_res.id = NULL;
324     current_res.rel = NULL;
325     current_res.record = NULL;
326     current_res.total = total_count;
327     current_res.checked = check_count;
328     current_res.deleted = deleted_count;
329     current_res.visible = visible_count;
330     current_res.excluded = excluded_count;
331
332     CLOSE core_cursor;
333
334     RETURN NEXT current_res;
335
336 END;
337 $func$ LANGUAGE PLPGSQL;
338
339  
340 COMMIT;