]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/XXXX.schema.dym_delayed_reify.sql
LP#1931737: Allow the delay of symspell updates
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / XXXX.schema.dym_delayed_reify.sql
1 BEGIN;
2
3 CREATE OR REPLACE FUNCTION search.disable_symspell_reification () RETURNS VOID AS $f$
4     INSERT INTO config.internal_flag (name,enabled)
5       VALUES ('ingest.disable_symspell_reification',TRUE)
6     ON CONFLICT (name) DO UPDATE SET enabled = TRUE;
7 $f$ LANGUAGE SQL;
8
9 CREATE OR REPLACE FUNCTION search.enable_symspell_reification () RETURNS VOID AS $f$
10     UPDATE config.internal_flag SET enabled = FALSE WHERE name = 'ingest.disable_symspell_reification';
11 $f$ LANGUAGE SQL;
12
13 CREATE OR REPLACE FUNCTION search.symspell_dictionary_full_reify () RETURNS SETOF search.symspell_dictionary AS $f$
14  WITH new_rows AS (
15     DELETE FROM search.symspell_dictionary_updates RETURNING *
16  ), computed_rows AS ( -- this collapses the rows deleted into the format we need for UPSERT
17     SELECT  SUM(keyword_count)    AS keyword_count,
18             SUM(title_count)      AS title_count,
19             SUM(author_count)     AS author_count,
20             SUM(subject_count)    AS subject_count,
21             SUM(series_count)     AS series_count,
22             SUM(identifier_count) AS identifier_count,
23
24             prefix_key,
25
26             ARRAY_REMOVE(ARRAY_AGG(DISTINCT keyword_suggestions[1]), NULL)    AS keyword_suggestions,
27             ARRAY_REMOVE(ARRAY_AGG(DISTINCT title_suggestions[1]), NULL)      AS title_suggestions,
28             ARRAY_REMOVE(ARRAY_AGG(DISTINCT author_suggestions[1]), NULL)     AS author_suggestions,
29             ARRAY_REMOVE(ARRAY_AGG(DISTINCT subject_suggestions[1]), NULL)    AS subject_suggestions,
30             ARRAY_REMOVE(ARRAY_AGG(DISTINCT series_suggestions[1]), NULL)     AS series_suggestions,
31             ARRAY_REMOVE(ARRAY_AGG(DISTINCT identifier_suggestions[1]), NULL) AS identifier_suggestions
32       FROM  new_rows
33       GROUP BY prefix_key
34  )
35  INSERT INTO search.symspell_dictionary AS d SELECT * FROM computed_rows
36  ON CONFLICT (prefix_key) DO UPDATE SET
37     keyword_count = GREATEST(0, d.keyword_count + EXCLUDED.keyword_count),
38     keyword_suggestions = evergreen.text_array_merge_unique(EXCLUDED.keyword_suggestions,d.keyword_suggestions),
39
40     title_count = GREATEST(0, d.title_count + EXCLUDED.title_count),
41     title_suggestions = evergreen.text_array_merge_unique(EXCLUDED.title_suggestions,d.title_suggestions),
42
43     author_count = GREATEST(0, d.author_count + EXCLUDED.author_count),
44     author_suggestions = evergreen.text_array_merge_unique(EXCLUDED.author_suggestions,d.author_suggestions),
45
46     subject_count = GREATEST(0, d.subject_count + EXCLUDED.subject_count),
47     subject_suggestions = evergreen.text_array_merge_unique(EXCLUDED.subject_suggestions,d.subject_suggestions),
48
49     series_count = GREATEST(0, d.series_count + EXCLUDED.series_count),
50     series_suggestions = evergreen.text_array_merge_unique(EXCLUDED.series_suggestions,d.series_suggestions),
51
52     identifier_count = GREATEST(0, d.identifier_count + EXCLUDED.identifier_count),
53     identifier_suggestions = evergreen.text_array_merge_unique(EXCLUDED.identifier_suggestions,d.identifier_suggestions)
54  RETURNING *;
55 $f$ LANGUAGE SQL;
56
57 -- Updated again to check for delayed symspell reification
58 CREATE OR REPLACE FUNCTION metabib.reingest_metabib_field_entries(
59     bib_id BIGINT,
60     skip_facet BOOL DEFAULT FALSE,
61     skip_display BOOL DEFAULT FALSE,
62     skip_browse BOOL DEFAULT FALSE,
63     skip_search BOOL DEFAULT FALSE,
64     only_fields INT[] DEFAULT '{}'::INT[]
65 ) RETURNS VOID AS $func$
66 DECLARE
67     fclass          RECORD;
68     ind_data        metabib.field_entry_template%ROWTYPE;
69     mbe_row         metabib.browse_entry%ROWTYPE;
70     mbe_id          BIGINT;
71     b_skip_facet    BOOL;
72     b_skip_display    BOOL;
73     b_skip_browse   BOOL;
74     b_skip_search   BOOL;
75     value_prepped   TEXT;
76     field_list      INT[] := only_fields;
77     field_types     TEXT[] := '{}'::TEXT[];
78 BEGIN
79
80     IF field_list = '{}'::INT[] THEN
81         SELECT ARRAY_AGG(id) INTO field_list FROM config.metabib_field;
82     END IF;
83
84     SELECT COALESCE(NULLIF(skip_facet, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_facet_indexing' AND enabled)) INTO b_skip_facet;
85     SELECT COALESCE(NULLIF(skip_display, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_display_indexing' AND enabled)) INTO b_skip_display;
86     SELECT COALESCE(NULLIF(skip_browse, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_browse_indexing' AND enabled)) INTO b_skip_browse;
87     SELECT COALESCE(NULLIF(skip_search, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_search_indexing' AND enabled)) INTO b_skip_search;
88
89     IF NOT b_skip_facet THEN field_types := field_types || '{facet}'; END IF;
90     IF NOT b_skip_display THEN field_types := field_types || '{display}'; END IF;
91     IF NOT b_skip_browse THEN field_types := field_types || '{browse}'; END IF;
92     IF NOT b_skip_search THEN field_types := field_types || '{search}'; END IF;
93
94     PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
95     IF NOT FOUND THEN
96         IF NOT b_skip_search THEN
97             FOR fclass IN SELECT * FROM config.metabib_class LOOP
98                 -- RAISE NOTICE 'Emptying out %', fclass.name;
99                 EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
100             END LOOP;
101         END IF;
102         IF NOT b_skip_facet THEN
103             DELETE FROM metabib.facet_entry WHERE source = bib_id;
104         END IF;
105         IF NOT b_skip_display THEN
106             DELETE FROM metabib.display_entry WHERE source = bib_id;
107         END IF;
108         IF NOT b_skip_browse THEN
109             DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
110         END IF;
111     END IF;
112
113     FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id, ' ', field_types, field_list ) LOOP
114
115     -- don't store what has been normalized away
116         CONTINUE WHEN ind_data.value IS NULL;
117
118         IF ind_data.field < 0 THEN
119             ind_data.field = -1 * ind_data.field;
120         END IF;
121
122         IF ind_data.facet_field AND NOT b_skip_facet THEN
123             INSERT INTO metabib.facet_entry (field, source, value)
124                 VALUES (ind_data.field, ind_data.source, ind_data.value);
125         END IF;
126
127         IF ind_data.display_field AND NOT b_skip_display THEN
128             INSERT INTO metabib.display_entry (field, source, value)
129                 VALUES (ind_data.field, ind_data.source, ind_data.value);
130         END IF;
131
132
133         IF ind_data.browse_field AND NOT b_skip_browse THEN
134             -- A caveat about this SELECT: this should take care of replacing
135             -- old mbe rows when data changes, but not if normalization (by
136             -- which I mean specifically the output of
137             -- evergreen.oils_tsearch2()) changes.  It may or may not be
138             -- expensive to add a comparison of index_vector to index_vector
139             -- to the WHERE clause below.
140
141             CONTINUE WHEN ind_data.sort_value IS NULL;
142
143             value_prepped := metabib.browse_normalize(ind_data.value, ind_data.field);
144             IF ind_data.browse_nocase THEN
145                 SELECT INTO mbe_row * FROM metabib.browse_entry
146                     WHERE evergreen.lowercase(value) = evergreen.lowercase(value_prepped) AND sort_value = ind_data.sort_value
147                     ORDER BY sort_value, value LIMIT 1; -- gotta pick something, I guess
148             ELSE
149                 SELECT INTO mbe_row * FROM metabib.browse_entry
150                     WHERE value = value_prepped AND sort_value = ind_data.sort_value;
151             END IF;
152
153             IF FOUND THEN
154                 mbe_id := mbe_row.id;
155             ELSE
156                 INSERT INTO metabib.browse_entry
157                     ( value, sort_value ) VALUES
158                     ( value_prepped, ind_data.sort_value );
159
160                 mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
161             END IF;
162
163             INSERT INTO metabib.browse_entry_def_map (entry, def, source, authority)
164                 VALUES (mbe_id, ind_data.field, ind_data.source, ind_data.authority);
165         END IF;
166
167         IF ind_data.search_field AND NOT b_skip_search THEN
168             -- Avoid inserting duplicate rows
169             EXECUTE 'SELECT 1 FROM metabib.' || ind_data.field_class ||
170                 '_field_entry WHERE field = $1 AND source = $2 AND value = $3'
171                 INTO mbe_id USING ind_data.field, ind_data.source, ind_data.value;
172                 -- RAISE NOTICE 'Search for an already matching row returned %', mbe_id;
173             IF mbe_id IS NULL THEN
174                 EXECUTE $$
175                 INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
176                     VALUES ($$ ||
177                         quote_literal(ind_data.field) || $$, $$ ||
178                         quote_literal(ind_data.source) || $$, $$ ||
179                         quote_literal(ind_data.value) ||
180                     $$);$$;
181             END IF;
182         END IF;
183
184     END LOOP;
185
186     IF NOT b_skip_search THEN
187         PERFORM metabib.update_combined_index_vectors(bib_id);
188         PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_symspell_reification' AND enabled;
189         IF NOT FOUND THEN
190             PERFORM search.symspell_dictionary_reify();
191         END IF;
192     END IF;
193
194     RETURN;
195 END;
196 $func$ LANGUAGE PLPGSQL;
197
198 COMMIT;
199