authority Functions

This page documents all 56 function(s) in the authority schema.

Function Index

Function Return Type Language Volatility Security

apply_propagate_changes(aid bigint, bid bigint)

bigint

plpgsql

VOLATILE

atag_authority_tags(atag text)

integer[]

sql

VOLATILE

atag_authority_tags_refs(atag text)

integer[]

sql

VOLATILE

atag_browse_center(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

atag_browse_center_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

atag_browse_top(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

atag_browse_top_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

atag_search_heading(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

atag_search_heading_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

atag_search_rank(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

atag_search_rank_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_authority_tags(a text)

integer[]

sql

VOLATILE

axis_authority_tags_refs(a text)

integer[]

sql

VOLATILE

axis_browse_center(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_browse_center_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_browse_top(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_browse_top_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_search_heading(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_search_heading_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_search_rank(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

axis_search_rank_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_authority_tags(btag text)

integer[]

sql

VOLATILE

btag_authority_tags_refs(btag text)

integer[]

sql

VOLATILE

btag_browse_center(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_browse_center_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_browse_top(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_browse_top_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_search_heading(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_search_heading_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_search_rank(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

btag_search_rank_refs(a text, q text, page integer DEFAULT …​)

SETOF bigint

sql

VOLATILE

calculate_authority_linking(rec_id bigint, rec_control_set intege…​)

SETOF authority.authority_linking

plpgsql

VOLATILE

extract_headings(marc text, restrict integer[] DEFAULT…​)

SETOF authority.heading

plpgsql

VOLATILE

extract_headings(rid bigint, restrict integer[] DEFAUL…​)

SETOF authority.heading

plpgsql

VOLATILE

extract_thesaurus(marcxml text)

text

plpgsql

STABLE

flatten_marc(rid bigint)

SETOF authority.full_rec

plpgsql

VOLATILE

generate_overlay_template(bigint)

text

sql

VOLATILE

generate_overlay_template(source_xml text)

text

plpgsql

STABLE

indexing_delete(auth authority.record_entry, extra te…​)

boolean

plpgsql

VOLATILE

indexing_update(auth authority.record_entry, insert_o…​)

boolean

plpgsql

VOLATILE

map_thesaurus_to_control_set()

trigger

plpgsql

VOLATILE

merge_records(target_record bigint, source_record b…​)

integer

plpgsql

VOLATILE

normalize_heading(marcxml text)

text

sql

STABLE

normalize_heading(marcxml text, no_thesaurus boolean)

text

plpgsql

STABLE

normalize_heading_for_upsert()

trigger

plpgsql

VOLATILE

propagate_changes(aid bigint)

SETOF bigint

sql

VOLATILE

propagate_changes(aid bigint, bid bigint)

bigint

plpgsql

VOLATILE

reingest_authority_full_rec(auth_id bigint)

void

plpgsql

VOLATILE

reingest_authority_rec_descriptor(auth_id bigint)

void

plpgsql

VOLATILE

simple_heading_browse_center(atag_list integer[], q text, page int…​)

SETOF bigint

plpgsql

VOLATILE

simple_heading_browse_top(atag_list integer[], q text, page int…​)

SETOF bigint

plpgsql

VOLATILE

simple_heading_find_pivot(a integer[], q text, thesauruses text…​)

text

plpgsql

VOLATILE

simple_heading_search_heading(atag_list integer[], q text, page int…​)

SETOF bigint

sql

VOLATILE

simple_heading_search_rank(atag_list integer[], q text, page int…​)

SETOF bigint

sql

VOLATILE

simple_heading_set(marcxml text)

SETOF authority.simple_heading

plpgsql

STABLE

simple_normalize_heading(marcxml text)

text

sql

STABLE

apply_propagate_changes

Signature: authority.apply_propagate_changes(aid bigint, bid bigint)

Returns: bigint

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    bib_forced  BOOL := FALSE;
    bib_rec     biblio.record_entry%ROWTYPE;
    new_marc    TEXT;
BEGIN

    SELECT INTO bib_rec * FROM biblio.record_entry WHERE id = bid;

    new_marc := vandelay.merge_record_xml(
        bib_rec.marc, authority.generate_overlay_template(aid));

    IF new_marc = bib_rec.marc THEN
        -- Authority record change had no impact on this bib record.
        -- Nothing left to do.
        RETURN aid;
    END IF;

    PERFORM 1 FROM config.global_flag
        WHERE name = 'ingest.disable_authority_auto_update_bib_meta'
            AND enabled;

    IF NOT FOUND THEN
        -- update the bib record editor and edit_date
        bib_rec.editor := (
            SELECT editor FROM authority.record_entry WHERE id = aid);
        bib_rec.edit_date = NOW();
    END IF;

    PERFORM action.set_queued_ingest_force('ingest.queued.biblio.update.disabled');

    UPDATE biblio.record_entry SET
        marc = new_marc,
        editor = bib_rec.editor,
        edit_date = bib_rec.edit_date
    WHERE id = bid;

    PERFORM action.clear_queued_ingest_force();

    RETURN aid;

END;

atag_authority_tags

Signature: authority.atag_authority_tags(atag text)

Returns: integer[]

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT ARRAY_AGG(id) FROM authority.control_set_authority_field WHERE tag = $1

atag_authority_tags_refs

Signature: authority.atag_authority_tags_refs(atag text)

Returns: integer[]

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT ARRAY_AGG(y) from (
        SELECT  unnest(ARRAY_CAT(
                    ARRAY[a.id],
                    (SELECT ARRAY_AGG(x.id) FROM authority.control_set_authority_field x WHERE x.main_entry = a.id)
                )) y
      FROM  authority.control_set_authority_field a
      WHERE a.tag = $1) x

atag_browse_center

Signature: authority.atag_browse_center(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 9, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_center(authority.atag_authority_tags($1), $2, $3, $4, $5)

atag_browse_center_refs

Signature: authority.atag_browse_center_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 9, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_center(authority.atag_authority_tags_refs($1), $2, $3, $4, $5)

atag_browse_top

Signature: authority.atag_browse_top(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_top(authority.atag_authority_tags($1), $2, $3, $4, $5)

atag_browse_top_refs

Signature: authority.atag_browse_top_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_top(authority.atag_authority_tags_refs($1), $2, $3, $4, $5)

atag_search_heading

Signature: authority.atag_search_heading(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_heading(authority.atag_authority_tags($1), $2, $3, $4, $5)

atag_search_heading_refs

Signature: authority.atag_search_heading_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_heading(authority.atag_authority_tags_refs($1), $2, $3, $4, $5)

atag_search_rank

Signature: authority.atag_search_rank(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_rank(authority.atag_authority_tags($1), $2, $3, $4, $5)

atag_search_rank_refs

Signature: authority.atag_search_rank_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_rank(authority.atag_authority_tags_refs($1), $2, $3, $4, $5)

axis_authority_tags

Signature: authority.axis_authority_tags(a text)

Returns: integer[]

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT ARRAY_AGG(field) FROM authority.browse_axis_authority_field_map WHERE axis = $1;

axis_authority_tags_refs

Signature: authority.axis_authority_tags_refs(a text)

Returns: integer[]

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT ARRAY_AGG(y) from (
       SELECT  unnest(ARRAY_CAT(
                 ARRAY[a.field],
                 (SELECT ARRAY_AGG(x.id) FROM authority.control_set_authority_field x WHERE x.main_entry = a.field)
             )) y
       FROM  authority.browse_axis_authority_field_map a
       WHERE axis = $1) x

axis_browse_center

Signature: authority.axis_browse_center(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 9, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_center(authority.axis_authority_tags($1), $2, $3, $4, $5)

axis_browse_center_refs

Signature: authority.axis_browse_center_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 9, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_center(authority.axis_authority_tags_refs($1), $2, $3, $4, $5)

axis_browse_top

Signature: authority.axis_browse_top(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_top(authority.axis_authority_tags($1), $2, $3, $4, $5)

axis_browse_top_refs

Signature: authority.axis_browse_top_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_top(authority.axis_authority_tags_refs($1), $2, $3, $4, $5)

axis_search_heading

Signature: authority.axis_search_heading(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_heading(authority.axis_authority_tags($1), $2, $3, $4, $5)

axis_search_heading_refs

Signature: authority.axis_search_heading_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_heading(authority.axis_authority_tags_refs($1), $2, $3, $4, $5)

axis_search_rank

Signature: authority.axis_search_rank(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_rank(authority.axis_authority_tags($1), $2, $3, $4, $5)

axis_search_rank_refs

Signature: authority.axis_search_rank_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_rank(authority.axis_authority_tags_refs($1), $2, $3, $4, $5)

btag_authority_tags

Signature: authority.btag_authority_tags(btag text)

Returns: integer[]

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT ARRAY_AGG(authority_field) FROM authority.control_set_bib_field WHERE tag = $1

btag_authority_tags_refs

Signature: authority.btag_authority_tags_refs(btag text)

Returns: integer[]

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT ARRAY_AGG(y) from (
        SELECT  unnest(ARRAY_CAT(
                    ARRAY[a.authority_field],
                    (SELECT ARRAY_AGG(x.id) FROM authority.control_set_authority_field x WHERE x.main_entry = a.authority_field)
                )) y
      FROM  authority.control_set_bib_field a
      WHERE a.tag = $1) x

btag_browse_center

Signature: authority.btag_browse_center(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 9, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_center(authority.btag_authority_tags($1), $2, $3, $4, $5)

btag_browse_center_refs

Signature: authority.btag_browse_center_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 9, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_center(authority.btag_authority_tags_refs($1), $2, $3, $4, $5)

btag_browse_top

Signature: authority.btag_browse_top(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_top(authority.btag_authority_tags($1), $2, $3, $4, $5)

btag_browse_top_refs

Signature: authority.btag_browse_top_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_browse_top(authority.btag_authority_tags_refs($1), $2, $3, $4, $5)

btag_search_heading

Signature: authority.btag_search_heading(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_heading(authority.btag_authority_tags($1), $2, $3, $4, $5)

btag_search_heading_refs

Signature: authority.btag_search_heading_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_heading(authority.btag_authority_tags_refs($1), $2, $3, $4, $5)

btag_search_rank

Signature: authority.btag_search_rank(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_rank(authority.btag_authority_tags($1), $2, $3, $4, $5)

btag_search_rank_refs

Signature: authority.btag_search_rank_refs(a text, q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT * FROM authority.simple_heading_search_rank(authority.btag_authority_tags_refs($1), $2, $3, $4, $5)

calculate_authority_linking

Signature: authority.calculate_authority_linking(rec_id bigint, rec_control_set integer, rec_marc_xml xml)

Returns: SETOF authority.authority_linking

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    acsaf       authority.control_set_authority_field%ROWTYPE;
    link        TEXT;
    aal         authority.authority_linking%ROWTYPE;
BEGIN
    IF rec_control_set IS NULL THEN
        -- No control_set on record?  Guess at one
        SELECT control_set INTO rec_control_set
            FROM authority.control_set_authority_field
            WHERE tag IN (
                SELECT UNNEST(
                    XPATH('//*[starts-with(@tag,"1")]/@tag',rec_marc_xml)::TEXT[]
                )
            ) LIMIT 1;

        IF NOT FOUND THEN
            RAISE WARNING 'Could not even guess at control set for authority record %', rec_id;
            RETURN;
        END IF;
    END IF;

    aal.source := rec_id;

    FOR acsaf IN
        SELECT * FROM authority.control_set_authority_field
        WHERE control_set = rec_control_set
            AND linking_subfield IS NOT NULL
            AND main_entry IS NOT NULL
    LOOP
        -- Loop over the trailing-number contents of all linking subfields
        FOR link IN
            SELECT  SUBSTRING( x::TEXT, '\d+$' )
              FROM  UNNEST(
                        XPATH(
                            '//*[@tag="'
                                || acsaf.tag
                                || '"]/*[@code="'
                                || acsaf.linking_subfield
                                || '"]/text()',
                            rec_marc_xml
                        )
                    ) x
        LOOP

            -- Ignore links that are null, malformed, circular, or point to
            -- non-existent authority records.
            IF link IS NOT NULL AND link::BIGINT <> rec_id THEN
                PERFORM * FROM authority.record_entry WHERE id = link::BIGINT;
                IF FOUND THEN
                    aal.target := link::BIGINT;
                    aal.field := acsaf.id;
                    RETURN NEXT aal;
                END IF;
            END IF;
        END LOOP;
    END LOOP;
END;

extract_headings

Signature: authority.extract_headings(marc text, restrict integer[] DEFAULT NULL::integer[])

Returns: SETOF authority.heading

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    idx         authority.heading_field%ROWTYPE;
    xfrm        config.xml_transform%ROWTYPE;
    prev_xfrm   TEXT;
    transformed_xml TEXT;
    heading_node    TEXT;
    heading_node_list   TEXT[];
    component_node    TEXT;
    component_node_list   TEXT[];
    raw_text    TEXT;
    normalized_text    TEXT;
    normalizer  RECORD;
    curr_text   TEXT;
    joiner      TEXT;
    type_value  TEXT;
    base_thesaurus TEXT := NULL;
    output_row  authority.heading;
BEGIN

    -- Loop over the indexing entries
    FOR idx IN SELECT * FROM authority.heading_field WHERE restrict IS NULL OR id = ANY (restrict) ORDER BY format LOOP

        output_row.field   := idx.id;
        output_row.type    := idx.heading_type;
        output_row.purpose := idx.heading_purpose;

        joiner := COALESCE(idx.joiner, ' ');

        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(marc, xfrm.xslt);
            ELSE
                transformed_xml := marc;
            END IF;

            prev_xfrm := xfrm.name;
        END IF;

        IF idx.thesaurus_xpath IS NOT NULL THEN
            base_thesaurus := ARRAY_TO_STRING(oils_xpath(idx.thesaurus_xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
        END IF;

        heading_node_list := oils_xpath( idx.heading_xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );

        FOR heading_node IN SELECT x FROM unnest(heading_node_list) AS x LOOP

            CONTINUE WHEN heading_node !~ E'^\\s*<';

            output_row.variant_type := NULL;
            output_row.related_type := NULL;
            output_row.thesaurus    := NULL;
            output_row.heading      := NULL;

            IF idx.heading_purpose = 'variant' AND idx.type_xpath IS NOT NULL THEN
                type_value := ARRAY_TO_STRING(oils_xpath(idx.type_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
                BEGIN
                    output_row.variant_type := type_value;
                EXCEPTION WHEN invalid_text_representation THEN
                    RAISE NOTICE 'Do not recognize variant heading type %', type_value;
                END;
            END IF;
            IF idx.heading_purpose = 'related' AND idx.type_xpath IS NOT NULL THEN
                type_value := ARRAY_TO_STRING(oils_xpath(idx.type_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
                BEGIN
                    output_row.related_type := type_value;
                EXCEPTION WHEN invalid_text_representation THEN
                    RAISE NOTICE 'Do not recognize related heading type %', type_value;
                END;
            END IF;

            IF idx.thesaurus_override_xpath IS NOT NULL THEN
                output_row.thesaurus := ARRAY_TO_STRING(oils_xpath(idx.thesaurus_override_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]), '');
            END IF;
            IF output_row.thesaurus IS NULL THEN
                output_row.thesaurus := base_thesaurus;
            END IF;

            raw_text := NULL;

            -- now iterate over components of heading
            component_node_list := oils_xpath( idx.component_xpath, heading_node, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
            FOR component_node IN SELECT x FROM unnest(component_node_list) AS x LOOP
            -- XXX much of this should be moved into oils_xpath_string...
                curr_text := ARRAY_TO_STRING(array_remove(array_remove(
                    oils_xpath( '//text()', -- get the content of all the nodes within the main selected node
                        REGEXP_REPLACE( component_node, E'\\s+', ' ', 'g' ) -- Translate adjacent whitespace to a single space
                    ), ' '), ''),  -- throw away morally empty (bankrupt?) strings
                    joiner
                );

                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;
            END LOOP;

            IF raw_text IS NOT NULL THEN
                output_row.heading := raw_text;
                normalized_text := raw_text;

                FOR normalizer IN
                    SELECT  n.func AS func,
                            n.param_count AS param_count,
                            m.params AS params
                    FROM  config.index_normalizer n
                            JOIN authority.heading_field_norm_map m ON (m.norm = n.id)
                    WHERE m.field = idx.id
                    ORDER BY m.pos LOOP

                        EXECUTE 'SELECT ' || normalizer.func || '(' ||
                            quote_literal( normalized_text ) ||
                            CASE
                                WHEN normalizer.param_count > 0
                                    THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
                                    ELSE ''
                                END ||
                            ')' INTO normalized_text;

                END LOOP;

                output_row.normalized_heading := normalized_text;

                RETURN NEXT output_row;
            END IF;
        END LOOP;

    END LOOP;
END;

extract_headings

Signature: authority.extract_headings(rid bigint, restrict integer[] DEFAULT NULL::integer[])

Returns: SETOF authority.heading

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    auth        authority.record_entry%ROWTYPE;
    output_row  authority.heading;
BEGIN
    -- Get the record
    SELECT INTO auth * FROM authority.record_entry WHERE id = rid;

    RETURN QUERY SELECT * FROM authority.extract_headings(auth.marc, restrict);
END;

extract_thesaurus

Signature: authority.extract_thesaurus(marcxml text)

Returns: text

Language

plpgsql

Volatility

STABLE

Strict

Yes (returns NULL on NULL input)

Security Definer

No

DECLARE
    thes_code TEXT;
BEGIN
    thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
    IF thes_code IS NULL THEN
        thes_code := '|';
    ELSIF thes_code = 'z' THEN
        thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), 'z' );
    ELSE
        SELECT code INTO thes_code FROM authority.thesaurus WHERE short_code = thes_code;
        IF NOT FOUND THEN
            thes_code := '|'; -- default
        END IF;
    END IF;
    RETURN thes_code;
END;

flatten_marc

Signature: authority.flatten_marc(rid bigint)

Returns: SETOF authority.full_rec

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
	auth	authority.record_entry%ROWTYPE;
	output	authority.full_rec%ROWTYPE;
	field	RECORD;
BEGIN
	SELECT INTO auth * FROM authority.record_entry WHERE id = rid;

	FOR field IN SELECT * FROM vandelay.flatten_marc( auth.marc ) LOOP
		output.record := rid;
		output.ind1 := field.ind1;
		output.ind2 := field.ind2;
		output.tag := field.tag;
		output.subfield := field.subfield;
		output.value := field.value;

		RETURN NEXT output;
	END LOOP;
END;

generate_overlay_template

Signature: authority.generate_overlay_template(bigint)

Returns: text

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT authority.generate_overlay_template( marc ) FROM authority.record_entry WHERE id = $1;

generate_overlay_template

Signature: authority.generate_overlay_template(source_xml text)

Returns: text

Language

plpgsql

Volatility

STABLE

Strict

No

Security Definer

No

DECLARE
    cset                INT;
    main_entry          authority.control_set_authority_field%ROWTYPE;
    bib_field           authority.control_set_bib_field%ROWTYPE;
    auth_id             INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT;
    tmp_data            XML;
    replace_data        XML[] DEFAULT '{}'::XML[];
    replace_rules       TEXT[] DEFAULT '{}'::TEXT[];
    auth_field          XML[];
    auth_i1             TEXT;
    auth_i2             TEXT;
BEGIN
    IF auth_id IS NULL THEN
        RETURN NULL;
    END IF;

    -- Default to the LoC crontrol set
    SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;

    -- if none, make a best guess
    IF cset IS NULL THEN
        SELECT  control_set INTO cset
          FROM  authority.control_set_authority_field
          WHERE tag IN (
                    SELECT  UNNEST(XPATH('//*[local-name()="datafield" and starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[])
                      FROM  authority.record_entry
                      WHERE id = auth_id
                )
          LIMIT 1;
    END IF;

    -- if STILL none, no-op change
    IF cset IS NULL THEN
        RETURN XMLELEMENT(
            name record,
            XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
            XMLELEMENT( name leader, '00881nam a2200193   4500'),
            XMLELEMENT(
                name datafield,
                XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
                XMLELEMENT(
                    name subfield,
                    XMLATTRIBUTES('d' AS code),
                    '901c'
                )
            )
        )::TEXT;
    END IF;

    FOR main_entry IN SELECT * FROM authority.control_set_authority_field acsaf WHERE acsaf.control_set = cset AND acsaf.main_entry IS NULL ORDER BY acsaf.tag LOOP
        auth_field := XPATH('//*[local-name()="datafield" and @tag="'||main_entry.tag||'"][1]',source_xml::XML);
        auth_i1 := (XPATH('//*[local-name()="datafield"]/@ind1',auth_field[1]))[1];
        auth_i2 := (XPATH('//*[local-name()="datafield"]/@ind2',auth_field[1]))[1];
        IF ARRAY_LENGTH(auth_field,1) > 0 THEN
            FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id ORDER BY control_set_bib_field.tag LOOP
                SELECT XMLELEMENT( -- XMLAGG avoids magical <element> creation, but requires unnest subquery
                    name datafield,
                    XMLATTRIBUTES(bib_field.tag AS tag, auth_i1 AS ind1, auth_i2 AS ind2),
                    XMLAGG(UNNEST)
                ) INTO tmp_data FROM UNNEST(XPATH('//*[local-name()="subfield"]', auth_field[1]));
                replace_data := replace_data || tmp_data;
                replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' );
                tmp_data = NULL;
            END LOOP;
            EXIT;
        END IF;
    END LOOP;

    SELECT XMLAGG(UNNEST) INTO tmp_data FROM UNNEST(replace_data);

    RETURN XMLELEMENT(
        name record,
        XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
        XMLELEMENT( name leader, '00881nam a2200193   4500'),
        tmp_data,
        XMLELEMENT(
            name datafield,
            XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
            XMLELEMENT(
                name subfield,
                XMLATTRIBUTES('r' AS code),
                ARRAY_TO_STRING(replace_rules,',')
            )
        )
    )::TEXT;
END;

indexing_delete

Signature: authority.indexing_delete(auth authority.record_entry, extra text DEFAULT NULL::text)

Returns: boolean

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    tmp_bool BOOL;
    diag_detail     TEXT;
    diag_context    TEXT;
BEGIN
    DELETE FROM authority.bib_linking WHERE authority = NEW.id; -- Avoid updating fields in bibs that are no longer visible
    DELETE FROM authority.full_rec WHERE record = NEW.id; -- Avoid validating fields against deleted authority records
    DELETE FROM authority.simple_heading WHERE record = NEW.id;
      -- Should remove matching $0 from controlled fields at the same time?

    -- XXX What do we about the actual linking subfields present in
    -- authority records that target this one when this happens?
    DELETE FROM authority.authority_linking WHERE source = NEW.id OR target = NEW.id;

    RETURN TRUE;
EXCEPTION WHEN OTHERS THEN
    GET STACKED DIAGNOSTICS diag_detail  = PG_EXCEPTION_DETAIL,
                            diag_context = PG_EXCEPTION_CONTEXT;
    RAISE WARNING '%\n%', diag_detail, diag_context;
    RETURN FALSE;
END;

indexing_update

Signature: authority.indexing_update(auth authority.record_entry, insert_only boolean DEFAULT false, old_heading text DEFAULT NULL::text)

Returns: boolean

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    ashs    authority.simple_heading%ROWTYPE;
    mbe_row metabib.browse_entry%ROWTYPE;
    mbe_id  BIGINT;
    ash_id  BIGINT;
    diag_detail     TEXT;
    diag_context    TEXT;
BEGIN

    -- Unless there's a setting stopping us, propagate these updates to any linked bib records when the heading changes
    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_auto_update' AND enabled;

    IF NOT FOUND AND auth.heading <> old_heading THEN
        PERFORM authority.propagate_changes(auth.id);
    END IF;

    IF NOT insert_only THEN
        DELETE FROM authority.authority_linking WHERE source = auth.id;
        DELETE FROM authority.simple_heading WHERE record = auth.id;
    END IF;

    INSERT INTO authority.authority_linking (source, target, field)
        SELECT source, target, field FROM authority.calculate_authority_linking(
            auth.id, auth.control_set, auth.marc::XML
        );

    FOR ashs IN SELECT * FROM authority.simple_heading_set(auth.marc) LOOP

        INSERT INTO authority.simple_heading (record,atag,value,sort_value,thesaurus)
            VALUES (ashs.record, ashs.atag, ashs.value, ashs.sort_value, ashs.thesaurus);
            ash_id := CURRVAL('authority.simple_heading_id_seq'::REGCLASS);

        SELECT INTO mbe_row * FROM metabib.browse_entry
            WHERE value = ashs.value AND sort_value = ashs.sort_value;

        IF FOUND THEN
            mbe_id := mbe_row.id;
        ELSE
            INSERT INTO metabib.browse_entry
                ( value, sort_value ) VALUES
                ( ashs.value, ashs.sort_value );

            mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
        END IF;

        INSERT INTO metabib.browse_entry_simple_heading_map (entry,simple_heading) VALUES (mbe_id,ash_id);

    END LOOP;

    -- Flatten and insert the afr data
    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_full_rec' AND enabled;
    IF NOT FOUND THEN
        PERFORM authority.reingest_authority_full_rec(auth.id);
        PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_rec_descriptor' AND enabled;
        IF NOT FOUND THEN
            PERFORM authority.reingest_authority_rec_descriptor(auth.id);
        END IF;
    END IF;

    PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_symspell_reification' AND enabled;
    IF NOT FOUND THEN
        PERFORM search.symspell_dictionary_reify();
    END IF;

    RETURN TRUE;
EXCEPTION WHEN OTHERS THEN
    GET STACKED DIAGNOSTICS diag_detail  = PG_EXCEPTION_DETAIL,
                            diag_context = PG_EXCEPTION_CONTEXT;
    RAISE WARNING '%\n%', diag_detail, diag_context;
    RETURN FALSE;
END;

map_thesaurus_to_control_set

Signature: authority.map_thesaurus_to_control_set()

Returns: trigger

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

BEGIN
    IF NEW.control_set IS NULL THEN
        SELECT  control_set INTO NEW.control_set
          FROM  authority.thesaurus
          WHERE authority.extract_thesaurus(NEW.marc) = code;
    END IF;

    RETURN NEW;
END;

merge_records

Signature: authority.merge_records(target_record bigint, source_record bigint)

Returns: integer

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    moved_objects INT := 0;
    bib_id        INT := 0;
    bib_rec       biblio.record_entry%ROWTYPE;
    auth_link     authority.bib_linking%ROWTYPE;
    ingest_same   boolean;
BEGIN

    -- Defining our terms:
    -- "target record" = the record that will survive the merge
    -- "source record" = the record that is sacrifing its existence and being
    --   replaced by the target record

    -- 1. Update all bib records with the ID from target_record in their $0
    FOR bib_rec IN
            SELECT  bre.*
              FROM  biblio.record_entry bre
                    JOIN authority.bib_linking abl ON abl.bib = bre.id
              WHERE abl.authority = source_record
        LOOP

        UPDATE  biblio.record_entry
          SET   marc = REGEXP_REPLACE(
                    marc,
                    E'(<subfield\\s+code="0"\\s*>[^<]*?\\))' || source_record || '<',
                    E'\\1' || target_record || '<',
                    'g'
                )
          WHERE id = bib_rec.id;

          moved_objects := moved_objects + 1;
    END LOOP;

    -- 2. Grab the current value of reingest on same MARC flag
    SELECT  enabled INTO ingest_same
      FROM  config.internal_flag
      WHERE name = 'ingest.reingest.force_on_same_marc'
    ;

    -- 3. Temporarily set reingest on same to TRUE
    UPDATE  config.internal_flag
      SET   enabled = TRUE
      WHERE name = 'ingest.reingest.force_on_same_marc'
    ;

    -- 4. Make a harmless update to target_record to trigger auto-update
    --    in linked bibliographic records
    UPDATE  authority.record_entry
      SET   deleted = FALSE
      WHERE id = target_record;

    -- 5. "Delete" source_record
    DELETE FROM authority.record_entry WHERE id = source_record;

    -- 6. Set "reingest on same MARC" flag back to initial value
    UPDATE  config.internal_flag
      SET   enabled = ingest_same
      WHERE name = 'ingest.reingest.force_on_same_marc'
    ;

    RETURN moved_objects;
END;

normalize_heading

Signature: authority.normalize_heading(marcxml text)

Returns: text

Language

sql

Volatility

STABLE

Strict

Yes (returns NULL on NULL input)

Security Definer

No

Extract the authority heading, thesaurus, and NACO-normalized values from an authority record. The primary purpose is to build a unique index to defend against duplicated authority records from the same thesaurus.

    SELECT authority.normalize_heading($1, FALSE);

normalize_heading

Signature: authority.normalize_heading(marcxml text, no_thesaurus boolean)

Returns: text

Language

plpgsql

Volatility

STABLE

Strict

Yes (returns NULL on NULL input)

Security Definer

No

DECLARE
    acsaf           authority.control_set_authority_field%ROWTYPE;
    tag_used        TEXT;
    nfi_used        TEXT;
    sf              TEXT;
    sf_node         TEXT;
    tag_node        TEXT;
    thes_code       TEXT;
    cset            INT;
    heading_text    TEXT;
    tmp_text        TEXT;
    first_sf        BOOL;
    auth_id         INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
BEGIN
    SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;

    IF cset IS NULL THEN
        SELECT  control_set INTO cset
          FROM  authority.control_set_authority_field
          WHERE tag IN (SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
          LIMIT 1;
    END IF;

    heading_text := '';
    FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset AND main_entry IS NULL LOOP
        tag_used := acsaf.tag;
        nfi_used := acsaf.nfi;
        first_sf := TRUE;

        FOR tag_node IN SELECT unnest(oils_xpath('//*[@tag="'||tag_used||'"]',marcxml))
        LOOP
            FOR sf_node IN SELECT unnest(oils_xpath('//*[local-name() = "subfield" and contains("'||acsaf.sf_list||'",@code)]',tag_node))
            LOOP

                tmp_text := oils_xpath_string('.', sf_node);
                sf := oils_xpath_string('//*/@code', sf_node);

                IF first_sf AND tmp_text IS NOT NULL AND nfi_used IS NOT NULL THEN

                    tmp_text := SUBSTRING(
                        tmp_text FROM
                        COALESCE(
                            NULLIF(
                                REGEXP_REPLACE(
                                    oils_xpath_string('//*[local-name() = "datafield"]/@ind'||nfi_used, tag_node),
                                    $$\D+$$,
                                    '',
                                    'g'
                                ),
                                ''
                            )::INT,
                            0
                        ) + 1
                    );

                END IF;

                first_sf := FALSE;

                IF tmp_text IS NOT NULL AND tmp_text <> '' THEN
                    heading_text := heading_text || E'\u2021' || sf || ' ' || tmp_text;
                END IF;
            END LOOP;

            EXIT WHEN heading_text <> '';
        END LOOP;

        EXIT WHEN heading_text <> '';
    END LOOP;

    IF heading_text <> '' THEN
        IF no_thesaurus IS TRUE THEN
            heading_text := tag_used || ' ' || public.naco_normalize(heading_text);
        ELSE
            thes_code := authority.extract_thesaurus(marcxml);
            heading_text := tag_used || '_' || COALESCE(nfi_used,'-') || '_' || thes_code || ' ' || public.naco_normalize(heading_text);
        END IF;
    ELSE
        heading_text := 'NOHEADING_' || thes_code || ' ' || MD5(marcxml);
    END IF;

    RETURN heading_text;
END;

normalize_heading_for_upsert

Signature: authority.normalize_heading_for_upsert()

Returns: trigger

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

BEGIN
    NEW.heading := authority.normalize_heading( NEW.marc );
    NEW.simple_heading := authority.simple_normalize_heading( NEW.marc );
    RETURN NEW;
END;

propagate_changes

Signature: authority.propagate_changes(aid bigint)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT authority.propagate_changes( authority, bib ) FROM authority.bib_linking WHERE authority = $1;

propagate_changes

Signature: authority.propagate_changes(aid bigint, bid bigint)

Returns: bigint

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    queuing_success BOOL := FALSE;
BEGIN

    PERFORM 1 FROM config.global_flag
        WHERE name IN ('ingest.queued.all','ingest.queued.authority.propagate')
            AND enabled;

    IF FOUND THEN
        -- XXX enqueue special 'propagate' bib action
        SELECT action.enqueue_ingest_entry( bid, 'biblio', NOW(), NULL, 'propagate', aid::TEXT) INTO queuing_success;

        IF queuing_success THEN
            RETURN aid;
        END IF;
    END IF;

    PERFORM authority.apply_propagate_changes(aid, bid);
    RETURN aid;
END;

reingest_authority_full_rec

Signature: authority.reingest_authority_full_rec(auth_id bigint)

Returns: void

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

BEGIN
    DELETE FROM authority.full_rec WHERE record = auth_id;
    INSERT INTO authority.full_rec (record, tag, ind1, ind2, subfield, value)
        SELECT record, tag, ind1, ind2, subfield, value FROM authority.flatten_marc( auth_id );

    RETURN;
END;

reingest_authority_rec_descriptor

Signature: authority.reingest_authority_rec_descriptor(auth_id bigint)

Returns: void

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

BEGIN
    DELETE FROM authority.rec_descriptor WHERE record = auth_id;
    INSERT INTO authority.rec_descriptor (record, record_status, encoding_level, thesaurus)
        SELECT  auth_id,
                vandelay.marc21_extract_fixed_field(marc,'RecStat'),
                vandelay.marc21_extract_fixed_field(marc,'ELvl'),
                authority.extract_thesaurus(marc)
          FROM  authority.record_entry
          WHERE id = auth_id;
    RETURN;
END;

simple_heading_browse_center

Signature: authority.simple_heading_browse_center(atag_list integer[], q text, page integer DEFAULT 0, pagesize integer DEFAULT 9, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    pivot_sort_value    TEXT;
    boffset             INT DEFAULT 0;
    aoffset             INT DEFAULT 0;
    blimit              INT DEFAULT 0;
    alimit              INT DEFAULT 0;
BEGIN

    pivot_sort_value := authority.simple_heading_find_pivot(atag_list,q,thesauruses);

    IF page = 0 THEN
        blimit := pagesize / 2;
        alimit := blimit;

        IF pagesize % 2 <> 0 THEN
            alimit := alimit + 1;
        END IF;
    ELSE
        blimit := pagesize;
        alimit := blimit;

        boffset := pagesize / 2;
        aoffset := boffset;

        IF pagesize % 2 <> 0 THEN
            boffset := boffset + 1;
        END IF;
    END IF;

    IF page <= 0 THEN
        RETURN QUERY
            -- "bottom" half of the browse results
            SELECT id FROM (
                SELECT  ash.id,
                        row_number() over ()
                  FROM  authority.simple_heading ash
                  WHERE ash.atag = ANY (atag_list)
                        AND CASE thesauruses
                            WHEN '' THEN TRUE
                            ELSE ash.thesaurus = ANY(regexp_split_to_array(thesauruses, ','))
                            END
                        AND ash.sort_value < pivot_sort_value
                  ORDER BY ash.sort_value DESC
                  LIMIT blimit
                  OFFSET ABS(page) * pagesize - boffset
            ) x ORDER BY row_number DESC;
    END IF;

    IF page >= 0 THEN
        RETURN QUERY
            -- "bottom" half of the browse results
            SELECT  ash.id
              FROM  authority.simple_heading ash
              WHERE ash.atag = ANY (atag_list)
                    AND CASE thesauruses
                        WHEN '' THEN TRUE
                        ELSE ash.thesaurus = ANY(regexp_split_to_array(thesauruses, ','))
                        END
                    AND ash.sort_value >= pivot_sort_value
              ORDER BY ash.sort_value
              LIMIT alimit
              OFFSET ABS(page) * pagesize - aoffset;
    END IF;
END;

simple_heading_browse_top

Signature: authority.simple_heading_browse_top(atag_list integer[], q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    pivot_sort_value    TEXT;
BEGIN

    pivot_sort_value := authority.simple_heading_find_pivot(atag_list,q,thesauruses);

    IF page < 0 THEN
        RETURN QUERY
            -- "bottom" half of the browse results
            SELECT id FROM (
                SELECT  ash.id,
                        row_number() over ()
                  FROM  authority.simple_heading ash
                  WHERE ash.atag = ANY (atag_list)
                        AND CASE thesauruses
                            WHEN '' THEN TRUE
                            ELSE ash.thesaurus = ANY(regexp_split_to_array(thesauruses, ','))
                            END
                        AND ash.sort_value < pivot_sort_value
                  ORDER BY ash.sort_value DESC
                  LIMIT pagesize
                  OFFSET (ABS(page) - 1) * pagesize
            ) x ORDER BY row_number DESC;
    END IF;

    IF page >= 0 THEN
        RETURN QUERY
            -- "bottom" half of the browse results
            SELECT  ash.id
              FROM  authority.simple_heading ash
              WHERE ash.atag = ANY (atag_list)
                AND CASE thesauruses
                    WHEN '' THEN TRUE
                    ELSE ash.thesaurus = ANY(regexp_split_to_array(thesauruses, ','))
                    END
                    AND ash.sort_value >= pivot_sort_value
              ORDER BY ash.sort_value
              LIMIT pagesize
              OFFSET ABS(page) * pagesize ;
    END IF;
END;

simple_heading_find_pivot

Signature: authority.simple_heading_find_pivot(a integer[], q text, thesauruses text DEFAULT ''::text)

Returns: text

Language

plpgsql

Volatility

VOLATILE

Strict

No

Security Definer

No

DECLARE
    sort_value_row  RECORD;
    value_row       RECORD;
    t_term          TEXT;
BEGIN

    t_term := public.naco_normalize(q);

    SELECT  CASE WHEN ash.sort_value LIKE t_term || '%' THEN 1 ELSE 0 END
                + CASE WHEN ash.value LIKE t_term || '%' THEN 1 ELSE 0 END AS rank,
            ash.sort_value
      INTO  sort_value_row
      FROM  authority.simple_heading ash
      WHERE ash.atag = ANY (a)
            AND ash.sort_value >= t_term
            AND CASE thesauruses
                WHEN '' THEN TRUE
                ELSE ash.thesaurus = ANY(regexp_split_to_array(thesauruses, ','))
                END
      ORDER BY rank DESC, ash.sort_value
      LIMIT 1;

    SELECT  CASE WHEN ash.sort_value LIKE t_term || '%' THEN 1 ELSE 0 END
                + CASE WHEN ash.value LIKE t_term || '%' THEN 1 ELSE 0 END AS rank,
            ash.sort_value
      INTO  value_row
      FROM  authority.simple_heading ash
      WHERE ash.atag = ANY (a)
            AND ash.value >= t_term
            AND CASE thesauruses
                WHEN '' THEN TRUE
                ELSE ash.thesaurus = ANY(regexp_split_to_array(thesauruses, ','))
                END
      ORDER BY rank DESC, ash.sort_value
      LIMIT 1;

    IF value_row.rank > sort_value_row.rank THEN
        RETURN value_row.sort_value;
    ELSE
        RETURN sort_value_row.sort_value;
    END IF;
END;

simple_heading_search_heading

Signature: authority.simple_heading_search_heading(atag_list integer[], q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT  ash.id
      FROM  authority.simple_heading ash,
            public.naco_normalize($2) t(term),
            plainto_tsquery('keyword'::regconfig,$2) ptsq(term)
      WHERE ash.atag = ANY ($1)
            AND ash.index_vector @@ ptsq.term
            AND CASE $5
                WHEN '' THEN TRUE
                ELSE ash.thesaurus = ANY(regexp_split_to_array($5, ','))
                END
      ORDER BY ash.sort_value
      LIMIT $4
      OFFSET $4 * $3;

simple_heading_search_rank

Signature: authority.simple_heading_search_rank(atag_list integer[], q text, page integer DEFAULT 0, pagesize integer DEFAULT 10, thesauruses text DEFAULT ''::text)

Returns: SETOF bigint

Language

sql

Volatility

VOLATILE

Strict

No

Security Definer

No

    SELECT  ash.id
      FROM  authority.simple_heading ash,
            public.naco_normalize($2) t(term),
            plainto_tsquery('keyword'::regconfig,$2) ptsq(term)
      WHERE ash.atag = ANY ($1)
            AND ash.index_vector @@ ptsq.term
            AND CASE $5
                WHEN '' THEN TRUE
                ELSE ash.thesaurus = ANY(regexp_split_to_array($5, ','))
                END
      ORDER BY ts_rank_cd(ash.index_vector,ptsq.term,14)::numeric
                    + CASE WHEN ash.sort_value LIKE t.term || '%' THEN 2 ELSE 0 END
                    + CASE WHEN ash.value LIKE t.term || '%' THEN 1 ELSE 0 END DESC
      LIMIT $4
      OFFSET $4 * $3;

simple_heading_set

Signature: authority.simple_heading_set(marcxml text)

Returns: SETOF authority.simple_heading

Language

plpgsql

Volatility

STABLE

Strict

Yes (returns NULL on NULL input)

Security Definer

No

DECLARE
    res             authority.simple_heading%ROWTYPE;
    acsaf           authority.control_set_authority_field%ROWTYPE;
    heading_row     authority.heading%ROWTYPE;
    tag_used        TEXT;
    nfi_used        TEXT;
    sf              TEXT;
    cset            INT;
    heading_text    TEXT;
    joiner_text     TEXT;
    sort_text       TEXT;
    tmp_text        TEXT;
    tmp_xml         TEXT;
    first_sf        BOOL;
    auth_id         INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
BEGIN

    SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;

    IF cset IS NULL THEN
        SELECT  control_set INTO cset
          FROM  authority.control_set_authority_field
          WHERE tag IN ( SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
          LIMIT 1;
    END IF;

    res.record := auth_id;
    res.thesaurus := authority.extract_thesaurus(marcxml);

    FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
        res.atag := acsaf.id;

        IF acsaf.heading_field IS NULL THEN
            tag_used := acsaf.tag;
            nfi_used := acsaf.nfi;
            joiner_text := COALESCE(acsaf.joiner, ' ');

            FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)::TEXT[]) LOOP

                heading_text := COALESCE(
                    oils_xpath_string('//*[local-name()="subfield" and contains("'||acsaf.display_sf_list||'",@code)]', tmp_xml, joiner_text),
                    ''
                );

                IF nfi_used IS NOT NULL THEN

                    sort_text := SUBSTRING(
                        heading_text FROM
                        COALESCE(
                            NULLIF(
                                REGEXP_REPLACE(
                                    oils_xpath_string('//*[local-name()="datafield"]/@ind'||nfi_used, tmp_xml::TEXT),
                                    $$\D+$$,
                                    '',
                                    'g'
                                ),
                                ''
                            )::INT,
                            0
                        ) + 1
                    );

                ELSE
                    sort_text := heading_text;
                END IF;

                IF heading_text IS NOT NULL AND heading_text <> '' THEN
                    res.value := heading_text;
                    res.sort_value := public.naco_normalize(sort_text);
                    res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
                    RETURN NEXT res;
                END IF;

            END LOOP;
        ELSE
            FOR heading_row IN SELECT * FROM authority.extract_headings(marcxml, ARRAY[acsaf.heading_field]) LOOP
                res.value := heading_row.heading;
                res.sort_value := heading_row.normalized_heading;
                res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
                RETURN NEXT res;
            END LOOP;
        END IF;
    END LOOP;

    RETURN;
END;

simple_normalize_heading

Signature: authority.simple_normalize_heading(marcxml text)

Returns: text

Language

sql

Volatility

STABLE

Strict

Yes (returns NULL on NULL input)

Security Definer

No

    SELECT authority.normalize_heading($1, TRUE);