From: Lebbeous Fogle-Weekley Date: Tue, 30 Apr 2013 22:06:33 +0000 (-0400) Subject: Ditch our own viz tests and just use query_parser_fts() X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=affa55666d8c95c87960d7dc2b5ab1734fbe99d4;p=evergreen%2Fequinox.git Ditch our own viz tests and just use query_parser_fts() After a talk with Mike yesterday we realized this was even possible. Or maybe that was already clear to him but not yet to me. This has taken a while to get almost right. Signed-off-by: Lebbeous Fogle-Weekley --- diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.bib-auth-browse.sql b/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.bib-auth-browse.sql index daaed50631..d795e88481 100644 --- a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.bib-auth-browse.sql +++ b/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.bib-auth-browse.sql @@ -6885,96 +6885,6 @@ Revision 1.2 - Added Log Comment 2003/03/24 19:37:42 ckeith -- ---------------------------------------------------- -- XXX TODO From here down, add this to stock SQL files --- The following view supports checking for visibility for OPAC browse. -CREATE OR REPLACE VIEW asset.visible_holdings AS -SELECT - bre.id AS record, - COALESCE( - aovc.circ_lib, acn_for_uri_map.owning_lib, acp_for_peer_bibs.circ_lib - ) AS ou, - COALESCE(aovc_acp.location, acp_for_peer_bibs.location) AS copy_location -FROM biblio.record_entry bre -LEFT JOIN asset.opac_visible_copies aovc - ON (aovc.record = bre.id) -LEFT JOIN asset.copy aovc_acp - ON (aovc.copy_id = aovc_acp.id) -LEFT JOIN asset.call_number acn_for_uri_map - ON (acn_for_uri_map.record = aovc.record) -LEFT JOIN asset.uri_call_number_map aucnm - ON (aucnm.call_number = acn_for_uri_map.id) -LEFT JOIN asset.uri auri - ON (aucnm.uri = auri.id) -LEFT JOIN biblio.peer_bib_copy_map bpbcm - ON (bpbcm.peer_record = bre.id) -LEFT JOIN asset.copy acp_for_peer_bibs - ON (bpbcm.target_copy = acp_for_peer_bibs.id ) -LEFT JOIN asset.copy_location peer_copy_loc - ON (peer_copy_loc.id = acp_for_peer_bibs.location ) -LEFT JOIN config.copy_status peer_copy_status - ON (peer_copy_status.id = acp_for_peer_bibs.status) -WHERE - NOT bre.deleted AND - COALESCE(auri.active, TRUE) AND - NOT COALESCE(acp_for_peer_bibs.deleted, FALSE) AND - COALESCE( - acp_for_peer_bibs.opac_visible, - peer_copy_loc.opac_visible, - peer_copy_status.opac_visible, - TRUE -- URIs and things on aovc are already known to be visible - ) -UNION -SELECT - bre.id AS record, - aou.id AS ou, - NULL AS copy_location -FROM biblio.record_entry bre -INNER JOIN config.bib_source cbs - ON (cbs.id = bre.source AND cbs.transcendant) -INNER JOIN actor.org_unit aou ON (true) -WHERE NOT bre.deleted ; - --- This view supports checking for holdings in scope for staff browse. - -CREATE OR REPLACE VIEW asset.staff_holdings AS -SELECT - bre.id AS record, - COALESCE( - acp.circ_lib, acn_for_uri_map.owning_lib, acp_for_peer_bibs.circ_lib - ) AS ou, - COALESCE(acp.location, acp_for_peer_bibs.location) AS copy_location -FROM biblio.record_entry bre -LEFT JOIN asset.call_number acn - ON (acn.record = bre.id) -LEFT JOIN asset.copy acp - ON (acp.call_number = acn.id) -LEFT JOIN asset.call_number acn_for_uri_map - ON (acn_for_uri_map.record = bre.id) -LEFT JOIN asset.uri_call_number_map aucnm - ON (aucnm.call_number = acn_for_uri_map.id) -LEFT JOIN asset.uri auri - ON (aucnm.uri = auri.id) -LEFT JOIN biblio.peer_bib_copy_map bpbcm - ON (bpbcm.peer_record = bre.id) -LEFT JOIN asset.copy acp_for_peer_bibs - ON (bpbcm.target_copy = acp_for_peer_bibs.id ) -LEFT JOIN asset.copy_location peer_copy_loc - ON (peer_copy_loc.id = acp_for_peer_bibs.location ) -LEFT JOIN config.copy_status peer_copy_status - ON (peer_copy_status.id = acp_for_peer_bibs.status) -WHERE - NOT bre.deleted AND - COALESCE(auri.active, TRUE) AND - NOT COALESCE(acp_for_peer_bibs.deleted, FALSE) -UNION -SELECT - bre.id AS record, - aou.id AS ou, - NULL AS copy_location -FROM biblio.record_entry bre -INNER JOIN config.bib_source cbs - ON (cbs.id = bre.source AND cbs.transcendant) -INNER JOIN actor.org_unit aou ON (true) -WHERE NOT bre.deleted ; ALTER TABLE metabib.browse_entry ADD COLUMN sort_value TEXT; CREATE OR REPLACE FUNCTION metabib.browse_entry_sort_value() @@ -7003,7 +6913,7 @@ CREATE INDEX CONCURRENTLY browse_entry_sort_value_idx -- indices. -- CREATE INDEX CONCURRENTLY browse_entry_sort_value_idx_desc --- ON metabib.browse_entry USING BTREE (sort_value DESC); +-- ON metabib.browse_entry USING BTREE (sort_value DESC); CREATE TYPE metabib.flat_browse_entry_appearance AS ( browse_entry BIGINT, @@ -7014,82 +6924,19 @@ CREATE TYPE metabib.flat_browse_entry_appearance AS ( ); -CREATE OR REPLACE FUNCTION metabib._browse_joins_and_where( +CREATE OR REPLACE FUNCTION metabib.browse_pivot( search_field INT[], - browse_term TEXT, - context_org INT DEFAULT NULL, - context_loc_group INT DEFAULT NULL, - staff BOOL DEFAULT FALSE -) RETURNS TEXT[] AS $p$ -DECLARE - joins TEXT; - where_clause TEXT; - scope_test_view TEXT; + browse_term TEXT +) RETURNS SETOF TEXT AS $p$ BEGIN - joins := ' + RETURN QUERY EXECUTE 'SELECT mbe.sort_value FROM metabib.browse_entry mbe JOIN metabib.browse_entry_def_map mbedm ON ( mbedm.entry = mbe.id AND mbedm.def = ANY(' || quote_literal(search_field) || ') - ) '; - where_clause := ''; - - IF staff THEN - scope_test_view := 'asset.staff_holdings'; - ELSE - scope_test_view := 'asset.visible_holdings'; - END IF; - - IF context_org IS NOT NULL OR context_loc_group IS NOT NULL THEN - - joins := joins || ' JOIN ' || scope_test_view || - ' scope_test ON (scope_test.record = mbedm.source) '; - - IF context_org IS NOT NULL THEN - where_clause := where_clause || - 'scope_test.ou IN ( - SELECT id FROM actor.org_unit_descendants(' || - context_org || ')) AND '; - END IF; - - IF context_loc_group IS NOT NULL THEN - where_clause := where_clause || - '(scope_test.copy_location IS NULL OR - scope_test.copy_location IN (SELECT location FROM asset.copy_location_group_map WHERE lgroup = ' || - context_loc_group || ')) AND '; - END IF; - END IF; - - RETURN ARRAY[joins, where_clause]; -END; - -$p$ LANGUAGE PLPGSQL; - -CREATE OR REPLACE FUNCTION metabib.browse_pivot( - search_field INT[], - browse_term TEXT, - context_org INT DEFAULT NULL, - context_loc_group INT DEFAULT NULL -) RETURNS TEXT AS $p$ -DECLARE - joins TEXT; - where_clause TEXT; - joins_and_where TEXT[]; - result TEXT; -BEGIN - joins_and_where := metabib._browse_joins_and_where( - search_field, browse_term, context_org, context_loc_group - ); - - joins := joins_and_where[1]; - where_clause := joins_and_where[2]; - - EXECUTE 'SELECT mbe.sort_value FROM metabib.browse_entry mbe ' || - joins || 'WHERE ' || where_clause || - ' mbe.sort_value >= public.search_normalize(' || + ) + WHERE mbe.sort_value >= public.search_normalize(' || quote_literal(browse_term) || - ') ORDER BY mbe.sort_value LIMIT 1 ' INTO result; - - RETURN result; -- note, can be NULL + ') ORDER BY mbe.sort_value LIMIT 1 '; END; $p$ LANGUAGE PLPGSQL; @@ -7103,57 +6950,45 @@ CREATE OR REPLACE FUNCTION metabib.browse( result_offset INT DEFAULT 0 -- Can be negative! ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$ DECLARE - joins TEXT; - where_clause TEXT; - joins_and_where TEXT[]; - result_query TEXT; + inner_query TEXT; + whole_query TEXT; + loc_query_part TEXT; pivot_sort_value TEXT; f RECORD; r metabib.flat_browse_entry_appearance%ROWTYPE; use_offset INT; BEGIN - pivot_sort_value := metabib.browse_pivot( - search_field, browse_term, context_org, context_loc_group - ); + SELECT INTO pivot_sort_value * FROM metabib.browse_pivot(search_field, browse_term); IF pivot_sort_value IS NULL THEN RETURN; END IF; - joins_and_where := metabib._browse_joins_and_where( - search_field, browse_term, context_org, context_loc_group - ); - - joins := joins_and_where[1]; - where_clause := joins_and_where[2]; - - result_query := - 'SELECT mbe.id, mbe.value, mbe.sort_value, - ARRAY_TO_STRING( - (SELECT ARRAY_AGG(field) FROM ( - SELECT DISTINCT UNNEST(ARRAY_AGG(mbedm.def)) AS field - ) y), - $$,$$ - ) AS fields, - ARRAY_TO_STRING(ARRAY_AGG(mbedm.authority), $$,$$) AS authorities, - (SELECT COUNT(source) FROM ( - SELECT DISTINCT UNNEST(ARRAY_AGG(mbedm.source)) AS source - ) x) sources - FROM metabib.browse_entry mbe ' || - joins || - 'WHERE ' || where_clause; + inner_query := ' + SELECT + mbe.id AS id, + (SELECT ARRAY_AGG(src) FROM ( + SELECT DISTINCT UNNEST(ARRAY_AGG(mbedm.source)) AS src + ) ss) AS records, + 1 AS rel + FROM metabib.browse_entry mbe + JOIN metabib.browse_entry_def_map mbedm ON ( + mbedm.entry = mbe.id AND + mbedm.def = ANY(' || quote_literal(search_field) || ') + ) + WHERE '; -- PostgreSQL is not magic. We can't actually pass a negative offset. IF result_offset >= 0 THEN use_offset := result_offset; - result_query := result_query || + inner_query := inner_query || ' mbe.sort_value >= ' || quote_literal(pivot_sort_value) || - ' GROUP BY 1,2,3 ORDER BY mbe.sort_value '; + ' GROUP BY 1,3,mbe.sort_value ORDER BY mbe.sort_value '; ELSE -- Step 1 of 2 to deliver what the user wants with a negative offset: - result_query := result_query || + inner_query := inner_query || ' mbe.sort_value < ' || quote_literal(pivot_sort_value) || - ' GROUP BY 1,2,3 ORDER BY mbe.sort_value DESC '; + ' GROUP BY 1,3,mbe.sort_value ORDER BY mbe.sort_value DESC '; use_offset := ABS(result_offset) - result_limit; IF use_offset < 0 THEN @@ -7167,22 +7002,46 @@ BEGIN END IF; END IF; - result_query := result_query || - ' LIMIT ' || result_limit || ' OFFSET ' || use_offset; - - IF result_offset < 0 THEN - -- Step 2 of 2 to deliver what the user wants with a negative offset: - result_query := 'SELECT * FROM (' || result_query || - ') x ORDER BY sort_value ASC'; -- Un-reverse the result set. +-- XXX result_query := result_query || +-- XXX ' LIMIT ' || result_limit || ' OFFSET ' || use_offset; +-- XXX +-- XXX IF result_offset < 0 THEN +-- XXX -- Step 2 of 2 to deliver what the user wants with a negative offset: +-- XXX result_query := 'SELECT * FROM (' || result_query || +-- XXX ') x ORDER BY sort_value ASC'; -- Un-reverse the result set. +-- XXX END IF; + + IF context_loc_group IS NULL THEN + loc_query_part := 'NULL, '; + ELSE + loc_query_part := + '(SELECT location FROM asset.copy_location_group_map WHERE + lgroup = ' || quote_literal(context_loc_group) || '), '; END IF; --- RAISE NOTICE 'query is { % }', result_query; - FOR f IN EXECUTE result_query LOOP + whole_query := 'SELECT * FROM search.query_parser_fts(' || + quote_literal(context_org) || + ', NULL, ' || + quote_literal(inner_query) || + ', NULL, ' || + loc_query_part || + use_offset || ',' || + result_limit || + ', 10000, + NULL, ' || + staff || + ', FALSE)'; + RAISE NOTICE 'query is { % }', whole_query; + + FOR f IN EXECUTE whole_query LOOP + IF f.id IS NULL THEN + CONTINUE; -- We don't need the summary row + END IF; r.browse_entry := f.id; - r.value := f.value; - r.fields := f.fields; - r.authorities := f.authorities; - r.sources := f.sources; + r.value := NULL; -- XXX rest of these are TODO + r.fields := NULL; + r.authorities := NULL; + r.sources := NULL; RETURN NEXT r; END LOOP;