From: Dan Scott Date: Sat, 11 Jun 2011 11:03:29 +0000 (-0400) Subject: Merge branch 'master' of git.evergreen-ils.org:Evergreen into dbs/unnest_master X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=68f872f4f683d1557df9f0e67b2e645d51f608d2;p=evergreen%2Fmasslnc.git Merge branch 'master' of git.evergreen-ils.org:Evergreen into dbs/unnest_master Also update the now-conflicting SQL upgrade scripts. Conflicts: Open-ILS/src/sql/Pg/002.schema.config.sql --- 68f872f4f683d1557df9f0e67b2e645d51f608d2 diff --cc Open-ILS/src/sql/Pg/002.schema.config.sql index 26a3a3f922,9b5bffb362..bdd4f0a7ef --- a/Open-ILS/src/sql/Pg/002.schema.config.sql +++ b/Open-ILS/src/sql/Pg/002.schema.config.sql @@@ -86,7 -86,7 +86,7 @@@ CREATE TRIGGER no_overlapping_dep BEFORE INSERT OR UPDATE ON config.db_patch_dependencies FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates'); - INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0554', :eg_version); -- dbs -INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0550', :eg_version); -- phasefx/jamesrf ++INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0556', :eg_version); -- dbs CREATE TABLE config.bib_source ( id SERIAL PRIMARY KEY, diff --cc Open-ILS/src/sql/Pg/upgrade/0555.unnest_oils_xpath_table.sql index 0000000000,0000000000..117dba29e1 new file mode 100644 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/0555.unnest_oils_xpath_table.sql @@@ -1,0 -1,0 +1,71 @@@ ++-- Evergreen DB patch 0549.unnest_oils_xpath_table.sql ++-- ++-- Replace usage of custom explode_array() function with native unnest() ++-- ++BEGIN; ++ ++-- check whether patch can be applied ++SELECT evergreen.upgrade_deps_block_check('0549', :eg_version); ++ ++CREATE OR REPLACE FUNCTION oils_xpath_table ( key TEXT, document_field TEXT, relation_name TEXT, xpaths TEXT, criteria TEXT ) RETURNS SETOF RECORD AS $func$ ++DECLARE ++ xpath_list TEXT[]; ++ select_list TEXT[]; ++ where_list TEXT[]; ++ q TEXT; ++ out_record RECORD; ++ empty_test RECORD; ++BEGIN ++ xpath_list := STRING_TO_ARRAY( xpaths, '|' ); ++ ++ select_list := ARRAY_APPEND( select_list, key || '::INT AS key' ); ++ ++ FOR i IN 1 .. ARRAY_UPPER(xpath_list,1) LOOP ++ IF xpath_list[i] = 'null()' THEN ++ select_list := ARRAY_APPEND( select_list, 'NULL::TEXT AS c_' || i ); ++ ELSE ++ select_list := ARRAY_APPEND( ++ select_list, ++ $sel$ ++ unnest( ++ COALESCE( ++ NULLIF( ++ oils_xpath( ++ $sel$ || ++ quote_literal( ++ CASE ++ WHEN xpath_list[i] ~ $re$/[^/[]*@[^/]+$$re$ OR xpath_list[i] ~ $re$text\(\)$$re$ THEN xpath_list[i] ++ ELSE xpath_list[i] || '//text()' ++ END ++ ) || ++ $sel$, ++ $sel$ || document_field || $sel$ ++ ), ++ '{}'::TEXT[] ++ ), ++ '{NULL}'::TEXT[] ++ ) ++ ) AS c_$sel$ || i ++ ); ++ where_list := ARRAY_APPEND( ++ where_list, ++ 'c_' || i || ' IS NOT NULL' ++ ); ++ END IF; ++ END LOOP; ++ ++ q := $q$ ++SELECT * FROM ( ++ SELECT $q$ || ARRAY_TO_STRING( select_list, ', ' ) || $q$ FROM $q$ || relation_name || $q$ WHERE ($q$ || criteria || $q$) ++)x WHERE $q$ || ARRAY_TO_STRING( where_list, ' OR ' ); ++ -- RAISE NOTICE 'query: %', q; ++ ++ FOR out_record IN EXECUTE q LOOP ++ RETURN NEXT out_record; ++ END LOOP; ++ ++ RETURN; ++END; ++$func$ LANGUAGE PLPGSQL IMMUTABLE; ++ ++COMMIT; diff --cc Open-ILS/src/sql/Pg/upgrade/0556.unnest_biblio_extract_metabib_field_entry.sql index 0000000000,0000000000..41d26e5803 new file mode 100644 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/0556.unnest_biblio_extract_metabib_field_entry.sql @@@ -1,0 -1,0 +1,113 @@@ ++-- Evergreen DB patch 0550.unnest_biblio_extract_metabib_field_entry.sql ++-- ++-- Replace usage of custom explode_array() function with native unnest() ++-- ++BEGIN; ++ ++-- check whether patch can be applied ++SELECT evergreen.upgrade_deps_block_check('0550', :eg_version); ++ ++CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$ ++DECLARE ++ bib biblio.record_entry%ROWTYPE; ++ idx config.metabib_field%ROWTYPE; ++ xfrm config.xml_transform%ROWTYPE; ++ prev_xfrm TEXT; ++ transformed_xml TEXT; ++ xml_node TEXT; ++ xml_node_list TEXT[]; ++ facet_text TEXT; ++ raw_text TEXT; ++ curr_text TEXT; ++ joiner TEXT := default_joiner; -- XXX will index defs supply a joiner? ++ output_row metabib.field_entry_template%ROWTYPE; ++BEGIN ++ ++ -- Get the record ++ SELECT INTO bib * FROM biblio.record_entry WHERE id = rid; ++ ++ -- Loop over the indexing entries ++ FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP ++ ++ SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format; ++ ++ -- See if we can skip the XSLT ... it's expensive ++ IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN ++ -- Can't skip the transform ++ IF xfrm.xslt <> '---' THEN ++ transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt); ++ ELSE ++ transformed_xml := bib.marc; ++ END IF; ++ ++ prev_xfrm := xfrm.name; ++ END IF; ++ ++ xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] ); ++ ++ raw_text := NULL; ++ FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP ++ CONTINUE WHEN xml_node !~ E'^\\s*<'; ++ ++ curr_text := ARRAY_TO_STRING( ++ oils_xpath( '//text()', ++ REGEXP_REPLACE( -- This escapes all &s not followed by "amp;". Data ise returned from oils_xpath (above) in UTF-8, not entity encoded ++ REGEXP_REPLACE( -- This escapes embeded [^<]+)(<)([^>]+<)$re$, ++ E'\\1<\\3', ++ 'g' ++ ), ++ '&(?!amp;)', ++ '&', ++ 'g' ++ ) ++ ), ++ ' ' ++ ); ++ ++ CONTINUE WHEN curr_text IS NULL OR curr_text = ''; ++ ++ IF raw_text IS NOT NULL THEN ++ raw_text := raw_text || joiner; ++ END IF; ++ ++ raw_text := COALESCE(raw_text,'') || curr_text; ++ ++ -- insert raw node text for faceting ++ IF idx.facet_field THEN ++ ++ IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN ++ facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] ); ++ ELSE ++ facet_text := curr_text; ++ END IF; ++ ++ output_row.field_class = idx.field_class; ++ output_row.field = -1 * idx.id; ++ output_row.source = rid; ++ output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g')); ++ ++ RETURN NEXT output_row; ++ END IF; ++ ++ END LOOP; ++ ++ CONTINUE WHEN raw_text IS NULL OR raw_text = ''; ++ ++ -- insert combined node text for searching ++ IF idx.search_field THEN ++ output_row.field_class = idx.field_class; ++ output_row.field = idx.id; ++ output_row.source = rid; ++ output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g')); ++ ++ RETURN NEXT output_row; ++ END IF; ++ ++ END LOOP; ++ ++END; ++$func$ LANGUAGE PLPGSQL; ++ ++COMMIT;