Upgrade for LP#1271661 commit collab/miker/1304559_and_1271661_vandelay_fixes_with_upgrades
authorMike Rylander <mrylander@gmail.com>
Tue, 8 Apr 2014 20:38:57 +0000 (16:38 -0400)
committerMike Rylander <mrylander@gmail.com>
Tue, 8 Apr 2014 20:47:28 +0000 (16:47 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/sql/Pg/upgrade/YYYY.schema.use-unlogged-instead-of-temp.sql [new file with mode: 0644]

diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.use-unlogged-instead-of-temp.sql b/Open-ILS/src/sql/Pg/upgrade/YYYY.schema.use-unlogged-instead-of-temp.sql
new file mode 100644 (file)
index 0000000..e041691
--- /dev/null
@@ -0,0 +1,160 @@
+BEGIN;
+
+CREATE UNLOGGED TABLE vandelay.tmp_qrows ( q INTEGER );
+CREATE UNLOGGED TABLE vandelay.tmp_jrows ( j TEXT );
+
+CREATE OR REPLACE FUNCTION vandelay.match_set_test_marcxml(
+    match_set_id INTEGER, record_xml TEXT, bucket_id INTEGER 
+) RETURNS SETOF vandelay.match_set_test_result AS $$
+DECLARE
+    tags_rstore HSTORE;
+    svf_rstore  HSTORE;
+    coal        TEXT;
+    joins       TEXT;
+    query_      TEXT;
+    wq          TEXT;
+    qvalue      INTEGER;
+    rec         RECORD;
+BEGIN
+    tags_rstore := vandelay.flatten_marc_hstore(record_xml);
+    svf_rstore := vandelay.extract_rec_attrs(record_xml);
+
+    -- generate the where clause and return that directly (into wq), and as
+    -- a side-effect, populate the _vandelay_tmp_[qj]rows tables.
+    wq := vandelay.get_expr_from_match_set(match_set_id, tags_rstore);
+
+    query_ := 'SELECT DISTINCT(record), ';
+
+    -- qrows table is for the quality bits we add to the SELECT clause
+    SELECT STRING_AGG(
+        'COALESCE(n' || q::TEXT || '.quality, 0)', ' + '
+    ) INTO coal FROM vandelay.tmp_qrows;
+
+    -- our query string so far is the SELECT clause and the inital FROM.
+    -- no JOINs yet nor the WHERE clause
+    query_ := query_ || coal || ' AS quality ' || E'\n';
+
+    -- jrows table is for the joins we must make (and the real text conditions)
+    SELECT STRING_AGG(j, E'\n') INTO joins
+        FROM vandelay.tmp_jrows;
+
+    -- add those joins and the where clause to our query.
+    query_ := query_ || joins || E'\n';
+
+    -- join the record bucket
+    IF bucket_id IS NOT NULL THEN
+        query_ := query_ || 'JOIN container.biblio_record_entry_bucket_item ' ||
+            'brebi ON (brebi.target_biblio_record_entry = record ' ||
+            'AND brebi.bucket = ' || bucket_id || E')\n';
+    END IF;
+
+    query_ := query_ || 'JOIN biblio.record_entry bre ON (bre.id = record) ' || 'WHERE ' || wq || ' AND not bre.deleted';
+
+    -- this will return rows of record,quality
+    FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
+        RETURN NEXT rec;
+    END LOOP;
+
+    DELETE FROM vandelay.tmp_qrows;
+    DELETE FROM vandelay.tmp_jrows;
+    RETURN;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_push_qrow(
+    node vandelay.match_set_point
+) RETURNS VOID AS $$
+DECLARE
+BEGIN
+    INSERT INTO vandelay.tmp_qrows (q) VALUES (node.id);
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_push_jrow(
+    node vandelay.match_set_point,
+    tags_rstore HSTORE
+) RETURNS VOID AS $$
+DECLARE
+    jrow        TEXT;
+    my_alias    TEXT;
+    op          TEXT;
+    tagkey      TEXT;
+    caseless    BOOL;
+    jrow_count  INT;
+    my_using    TEXT;
+    my_join     TEXT;
+BEGIN
+    -- remember $1 is tags_rstore, and $2 is svf_rstore
+
+    caseless := FALSE;
+    SELECT COUNT(*) INTO jrow_count FROM vandelay.tmp_jrows;
+    IF jrow_count > 0 THEN
+        my_using := ' USING (record)';
+        my_join := 'FULL OUTER JOIN';
+    ELSE
+        my_using := '';
+        my_join := 'FROM';
+    END IF;
+
+    IF node.tag IS NOT NULL THEN
+        caseless := (node.tag IN ('020', '022', '024'));
+        tagkey := node.tag;
+        IF node.subfield IS NOT NULL THEN
+            tagkey := tagkey || node.subfield;
+        END IF;
+    END IF;
+
+    my_alias := 'n' || node.id::TEXT;
+
+    jrow := my_join || ' (SELECT *, ';
+    IF node.tag IS NOT NULL THEN
+        IF node.negate THEN
+            IF caseless THEN
+                op := 'NOT LIKE';
+            ELSE
+                op := '<>';
+            END IF;
+        ELSE
+            IF caseless THEN
+                op := 'LIKE';
+            ELSE
+                op := '=';
+            END IF;
+        END IF;
+
+        jrow := jrow  || node.quality ||
+            ' AS quality FROM metabib.full_rec mfr WHERE mfr.tag = ''' ||
+            node.tag || '''';
+        IF node.subfield IS NOT NULL THEN
+            jrow := jrow || ' AND mfr.subfield = ''' ||
+                node.subfield || '''';
+        END IF;
+        jrow := jrow || ' AND (';
+        jrow := jrow || vandelay._node_tag_comparisons(caseless, op, tags_rstore, tagkey);
+        jrow := jrow || ')) ' || my_alias || my_using || E'\n';
+    ELSE    -- svf XXX TODO multi and composite attrs are not supported yet
+        jrow := jrow || 'mra.source AS record, ' || node.quality ||
+            ' AS quality FROM metabib.record_attr_vector_list mra,' ||
+            ' config.coded_value_map ccvm WHERE' ||
+            ' ccvm.ctype = ' || quote_literal(node.svf) ||
+            ' AND  ccvm.code = ' || quote_literal( ($2 -> node.svf) ) || ' AND';
+
+        IF node.negate THEN
+            jrow := jrow || ' NOT (';
+        END IF;
+
+        jrow := jrow || ' mra.vlist @> intset(ccvm.id)';
+
+        IF node.negate THEN
+            jrow := jrow || ' )';
+        END IF;
+
+        jrow := jrow || ' ' || my_alias || my_using || E'\n';
+
+    END IF;
+    INSERT INTO vandelay.tmp_jrows (j) VALUES (jrow);
+END;
+$$ LANGUAGE PLPGSQL;
+
+COMMIT;
+