<?xml version="1.0" encoding="UTF-8"?><database name="egdb3_11_7" schema="actor" type="PostgreSQL - 15.10 (Ubuntu 15.10-1.pgdg24.04+1)">
   <sequences>
      <sequence increment="1" name="address_alert_id_seq" startValue="1"/>
      <sequence increment="1" name="card_id_seq" startValue="1"/>
      <sequence increment="1" name="copy_alert_suppress_id_seq" startValue="1"/>
      <sequence increment="1" name="org_address_id_seq" startValue="1"/>
      <sequence increment="1" name="org_lasso_id_seq" startValue="1"/>
      <sequence increment="1" name="org_lasso_map_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_closed_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_custom_tree_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_custom_tree_node_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_proximity_adjustment_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_proximity_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_setting_id_seq" startValue="1"/>
      <sequence increment="1" name="org_unit_type_id_seq" startValue="1"/>
      <sequence increment="1" name="passwd_id_seq" startValue="1"/>
      <sequence increment="1" name="search_filter_group_entry_id_seq" startValue="1"/>
      <sequence increment="1" name="search_filter_group_id_seq" startValue="1"/>
      <sequence increment="1" name="search_query_id_seq" startValue="1"/>
      <sequence increment="1" name="stat_cat_entry_default_id_seq" startValue="1"/>
      <sequence increment="1" name="stat_cat_entry_id_seq" startValue="1"/>
      <sequence increment="1" name="stat_cat_entry_usr_map_id_seq" startValue="1"/>
      <sequence increment="1" name="stat_cat_id_seq" startValue="1"/>
      <sequence increment="1" name="toolbar_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_activity_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_address_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_message_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_org_unit_opt_in_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_password_reset_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_privacy_waiver_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_saved_search_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_setting_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_standing_penalty_id_seq" startValue="1"/>
      <sequence increment="1" name="usr_usrgroup_seq" startValue="1"/>
      <sequence increment="1" name="workstation_id_seq" startValue="1"/>
      <sequence increment="1" name="workstation_setting_id_seq" startValue="1"/>
   </sequences>
   <tables>
      <table name="address_alert" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.address_alert_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="owner" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="address_alert_owner_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="true" digits="0" id="2" name="active" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="true" digits="0" id="3" name="match_all" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="alert_message" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="street1" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="street2" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="city" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="county" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="state" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="country" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="11" name="post_code" nullable="true" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="passwd_type"/>
         </column>
         <column autoUpdated="false" defaultValue="false" digits="0" id="12" name="mailing_address" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="13" name="billing_address" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="address_alert_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
      </table>
      <table name="card" numRows="380" remarks="Library Cards&#10;&#10;Each User has one or more library cards.  The current &quot;main&quot;&#10;card is linked to here from the actor.usr table, and it is up&#10;to the consortium policy whether more than one card can be&#10;active for any one user at a given time." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.card_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="card_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="barcode" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="true" digits="0" id="3" name="active" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="card_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_card_barcode_evergreen_lowercase_idx" unique="false"/>
         <index name="actor_card_usr_idx" unique="false">
            <column ascending="true" name="usr"/>
         </index>
         <index name="card_barcode_key" unique="true">
            <column ascending="true" name="barcode"/>
         </index>
      </table>
      <table name="copy_alert_suppress" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.copy_alert_suppress_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="org" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="copy_alert_suppress_org_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="alert_type" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="copy_alert_suppress_alert_type_fkey" implied="false" onDeleteCascade="true" schema="config" table="copy_alert_type"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="copy_alert_suppress_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
      </table>
      <table name="hours_of_operation" remarks="When does this org_unit usually open and close?  (Variations&#10;are expressed in the actor.org_unit_closed table.)" schema="actor" type="TABLE">
         <column autoUpdated="false" defaultValue="null" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="hours_of_operation_id_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="'09:00:00'::time without time zone" digits="6" id="1" name="dow_0_open" nullable="false" remarks="When does this org_unit open on Monday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="'17:00:00'::time without time zone" digits="6" id="2" name="dow_0_close" nullable="false" remarks="When does this org_unit close on Monday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="dow_0_note" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="'09:00:00'::time without time zone" digits="6" id="4" name="dow_1_open" nullable="false" remarks="When does this org_unit open on Tuesday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="'17:00:00'::time without time zone" digits="6" id="5" name="dow_1_close" nullable="false" remarks="When does this org_unit close on Tuesday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="dow_1_note" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="'09:00:00'::time without time zone" digits="6" id="7" name="dow_2_open" nullable="false" remarks="When does this org_unit open on Wednesday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="'17:00:00'::time without time zone" digits="6" id="8" name="dow_2_close" nullable="false" remarks="When does this org_unit close on Wednesday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="dow_2_note" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="'09:00:00'::time without time zone" digits="6" id="10" name="dow_3_open" nullable="false" remarks="When does this org_unit open on Thursday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="'17:00:00'::time without time zone" digits="6" id="11" name="dow_3_close" nullable="false" remarks="When does this org_unit close on Thursday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="12" name="dow_3_note" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="'09:00:00'::time without time zone" digits="6" id="13" name="dow_4_open" nullable="false" remarks="When does this org_unit open on Friday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="'17:00:00'::time without time zone" digits="6" id="14" name="dow_4_close" nullable="false" remarks="When does this org_unit close on Friday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="15" name="dow_4_note" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="'09:00:00'::time without time zone" digits="6" id="16" name="dow_5_open" nullable="false" remarks="When does this org_unit open on Saturday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="'17:00:00'::time without time zone" digits="6" id="17" name="dow_5_close" nullable="false" remarks="When does this org_unit close on Saturday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="18" name="dow_5_note" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="'09:00:00'::time without time zone" digits="6" id="19" name="dow_6_open" nullable="false" remarks="When does this org_unit open on Sunday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="'17:00:00'::time without time zone" digits="6" id="20" name="dow_6_close" nullable="false" remarks="When does this org_unit close on Sunday?" size="15" type="time" typeCode="92"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="21" name="dow_6_note" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="hours_of_operation_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
      </table>
      <table name="org_address" numRows="70" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_address_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="billing_address" foreignKey="actor_org_unit_billing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
            <child column="holds_address" foreignKey="actor_org_unit_holds_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
            <child column="ill_address" foreignKey="actor_org_unit_ill_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
            <child column="mailing_address" foreignKey="actor_org_unit_mailing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="true" digits="0" id="1" name="valid" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="'MAILING'::text" digits="0" id="2" name="address_type" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="org_unit" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_address_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="street1" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="street2" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="city" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="county" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="state" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="country" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="post_code" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="passwd_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="11" name="san" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="17" id="12" name="latitude" nullable="true" remarks="" size="17" type="float8" typeCode="8"/>
         <column autoUpdated="false" defaultValue="null" digits="17" id="13" name="longitude" nullable="true" remarks="" size="17" type="float8" typeCode="8"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_address_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_org_address_org_unit_idx" unique="false">
            <column ascending="true" name="org_unit"/>
         </index>
      </table>
      <table name="org_lasso" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_lasso_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="lasso" foreignKey="org_lasso_map_lasso_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_lasso_map"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="name" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="2" name="global" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_lasso_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="org_lasso_name_key" unique="true">
            <column ascending="true" name="name"/>
         </index>
      </table>
      <table name="org_lasso_map" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_lasso_map_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="lasso" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_lasso_map_lasso_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_lasso"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="org_unit" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_lasso_map_org_unit_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_lasso_map_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="ou_lasso_lasso_ou_idx" unique="true">
            <column ascending="true" name="lasso"/>
            <column ascending="true" name="org_unit"/>
         </index>
         <index name="ou_lasso_org_unit_idx" unique="false">
            <column ascending="true" name="org_unit"/>
         </index>
      </table>
      <table name="org_unit" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="org_unit" foreignKey="cancel_reason_org_unit_fkey" implied="false" onDeleteCascade="false" schema="acq" table="cancel_reason"/>
            <child column="org_unit" foreignKey="claim_event_type_org_unit_fkey" implied="false" onDeleteCascade="false" schema="acq" table="claim_event_type"/>
            <child column="org_unit" foreignKey="claim_policy_org_unit_fkey" implied="false" onDeleteCascade="false" schema="acq" table="claim_policy"/>
            <child column="org_unit" foreignKey="claim_type_org_unit_fkey" implied="false" onDeleteCascade="false" schema="acq" table="claim_type"/>
            <child column="owner" foreignKey="distribution_formula_owner_fkey" implied="false" onDeleteCascade="false" schema="acq" table="distribution_formula"/>
            <child column="owning_lib" foreignKey="distribution_formula_entry_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="acq" table="distribution_formula_entry"/>
            <child column="org" foreignKey="fund_org_fkey" implied="false" onDeleteCascade="true" schema="acq" table="fund"/>
            <child column="org" foreignKey="fund_allocation_percent_org_fkey" implied="false" onDeleteCascade="false" schema="acq" table="fund_allocation_percent"/>
            <child column="owner" foreignKey="fund_tag_owner_fkey" implied="false" onDeleteCascade="false" schema="acq" table="fund_tag"/>
            <child column="owner" foreignKey="funding_source_owner_fkey" implied="false" onDeleteCascade="false" schema="acq" table="funding_source"/>
            <child column="receiver" foreignKey="invoice_receiver_fkey" implied="false" onDeleteCascade="false" schema="acq" table="invoice"/>
            <child column="owning_lib" foreignKey="lineitem_alert_text_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem_alert_text"/>
            <child column="owning_lib" foreignKey="lineitem_detail_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem_detail"/>
            <child column="org_unit" foreignKey="picklist_org_unit_fkey" implied="false" onDeleteCascade="false" schema="acq" table="picklist"/>
            <child column="owner" foreignKey="provider_owner_fkey" implied="false" onDeleteCascade="false" schema="acq" table="provider"/>
            <child column="ordering_agency" foreignKey="purchase_order_ordering_agency_fkey" implied="false" onDeleteCascade="false" schema="acq" table="purchase_order"/>
            <child column="receiver" foreignKey="shipment_notification_receiver_fkey" implied="false" onDeleteCascade="false" schema="acq" table="shipment_notification"/>
            <child column="pickup_lib" foreignKey="user_request_pickup_lib_fkey" implied="false" onDeleteCascade="false" schema="acq" table="user_request"/>
            <child column="circ_lib" foreignKey="action_circulation_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="action" table="circulation"/>
            <child column="org" foreignKey="curbside_org_fkey" implied="false" onDeleteCascade="true" schema="action" table="curbside"/>
            <child column="owning_lib" foreignKey="fieldset_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="action" table="fieldset"/>
            <child column="owning_lib" foreignKey="fieldset_group_owning_lib_fkey" implied="false" onDeleteCascade="true" schema="action" table="fieldset_group"/>
            <child column="current_shelf_lib" foreignKey="hold_request_current_shelf_lib_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_request"/>
            <child column="fulfillment_lib" foreignKey="hold_request_fulfillment_lib_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_request"/>
            <child column="pickup_lib" foreignKey="hold_request_pickup_lib_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_request"/>
            <child column="request_lib" foreignKey="hold_request_request_lib_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_request"/>
            <child column="org_unit" foreignKey="in_house_use_org_unit_fkey" implied="false" onDeleteCascade="false" schema="action" table="in_house_use"/>
            <child column="org_unit" foreignKey="non_cat_in_house_use_org_unit_fkey" implied="false" onDeleteCascade="false" schema="action" table="non_cat_in_house_use"/>
            <child column="circ_lib" foreignKey="non_cataloged_circulation_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="action" table="non_cataloged_circulation"/>
            <child column="owner" foreignKey="survey_owner_fkey" implied="false" onDeleteCascade="false" schema="action" table="survey"/>
            <child column="dest" foreignKey="transit_copy_dest_fkey" implied="false" onDeleteCascade="false" schema="action" table="transit_copy"/>
            <child column="prev_dest" foreignKey="transit_copy_prev_dest_fkey" implied="false" onDeleteCascade="false" schema="action" table="transit_copy"/>
            <child column="source" foreignKey="transit_copy_source_fkey" implied="false" onDeleteCascade="false" schema="action" table="transit_copy"/>
            <child column="context_library" foreignKey="event_context_library_fkey" implied="false" onDeleteCascade="false" schema="action_trigger" table="event"/>
            <child column="owner" foreignKey="event_def_group_owner_fkey" implied="false" onDeleteCascade="false" schema="action_trigger" table="event_def_group"/>
            <child column="owner" foreignKey="event_definition_owner_fkey" implied="false" onDeleteCascade="false" schema="action_trigger" table="event_definition"/>
            <child column="owner" foreignKey="address_alert_owner_fkey" implied="false" onDeleteCascade="false" schema="actor" table="address_alert"/>
            <child column="org" foreignKey="copy_alert_suppress_org_fkey" implied="false" onDeleteCascade="true" schema="actor" table="copy_alert_suppress"/>
            <child column="id" foreignKey="hours_of_operation_id_fkey" implied="false" onDeleteCascade="true" schema="actor" table="hours_of_operation"/>
            <child column="org_unit" foreignKey="org_address_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_address"/>
            <child column="org_unit" foreignKey="org_lasso_map_org_unit_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_lasso_map"/>
            <child column="parent_ou" foreignKey="org_unit_parent_ou_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
            <child column="org_unit" foreignKey="org_unit_closed_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_closed"/>
            <child column="org_unit" foreignKey="org_unit_custom_tree_node_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_custom_tree_node"/>
            <child column="hold_pickup_lib" foreignKey="org_unit_proximity_adjustment_hold_pickup_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_proximity_adjustment"/>
            <child column="hold_request_lib" foreignKey="org_unit_proximity_adjustment_hold_request_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_proximity_adjustment"/>
            <child column="item_circ_lib" foreignKey="org_unit_proximity_adjustment_item_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_proximity_adjustment"/>
            <child column="item_owning_lib" foreignKey="org_unit_proximity_adjustment_item_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_proximity_adjustment"/>
            <child column="org_unit" foreignKey="org_unit_setting_org_unit_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit_setting"/>
            <child column="owner" foreignKey="search_filter_group_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="search_filter_group"/>
            <child column="owner" foreignKey="actor_stat_cat_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat"/>
            <child column="owner" foreignKey="actor_stat_cat_entry_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat_entry"/>
            <child column="owner" foreignKey="stat_cat_entry_default_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat_entry_default"/>
            <child column="org" foreignKey="toolbar_org_fkey" implied="false" onDeleteCascade="true" schema="actor" table="toolbar"/>
            <child column="home_ou" foreignKey="actor_usr_home_ou_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
            <child column="sending_lib" foreignKey="usr_message_sending_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_message"/>
            <child column="org_unit" foreignKey="usr_org_unit_opt_in_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_org_unit_opt_in"/>
            <child column="org_unit" foreignKey="usr_standing_penalty_org_unit_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr_standing_penalty"/>
            <child column="owning_lib" foreignKey="workstation_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="workstation"/>
            <child column="owning_lib" foreignKey="asset_call_number_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="call_number"/>
            <child column="owning_lib" foreignKey="call_number_prefix_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="call_number_prefix"/>
            <child column="owning_lib" foreignKey="call_number_suffix_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="call_number_suffix"/>
            <child column="circ_lib" foreignKey="copy_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy"/>
            <child column="owning_lib" foreignKey="copy_location_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_location"/>
            <child column="owner" foreignKey="copy_location_group_owner_fkey" implied="false" onDeleteCascade="true" schema="asset" table="copy_location_group"/>
            <child column="org" foreignKey="copy_location_order_org_fkey" implied="false" onDeleteCascade="true" schema="asset" table="copy_location_order"/>
            <child column="owner" foreignKey="copy_tag_owner_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_tag"/>
            <child column="circ_lib" foreignKey="copy_template_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_template"/>
            <child column="owning_lib" foreignKey="copy_template_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_template"/>
            <child column="owning_lib" foreignKey="course_module_course_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="course_module_course"/>
            <child column="original_circ_lib" foreignKey="course_module_course_materials_original_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="course_module_course_materials"/>
            <child column="owning_lib" foreignKey="course_module_term_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="asset" table="course_module_term"/>
            <child column="owner" foreignKey="a_sc_owner_fkey" implied="false" onDeleteCascade="true" schema="asset" table="stat_cat"/>
            <child column="owner" foreignKey="a_sce_owner_fkey" implied="false" onDeleteCascade="true" schema="asset" table="stat_cat_entry"/>
            <child column="owner" foreignKey="biblio_record_entry_owner_fkey" implied="false" onDeleteCascade="false" schema="biblio" table="record_entry"/>
            <child column="pickup_lib" foreignKey="reservation_pickup_lib_fkey" implied="false" onDeleteCascade="false" schema="booking" table="reservation"/>
            <child column="request_lib" foreignKey="reservation_request_lib_fkey" implied="false" onDeleteCascade="false" schema="booking" table="reservation"/>
            <child column="owner" foreignKey="resource_owner_fkey" implied="false" onDeleteCascade="false" schema="booking" table="resource"/>
            <child column="owner" foreignKey="resource_attr_owner_fkey" implied="false" onDeleteCascade="false" schema="booking" table="resource_attr"/>
            <child column="owner" foreignKey="resource_attr_value_owner_fkey" implied="false" onDeleteCascade="false" schema="booking" table="resource_attr_value"/>
            <child column="owner" foreignKey="resource_type_owner_fkey" implied="false" onDeleteCascade="false" schema="booking" table="resource_type"/>
            <child column="org_unit" foreignKey="config_barcode_completion_org_unit_fkey" implied="false" onDeleteCascade="true" schema="config" table="barcode_completion"/>
            <child column="owner" foreignKey="config_billing_type_owner_fkey" implied="false" onDeleteCascade="true" schema="config" table="billing_type"/>
            <child column="owning_lib" foreignKey="circ_limit_set_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="config" table="circ_limit_set"/>
            <child column="copy_circ_lib" foreignKey="circ_matrix_matchpoint_copy_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="config" table="circ_matrix_matchpoint"/>
            <child column="copy_owning_lib" foreignKey="circ_matrix_matchpoint_copy_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="config" table="circ_matrix_matchpoint"/>
            <child column="org_unit" foreignKey="circ_matrix_matchpoint_org_unit_fkey" implied="false" onDeleteCascade="false" schema="config" table="circ_matrix_matchpoint"/>
            <child column="user_home_ou" foreignKey="circ_matrix_matchpoint_user_home_ou_fkey" implied="false" onDeleteCascade="false" schema="config" table="circ_matrix_matchpoint"/>
            <child column="scope_org" foreignKey="copy_alert_type_scope_org_fkey" implied="false" onDeleteCascade="true" schema="config" table="copy_alert_type"/>
            <child column="owner" foreignKey="copy_tag_type_owner_fkey" implied="false" onDeleteCascade="false" schema="config" table="copy_tag_type"/>
            <child column="owning_lib" foreignKey="config_filter_dialog_filter_set_owning_lib_fkey" implied="false" onDeleteCascade="true" schema="config" table="filter_dialog_filter_set"/>
            <child column="org_unit" foreignKey="floating_group_member_org_unit_fkey" implied="false" onDeleteCascade="false" schema="config" table="floating_group_member"/>
            <child column="owner" foreignKey="cgs_owner_fkey" implied="false" onDeleteCascade="false" schema="config" table="geolocation_service"/>
            <child column="item_circ_ou" foreignKey="hold_matrix_matchpoint_item_circ_ou_fkey" implied="false" onDeleteCascade="false" schema="config" table="hold_matrix_matchpoint"/>
            <child column="item_owning_ou" foreignKey="hold_matrix_matchpoint_item_owning_ou_fkey" implied="false" onDeleteCascade="false" schema="config" table="hold_matrix_matchpoint"/>
            <child column="pickup_ou" foreignKey="hold_matrix_matchpoint_pickup_ou_fkey" implied="false" onDeleteCascade="false" schema="config" table="hold_matrix_matchpoint"/>
            <child column="request_ou" foreignKey="hold_matrix_matchpoint_request_ou_fkey" implied="false" onDeleteCascade="false" schema="config" table="hold_matrix_matchpoint"/>
            <child column="user_home_ou" foreignKey="hold_matrix_matchpoint_user_home_ou_fkey" implied="false" onDeleteCascade="false" schema="config" table="hold_matrix_matchpoint"/>
            <child column="owner" foreignKey="idl_field_doc_owner_fkey" implied="false" onDeleteCascade="true" schema="config" table="idl_field_doc"/>
            <child column="owner" foreignKey="config_marc_field_owner_fkey" implied="false" onDeleteCascade="false" schema="config" table="marc_field"/>
            <child column="owner" foreignKey="config_marc_subfield_owner_fkey" implied="false" onDeleteCascade="false" schema="config" table="marc_subfield"/>
            <child column="org_unit" foreignKey="config_openathens_identity_ou_fkey" implied="false" onDeleteCascade="true" schema="config" table="openathens_identity"/>
            <child column="org" foreignKey="config_org_unit_setting_type_log_fkey" implied="false" onDeleteCascade="true" schema="config" table="org_unit_setting_type_log"/>
            <child column="owner" foreignKey="cpt_owner_fkey" implied="false" onDeleteCascade="false" schema="config" table="print_template"/>
            <child column="owner" foreignKey="config_remote_account_owner_fkey" implied="false" onDeleteCascade="true" schema="config" table="remote_account"/>
            <child column="context_org" foreignKey="remoteauth_profile_context_org_fkey" implied="false" onDeleteCascade="true" schema="config" table="remoteauth_profile"/>
            <child column="owner" foreignKey="cusppe_owner_fkey" implied="false" onDeleteCascade="true" schema="config" table="ui_staff_portal_page_entry"/>
            <child column="org_unit" foreignKey="weight_assoc_org_unit_fkey" implied="false" onDeleteCascade="true" schema="config" table="weight_assoc"/>
            <child column="owner" foreignKey="z3950_source_creds_owner_fkey" implied="false" onDeleteCascade="true" schema="config" table="z3950_source_credentials"/>
            <child column="owning_lib" foreignKey="biblio_record_entry_bucket_owning_lib_fkey" implied="false" onDeleteCascade="true" schema="container" table="biblio_record_entry_bucket"/>
            <child column="owning_lib" foreignKey="call_number_bucket_owning_lib_fkey" implied="false" onDeleteCascade="true" schema="container" table="call_number_bucket"/>
            <child column="owner" foreignKey="carousel_owner_fkey" implied="false" onDeleteCascade="false" schema="container" table="carousel"/>
            <child column="org_unit" foreignKey="carousel_org_unit_org_unit_fkey" implied="false" onDeleteCascade="false" schema="container" table="carousel_org_unit"/>
            <child column="owning_lib" foreignKey="copy_bucket_owning_lib_fkey" implied="false" onDeleteCascade="true" schema="container" table="copy_bucket"/>
            <child column="owning_lib" foreignKey="user_bucket_owning_lib_fkey" implied="false" onDeleteCascade="true" schema="container" table="user_bucket"/>
            <child column="location" foreignKey="collections_tracker_location_fkey" implied="false" onDeleteCascade="false" schema="money" table="collections_tracker"/>
            <child column="org_unit" foreignKey="grp_penalty_threshold_org_unit_fkey" implied="false" onDeleteCascade="true" schema="permission" table="grp_penalty_threshold"/>
            <child column="org" foreignKey="grp_tree_display_entry_org_fkey" implied="false" onDeleteCascade="false" schema="permission" table="grp_tree_display_entry"/>
            <child column="work_ou" foreignKey="usr_work_ou_map_work_ou_fkey" implied="false" onDeleteCascade="true" schema="permission" table="usr_work_ou_map"/>
            <child column="scope" foreignKey="badge_scope_fkey" implied="false" onDeleteCascade="true" schema="rating" table="badge"/>
            <child column="share_with" foreignKey="output_folder_share_with_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="output_folder"/>
            <child column="share_with" foreignKey="report_folder_share_with_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="report_folder"/>
            <child column="share_with" foreignKey="template_folder_share_with_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="template_folder"/>
            <child column="holding_lib" foreignKey="distribution_holding_lib_fkey" implied="false" onDeleteCascade="false" schema="serial" table="distribution"/>
            <child column="owning_lib" foreignKey="pattern_template_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="serial" table="pattern_template"/>
            <child column="owning_lib" foreignKey="record_entry_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="serial" table="record_entry"/>
            <child column="owning_lib" foreignKey="subscription_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="serial" table="subscription"/>
            <child column="owning_lib" foreignKey="session_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="url_verify" table="session"/>
            <child column="owner" foreignKey="import_bib_trash_group_owner_fkey" implied="false" onDeleteCascade="false" schema="vandelay" table="import_bib_trash_group"/>
            <child column="owner" foreignKey="import_item_attr_definition_owner_fkey" implied="false" onDeleteCascade="true" schema="vandelay" table="import_item_attr_definition"/>
            <child column="owner" foreignKey="match_set_owner_fkey" implied="false" onDeleteCascade="true" schema="vandelay" table="match_set"/>
            <child column="owner" foreignKey="merge_profile_owner_fkey" implied="false" onDeleteCascade="true" schema="vandelay" table="merge_profile"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="parent_ou" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_parent_ou_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="ou_type" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_ou_type_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="ill_address" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_org_unit_ill_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_address"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="holds_address" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_org_unit_holds_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_address"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="mailing_address" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_org_unit_mailing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_address"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="billing_address" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_org_unit_billing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_address"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="shortname" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="email" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="phone" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="true" digits="0" id="11" name="opac_visible" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="1" digits="0" id="12" name="fiscal_calendar" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_fiscal_calendar_fkey" implied="false" onDeleteCascade="false" schema="acq" table="fiscal_calendar"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_org_unit_billing_address_idx" unique="false">
            <column ascending="true" name="billing_address"/>
         </index>
         <index name="actor_org_unit_holds_address_idx" unique="false">
            <column ascending="true" name="holds_address"/>
         </index>
         <index name="actor_org_unit_ill_address_idx" unique="false">
            <column ascending="true" name="ill_address"/>
         </index>
         <index name="actor_org_unit_mailing_address_idx" unique="false">
            <column ascending="true" name="mailing_address"/>
         </index>
         <index name="actor_org_unit_ou_type_idx" unique="false">
            <column ascending="true" name="ou_type"/>
         </index>
         <index name="actor_org_unit_parent_ou_idx" unique="false">
            <column ascending="true" name="parent_ou"/>
         </index>
         <index name="org_unit_name_key" unique="true">
            <column ascending="true" name="name"/>
         </index>
         <index name="org_unit_shortname_key" unique="true">
            <column ascending="true" name="shortname"/>
         </index>
      </table>
      <table name="org_unit_closed" numRows="1091" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_closed_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="org_unit" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_closed_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="6" id="2" name="close_start" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="3" name="close_end" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="4" name="full_day" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="5" name="multi_day" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="reason" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="emergency_closing" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_closed_emergency_closing_fkey" implied="false" onDeleteCascade="false" schema="action" table="emergency_closing"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_closed_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
      </table>
      <table name="org_unit_custom_tree" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_custom_tree_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="tree" foreignKey="org_unit_custom_tree_node_tree_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_custom_tree_node"/>
         </column>
         <column autoUpdated="false" defaultValue="false" digits="0" id="1" name="active" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="'opac'::actor.org_unit_custom_tree_purpose" digits="0" id="2" name="purpose" nullable="false" remarks="" size="2147483647" type="&quot;actor&quot;.&quot;org_unit_custom_tree_purpose&quot;" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_custom_tree_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="org_unit_custom_tree_purpose_key" unique="true">
            <column ascending="true" name="purpose"/>
         </index>
      </table>
      <table name="org_unit_custom_tree_node" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_custom_tree_node_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="parent_node" foreignKey="org_unit_custom_tree_node_parent_node_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_custom_tree_node"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="tree" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_custom_tree_node_tree_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_custom_tree"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="org_unit" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_custom_tree_node_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="parent_node" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_custom_tree_node_parent_node_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_custom_tree_node"/>
         </column>
         <column autoUpdated="false" defaultValue="0" digits="0" id="4" name="sibling_order" nullable="false" remarks="" size="10" type="int4" typeCode="4"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_custom_tree_node_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="aouctn_once_per_org" unique="true">
            <column ascending="true" name="tree"/>
            <column ascending="true" name="org_unit"/>
         </index>
      </table>
      <table name="org_unit_proximity" numRows="991" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_proximity_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="19" type="bigserial" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="from_org" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="to_org" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="prox" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_proximity_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="from_prox_idx" unique="false">
            <column ascending="true" name="from_org"/>
         </index>
      </table>
      <table name="org_unit_proximity_adjustment" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_proximity_adjustment_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="item_circ_lib" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_proximity_adjustment_item_circ_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="item_owning_lib" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_proximity_adjustment_item_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="copy_location" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_org_unit_proximity_copy_location_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_location"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="hold_pickup_lib" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_proximity_adjustment_hold_pickup_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="hold_request_lib" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_proximity_adjustment_hold_request_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="0" digits="0" id="6" name="pos" nullable="false" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="7" name="absolute_adjustment" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="prox_adjustment" nullable="true" remarks="" size="0" type="numeric" typeCode="2"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="circ_mod" nullable="true" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="code" foreignKey="actor_org_unit_proximity_adjustment_circ_mod_fkey" implied="false" onDeleteCascade="false" schema="config" table="circ_modifier"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_proximity_adjustment_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="prox_adj_circ_lib_idx" unique="false">
            <column ascending="true" name="item_circ_lib"/>
         </index>
         <index name="prox_adj_circ_mod_idx" unique="false">
            <column ascending="true" name="circ_mod"/>
         </index>
         <index name="prox_adj_copy_location_idx" unique="false">
            <column ascending="true" name="copy_location"/>
         </index>
         <index name="prox_adj_once_idx" unique="true">
            <column ascending="true" name="pos"/>
         </index>
         <index name="prox_adj_owning_lib_idx" unique="false">
            <column ascending="true" name="item_owning_lib"/>
         </index>
         <index name="prox_adj_pickup_lib_idx" unique="false">
            <column ascending="true" name="hold_pickup_lib"/>
         </index>
         <index name="prox_adj_request_lib_idx" unique="false">
            <column ascending="true" name="hold_request_lib"/>
         </index>
         <checkConstraint constraint="((COALESCE((item_circ_lib)::text, (item_owning_lib)::text, (copy_location)::text, (hold_pickup_lib)::text, (hold_request_lib)::text, circ_mod) IS NOT NULL))" name="prox_adj_criterium"/>
      </table>
      <table name="org_unit_setting" remarks="Org Unit settings&#10;&#10;This table contains any arbitrary settings that a client&#10;program would like to save for an org unit." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_setting_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="19" type="bigserial" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="org_unit" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_setting_org_unit_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="name" foreignKey="org_unit_setting_name_fkey" implied="false" onDeleteCascade="false" schema="config" table="org_unit_setting_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="value" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_setting_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_org_unit_setting_usr_idx" unique="false">
            <column ascending="true" name="org_unit"/>
         </index>
         <index name="ou_once_per_key" unique="true">
            <column ascending="true" name="org_unit"/>
            <column ascending="true" name="name"/>
         </index>
         <checkConstraint constraint="(is_json(value))" name="aous_must_be_json"/>
      </table>
      <table name="org_unit_type" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.org_unit_type_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="ou_type" foreignKey="org_unit_ou_type_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
            <child column="parent" foreignKey="org_unit_type_parent_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_type"/>
            <child column="transit_range" foreignKey="hold_matrix_matchpoint_transit_range_fkey" implied="false" onDeleteCascade="false" schema="config" table="hold_matrix_matchpoint"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="opac_label" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="depth" nullable="false" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="parent" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="org_unit_type_parent_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit_type"/>
         </column>
         <column autoUpdated="false" defaultValue="true" digits="0" id="5" name="can_have_vols" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="true" digits="0" id="6" name="can_have_users" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="org_unit_type_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_org_unit_type_parent_idx" unique="false">
            <column ascending="true" name="parent"/>
         </index>
      </table>
      <table name="passwd" numRows="137" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.passwd_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="passwd_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="salt" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="passwd" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="passwd_type" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="code" foreignKey="passwd_passwd_type_fkey" implied="false" onDeleteCascade="false" schema="actor" table="passwd_type"/>
         </column>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="5" name="create_date" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="6" name="edit_date" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="passwd_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="passwd_type_once_per_user" unique="true">
            <column ascending="true" name="usr"/>
            <column ascending="true" name="passwd_type"/>
         </index>
      </table>
      <table name="passwd_type" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="false" defaultValue="null" digits="0" id="0" name="code" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <child column="post_code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="address_alert"/>
            <child column="post_code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="org_address"/>
            <child column="passwd_type" foreignKey="passwd_passwd_type_fkey" implied="false" onDeleteCascade="false" schema="actor" table="passwd"/>
            <child column="code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="search_filter_group"/>
            <child column="post_code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="usr_address"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="2" name="login" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="regex" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="crypt_algo" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="iter_count" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <primaryKey column="code" sequenceNumberInPK="1"/>
         <index name="passwd_type_pkey" unique="true">
            <column ascending="true" name="code"/>
         </index>
         <index name="passwd_type_name_key" unique="true">
            <column ascending="true" name="name"/>
         </index>
         <checkConstraint constraint="(((iter_count IS NULL) OR (iter_count &gt; 0)))" name="passwd_type_iter_count_check"/>
      </table>
      <table name="search_filter_group" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.search_filter_group_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="grp" foreignKey="search_filter_group_entry_grp_fkey" implied="false" onDeleteCascade="true" schema="actor" table="search_filter_group_entry"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="owner" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="search_filter_group_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="code" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="passwd_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="label" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="4" name="create_date" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="search_filter_group_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="asfg_code_once_per_org" unique="true">
            <column ascending="true" name="owner"/>
            <column ascending="true" name="code"/>
         </index>
         <index name="asfg_label_once_per_org" unique="true">
            <column ascending="true" name="owner"/>
            <column ascending="true" name="label"/>
         </index>
      </table>
      <table name="search_filter_group_entry" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.search_filter_group_entry_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="grp" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="search_filter_group_entry_grp_fkey" implied="false" onDeleteCascade="true" schema="actor" table="search_filter_group"/>
         </column>
         <column autoUpdated="false" defaultValue="0" digits="0" id="2" name="pos" nullable="false" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="query" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="search_filter_group_entry_query_fkey" implied="false" onDeleteCascade="true" schema="actor" table="search_query"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="search_filter_group_entry_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="asfge_query_once_per_group" unique="true">
            <column ascending="true" name="grp"/>
            <column ascending="true" name="query"/>
         </index>
      </table>
      <table name="search_query" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.search_query_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="query" foreignKey="search_filter_group_entry_query_fkey" implied="false" onDeleteCascade="true" schema="actor" table="search_filter_group_entry"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="label" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="query_text" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="search_query_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
      </table>
      <table name="stat_cat" remarks="User Statistical Catagories&#10;&#10;Local data collected about Users is placed into a Statistical&#10;Catagory.  Here's where those catagories are defined." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.stat_cat_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="stat_cat" foreignKey="actor_stat_cat_entry_stat_cat_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat_entry"/>
            <child column="stat_cat" foreignKey="stat_cat_entry_default_stat_cat_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat_entry_default"/>
            <child column="stat_cat" foreignKey="actor_sceum_sc_fkey" implied="false" onDeleteCascade="false" schema="actor" table="stat_cat_entry_usr_map"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="owner" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_stat_cat_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="3" name="opac_visible" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="4" name="usr_summary" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="sip_field" nullable="true" remarks="" size="2" type="bpchar" typeCode="1">
            <parent column="field" foreignKey="stat_cat_sip_field_fkey" implied="false" onDeleteCascade="false" schema="actor" table="stat_cat_sip_fields"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="sip_format" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="7" name="checkout_archive" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="8" name="required" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="true" digits="0" id="9" name="allow_freetext" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="stat_cat_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="sc_once_per_owner" unique="true">
            <column ascending="true" name="owner"/>
            <column ascending="true" name="name"/>
         </index>
      </table>
      <table name="stat_cat_entry" remarks="User Statistical Catagory Entries&#10;&#10;Local data collected about Users is placed into a Statistical&#10;Catagory.  Each library can create entries into any of its own&#10;stat_cats, its ancestors' stat_cats, or its descendants' stat_cats." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.stat_cat_entry_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="stat_cat_entry" foreignKey="stat_cat_entry_default_stat_cat_entry_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat_entry_default"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="stat_cat" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_stat_cat_entry_stat_cat_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="owner" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_stat_cat_entry_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="value" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="stat_cat_entry_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="sce_once_per_owner" unique="true">
            <column ascending="true" name="stat_cat"/>
            <column ascending="true" name="owner"/>
            <column ascending="true" name="value"/>
         </index>
      </table>
      <table name="stat_cat_entry_default" remarks="User Statistical Category Default Entry&#10;&#10;A library may choose one of the stat_cat entries to be the&#10;default entry." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.stat_cat_entry_default_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="stat_cat_entry" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="stat_cat_entry_default_stat_cat_entry_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat_entry"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="stat_cat" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="stat_cat_entry_default_stat_cat_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="owner" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="stat_cat_entry_default_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="stat_cat_entry_default_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="sced_once_per_owner" unique="true">
            <column ascending="true" name="stat_cat"/>
            <column ascending="true" name="owner"/>
         </index>
      </table>
      <table name="stat_cat_entry_usr_map" remarks="Statistical Catagory Entry to User map&#10;&#10;Records the stat_cat entries for each user." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.stat_cat_entry_usr_map_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="19" type="bigserial" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="stat_cat_entry" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="stat_cat" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_sceum_sc_fkey" implied="false" onDeleteCascade="false" schema="actor" table="stat_cat"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="target_usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_sceum_tu_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="stat_cat_entry_usr_map_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_stat_cat_entry_usr_idx" unique="false">
            <column ascending="true" name="target_usr"/>
         </index>
         <index name="sc_once_per_usr" unique="true">
            <column ascending="true" name="target_usr"/>
            <column ascending="true" name="stat_cat"/>
         </index>
      </table>
      <table name="stat_cat_sip_fields" remarks="Actor Statistical Category SIP Fields&#10;&#10;Contains the list of valid SIP Field identifiers for&#10;Statistical Categories." schema="actor" type="TABLE">
         <column autoUpdated="false" defaultValue="null" digits="0" id="0" name="field" nullable="false" remarks="" size="2" type="bpchar" typeCode="1">
            <child column="sip_field" foreignKey="stat_cat_sip_field_fkey" implied="false" onDeleteCascade="false" schema="actor" table="stat_cat"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="2" name="one_only" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="field" sequenceNumberInPK="1"/>
         <index name="stat_cat_sip_fields_pkey" unique="true">
            <column ascending="true" name="field"/>
         </index>
      </table>
      <table name="toolbar" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.toolbar_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="19" type="bigserial" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="ws" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="toolbar_ws_fkey" implied="false" onDeleteCascade="true" schema="actor" table="workstation"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="org" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="toolbar_org_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="usr" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="toolbar_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="label" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="layout" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="toolbar_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="label_once_per_org" unique="true">
            <column ascending="true" name="org"/>
            <column ascending="true" name="label"/>
         </index>
         <index name="label_once_per_usr" unique="true">
            <column ascending="true" name="usr"/>
            <column ascending="true" name="label"/>
         </index>
         <index name="label_once_per_ws" unique="true">
            <column ascending="true" name="ws"/>
            <column ascending="true" name="label"/>
         </index>
         <checkConstraint constraint="(is_json(layout))" name="layout_must_be_json"/>
         <checkConstraint constraint="((((ws IS NOT NULL) AND (COALESCE(org, usr) IS NULL)) OR ((org IS NOT NULL) AND (COALESCE(ws, usr) IS NULL)) OR ((usr IS NOT NULL) AND (COALESCE(org, ws) IS NULL))))" name="only_one_type"/>
      </table>
      <table name="usr" numRows="379" remarks="User objects&#10;&#10;This table contains the core User objects that describe both&#10;staff members and patrons.  The difference between the two&#10;types of users is based on the user's permissions." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="creator" foreignKey="claim_event_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="claim_event"/>
            <child column="creator" foreignKey="distribution_formula_application_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="distribution_formula_application"/>
            <child column="allocator" foreignKey="fund_allocation_allocator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="fund_allocation"/>
            <child column="allocator" foreignKey="fund_allocation_percent_allocator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="fund_allocation_percent"/>
            <child column="transfer_user" foreignKey="fund_transfer_transfer_user_fkey" implied="false" onDeleteCascade="false" schema="acq" table="fund_transfer"/>
            <child column="closed_by" foreignKey="invoice_closed_by_fkey" implied="false" onDeleteCascade="false" schema="acq" table="invoice"/>
            <child column="creator" foreignKey="lineitem_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem"/>
            <child column="editor" foreignKey="lineitem_editor_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem"/>
            <child column="selector" foreignKey="lineitem_selector_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem"/>
            <child column="receiver" foreignKey="lineitem_detail_receiver_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem_detail"/>
            <child column="creator" foreignKey="lineitem_note_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem_note"/>
            <child column="editor" foreignKey="lineitem_note_editor_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem_note"/>
            <child column="usr" foreignKey="lineitem_usr_attr_definition_usr_fkey" implied="false" onDeleteCascade="false" schema="acq" table="lineitem_usr_attr_definition"/>
            <child column="creator" foreignKey="picklist_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="picklist"/>
            <child column="editor" foreignKey="picklist_editor_fkey" implied="false" onDeleteCascade="false" schema="acq" table="picklist"/>
            <child column="owner" foreignKey="picklist_owner_fkey" implied="false" onDeleteCascade="false" schema="acq" table="picklist"/>
            <child column="creator" foreignKey="po_note_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="po_note"/>
            <child column="editor" foreignKey="po_note_editor_fkey" implied="false" onDeleteCascade="false" schema="acq" table="po_note"/>
            <child column="creator" foreignKey="provider_note_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="provider_note"/>
            <child column="editor" foreignKey="provider_note_editor_fkey" implied="false" onDeleteCascade="false" schema="acq" table="provider_note"/>
            <child column="creator" foreignKey="purchase_order_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="purchase_order"/>
            <child column="editor" foreignKey="purchase_order_editor_fkey" implied="false" onDeleteCascade="false" schema="acq" table="purchase_order"/>
            <child column="owner" foreignKey="purchase_order_owner_fkey" implied="false" onDeleteCascade="false" schema="acq" table="purchase_order"/>
            <child column="creator" foreignKey="serial_claim_event_creator_fkey" implied="false" onDeleteCascade="false" schema="acq" table="serial_claim_event"/>
            <child column="processed_by" foreignKey="shipment_notification_processed_by_fkey" implied="false" onDeleteCascade="false" schema="acq" table="shipment_notification"/>
            <child column="usr" foreignKey="user_request_usr_fkey" implied="false" onDeleteCascade="false" schema="acq" table="user_request"/>
            <child column="staff" foreignKey="batch_hold_event_staff_fkey" implied="false" onDeleteCascade="true" schema="action" table="batch_hold_event"/>
            <child column="usr" foreignKey="action_circulation_usr_fkey" implied="false" onDeleteCascade="false" schema="action" table="circulation"/>
            <child column="delivery_staff" foreignKey="curbside_delivery_staff_fkey" implied="false" onDeleteCascade="true" schema="action" table="curbside"/>
            <child column="patron" foreignKey="curbside_patron_fkey" implied="false" onDeleteCascade="true" schema="action" table="curbside"/>
            <child column="stage_staff" foreignKey="curbside_stage_staff_fkey" implied="false" onDeleteCascade="true" schema="action" table="curbside"/>
            <child column="creator" foreignKey="emergency_closing_creator_fkey" implied="false" onDeleteCascade="true" schema="action" table="emergency_closing"/>
            <child column="owner" foreignKey="fieldset_owner_fkey" implied="false" onDeleteCascade="false" schema="action" table="fieldset"/>
            <child column="creator" foreignKey="fieldset_group_creator_fkey" implied="false" onDeleteCascade="true" schema="action" table="fieldset_group"/>
            <child column="notify_staff" foreignKey="hold_notification_notify_staff_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_notification"/>
            <child column="fulfillment_staff" foreignKey="hold_request_fulfillment_staff_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_request"/>
            <child column="requestor" foreignKey="hold_request_requestor_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_request"/>
            <child column="usr" foreignKey="hold_request_usr_fkey" implied="false" onDeleteCascade="false" schema="action" table="hold_request"/>
            <child column="staff" foreignKey="in_house_use_staff_fkey" implied="false" onDeleteCascade="false" schema="action" table="in_house_use"/>
            <child column="who" foreignKey="ingest_queue_who_fkey" implied="false" onDeleteCascade="false" schema="action" table="ingest_queue"/>
            <child column="staff" foreignKey="non_cat_in_house_use_staff_fkey" implied="false" onDeleteCascade="false" schema="action" table="non_cat_in_house_use"/>
            <child column="patron" foreignKey="non_cataloged_circulation_patron_fkey" implied="false" onDeleteCascade="false" schema="action" table="non_cataloged_circulation"/>
            <child column="staff" foreignKey="non_cataloged_circulation_staff_fkey" implied="false" onDeleteCascade="false" schema="action" table="non_cataloged_circulation"/>
            <child column="usr" foreignKey="usr_circ_history_usr_fkey" implied="false" onDeleteCascade="false" schema="action" table="usr_circ_history"/>
            <child column="context_user" foreignKey="event_context_user_fkey" implied="false" onDeleteCascade="false" schema="action_trigger" table="event"/>
            <child column="usr" foreignKey="card_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="card"/>
            <child column="usr" foreignKey="passwd_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="passwd"/>
            <child column="target_usr" foreignKey="actor_sceum_tu_fkey" implied="false" onDeleteCascade="true" schema="actor" table="stat_cat_entry_usr_map"/>
            <child column="usr" foreignKey="toolbar_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="toolbar"/>
            <child column="usr" foreignKey="usr_activity_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_activity"/>
            <child column="usr" foreignKey="usr_address_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_address"/>
            <child column="editor" foreignKey="usr_message_editor_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_message"/>
            <child column="usr" foreignKey="usr_message_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_message"/>
            <child column="staff" foreignKey="usr_org_unit_opt_in_staff_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_org_unit_opt_in"/>
            <child column="usr" foreignKey="usr_org_unit_opt_in_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_org_unit_opt_in"/>
            <child column="usr" foreignKey="usr_password_reset_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_password_reset"/>
            <child column="usr" foreignKey="usr_privacy_waiver_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr_privacy_waiver"/>
            <child column="owner" foreignKey="usr_saved_search_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr_saved_search"/>
            <child column="usr" foreignKey="usr_setting_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr_setting"/>
            <child column="staff" foreignKey="usr_standing_penalty_staff_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_standing_penalty"/>
            <child column="usr" foreignKey="usr_standing_penalty_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr_standing_penalty"/>
            <child column="creator" foreignKey="asset_call_number_creator_fkey" implied="false" onDeleteCascade="false" schema="asset" table="call_number"/>
            <child column="editor" foreignKey="asset_call_number_editor_fkey" implied="false" onDeleteCascade="false" schema="asset" table="call_number"/>
            <child column="creator" foreignKey="asset_call_number_note_creator_fkey" implied="false" onDeleteCascade="false" schema="asset" table="call_number_note"/>
            <child column="creator" foreignKey="asset_copy_creator_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy"/>
            <child column="editor" foreignKey="asset_copy_editor_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy"/>
            <child column="ack_staff" foreignKey="copy_alert_ack_staff_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_alert"/>
            <child column="create_staff" foreignKey="copy_alert_create_staff_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_alert"/>
            <child column="creator" foreignKey="asset_copy_note_creator_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_note"/>
            <child column="creator" foreignKey="copy_template_creator_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_template"/>
            <child column="editor" foreignKey="copy_template_editor_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_template"/>
            <child column="usr" foreignKey="course_module_course_users_usr_fkey" implied="false" onDeleteCascade="false" schema="asset" table="course_module_course_users"/>
            <child column="creator" foreignKey="biblio_record_entry_creator_fkey" implied="false" onDeleteCascade="false" schema="biblio" table="record_entry"/>
            <child column="editor" foreignKey="biblio_record_entry_editor_fkey" implied="false" onDeleteCascade="false" schema="biblio" table="record_entry"/>
            <child column="creator" foreignKey="biblio_record_note_creator_fkey" implied="false" onDeleteCascade="false" schema="biblio" table="record_note"/>
            <child column="editor" foreignKey="biblio_record_note_editor_fkey" implied="false" onDeleteCascade="false" schema="biblio" table="record_note"/>
            <child column="capture_staff" foreignKey="reservation_capture_staff_fkey" implied="false" onDeleteCascade="false" schema="booking" table="reservation"/>
            <child column="usr" foreignKey="booking_reservation_usr_fkey" implied="false" onDeleteCascade="false" schema="booking" table="reservation"/>
            <child column="creator" foreignKey="config_filter_dialog_filter_set_creator_fkey" implied="false" onDeleteCascade="true" schema="config" table="filter_dialog_filter_set"/>
            <child column="owner" foreignKey="biblio_record_entry_bucket_owner_fkey" implied="false" onDeleteCascade="true" schema="container" table="biblio_record_entry_bucket"/>
            <child column="owner" foreignKey="call_number_bucket_owner_fkey" implied="false" onDeleteCascade="true" schema="container" table="call_number_bucket"/>
            <child column="creator" foreignKey="carousel_creator_fkey" implied="false" onDeleteCascade="false" schema="container" table="carousel"/>
            <child column="editor" foreignKey="carousel_editor_fkey" implied="false" onDeleteCascade="false" schema="container" table="carousel"/>
            <child column="owner" foreignKey="copy_bucket_owner_fkey" implied="false" onDeleteCascade="true" schema="container" table="copy_bucket"/>
            <child column="owner" foreignKey="user_bucket_owner_fkey" implied="false" onDeleteCascade="true" schema="container" table="user_bucket"/>
            <child column="target_user" foreignKey="user_bucket_item_target_user_fkey" implied="false" onDeleteCascade="true" schema="container" table="user_bucket_item"/>
            <child column="usr" foreignKey="money_billable_xact_usr_fkey" implied="false" onDeleteCascade="false" schema="money" table="billable_xact"/>
            <child column="collector" foreignKey="collections_tracker_collector_fkey" implied="false" onDeleteCascade="false" schema="money" table="collections_tracker"/>
            <child column="usr" foreignKey="collections_tracker_usr_fkey" implied="false" onDeleteCascade="false" schema="money" table="collections_tracker"/>
            <child column="usr" foreignKey="usr_grp_map_usr_fkey" implied="false" onDeleteCascade="true" schema="permission" table="usr_grp_map"/>
            <child column="usr" foreignKey="usr_object_perm_map_usr_fkey" implied="false" onDeleteCascade="true" schema="permission" table="usr_object_perm_map"/>
            <child column="usr" foreignKey="usr_perm_map_usr_fkey" implied="false" onDeleteCascade="true" schema="permission" table="usr_perm_map"/>
            <child column="usr" foreignKey="usr_work_ou_map_usr_fkey" implied="false" onDeleteCascade="true" schema="permission" table="usr_work_ou_map"/>
            <child column="owner" foreignKey="output_folder_owner_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="output_folder"/>
            <child column="owner" foreignKey="report_owner_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="report"/>
            <child column="owner" foreignKey="report_folder_owner_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="report_folder"/>
            <child column="runner" foreignKey="schedule_runner_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="schedule"/>
            <child column="owner" foreignKey="template_owner_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="template"/>
            <child column="owner" foreignKey="template_folder_owner_fkey" implied="false" onDeleteCascade="false" schema="reporter" table="template_folder"/>
            <child column="creator" foreignKey="distribution_note_creator_fkey" implied="false" onDeleteCascade="false" schema="serial" table="distribution_note"/>
            <child column="creator" foreignKey="issuance_creator_fkey" implied="false" onDeleteCascade="false" schema="serial" table="issuance"/>
            <child column="editor" foreignKey="issuance_editor_fkey" implied="false" onDeleteCascade="false" schema="serial" table="issuance"/>
            <child column="creator" foreignKey="item_creator_fkey" implied="false" onDeleteCascade="false" schema="serial" table="item"/>
            <child column="editor" foreignKey="item_editor_fkey" implied="false" onDeleteCascade="false" schema="serial" table="item"/>
            <child column="creator" foreignKey="item_note_creator_fkey" implied="false" onDeleteCascade="false" schema="serial" table="item_note"/>
            <child column="reader" foreignKey="routing_list_user_reader_fkey" implied="false" onDeleteCascade="true" schema="serial" table="routing_list_user"/>
            <child column="creator" foreignKey="subscription_note_creator_fkey" implied="false" onDeleteCascade="false" schema="serial" table="subscription_note"/>
            <child column="creator" foreignKey="serial_unit_creator_fkey" implied="false" onDeleteCascade="false" schema="serial" table="unit"/>
            <child column="editor" foreignKey="serial_unit_editor_fkey" implied="false" onDeleteCascade="false" schema="serial" table="unit"/>
            <child column="requesting_usr" foreignKey="user_stage_requesting_usr_fkey" implied="false" onDeleteCascade="false" schema="staging" table="user_stage"/>
            <child column="creator" foreignKey="session_creator_fkey" implied="false" onDeleteCascade="false" schema="url_verify" table="session"/>
            <child column="usr" foreignKey="verification_attempt_usr_fkey" implied="false" onDeleteCascade="false" schema="url_verify" table="verification_attempt"/>
            <child column="owner" foreignKey="queue_owner_fkey" implied="false" onDeleteCascade="false" schema="vandelay" table="queue"/>
            <child column="usr" foreignKey="session_tracker_usr_fkey" implied="false" onDeleteCascade="false" schema="vandelay" table="session_tracker"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="card" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="profile" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_usr_profile_fkey" implied="false" onDeleteCascade="false" schema="permission" table="grp_tree"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="usrname" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="email" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="passwd" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="1" digits="0" id="6" name="standing" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_standing_fkey" implied="false" onDeleteCascade="false" schema="config" table="standing"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="ident_type" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_ident_type_fkey" implied="false" onDeleteCascade="false" schema="config" table="identification_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="ident_value" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="ident_type2" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_ident_type2_fkey" implied="false" onDeleteCascade="false" schema="config" table="identification_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="ident_value2" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="1" digits="0" id="11" name="net_access_level" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_net_access_level_fkey" implied="false" onDeleteCascade="false" schema="config" table="net_access_level"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="12" name="photo_url" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="13" name="prefix" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="14" name="first_given_name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="15" name="second_given_name" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="16" name="family_name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="17" name="suffix" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="18" name="guardian" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="19" name="pref_prefix" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="20" name="pref_first_given_name" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="21" name="pref_second_given_name" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="22" name="pref_family_name" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="23" name="pref_suffix" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="24" name="name_keywords" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="25" name="name_kw_tsvector" nullable="true" remarks="" size="2147483647" type="tsvector" typeCode="1111"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="26" name="alias" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="27" name="day_phone" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="28" name="evening_phone" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="29" name="other_phone" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="30" name="mailing_address" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_usr_mailing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_address"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="31" name="billing_address" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_usr_billing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_address"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="32" name="home_ou" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="actor_usr_home_ou_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="33" name="dob" nullable="true" remarks="" size="13" type="date" typeCode="91"/>
         <column autoUpdated="false" defaultValue="true" digits="0" id="34" name="active" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="35" name="master_account" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="36" name="super_user" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="37" name="barred" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="38" name="deleted" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="39" name="juvenile" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="true" defaultValue="nextval('actor.usr_usrgroup_seq'::regclass)" digits="0" id="40" name="usrgroup" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="0" digits="0" id="41" name="claims_returned_count" nullable="false" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="0.00" digits="2" id="42" name="credit_forward_balance" nullable="false" remarks="" size="6" type="numeric" typeCode="2"/>
         <column autoUpdated="false" defaultValue="'none'::text" digits="0" id="43" name="last_xact_id" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="44" name="create_date" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="(now() + '3 years'::interval)" digits="6" id="45" name="expire_date" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="0" digits="0" id="46" name="claims_never_checked_out_count" nullable="false" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="47" name="last_update_time" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="48" name="locale" nullable="true" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="code" foreignKey="usr_locale_fkey" implied="false" onDeleteCascade="false" schema="config" table="i18n_locale"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_usr_billing_address_idx" unique="false">
            <column ascending="true" name="billing_address"/>
         </index>
         <index name="actor_usr_day_phone_idx" unique="false"/>
         <index name="actor_usr_day_phone_idx_numeric" unique="false"/>
         <index name="actor_usr_email_idx" unique="false"/>
         <index name="actor_usr_evening_phone_idx" unique="false"/>
         <index name="actor_usr_evening_phone_idx_numeric" unique="false"/>
         <index name="actor_usr_family_name_idx" unique="false"/>
         <index name="actor_usr_family_name_unaccent_idx" unique="false"/>
         <index name="actor_usr_first_given_name_idx" unique="false"/>
         <index name="actor_usr_first_given_name_unaccent_idx" unique="false"/>
         <index name="actor_usr_guardian_idx" unique="false"/>
         <index name="actor_usr_guardian_unaccent_idx" unique="false"/>
         <index name="actor_usr_home_ou_idx" unique="false">
            <column ascending="true" name="home_ou"/>
         </index>
         <index name="actor_usr_ident_value2_idx" unique="false"/>
         <index name="actor_usr_ident_value_idx" unique="false"/>
         <index name="actor_usr_mailing_address_idx" unique="false">
            <column ascending="true" name="mailing_address"/>
         </index>
         <index name="actor_usr_other_phone_idx" unique="false"/>
         <index name="actor_usr_other_phone_idx_numeric" unique="false"/>
         <index name="actor_usr_pref_family_name_idx" unique="false"/>
         <index name="actor_usr_pref_family_name_unaccent_idx" unique="false"/>
         <index name="actor_usr_pref_first_given_name_idx" unique="false"/>
         <index name="actor_usr_pref_first_given_name_unaccent_idx" unique="false"/>
         <index name="actor_usr_pref_second_given_name_idx" unique="false"/>
         <index name="actor_usr_pref_second_given_name_unaccent_idx" unique="false"/>
         <index name="actor_usr_second_given_name_idx" unique="false"/>
         <index name="actor_usr_second_given_name_unaccent_idx" unique="false"/>
         <index name="actor_usr_usrgroup_idx" unique="false">
            <column ascending="true" name="usrgroup"/>
         </index>
         <index name="actor_usr_usrname_idx" unique="false"/>
         <index name="actor_usr_usrname_unaccent_idx" unique="false"/>
         <index name="usr_card_key" unique="true">
            <column ascending="true" name="card"/>
         </index>
         <index name="usr_usrname_key" unique="true">
            <column ascending="true" name="usrname"/>
         </index>
      </table>
      <table name="usr_activity" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_activity_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="19" type="bigserial" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="usr" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_activity_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="etype" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_activity_etype_fkey" implied="false" onDeleteCascade="false" schema="config" table="usr_activity_type"/>
         </column>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="3" name="event_time" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_activity_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="usr_activity_usr_idx" unique="false">
            <column ascending="true" name="usr"/>
         </index>
      </table>
      <table name="usr_address" numRows="379" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_address_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="billing_address" foreignKey="actor_usr_billing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
            <child column="mailing_address" foreignKey="actor_usr_mailing_address_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
            <child column="replaces" foreignKey="usr_address_replaces_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_address"/>
         </column>
         <column autoUpdated="false" defaultValue="true" digits="0" id="1" name="valid" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="true" digits="0" id="2" name="within_city_limits" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="'MAILING'::text" digits="0" id="3" name="address_type" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_address_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="street1" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="street2" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="city" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="county" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="state" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="country" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="11" name="post_code" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="code" foreignKey="Implied Constraint" implied="true" onDeleteCascade="false" schema="actor" table="passwd_type"/>
         </column>
         <column autoUpdated="false" defaultValue="false" digits="0" id="12" name="pending" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="13" name="replaces" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_address_replaces_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_address"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_address_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_usr_addr_city_idx" unique="false"/>
         <index name="actor_usr_addr_post_code_idx" unique="false"/>
         <index name="actor_usr_addr_state_idx" unique="false"/>
         <index name="actor_usr_addr_street1_idx" unique="false"/>
         <index name="actor_usr_addr_street2_idx" unique="false"/>
         <index name="actor_usr_addr_usr_idx" unique="false">
            <column ascending="true" name="usr"/>
         </index>
      </table>
      <table name="usr_message" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_message_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="usr_message" foreignKey="usr_standing_penalty_usr_message_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_standing_penalty"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_message_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="title" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="message" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="4" name="create_date" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="5" name="deleted" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="6" name="read_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="sending_lib" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_message_sending_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="false" digits="0" id="8" name="pub" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="9" name="stop_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="editor" nullable="true" remarks="" size="19" type="int8" typeCode="-5">
            <parent column="id" foreignKey="usr_message_editor_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="6" id="11" name="edit_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_message_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="aum_editor" unique="false">
            <column ascending="true" name="editor"/>
         </index>
         <index name="aum_usr" unique="false">
            <column ascending="true" name="usr"/>
         </index>
      </table>
      <table name="usr_message_limited" numRows="0" remarks="" schema="actor" type="VIEW" viewSql=" SELECT usr_message.id,&#10;    usr_message.usr,&#10;    usr_message.title,&#10;    usr_message.message,&#10;    usr_message.create_date,&#10;    usr_message.deleted,&#10;    usr_message.read_date,&#10;    usr_message.sending_lib,&#10;    usr_message.pub,&#10;    usr_message.stop_date,&#10;    usr_message.editor,&#10;    usr_message.edit_date&#10;   FROM actor.usr_message&#10;  WHERE (usr_message.pub AND (NOT usr_message.deleted));">
         <column autoUpdated="false" defaultValue="null" digits="0" id="0" name="id" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="usr" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="title" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="message" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="4" name="create_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="deleted" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="6" name="read_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="sending_lib" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="pub" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="9" name="stop_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="editor" nullable="true" remarks="" size="19" type="int8" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="11" name="edit_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
      </table>
      <table name="usr_message_penalty" numRows="0" remarks="" schema="actor" type="VIEW" viewSql=" SELECT ausp.id,&#10;    ausp.id AS ausp_id,&#10;    aum.id AS aum_id,&#10;    ausp.org_unit,&#10;    ausp.org_unit AS ausp_org_unit,&#10;    aum.sending_lib AS aum_sending_lib,&#10;    ausp.usr,&#10;    ausp.usr AS ausp_usr,&#10;    aum.usr AS aum_usr,&#10;    ausp.standing_penalty,&#10;    ausp.staff,&#10;    ausp.set_date AS create_date,&#10;    ausp.set_date AS ausp_set_date,&#10;    aum.create_date AS aum_create_date,&#10;    ausp.stop_date,&#10;    ausp.stop_date AS ausp_stop_date,&#10;    aum.stop_date AS aum_stop_date,&#10;    ausp.usr_message AS ausp_usr_message,&#10;    aum.title,&#10;    aum.message,&#10;    aum.deleted,&#10;    aum.read_date,&#10;    aum.pub,&#10;    aum.editor,&#10;    aum.edit_date&#10;   FROM (actor.usr_standing_penalty ausp&#10;     LEFT JOIN actor.usr_message aum ON ((ausp.usr_message = aum.id)))&#10;UNION ALL&#10; SELECT aum.id,&#10;    NULL::integer AS ausp_id,&#10;    aum.id AS aum_id,&#10;    aum.sending_lib AS org_unit,&#10;    NULL::integer AS ausp_org_unit,&#10;    aum.sending_lib AS aum_sending_lib,&#10;    aum.usr,&#10;    NULL::integer AS ausp_usr,&#10;    aum.usr AS aum_usr,&#10;    NULL::integer AS standing_penalty,&#10;    NULL::integer AS staff,&#10;    aum.create_date,&#10;    NULL::timestamp with time zone AS ausp_set_date,&#10;    aum.create_date AS aum_create_date,&#10;    aum.stop_date,&#10;    NULL::timestamp with time zone AS ausp_stop_date,&#10;    aum.stop_date AS aum_stop_date,&#10;    NULL::integer AS ausp_usr_message,&#10;    aum.title,&#10;    aum.message,&#10;    aum.deleted,&#10;    aum.read_date,&#10;    aum.pub,&#10;    aum.editor,&#10;    aum.edit_date&#10;   FROM (actor.usr_message aum&#10;     LEFT JOIN actor.usr_standing_penalty ausp ON ((ausp.usr_message = aum.id)))&#10;  WHERE ((NOT aum.deleted) AND (ausp.id IS NULL));">
         <column autoUpdated="false" defaultValue="null" digits="0" id="0" name="id" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="ausp_id" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="aum_id" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="org_unit" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="ausp_org_unit" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="aum_sending_lib" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="usr" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="ausp_usr" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="8" name="aum_usr" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="9" name="standing_penalty" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="10" name="staff" nullable="true" remarks="" size="10" type="int4" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="11" name="create_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="12" name="ausp_set_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="13" name="aum_create_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="14" name="stop_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="15" name="ausp_stop_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="16" name="aum_stop_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="17" name="ausp_usr_message" nullable="true" remarks="" size="19" type="int8" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="18" name="title" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="19" name="message" nullable="true" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="20" name="deleted" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="21" name="read_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="22" name="pub" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="23" name="editor" nullable="true" remarks="" size="19" type="int8" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="24" name="edit_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
      </table>
      <table name="usr_org_unit_opt_in" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_org_unit_opt_in_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="org_unit" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_org_unit_opt_in_org_unit_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_org_unit_opt_in_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="staff" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_org_unit_opt_in_staff_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="4" name="opt_in_ts" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="5" name="opt_in_ws" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_org_unit_opt_in_opt_in_ws_fkey" implied="false" onDeleteCascade="false" schema="actor" table="workstation"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_org_unit_opt_in_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="usr_opt_in_once_per_org_unit" unique="true">
            <column ascending="true" name="usr"/>
            <column ascending="true" name="org_unit"/>
         </index>
         <index name="usr_org_unit_opt_in_staff_idx" unique="false">
            <column ascending="true" name="staff"/>
         </index>
      </table>
      <table name="usr_password_reset" remarks="Self-serve password reset requests" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_password_reset_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="uuid" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="usr" nullable="false" remarks="" size="19" type="int8" typeCode="-5">
            <parent column="id" foreignKey="usr_password_reset_usr_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="3" name="request_time" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="4" name="has_been_reset" nullable="false" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_password_reset_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_usr_password_reset_has_been_reset_idx" unique="false">
            <column ascending="true" name="has_been_reset"/>
         </index>
         <index name="actor_usr_password_reset_request_time_idx" unique="false">
            <column ascending="true" name="request_time"/>
         </index>
         <index name="actor_usr_password_reset_usr_idx" unique="false">
            <column ascending="true" name="usr"/>
         </index>
         <index name="actor_usr_password_reset_uuid_idx" unique="true">
            <column ascending="true" name="uuid"/>
         </index>
      </table>
      <table name="usr_privacy_waiver" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_privacy_waiver_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="19" type="bigserial" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="usr" nullable="false" remarks="" size="19" type="int8" typeCode="-5">
            <parent column="id" foreignKey="usr_privacy_waiver_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="3" name="place_holds" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="4" name="pickup_holds" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="5" name="view_history" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <column autoUpdated="false" defaultValue="false" digits="0" id="6" name="checkout_items" nullable="true" remarks="" size="1" type="bool" typeCode="-7"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_privacy_waiver_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_usr_privacy_waiver_usr_idx" unique="false">
            <column ascending="true" name="usr"/>
         </index>
      </table>
      <table name="usr_saved_search" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_saved_search_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="owner" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_saved_search_owner_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="3" name="create_date" nullable="false" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="query_text" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="'URL'::text" digits="0" id="5" name="query_type" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="6" name="target" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_saved_search_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="name_once_per_user" unique="true">
            <column ascending="true" name="owner"/>
            <column ascending="true" name="name"/>
         </index>
         <checkConstraint constraint="((query_type = 'URL'::text))" name="valid_query_text"/>
         <checkConstraint constraint="((target = ANY (ARRAY['record'::text, 'metarecord'::text, 'callnumber'::text])))" name="valid_target"/>
      </table>
      <table name="usr_setting" numRows="283" remarks="User settings&#10;&#10;This table contains any arbitrary settings that a client&#10;program would like to save for a user." schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_setting_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="19" type="bigserial" typeCode="-5"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_setting_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="name" foreignKey="usr_setting_name_fkey" implied="false" onDeleteCascade="true" schema="config" table="usr_setting_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="value" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_setting_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_usr_setting_usr_idx" unique="false">
            <column ascending="true" name="usr"/>
         </index>
         <index name="usr_once_per_key" unique="true">
            <column ascending="true" name="usr"/>
            <column ascending="true" name="name"/>
         </index>
      </table>
      <table name="usr_standing_penalty" numRows="98" remarks="User standing penalties" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.usr_message_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="org_unit" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_standing_penalty_org_unit_fkey" implied="false" onDeleteCascade="true" schema="actor" table="org_unit"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="usr" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_standing_penalty_usr_fkey" implied="false" onDeleteCascade="true" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="standing_penalty" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_standing_penalty_standing_penalty_fkey" implied="false" onDeleteCascade="true" schema="config" table="standing_penalty"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="4" name="staff" nullable="true" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="usr_standing_penalty_staff_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr"/>
         </column>
         <column autoUpdated="false" defaultValue="now()" digits="6" id="5" name="set_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="6" id="6" name="stop_date" nullable="true" remarks="" size="35" type="timestamptz" typeCode="93"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="7" name="usr_message" nullable="true" remarks="" size="19" type="int8" typeCode="-5">
            <parent column="id" foreignKey="usr_standing_penalty_usr_message_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_message"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="usr_standing_penalty_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_usr_standing_penalty_staff_idx" unique="false">
            <column ascending="true" name="staff"/>
         </index>
         <index name="actor_usr_standing_penalty_usr_idx" unique="false">
            <column ascending="true" name="usr"/>
         </index>
         <index name="usr_standing_penalty_usr_message_idx" unique="false">
            <column ascending="true" name="usr_message"/>
         </index>
      </table>
      <table name="workstation" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.workstation_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4">
            <child column="checkin_workstation" foreignKey="circulation_checkin_workstation_fkey" implied="false" onDeleteCascade="false" schema="action" table="circulation"/>
            <child column="workstation" foreignKey="circulation_workstation_fkey" implied="false" onDeleteCascade="false" schema="action" table="circulation"/>
            <child column="workstation" foreignKey="in_house_use_workstation_fkey" implied="false" onDeleteCascade="false" schema="action" table="in_house_use"/>
            <child column="workstation" foreignKey="non_cat_in_house_use_workstation_fkey" implied="false" onDeleteCascade="false" schema="action" table="non_cat_in_house_use"/>
            <child column="ws" foreignKey="toolbar_ws_fkey" implied="false" onDeleteCascade="true" schema="actor" table="toolbar"/>
            <child column="opt_in_ws" foreignKey="usr_org_unit_opt_in_opt_in_ws_fkey" implied="false" onDeleteCascade="false" schema="actor" table="usr_org_unit_opt_in"/>
            <child column="workstation" foreignKey="workstation_setting_workstation_fkey" implied="false" onDeleteCascade="true" schema="actor" table="workstation_setting"/>
            <child column="inventory_workstation" foreignKey="copy_inventory_inventory_workstation_fkey" implied="false" onDeleteCascade="false" schema="asset" table="copy_inventory"/>
            <child column="cash_drawer" foreignKey="bnm_desk_payment_cash_drawer_fkey" implied="false" onDeleteCascade="false" schema="money" table="bnm_desk_payment"/>
            <child column="workstation" foreignKey="session_tracker_workstation_fkey" implied="false" onDeleteCascade="true" schema="vandelay" table="session_tracker"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="owning_lib" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="workstation_owning_lib_fkey" implied="false" onDeleteCascade="false" schema="actor" table="org_unit"/>
         </column>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="workstation_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="workstation_name_key" unique="true">
            <column ascending="true" name="name"/>
         </index>
      </table>
      <table name="workstation_setting" remarks="" schema="actor" type="TABLE">
         <column autoUpdated="true" defaultValue="nextval('actor.workstation_setting_id_seq'::regclass)" digits="0" id="0" name="id" nullable="false" remarks="" size="10" type="serial" typeCode="4"/>
         <column autoUpdated="false" defaultValue="null" digits="0" id="1" name="workstation" nullable="false" remarks="" size="10" type="int4" typeCode="4">
            <parent column="id" foreignKey="workstation_setting_workstation_fkey" implied="false" onDeleteCascade="true" schema="actor" table="workstation"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="2" name="name" nullable="false" remarks="" size="2147483647" type="text" typeCode="12">
            <parent column="name" foreignKey="workstation_setting_name_fkey" implied="false" onDeleteCascade="true" schema="config" table="workstation_setting_type"/>
         </column>
         <column autoUpdated="false" defaultValue="null" digits="0" id="3" name="value" nullable="false" remarks="" size="2147483647" type="json" typeCode="1111"/>
         <primaryKey column="id" sequenceNumberInPK="1"/>
         <index name="workstation_setting_pkey" unique="true">
            <column ascending="true" name="id"/>
         </index>
         <index name="actor_workstation_setting_workstation_idx" unique="false">
            <column ascending="true" name="workstation"/>
         </index>
         <index name="ws_once_per_key" unique="true">
            <column ascending="true" name="workstation"/>
            <column ascending="true" name="name"/>
         </index>
      </table>
   </tables>
   <routines>
      <routine dataAccess="MODIFIES" deterministic="false" name="address_alert_matches(org_unit integer, street1 text, street2 text, city text, county text, state text, country text, post_code text, mailing_address boolean DEFAULT false, billing_address boolean DEFAULT false)" returnType="SETOF actor.address_alert" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT *
FROM actor.address_alert
WHERE
    active
    AND owner IN (SELECT id FROM actor.org_unit_ancestors($1)) 
    AND (
        (NOT mailing_address AND NOT billing_address)
        OR (mailing_address AND $9)
        OR (billing_address AND $10)
    )
    AND (
            (
                match_all
                AND COALESCE($2, '') ~* COALESCE(street1,   '.*')
                AND COALESCE($3, '') ~* COALESCE(street2,   '.*')
                AND COALESCE($4, '') ~* COALESCE(city,      '.*')
                AND COALESCE($5, '') ~* COALESCE(county,    '.*')
                AND COALESCE($6, '') ~* COALESCE(state,     '.*')
                AND COALESCE($7, '') ~* COALESCE(country,   '.*')
                AND COALESCE($8, '') ~* COALESCE(post_code, '.*')
            ) OR (
                NOT match_all 
                AND (  
                       $2 ~* street1
                    OR $3 ~* street2
                    OR $4 ~* city
                    OR $5 ~* county
                    OR $6 ~* state
                    OR $7 ~* country
                    OR $8 ~* post_code
                )
            )
        )
    ORDER BY actor.org_unit_proximity(owner, $1)]]></definition>
         <parameters>
            <parameter mode="IN" name="org_unit" type="integer"/>
            <parameter mode="IN" name="street1" type="text"/>
            <parameter mode="IN" name="street2" type="text"/>
            <parameter mode="IN" name="city" type="text"/>
            <parameter mode="IN" name="county" type="text"/>
            <parameter mode="IN" name="state" type="text"/>
            <parameter mode="IN" name="country" type="text"/>
            <parameter mode="IN" name="post_code" type="text"/>
            <parameter mode="IN" name="mailing_address" type="boolean"/>
            <parameter mode="IN" name="billing_address" type="boolean"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="approve_pending_address(pending_id integer)" returnType="bigint" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[Replaces an address with a pending address.  This is done by giving the pending 
address the ID of the old address.  The replaced address is retained with -id.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
    old_id INT;
BEGIN
    SELECT INTO old_id replaces FROM actor.usr_address where id = pending_id;
    IF old_id IS NULL THEN
        UPDATE actor.usr_address SET pending = 'f' WHERE id = pending_id;
        RETURN pending_id;
    END IF;
    -- address replaces an existing address
    DELETE FROM actor.usr_address WHERE id = -old_id;
    UPDATE actor.usr_address SET id = -id WHERE id = old_id;
    UPDATE actor.usr_address SET replaces = NULL, id = old_id, pending = 'f' WHERE id = pending_id;
    RETURN old_id;
END]]></definition>
         <parameters>
            <parameter mode="IN" name="pending_id" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="au_updated()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[BEGIN
    NEW.last_update_time := now();
	RETURN NEW;
END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="calculate_system_penalties(match_user integer, context_org integer)" returnType="SETOF actor.usr_standing_penalty" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    user_object         actor.usr%ROWTYPE;
    new_sp_row          actor.usr_standing_penalty%ROWTYPE;
    existing_sp_row     actor.usr_standing_penalty%ROWTYPE;
    collections_fines   permission.grp_penalty_threshold%ROWTYPE;
    max_fines           permission.grp_penalty_threshold%ROWTYPE;
    max_overdue         permission.grp_penalty_threshold%ROWTYPE;
    max_items_out       permission.grp_penalty_threshold%ROWTYPE;
    max_lost            permission.grp_penalty_threshold%ROWTYPE;
    max_longoverdue     permission.grp_penalty_threshold%ROWTYPE;
    penalty_id          INT;
    tmp_grp             INT;
    items_overdue       INT;
    items_out           INT;
    items_lost          INT;
    items_longoverdue   INT;
    context_org_list    INT[];
    current_fines        NUMERIC(8,2) := 0.0;
    tmp_fines            NUMERIC(8,2);
    tmp_groc            RECORD;
    tmp_circ            RECORD;
    tmp_org             actor.org_unit%ROWTYPE;
    tmp_penalty         config.standing_penalty%ROWTYPE;
    tmp_depth           INTEGER;
BEGIN
    SELECT INTO user_object * FROM actor.usr WHERE id = match_user;

    -- Max fines
    SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
    SELECT BTRIM(value,'"')::INT INTO penalty_id FROM actor.org_unit_ancestor_setting('circ.custom_penalty_override.PATRON_EXCEEDS_FINES', context_org);
    IF NOT FOUND THEN penalty_id := 1; END IF;

    -- Fail if the user has a high fine balance
    LOOP
        tmp_grp := user_object.profile;
        LOOP
            SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = penalty_id AND org_unit = tmp_org.id;

            IF max_fines.threshold IS NULL THEN
                SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
            ELSE
                EXIT;
            END IF;

            IF tmp_grp IS NULL THEN
                EXIT;
            END IF;
        END LOOP;

        IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
            EXIT;
        END IF;

        SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;

    END LOOP;

    IF max_fines.threshold IS NOT NULL THEN
        -- The IN clause in all of the RETURN QUERY calls is used to surface now-stale non-custom penalties
        -- so that the calling code can clear them at the boundary where custom penalties are configured.
        -- Otherwise we would see orphaned "stock" system penalties that would never go away on their own.
        RETURN QUERY
            SELECT  *
              FROM  actor.usr_standing_penalty
              WHERE usr = match_user
                    AND org_unit = max_fines.org_unit
                    AND (stop_date IS NULL or stop_date > NOW())
                    AND standing_penalty IN (1, penalty_id);

        SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( max_fines.org_unit );

        SELECT  SUM(f.balance_owed) INTO current_fines
          FROM  money.materialized_billable_xact_summary f
                JOIN (
                    SELECT  r.id
                      FROM  booking.reservation r
                      WHERE r.usr = match_user
                            AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
                            AND xact_finish IS NULL
                                UNION ALL
                    SELECT  g.id
                      FROM  money.grocery g
                      WHERE g.usr = match_user
                            AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
                            AND xact_finish IS NULL
                                UNION ALL
                    SELECT  circ.id
                      FROM  action.circulation circ
                      WHERE circ.usr = match_user
                            AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
                            AND xact_finish IS NULL ) l USING (id);

        IF current_fines >= max_fines.threshold THEN
            new_sp_row.usr := match_user;
            new_sp_row.org_unit := max_fines.org_unit;
            new_sp_row.standing_penalty := penalty_id;
            RETURN NEXT new_sp_row;
        END IF;
    END IF;

    -- Start over for max overdue
    SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
    SELECT BTRIM(value,'"')::INT INTO penalty_id FROM actor.org_unit_ancestor_setting('circ.custom_penalty_override.PATRON_EXCEEDS_OVERDUE_COUNT', context_org);
    IF NOT FOUND THEN penalty_id := 2; END IF;

    -- Fail if the user has too many overdue items
    LOOP
        tmp_grp := user_object.profile;
        LOOP

            SELECT * INTO max_overdue FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = penalty_id AND org_unit = tmp_org.id;

            IF max_overdue.threshold IS NULL THEN
                SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
            ELSE
                EXIT;
            END IF;

            IF tmp_grp IS NULL THEN
                EXIT;
            END IF;
        END LOOP;

        IF max_overdue.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
            EXIT;
        END IF;

        SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;

    END LOOP;

    IF max_overdue.threshold IS NOT NULL THEN

        RETURN QUERY
            SELECT  *
              FROM  actor.usr_standing_penalty
              WHERE usr = match_user
                    AND org_unit = max_overdue.org_unit
                    AND (stop_date IS NULL or stop_date > NOW())
                    AND standing_penalty IN (2, penalty_id);

        SELECT  INTO items_overdue COUNT(*)
          FROM  action.circulation circ
                JOIN  actor.org_unit_full_path( max_overdue.org_unit ) fp ON (circ.circ_lib = fp.id)
          WHERE circ.usr = match_user
            AND circ.checkin_time IS NULL
            AND circ.due_date < NOW()
            AND (circ.stop_fines = 'MAXFINES' OR circ.stop_fines IS NULL);

        IF items_overdue >= max_overdue.threshold::INT THEN
            new_sp_row.usr := match_user;
            new_sp_row.org_unit := max_overdue.org_unit;
            new_sp_row.standing_penalty := penalty_id;
            RETURN NEXT new_sp_row;
        END IF;
    END IF;

    -- Start over for max out
    SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
    SELECT BTRIM(value,'"')::INT INTO penalty_id FROM actor.org_unit_ancestor_setting('circ.custom_penalty_override.PATRON_EXCEEDS_CHECKOUT_COUNT', context_org);
    IF NOT FOUND THEN penalty_id := 3; END IF;

    -- Fail if the user has too many checked out items
    LOOP
        tmp_grp := user_object.profile;
        LOOP
            SELECT * INTO max_items_out FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = penalty_id AND org_unit = tmp_org.id;

            IF max_items_out.threshold IS NULL THEN
                SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
            ELSE
                EXIT;
            END IF;

            IF tmp_grp IS NULL THEN
                EXIT;
            END IF;
        END LOOP;

        IF max_items_out.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
            EXIT;
        END IF;

        SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;

    END LOOP;


    -- Fail if the user has too many items checked out
    IF max_items_out.threshold IS NOT NULL THEN

        RETURN QUERY
            SELECT  *
              FROM  actor.usr_standing_penalty
              WHERE usr = match_user
                    AND org_unit = max_items_out.org_unit
                    AND (stop_date IS NULL or stop_date > NOW())
                    AND standing_penalty IN (3, penalty_id);

        SELECT  INTO items_out COUNT(*)
          FROM  action.circulation circ
                JOIN  actor.org_unit_full_path( max_items_out.org_unit ) fp ON (circ.circ_lib = fp.id)
          WHERE circ.usr = match_user
                AND circ.checkin_time IS NULL
                AND (circ.stop_fines IN (
                    SELECT 'MAXFINES'::TEXT
                    UNION ALL
                    SELECT 'LONGOVERDUE'::TEXT
                    UNION ALL
                    SELECT 'LOST'::TEXT
                    WHERE 'true' ILIKE
                    (
                        SELECT CASE
                            WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.tally_lost', circ.circ_lib)) ILIKE 'true' THEN 'true'
                            ELSE 'false'
                        END
                    )
                    UNION ALL
                    SELECT 'CLAIMSRETURNED'::TEXT
                    WHERE 'false' ILIKE
                    (
                        SELECT CASE
                            WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.do_not_tally_claims_returned', circ.circ_lib)) ILIKE 'true' THEN 'true'
                            ELSE 'false'
                        END
                    )
                    ) OR circ.stop_fines IS NULL)
                AND xact_finish IS NULL;

           IF items_out >= max_items_out.threshold::INT THEN
            new_sp_row.usr := match_user;
            new_sp_row.org_unit := max_items_out.org_unit;
            new_sp_row.standing_penalty := penalty_id;
            RETURN NEXT new_sp_row;
           END IF;
    END IF;

    -- Start over for max lost
    SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
    SELECT BTRIM(value,'"')::INT INTO penalty_id FROM actor.org_unit_ancestor_setting('circ.custom_penalty_override.PATRON_EXCEEDS_LOST_COUNT', context_org);
    IF NOT FOUND THEN penalty_id := 5; END IF;

    -- Fail if the user has too many lost items
    LOOP
        tmp_grp := user_object.profile;
        LOOP

            SELECT * INTO max_lost FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = penalty_id AND org_unit = tmp_org.id;

            IF max_lost.threshold IS NULL THEN
                SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
            ELSE
                EXIT;
            END IF;

            IF tmp_grp IS NULL THEN
                EXIT;
            END IF;
        END LOOP;

        IF max_lost.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
            EXIT;
        END IF;

        SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;

    END LOOP;

    IF max_lost.threshold IS NOT NULL THEN

        RETURN QUERY
            SELECT  *
            FROM  actor.usr_standing_penalty
            WHERE usr = match_user
                AND org_unit = max_lost.org_unit
                AND (stop_date IS NULL or stop_date > NOW())
                AND standing_penalty IN (5, penalty_id);

        SELECT  INTO items_lost COUNT(*)
        FROM  action.circulation circ
            JOIN  actor.org_unit_full_path( max_lost.org_unit ) fp ON (circ.circ_lib = fp.id)
        WHERE circ.usr = match_user
            AND circ.checkin_time IS NULL
            AND (circ.stop_fines = 'LOST')
            AND xact_finish IS NULL;

        IF items_lost >= max_lost.threshold::INT AND 0 < max_lost.threshold::INT THEN
            new_sp_row.usr := match_user;
            new_sp_row.org_unit := max_lost.org_unit;
            new_sp_row.standing_penalty := penalty_id;
            RETURN NEXT new_sp_row;
        END IF;
    END IF;

    -- Start over for max longoverdue
    SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
    SELECT BTRIM(value,'"')::INT INTO penalty_id FROM actor.org_unit_ancestor_setting('circ.custom_penalty_override.PATRON_EXCEEDS_LONGOVERDUE_COUNT', context_org);
    IF NOT FOUND THEN penalty_id := 35; END IF;

    -- Fail if the user has too many longoverdue items
    LOOP
        tmp_grp := user_object.profile;
        LOOP

            SELECT * INTO max_longoverdue 
                FROM permission.grp_penalty_threshold 
                WHERE grp = tmp_grp AND 
                    penalty = penalty_id AND 
                    org_unit = tmp_org.id;

            IF max_longoverdue.threshold IS NULL THEN
                SELECT parent INTO tmp_grp 
                    FROM permission.grp_tree WHERE id = tmp_grp;
            ELSE
                EXIT;
            END IF;

            IF tmp_grp IS NULL THEN
                EXIT;
            END IF;
        END LOOP;

        IF max_longoverdue.threshold IS NOT NULL 
                OR tmp_org.parent_ou IS NULL THEN
            EXIT;
        END IF;

        SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;

    END LOOP;

    IF max_longoverdue.threshold IS NOT NULL THEN

        RETURN QUERY
            SELECT  *
            FROM  actor.usr_standing_penalty
            WHERE usr = match_user
                AND org_unit = max_longoverdue.org_unit
                AND (stop_date IS NULL or stop_date > NOW())
                AND standing_penalty IN (35, penalty_id);

        SELECT INTO items_longoverdue COUNT(*)
        FROM action.circulation circ
            JOIN actor.org_unit_full_path( max_longoverdue.org_unit ) fp 
                ON (circ.circ_lib = fp.id)
        WHERE circ.usr = match_user
            AND circ.checkin_time IS NULL
            AND (circ.stop_fines = 'LONGOVERDUE')
            AND xact_finish IS NULL;

        IF items_longoverdue >= max_longoverdue.threshold::INT 
                AND 0 < max_longoverdue.threshold::INT THEN
            new_sp_row.usr := match_user;
            new_sp_row.org_unit := max_longoverdue.org_unit;
            new_sp_row.standing_penalty := penalty_id;
            RETURN NEXT new_sp_row;
        END IF;
    END IF;


    -- Start over for collections warning
    SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
    SELECT BTRIM(value,'"')::INT INTO penalty_id FROM actor.org_unit_ancestor_setting('circ.custom_penalty_override.PATRON_EXCEEDS_COLLECTIONS_WARNING', context_org);
    IF NOT FOUND THEN penalty_id := 4; END IF;

    -- Fail if the user has a collections-level fine balance
    LOOP
        tmp_grp := user_object.profile;
        LOOP
            SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = penalty_id AND org_unit = tmp_org.id;

            IF max_fines.threshold IS NULL THEN
                SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
            ELSE
                EXIT;
            END IF;

            IF tmp_grp IS NULL THEN
                EXIT;
            END IF;
        END LOOP;

        IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
            EXIT;
        END IF;

        SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;

    END LOOP;

    IF max_fines.threshold IS NOT NULL THEN

        RETURN QUERY
            SELECT  *
              FROM  actor.usr_standing_penalty
              WHERE usr = match_user
                    AND org_unit = max_fines.org_unit
                    AND (stop_date IS NULL or stop_date > NOW())
                    AND standing_penalty IN (4, penalty_id);

        SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( max_fines.org_unit );

        SELECT  SUM(f.balance_owed) INTO current_fines
          FROM  money.materialized_billable_xact_summary f
                JOIN (
                    SELECT  r.id
                      FROM  booking.reservation r
                      WHERE r.usr = match_user
                            AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
                            AND r.xact_finish IS NULL
                                UNION ALL
                    SELECT  g.id
                      FROM  money.grocery g
                      WHERE g.usr = match_user
                            AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
                            AND g.xact_finish IS NULL
                                UNION ALL
                    SELECT  circ.id
                      FROM  action.circulation circ
                      WHERE circ.usr = match_user
                            AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
                            AND circ.xact_finish IS NULL ) l USING (id);

        IF current_fines >= max_fines.threshold THEN
            new_sp_row.usr := match_user;
            new_sp_row.org_unit := max_fines.org_unit;
            new_sp_row.standing_penalty := penalty_id;
            RETURN NEXT new_sp_row;
        END IF;
    END IF;

    -- Start over for in collections
    SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
    SELECT BTRIM(value,'"')::INT INTO penalty_id FROM actor.org_unit_ancestor_setting('circ.custom_penalty_override.PATRON_IN_COLLECTIONS', context_org);
    IF NOT FOUND THEN penalty_id := 30; END IF;

    -- Remove the in-collections penalty if the user has paid down enough
    -- This penalty is different, because this code is not responsible for creating 
    -- new in-collections penalties, only for removing them
    LOOP
        tmp_grp := user_object.profile;
        LOOP
            SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = penalty_id AND org_unit = tmp_org.id;

            IF max_fines.threshold IS NULL THEN
                SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
            ELSE
                EXIT;
            END IF;

            IF tmp_grp IS NULL THEN
                EXIT;
            END IF;
        END LOOP;

        IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
            EXIT;
        END IF;

        SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;

    END LOOP;

    IF max_fines.threshold IS NOT NULL THEN

        SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( max_fines.org_unit );

        -- first, see if the user had paid down to the threshold
        SELECT  SUM(f.balance_owed) INTO current_fines
          FROM  money.materialized_billable_xact_summary f
                JOIN (
                    SELECT  r.id
                      FROM  booking.reservation r
                      WHERE r.usr = match_user
                            AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
                            AND r.xact_finish IS NULL
                                UNION ALL
                    SELECT  g.id
                      FROM  money.grocery g
                      WHERE g.usr = match_user
                            AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
                            AND g.xact_finish IS NULL
                                UNION ALL
                    SELECT  circ.id
                      FROM  action.circulation circ
                      WHERE circ.usr = match_user
                            AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
                            AND circ.xact_finish IS NULL ) l USING (id);

        IF current_fines IS NULL OR current_fines <= max_fines.threshold THEN
            -- patron has paid down enough

            SELECT INTO tmp_penalty * FROM config.standing_penalty WHERE id = penalty_id;

            IF tmp_penalty.org_depth IS NOT NULL THEN

                -- since this code is not responsible for applying the penalty, it can't 
                -- guarantee the current context org will match the org at which the penalty 
                --- was applied.  search up the org tree until we hit the configured penalty depth
                SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
                SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;

                WHILE tmp_depth >= tmp_penalty.org_depth LOOP

                    RETURN QUERY
                        SELECT  *
                          FROM  actor.usr_standing_penalty
                          WHERE usr = match_user
                                AND org_unit = tmp_org.id
                                AND (stop_date IS NULL or stop_date > NOW())
                                AND standing_penalty IN (30, penalty_id);

                    IF tmp_org.parent_ou IS NULL THEN
                        EXIT;
                    END IF;

                    SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
                    SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
                END LOOP;

            ELSE

                -- no penalty depth is defined, look for exact matches

                RETURN QUERY
                    SELECT  *
                      FROM  actor.usr_standing_penalty
                      WHERE usr = match_user
                            AND org_unit = max_fines.org_unit
                            AND (stop_date IS NULL or stop_date > NOW())
                            AND standing_penalty IN (30, penalty_id);
            END IF;
    
        END IF;

    END IF;

    RETURN;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="match_user" type="integer"/>
            <parameter mode="IN" name="context_org" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="change_password(user_id integer, new_pw text, pw_type text DEFAULT 'main'::text)" returnType="void" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[Allows setting a salted password for a user by passing actor.usr id and the text of the password.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
    new_salt TEXT;
BEGIN
    SELECT actor.create_salt(pw_type) INTO new_salt;

    IF pw_type = 'main' THEN
        -- Only 'main' passwords are required to have
        -- the extra layer of MD5 hashing.
        PERFORM actor.set_passwd(
            user_id, pw_type, md5(new_salt || md5(new_pw)), new_salt
        );

    ELSE
        PERFORM actor.set_passwd(user_id, pw_type, new_pw, new_salt);
    END IF;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="user_id" type="integer"/>
            <parameter mode="IN" name="new_pw" type="text"/>
            <parameter mode="IN" name="pw_type" type="text"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="create_salt(pw_type text)" returnType="text" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    type_row actor.passwd_type%ROWTYPE;
BEGIN
    /* Returns a new salt based on the passwd_type encryption settings.
     * Returns NULL If the password type is not crypt()'ed.
     */

    SELECT INTO type_row * FROM actor.passwd_type WHERE code = pw_type;

    IF NOT FOUND THEN
        RETURN EXCEPTION 'No such password type: %', pw_type;
    END IF;

    IF type_row.iter_count IS NULL THEN
        -- This password type is unsalted.  That's OK.
        RETURN NULL;
    END IF;

    RETURN gen_salt(type_row.crypt_algo, type_row.iter_count);
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="pw_type" type="text"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="crypt_pw_insert()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[BEGIN
		NEW.passwd = MD5( NEW.passwd );
		RETURN NEW;
	END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="crypt_pw_update()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[BEGIN
		IF NEW.passwd <> OLD.passwd THEN
			NEW.passwd = MD5( NEW.passwd );
		END IF;
		RETURN NEW;
	END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="get_cascade_setting(setting_name text, org_id integer, user_id integer, workstation_id integer)" returnType="actor.cascade_setting_summary" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    setting_value JSON;
    summary actor.cascade_setting_summary;
    org_setting_type config.org_unit_setting_type%ROWTYPE;
BEGIN

    summary.name := setting_name;

    -- Collect the org setting type status first in case we exit early.
    -- The existance of an org setting type is not considered
    -- privileged information.
    SELECT INTO org_setting_type * 
        FROM config.org_unit_setting_type WHERE name = setting_name;
    IF FOUND THEN
        summary.has_org_setting := TRUE;
    ELSE
        summary.has_org_setting := FALSE;
    END IF;

    -- User and workstation settings have the same priority.
    -- Start with user settings since that's the simplest code path.
    -- The workstation_id is ignored if no user_id is provided.
    IF user_id IS NOT NULL THEN

        SELECT INTO summary.value value FROM actor.usr_setting
            WHERE usr = user_id AND name = setting_name;

        IF FOUND THEN
            -- if we have a value, we have a setting type
            summary.has_user_setting := TRUE;

            IF workstation_id IS NOT NULL THEN
                -- Only inform the caller about the workstation
                -- setting type disposition when a workstation id is
                -- provided.  Otherwise, it's NULL to indicate UNKNOWN.
                summary.has_workstation_setting := FALSE;
            END IF;

            RETURN summary;
        END IF;

        -- no user setting value, but a setting type may exist
        SELECT INTO summary.has_user_setting EXISTS (
            SELECT TRUE FROM config.usr_setting_type 
            WHERE name = setting_name
        );

        IF workstation_id IS NOT NULL THEN 

            IF NOT summary.has_user_setting THEN
                -- A workstation setting type may only exist when a user
                -- setting type does not.

                SELECT INTO summary.value value 
                    FROM actor.workstation_setting         
                    WHERE workstation = workstation_id AND name = setting_name;

                IF FOUND THEN
                    -- if we have a value, we have a setting type
                    summary.has_workstation_setting := TRUE;
                    RETURN summary;
                END IF;

                -- no value, but a setting type may exist
                SELECT INTO summary.has_workstation_setting EXISTS (
                    SELECT TRUE FROM config.workstation_setting_type 
                    WHERE name = setting_name
                );
            END IF;

            -- Finally make use of the workstation to determine the org
            -- unit if none is provided.
            IF org_id IS NULL AND summary.has_org_setting THEN
                SELECT INTO org_id owning_lib 
                    FROM actor.workstation WHERE id = workstation_id;
            END IF;
        END IF;
    END IF;

    -- Some org unit settings are protected by a view permission.
    -- First see if we have any data that needs protecting, then 
    -- check the permission if needed.

    IF NOT summary.has_org_setting THEN
        RETURN summary;
    END IF;

    -- avoid putting the value into the summary until we confirm
    -- the value should be visible to the caller.
    SELECT INTO setting_value value 
        FROM actor.org_unit_ancestor_setting(setting_name, org_id);

    IF NOT FOUND THEN
        -- No value found -- perm check is irrelevant.
        RETURN summary;
    END IF;

    IF org_setting_type.view_perm IS NOT NULL THEN

        IF user_id IS NULL THEN
            RAISE NOTICE 'Perm check required but no user_id provided';
            RETURN summary;
        END IF;

        IF NOT permission.usr_has_perm(
            user_id, (SELECT code FROM permission.perm_list 
                WHERE id = org_setting_type.view_perm), org_id) 
        THEN
            RAISE NOTICE 'Perm check failed for user % on %',
                user_id, org_setting_type.view_perm;
            RETURN summary;
        END IF;
    END IF;

    -- Perm check succeeded or was not necessary.
    summary.value := setting_value;
    RETURN summary;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="setting_name" type="text"/>
            <parameter mode="IN" name="org_id" type="integer"/>
            <parameter mode="IN" name="user_id" type="integer"/>
            <parameter mode="IN" name="workstation_id" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="get_cascade_setting_batch(setting_names text[], org_id integer, user_id integer, workstation_id integer)" returnType="SETOF actor.cascade_setting_summary" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[-- Returns a row per setting matching the setting name order.  If no 
-- value is applied, NULL is returned to retain name-response ordering.
DECLARE
    setting_name TEXT;
    summary actor.cascade_setting_summary;
BEGIN
    FOREACH setting_name IN ARRAY setting_names LOOP
        SELECT INTO summary * FROM actor.get_cascade_setting(
            setting_Name, org_id, user_id, workstation_id);
        RETURN NEXT summary;
    END LOOP;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="setting_names" type="text[]"/>
            <parameter mode="IN" name="org_id" type="integer"/>
            <parameter mode="IN" name="user_id" type="integer"/>
            <parameter mode="IN" name="workstation_id" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="get_salt(pw_usr integer, pw_type text)" returnType="text" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    pw_salt TEXT;
    type_row actor.passwd_type%ROWTYPE;
BEGIN
    /* Returns the salt for the requested user + type.  If the password 
     * type of "main" is requested and no password exists in actor.passwd, 
     * the user's existing password is migrated and the new salt is returned.
     * Returns NULL if the password type is not crypt'ed (iter_count is NULL).
     */

    SELECT INTO pw_salt salt FROM actor.passwd 
        WHERE usr = pw_usr AND passwd_type = pw_type;

    IF FOUND THEN
        RETURN pw_salt;
    END IF;

    IF pw_type = 'main' THEN
        -- Main password has not yet been migrated. 
        -- Do it now and return the newly created salt.
        RETURN actor.migrate_passwd(pw_usr);
    END IF;

    -- We have no salt to return.  actor.create_salt() needed.
    RETURN NULL;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="pw_usr" type="integer"/>
            <parameter mode="IN" name="pw_type" type="text"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="insert_usr_activity(usr integer, ewho text, ewhat text, ehow text)" returnType="SETOF actor.usr_activity" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    new_row actor.usr_activity%ROWTYPE;
BEGIN
    SELECT id INTO new_row.etype FROM actor.usr_activity_get_type(ewho, ewhat, ehow);
    IF FOUND THEN
        new_row.usr := usr;
        INSERT INTO actor.usr_activity (usr, etype) 
            VALUES (usr, new_row.etype)
            RETURNING * INTO new_row;
        RETURN NEXT new_row;
    END IF;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="usr" type="integer"/>
            <parameter mode="IN" name="ewho" type="text"/>
            <parameter mode="IN" name="ewhat" type="text"/>
            <parameter mode="IN" name="ehow" type="text"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="migrate_passwd(pw_usr integer)" returnType="text" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    pw_salt TEXT;
    usr_row actor.usr%ROWTYPE;
BEGIN
    /* Migrates legacy actor.usr.passwd value to actor.passwd with 
     * a password type 'main' and returns the new salt.  For backwards
     * compatibility with existing CHAP-style API's, we perform a 
     * layer of intermediate MD5(MD5()) hashing.  This is intermediate
     * hashing is not required of other passwords.
     */

    -- Avoid calling get_salt() here, because it may result in a 
    -- migrate_passwd() call, creating a loop.
    SELECT INTO pw_salt salt FROM actor.passwd 
        WHERE usr = pw_usr AND passwd_type = 'main';

    -- Only migrate passwords that have not already been migrated.
    IF FOUND THEN
        RETURN pw_salt;
    END IF;

    SELECT INTO usr_row * FROM actor.usr WHERE id = pw_usr;

    pw_salt := actor.create_salt('main');

    PERFORM actor.set_passwd(
        pw_usr, 'main', MD5(pw_salt || usr_row.passwd), pw_salt);

    -- clear the existing password
    UPDATE actor.usr SET passwd = '' WHERE id = usr_row.id;

    RETURN pw_salt;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="pw_usr" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_ancestor_at_depth(integer, integer)" returnType="actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT	a.*
	  FROM	actor.org_unit a
	  WHERE	id = ( SELECT FIRST(x.id)
	  		 FROM	actor.org_unit_ancestors($1) x
			   	JOIN actor.org_unit_type y
					ON x.ou_type = y.id AND y.depth = $2);]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_ancestor_setting(setting_name text, org_id integer)" returnType="SETOF actor.org_unit_setting" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[Search "up" the org_unit tree until we find the first occurrence of an 
org_unit_setting with the given name.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
    setting RECORD;
    cur_org INT;
BEGIN
    cur_org := org_id;
    LOOP
        SELECT INTO setting * FROM actor.org_unit_setting WHERE org_unit = cur_org AND name = setting_name;
        IF FOUND THEN
            RETURN NEXT setting;
            EXIT;
        END IF;
        SELECT INTO cur_org parent_ou FROM actor.org_unit WHERE id = cur_org;
        EXIT WHEN cur_org IS NULL;
    END LOOP;
    RETURN;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="setting_name" type="text"/>
            <parameter mode="IN" name="org_id" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_ancestor_setting_batch(org_id integer, setting_names text[])" returnType="SETOF actor.org_unit_setting" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[For each setting name passed, search "up" the org_unit tree until
we find the first occurrence of an org_unit_setting with the given name.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
    setting RECORD;
    setting_name TEXT;
    cur_org INT;
BEGIN
    FOREACH setting_name IN ARRAY setting_names
    LOOP
        cur_org := org_id;
        LOOP
            SELECT INTO setting * FROM actor.org_unit_setting WHERE org_unit = cur_org AND name = setting_name;
            IF FOUND THEN
                RETURN NEXT setting;
                EXIT;
            END IF;
            SELECT INTO cur_org parent_ou FROM actor.org_unit WHERE id = cur_org;
            EXIT WHEN cur_org IS NULL;
        END LOOP;
    END LOOP;
    RETURN;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="org_id" type="integer"/>
            <parameter mode="IN" name="setting_names" type="text[]"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_ancestor_setting_batch_by_org(setting_name text, org_ids integer[])" returnType="SETOF actor.org_unit_setting" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    setting RECORD;
    org_id INTEGER;
BEGIN
    /*  Returns one actor.org_unit_setting row per org unit ID provided.
        When no setting exists for a given org unit, the setting row
        will contain all empty values. */
    FOREACH org_id IN ARRAY org_ids LOOP
        SELECT INTO setting * FROM 
            actor.org_unit_ancestor_setting(setting_name, org_id);
        RETURN NEXT setting;
    END LOOP;
    RETURN;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="setting_name" type="text"/>
            <parameter mode="IN" name="org_ids" type="integer[]"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_ancestors(integer)" returnType="SETOF actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[WITH RECURSIVE org_unit_ancestors_distance(id, distance) AS (
            SELECT $1, 0
        UNION
            SELECT ou.parent_ou, ouad.distance+1
            FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad ON (ou.id = ouad.id)
            WHERE ou.parent_ou IS NOT NULL
    )
    SELECT ou.* FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad USING (id) ORDER BY ouad.distance DESC;]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_ancestors_distance(integer)" returnType="TABLE(id integer, distance integer)" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[WITH RECURSIVE org_unit_ancestors_distance(id, distance) AS (
            SELECT $1, 0
        UNION
            SELECT ou.parent_ou, ouad.distance+1
            FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad ON (ou.id = ouad.id)
            WHERE ou.parent_ou IS NOT NULL
    )
    SELECT * FROM org_unit_ancestors_distance;]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="TABLE" name="id" type="integer"/>
            <parameter mode="TABLE" name="distance" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_combined_ancestors(integer, integer)" returnType="SETOF actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT	*
	  FROM	actor.org_unit_ancestors($1)
			UNION
	SELECT	*
	  FROM	actor.org_unit_ancestors($2);]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_common_ancestors(integer, integer)" returnType="SETOF actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT	*
	  FROM	actor.org_unit_ancestors($1)
			INTERSECT
	SELECT	*
	  FROM	actor.org_unit_ancestors($2);]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_descendants(integer)" returnType="SETOF actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[WITH RECURSIVE descendant_depth AS (
        SELECT  ou.id,
                ou.parent_ou,
                out.depth
          FROM  actor.org_unit ou
                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
          WHERE ou.id = $1
            UNION ALL
        SELECT  ou.id,
                ou.parent_ou,
                out.depth
          FROM  actor.org_unit ou
                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
                JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
    ) SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id);]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_descendants(integer, integer)" returnType="SETOF actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[WITH RECURSIVE descendant_depth AS (
        SELECT  ou.id,
                ou.parent_ou,
                out.depth
          FROM  actor.org_unit ou
                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
                JOIN anscestor_depth ad ON (ad.id = ou.id)
          WHERE ad.depth = $2
            UNION ALL
        SELECT  ou.id,
                ou.parent_ou,
                out.depth
          FROM  actor.org_unit ou
                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
                JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
    ), anscestor_depth AS (
        SELECT  ou.id,
                ou.parent_ou,
                out.depth
          FROM  actor.org_unit ou
                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
          WHERE ou.id = $1
            UNION ALL
        SELECT  ou.id,
                ou.parent_ou,
                out.depth
          FROM  actor.org_unit ou
                JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
                JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
    ) SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id);]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_descendants_distance(integer)" returnType="TABLE(id integer, distance integer)" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[WITH RECURSIVE org_unit_descendants_distance(id, distance) AS (
            SELECT $1, 0
        UNION
            SELECT ou.id, oudd.distance+1
            FROM actor.org_unit ou JOIN org_unit_descendants_distance oudd ON (ou.parent_ou = oudd.id)
    )
    SELECT * FROM org_unit_descendants_distance;]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="TABLE" name="id" type="integer"/>
            <parameter mode="TABLE" name="distance" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_full_path(integer)" returnType="SETOF actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT  aou.*
      FROM  actor.org_unit AS aou
            JOIN (
                (SELECT au.id, t.depth FROM actor.org_unit_ancestors($1) AS au JOIN actor.org_unit_type t ON (au.ou_type = t.id))
                    UNION
                (SELECT au.id, t.depth FROM actor.org_unit_descendants($1) AS au JOIN actor.org_unit_type t ON (au.ou_type = t.id))
            ) AS ad ON (aou.id=ad.id)
      ORDER BY ad.depth;]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_full_path(integer, integer)" returnType="SETOF actor.org_unit" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT	* FROM actor.org_unit_full_path((actor.org_unit_ancestor_at_depth($1, $2)).id)]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_parent_protect()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
		current_aou actor.org_unit%ROWTYPE;
		seen_ous    INT[];
		depth_count INT;
	BEGIN
		current_aou := NEW;
		depth_count := 0;
		seen_ous := ARRAY[NEW.id];

		IF (TG_OP = 'UPDATE') THEN
			IF (NEW.parent_ou IS NOT DISTINCT FROM OLD.parent_ou) THEN
				RETURN NEW; -- Doing an UPDATE with no change, just return it
			END IF;
		END IF;

		LOOP
			IF current_aou.parent_ou IS NULL THEN -- Top of the org tree?
				RETURN NEW; -- No loop. Carry on.
			END IF;
			IF current_aou.parent_ou = ANY(seen_ous) THEN -- Parent is one we have seen?
				RAISE 'OU LOOP: Saw % twice', current_aou.parent_ou; -- LOOP! ABORT!
			END IF;
			-- Get the next one!
			SELECT INTO current_aou * FROM actor.org_unit WHERE id = current_aou.parent_ou;
			seen_ous := seen_ous || current_aou.id;
			depth_count := depth_count + 1;
			IF depth_count = 100 THEN
				RAISE 'OU CHECK TOO DEEP';
			END IF;
		END LOOP;

		RETURN NEW;
	END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_prox_update()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[BEGIN


IF TG_OP = 'DELETE' THEN

    DELETE FROM actor.org_unit_proximity WHERE (from_org = OLD.id or to_org= OLD.id);

END IF;

IF TG_OP = 'UPDATE' THEN

    IF NEW.parent_ou <> OLD.parent_ou THEN

        DELETE FROM actor.org_unit_proximity WHERE (from_org = OLD.id or to_org= OLD.id);
            INSERT INTO actor.org_unit_proximity (from_org, to_org, prox)
            SELECT  l.id, r.id, actor.org_unit_proximity(l.id,r.id)
                FROM  actor.org_unit l, actor.org_unit r
                WHERE (l.id = NEW.id or r.id = NEW.id);

    END IF;

END IF;

IF TG_OP = 'INSERT' THEN

     INSERT INTO actor.org_unit_proximity (from_org, to_org, prox)
     SELECT  l.id, r.id, actor.org_unit_proximity(l.id,r.id)
         FROM  actor.org_unit l, actor.org_unit r
         WHERE (l.id = NEW.id or r.id = NEW.id);

END IF;

RETURN null;

END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_proximity(integer, integer)" returnType="integer" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT COUNT(id)::INT FROM (
		SELECT id FROM actor.org_unit_combined_ancestors($1, $2)
			EXCEPT
		SELECT id FROM actor.org_unit_common_ancestors($1, $2)
	) z;]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="org_unit_simple_path(integer, integer)" returnType="integer[]" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[WITH RECURSIVE descendant_depth(id, path) AS (
        SELECT  aou.id,
                ARRAY[aou.id]
          FROM  actor.org_unit aou
                JOIN actor.org_unit_type aout ON (aout.id = aou.ou_type)
          WHERE aou.id = $2
            UNION ALL
        SELECT  aou.id,
                dd.path || ARRAY[aou.id]
          FROM  actor.org_unit aou
                JOIN actor.org_unit_type aout ON (aout.id = aou.ou_type)
                JOIN descendant_depth dd ON (dd.id = aou.parent_ou)
    ) SELECT dd.path
        FROM actor.org_unit aou
        JOIN descendant_depth dd USING (id)
        WHERE aou.id = $1 ORDER BY dd.path;]]></definition>
         <parameters>
            <parameter mode="IN" type="integer"/>
            <parameter mode="IN" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="permit_remoteauth(profile_name text, userid bigint)" returnType="text" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    usr               actor.usr%ROWTYPE;
    profile           config.remoteauth_profile%ROWTYPE;
    perm              TEXT;
    context_org_list  INT[];
    home_prox         INT;
    block             TEXT;
    penalty_count     INT;
BEGIN

    SELECT INTO usr * FROM actor.usr WHERE id = userid AND NOT deleted;
    IF usr IS NULL THEN
        RETURN 'not_found';
    END IF;

    IF usr.barred IS TRUE THEN
        RETURN 'blocked';
    END IF;

    SELECT INTO profile * FROM config.remoteauth_profile WHERE name = profile_name;
    SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( profile.context_org );

    -- user's home library must be within the context org
    IF profile.restrict_to_org IS TRUE AND usr.home_ou NOT IN (SELECT * FROM UNNEST(context_org_list)) THEN
        RETURN 'not_found';
    END IF;

    SELECT INTO perm code FROM permission.perm_list WHERE id = profile.perm;
    IF permission.usr_has_perm(usr.id, perm, profile.context_org) IS FALSE THEN
        RETURN 'not_found';
    END IF;
    
    IF usr.expire_date < NOW() AND profile.allow_expired IS FALSE THEN
        RETURN 'expired';
    END IF;

    IF usr.active IS FALSE AND profile.allow_inactive IS FALSE THEN
        RETURN 'blocked';
    END IF;

    -- Proximity of user's home_ou to context_org to see if penalties should be ignored.
    SELECT INTO home_prox prox FROM actor.org_unit_proximity WHERE from_org = usr.home_ou AND to_org = profile.context_org;

    -- Loop through the block list to see if the user has any matching penalties.
    IF profile.block_list IS NOT NULL THEN
        FOR block IN SELECT UNNEST(STRING_TO_ARRAY(profile.block_list, '|')) LOOP
            SELECT INTO penalty_count COUNT(DISTINCT csp.*)
                FROM  actor.usr_standing_penalty usp
                        JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
                WHERE usp.usr = usr.id
                        AND usp.org_unit IN ( SELECT * FROM UNNEST(context_org_list) )
                        AND ( usp.stop_date IS NULL or usp.stop_date > NOW() )
                        AND ( csp.ignore_proximity IS NULL OR csp.ignore_proximity < home_prox )
                        AND csp.block_list ~ block;
            IF penalty_count > 0 THEN
                -- User has penalties that match this block, so auth is not permitted.
                -- Don't bother testing the rest of the block list.
                RETURN 'blocked';
            END IF;
        END LOOP;
    END IF;

    -- User has passed all tests.
    RETURN 'success';

END;]]></definition>
         <parameters>
            <parameter mode="IN" name="profile_name" type="text"/>
            <parameter mode="IN" name="userid" type="bigint"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="purge_usr_activity_by_type(act_type integer)" returnType="void" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    cur_usr INTEGER;
BEGIN
    FOR cur_usr IN SELECT DISTINCT(usr)
        FROM actor.usr_activity WHERE etype = act_type LOOP
        DELETE FROM actor.usr_activity WHERE id IN (
            SELECT id
            FROM actor.usr_activity
            WHERE usr = cur_usr AND etype = act_type
            ORDER BY event_time DESC OFFSET 1
        );

    END LOOP;
END]]></definition>
         <parameters>
            <parameter mode="IN" name="act_type" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="restrict_usr_message_limited()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[BEGIN
    IF TG_OP = 'UPDATE' THEN
        UPDATE actor.usr_message
        SET    read_date = NEW.read_date,
               deleted   = NEW.deleted
        WHERE  id = NEW.id;
        RETURN NEW;
    END IF;
    RETURN NULL;
END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="set_passwd(pw_usr integer, pw_type text, new_pass text, new_salt text DEFAULT NULL::text)" returnType="boolean" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    pw_salt TEXT;
    pw_text TEXT;
BEGIN
    /* Sets the password value, creating a new actor.passwd row if needed.
     * If the password type supports it, the new_pass value is crypt()'ed.
     * For crypt'ed passwords, the salt comes from one of 3 places in order:
     * new_salt (if present), existing salt (if present), newly created 
     * salt.
     */

    IF new_salt IS NOT NULL THEN
        pw_salt := new_salt;
    ELSE 
        pw_salt := actor.get_salt(pw_usr, pw_type);

        IF pw_salt IS NULL THEN
            /* We have no salt for this user + type.  Assume they want a 
             * new salt.  If this type is unsalted, create_salt() will 
             * return NULL. */
            pw_salt := actor.create_salt(pw_type);
        END IF;
    END IF;

    IF pw_salt IS NULL THEN 
        pw_text := new_pass; -- unsalted, use as-is.
    ELSE
        pw_text := CRYPT(new_pass, pw_salt);
    END IF;

    UPDATE actor.passwd 
        SET passwd = pw_text, salt = pw_salt, edit_date = NOW()
        WHERE usr = pw_usr AND passwd_type = pw_type;

    IF NOT FOUND THEN
        -- no password row exists for this user + type.  Create one.
        INSERT INTO actor.passwd (usr, passwd_type, salt, passwd) 
            VALUES (pw_usr, pw_type, pw_salt, pw_text);
    END IF;

    RETURN TRUE;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="pw_usr" type="integer"/>
            <parameter mode="IN" name="pw_type" type="text"/>
            <parameter mode="IN" name="new_pass" type="text"/>
            <parameter mode="IN" name="new_salt" type="text"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="stat_cat_check()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    sipfield actor.stat_cat_sip_fields%ROWTYPE;
    use_count INT;
BEGIN
    IF NEW.sip_field IS NOT NULL THEN
        SELECT INTO sipfield * FROM actor.stat_cat_sip_fields WHERE field = NEW.sip_field;
        IF sipfield.one_only THEN
            SELECT INTO use_count count(id) FROM actor.stat_cat WHERE sip_field = NEW.sip_field AND id != NEW.id;
            IF use_count > 0 THEN
                RAISE EXCEPTION 'Sip field cannot be used twice';
            END IF;
        END IF;
    END IF;
    RETURN NEW;
END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="user_ingest_name_keywords()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[BEGIN
    NEW.name_kw_tsvector := TO_TSVECTOR(
        COALESCE(NEW.prefix, '')                || ' ' || 
        COALESCE(NEW.first_given_name, '')      || ' ' || 
        COALESCE(evergreen.unaccent_and_squash(NEW.first_given_name), '') || ' ' || 
        COALESCE(NEW.second_given_name, '')     || ' ' || 
        COALESCE(evergreen.unaccent_and_squash(NEW.second_given_name), '') || ' ' || 
        COALESCE(NEW.family_name, '')           || ' ' || 
        COALESCE(evergreen.unaccent_and_squash(NEW.family_name), '') || ' ' || 
        COALESCE(NEW.suffix, '')                || ' ' || 
        COALESCE(NEW.pref_prefix, '')            || ' ' || 
        COALESCE(NEW.pref_first_given_name, '')  || ' ' || 
        COALESCE(evergreen.unaccent_and_squash(NEW.pref_first_given_name), '') || ' ' || 
        COALESCE(NEW.pref_second_given_name, '') || ' ' || 
        COALESCE(evergreen.unaccent_and_squash(NEW.pref_second_given_name), '') || ' ' || 
        COALESCE(NEW.pref_family_name, '')       || ' ' || 
        COALESCE(evergreen.unaccent_and_squash(NEW.pref_family_name), '') || ' ' || 
        COALESCE(NEW.pref_suffix, '')            || ' ' || 
        COALESCE(NEW.name_keywords, '')
    );
    RETURN NEW;
END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="usr_activity_get_type(ewho text, ewhat text, ehow text)" returnType="SETOF config.usr_activity_type" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="sql"><![CDATA[SELECT * FROM config.usr_activity_type 
    WHERE 
        enabled AND 
        (ewho  IS NULL OR ewho  = $1) AND
        (ewhat IS NULL OR ewhat = $2) AND
        (ehow  IS NULL OR ehow  = $3) 
    ORDER BY 
        -- BOOL comparisons sort false to true
        COALESCE(ewho, '')  != COALESCE($1, ''),
        COALESCE(ewhat,'')  != COALESCE($2, ''),
        COALESCE(ehow, '')  != COALESCE($3, '') 
    LIMIT 1;]]></definition>
         <parameters>
            <parameter mode="IN" name="ewho" type="text"/>
            <parameter mode="IN" name="ewhat" type="text"/>
            <parameter mode="IN" name="ehow" type="text"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="usr_activity_transient_trg()" returnType="trigger" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[BEGIN
    DELETE FROM actor.usr_activity act USING config.usr_activity_type atype
        WHERE atype.transient AND 
            NEW.etype = atype.id AND
            act.etype = atype.id AND
            act.usr = NEW.usr;
    RETURN NEW;
END;]]></definition>
         <parameters>
            <parameter mode="IN"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="usr_delete(src_usr integer, dest_usr integer)" returnType="void" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[Logically deletes a user.  Removes personally identifiable information,
and purges associated data in other tables.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
	old_profile actor.usr.profile%type;
	old_home_ou actor.usr.home_ou%type;
	new_profile actor.usr.profile%type;
	new_home_ou actor.usr.home_ou%type;
	new_name    text;
	new_dob     actor.usr.dob%type;
BEGIN
	SELECT
		id || '-PURGED-' || now(),
		profile,
		home_ou,
		dob
	INTO
		new_name,
		old_profile,
		old_home_ou,
		new_dob
	FROM
		actor.usr
	WHERE
		id = src_usr;
	--
	-- Quit if no such user
	--
	IF old_profile IS NULL THEN
		RETURN;
	END IF;
	--
	perform actor.usr_purge_data( src_usr, dest_usr );
	--
	-- Find the root grp_tree and the root org_unit.  This would be simpler if we 
	-- could assume that there is only one root.  Theoretically, someday, maybe,
	-- there could be multiple roots, so we take extra trouble to get the right ones.
	--
	SELECT
		id
	INTO
		new_profile
	FROM
		permission.grp_ancestors( old_profile )
	WHERE
		parent is null;
	--
	SELECT
		id
	INTO
		new_home_ou
	FROM
		actor.org_unit_ancestors( old_home_ou )
	WHERE
		parent_ou is null;
	--
	-- Truncate date of birth
	--
	IF new_dob IS NOT NULL THEN
		new_dob := date_trunc( 'year', new_dob );
	END IF;
	--
	UPDATE
		actor.usr
		SET
			card = NULL,
			profile = new_profile,
			usrname = new_name,
			email = NULL,
			passwd = random()::text,
			standing = DEFAULT,
			ident_type = 
			(
				SELECT MIN( id )
				FROM config.identification_type
			),
			ident_value = NULL,
			ident_type2 = NULL,
			ident_value2 = NULL,
			net_access_level = DEFAULT,
			photo_url = NULL,
			prefix = NULL,
			first_given_name = new_name,
			second_given_name = NULL,
			family_name = new_name,
			suffix = NULL,
			alias = NULL,
            guardian = NULL,
			day_phone = NULL,
			evening_phone = NULL,
			other_phone = NULL,
			mailing_address = NULL,
			billing_address = NULL,
			home_ou = new_home_ou,
			dob = new_dob,
			active = FALSE,
			master_account = DEFAULT, 
			super_user = DEFAULT,
			barred = FALSE,
			deleted = TRUE,
			juvenile = DEFAULT,
			usrgroup = 0,
			claims_returned_count = DEFAULT,
			credit_forward_balance = DEFAULT,
			last_xact_id = DEFAULT,
			pref_prefix = NULL,
			pref_first_given_name = NULL,
			pref_second_given_name = NULL,
			pref_family_name = NULL,
			pref_suffix = NULL,
			name_keywords = NULL,
			create_date = now(),
			expire_date = now()
	WHERE
		id = src_usr;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="src_usr" type="integer"/>
            <parameter mode="IN" name="dest_usr" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="usr_merge(src_usr integer, dest_usr integer, del_addrs boolean, del_cards boolean, deactivate_cards boolean)" returnType="void" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[Merges all user date from src_usr to dest_usr.  When collisions occur, 
keep dest_usr's data and delete src_usr's data.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
	suffix TEXT;
	bucket_row RECORD;
	picklist_row RECORD;
	queue_row RECORD;
	folder_row RECORD;
BEGIN

    -- Bail if src_usr equals dest_usr because the result of merging a
    -- user with itself is not what you want.
    IF src_usr = dest_usr THEN
        RETURN;
    END IF;

    -- do some initial cleanup 
    UPDATE actor.usr SET card = NULL WHERE id = src_usr;
    UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
    UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;

    -- actor.*
    IF del_cards THEN
        DELETE FROM actor.card where usr = src_usr;
    ELSE
        IF deactivate_cards THEN
            UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
        END IF;
        UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
    END IF;


    IF del_addrs THEN
        DELETE FROM actor.usr_address WHERE usr = src_usr;
    ELSE
        UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
    END IF;

    UPDATE actor.usr_message SET usr = dest_usr WHERE usr = src_usr;
    -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
    UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
    PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
    PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);

    -- permission.*
    PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
    PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
    PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
    PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);


    -- container.*
	
	-- For each *_bucket table: transfer every bucket belonging to src_usr
	-- into the custody of dest_usr.
	--
	-- In order to avoid colliding with an existing bucket owned by
	-- the destination user, append the source user's id (in parenthesese)
	-- to the name.  If you still get a collision, add successive
	-- spaces to the name and keep trying until you succeed.
	--
	FOR bucket_row in
		SELECT id, name
		FROM   container.biblio_record_entry_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.biblio_record_entry_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = bucket_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	FOR bucket_row in
		SELECT id, name
		FROM   container.call_number_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.call_number_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = bucket_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	FOR bucket_row in
		SELECT id, name
		FROM   container.copy_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.copy_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = bucket_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	FOR bucket_row in
		SELECT id, name
		FROM   container.user_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.user_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = bucket_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;

    -- vandelay.*
	-- transfer queues the same way we transfer buckets (see above)
	FOR queue_row in
		SELECT id, name
		FROM   vandelay.queue
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  vandelay.queue
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = queue_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

    UPDATE vandelay.session_tracker SET usr = dest_usr WHERE usr = src_usr;

    -- money.*
    PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
    PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
    UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
    UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
    UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;

    -- action.*
    UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
    UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
    UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
    UPDATE action.usr_circ_history SET usr = dest_usr WHERE usr = src_usr;

    UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
    UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
    UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
    UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;

    UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
    UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
    UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
    UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
    UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;

    -- acq.*
    UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
	UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
    UPDATE acq.invoice SET closed_by = dest_usr WHERE closed_by = src_usr;

	-- transfer picklists the same way we transfer buckets (see above)
	FOR picklist_row in
		SELECT id, name
		FROM   acq.picklist
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  acq.picklist
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = picklist_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

    UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
    UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
    UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
    UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
    UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
    UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
    UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
    UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;

    -- asset.*
    UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
    UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
    UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
    UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
    UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
    UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;

    -- serial.*
    UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
    UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;

    -- reporter.*
    -- It's not uncommon to define the reporter schema in a replica 
    -- DB only, so don't assume these tables exist in the write DB.
    BEGIN
    	UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
    EXCEPTION WHEN undefined_table THEN
        -- do nothing
    END;
    BEGIN
    	UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
    EXCEPTION WHEN undefined_table THEN
        -- do nothing
    END;
    BEGIN
    	UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
    EXCEPTION WHEN undefined_table THEN
        -- do nothing
    END;
    BEGIN
		-- transfer folders the same way we transfer buckets (see above)
		FOR folder_row in
			SELECT id, name
			FROM   reporter.template_folder
			WHERE  owner = src_usr
		LOOP
			suffix := ' (' || src_usr || ')';
			LOOP
				BEGIN
					UPDATE  reporter.template_folder
					SET     owner = dest_usr, name = name || suffix
					WHERE   id = folder_row.id;
				EXCEPTION WHEN unique_violation THEN
					suffix := suffix || ' ';
					CONTINUE;
				END;
				EXIT;
			END LOOP;
		END LOOP;
    EXCEPTION WHEN undefined_table THEN
        -- do nothing
    END;
    BEGIN
		-- transfer folders the same way we transfer buckets (see above)
		FOR folder_row in
			SELECT id, name
			FROM   reporter.report_folder
			WHERE  owner = src_usr
		LOOP
			suffix := ' (' || src_usr || ')';
			LOOP
				BEGIN
					UPDATE  reporter.report_folder
					SET     owner = dest_usr, name = name || suffix
					WHERE   id = folder_row.id;
				EXCEPTION WHEN unique_violation THEN
					suffix := suffix || ' ';
					CONTINUE;
				END;
				EXIT;
			END LOOP;
		END LOOP;
    EXCEPTION WHEN undefined_table THEN
        -- do nothing
    END;
    BEGIN
		-- transfer folders the same way we transfer buckets (see above)
		FOR folder_row in
			SELECT id, name
			FROM   reporter.output_folder
			WHERE  owner = src_usr
		LOOP
			suffix := ' (' || src_usr || ')';
			LOOP
				BEGIN
					UPDATE  reporter.output_folder
					SET     owner = dest_usr, name = name || suffix
					WHERE   id = folder_row.id;
				EXCEPTION WHEN unique_violation THEN
					suffix := suffix || ' ';
					CONTINUE;
				END;
				EXIT;
			END LOOP;
		END LOOP;
    EXCEPTION WHEN undefined_table THEN
        -- do nothing
    END;

    -- propagate preferred name values from the source user to the
    -- destination user, but only when values are not being replaced.
    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr)
    UPDATE actor.usr SET 
        pref_prefix = 
            COALESCE(pref_prefix, (SELECT pref_prefix FROM susr)),
        pref_first_given_name = 
            COALESCE(pref_first_given_name, (SELECT pref_first_given_name FROM susr)),
        pref_second_given_name = 
            COALESCE(pref_second_given_name, (SELECT pref_second_given_name FROM susr)),
        pref_family_name = 
            COALESCE(pref_family_name, (SELECT pref_family_name FROM susr)),
        pref_suffix = 
            COALESCE(pref_suffix, (SELECT pref_suffix FROM susr))
    WHERE id = dest_usr;

    -- Copy and deduplicate name keywords
    -- String -> array -> rows -> DISTINCT -> array -> string
    WITH susr AS (SELECT * FROM actor.usr WHERE id = src_usr),
         dusr AS (SELECT * FROM actor.usr WHERE id = dest_usr)
    UPDATE actor.usr SET name_keywords = (
        WITH keywords AS (
            SELECT DISTINCT UNNEST(
                REGEXP_SPLIT_TO_ARRAY(
                    COALESCE((SELECT name_keywords FROM susr), '') || ' ' ||
                    COALESCE((SELECT name_keywords FROM dusr), ''),  E'\\s+'
                )
            ) AS parts
        ) SELECT STRING_AGG(kw.parts, ' ') FROM keywords kw
    ) WHERE id = dest_usr;

    -- Finally, delete the source user
    PERFORM actor.usr_delete(src_usr,dest_usr);

END;]]></definition>
         <parameters>
            <parameter mode="IN" name="src_usr" type="integer"/>
            <parameter mode="IN" name="dest_usr" type="integer"/>
            <parameter mode="IN" name="del_addrs" type="boolean"/>
            <parameter mode="IN" name="del_cards" type="boolean"/>
            <parameter mode="IN" name="deactivate_cards" type="boolean"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="usr_merge_rows(table_name text, col_name text, src_usr integer, dest_usr integer)" returnType="void" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[Attempts to move each row of the specified table from src_user to dest_user.  
Where conflicts exist, the conflicting "source" row is deleted.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
    sel TEXT;
    upd TEXT;
    del TEXT;
    cur_row RECORD;
BEGIN
    sel := 'SELECT id::BIGINT FROM ' || table_name || ' WHERE ' || quote_ident(col_name) || ' = ' || quote_literal(src_usr);
    upd := 'UPDATE ' || table_name || ' SET ' || quote_ident(col_name) || ' = ' || quote_literal(dest_usr) || ' WHERE id = ';
    del := 'DELETE FROM ' || table_name || ' WHERE id = ';
    FOR cur_row IN EXECUTE sel LOOP
        BEGIN
            --RAISE NOTICE 'Attempting to merge % %', table_name, cur_row.id;
            EXECUTE upd || cur_row.id;
        EXCEPTION WHEN unique_violation THEN
            --RAISE NOTICE 'Deleting conflicting % %', table_name, cur_row.id;
            EXECUTE del || cur_row.id;
        END;
    END LOOP;
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="table_name" type="text"/>
            <parameter mode="IN" name="col_name" type="text"/>
            <parameter mode="IN" name="src_usr" type="integer"/>
            <parameter mode="IN" name="dest_usr" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="usr_purge_data(src_usr integer, specified_dest_usr integer)" returnType="void" securityType="INVOKER" type="FUNCTION">
         <comment><![CDATA[Finds rows dependent on a given row in actor.usr and either deletes them
or reassigns them to a different user.]]></comment>
         <definition language="plpgsql"><![CDATA[DECLARE
	suffix TEXT;
	renamable_row RECORD;
	dest_usr INTEGER;
BEGIN

	IF specified_dest_usr IS NULL THEN
		dest_usr := 1; -- Admin user on stock installs
	ELSE
		dest_usr := specified_dest_usr;
	END IF;

    -- action_trigger.event (even doing this, event_output may--and probably does--contain PII and should have a retention/removal policy)
    UPDATE action_trigger.event SET context_user = dest_usr WHERE context_user = src_usr;

	-- acq.*
	UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
	UPDATE acq.lineitem SET creator = dest_usr WHERE creator = src_usr;
	UPDATE acq.lineitem SET editor = dest_usr WHERE editor = src_usr;
	UPDATE acq.lineitem SET selector = dest_usr WHERE selector = src_usr;
	UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
	UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
	UPDATE acq.invoice SET closed_by = dest_usr WHERE closed_by = src_usr;
	DELETE FROM acq.lineitem_usr_attr_definition WHERE usr = src_usr;

	-- Update with a rename to avoid collisions
	FOR renamable_row in
		SELECT id, name
		FROM   acq.picklist
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  acq.picklist
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = renamable_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	UPDATE acq.picklist SET creator = dest_usr WHERE creator = src_usr;
	UPDATE acq.picklist SET editor = dest_usr WHERE editor = src_usr;
	UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
	UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
	UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
	UPDATE acq.purchase_order SET creator = dest_usr WHERE creator = src_usr;
	UPDATE acq.purchase_order SET editor = dest_usr WHERE editor = src_usr;
	UPDATE acq.claim_event SET creator = dest_usr WHERE creator = src_usr;

	-- action.*
	DELETE FROM action.circulation WHERE usr = src_usr;
	UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
	UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
	UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
	UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
	UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
	DELETE FROM action.hold_request WHERE usr = src_usr;
	UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
	UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
	DELETE FROM action.non_cataloged_circulation WHERE patron = src_usr;
	UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
	DELETE FROM action.survey_response WHERE usr = src_usr;
	UPDATE action.fieldset SET owner = dest_usr WHERE owner = src_usr;
	DELETE FROM action.usr_circ_history WHERE usr = src_usr;
	UPDATE action.curbside SET notes = NULL WHERE patron = src_usr;

	-- actor.*
	DELETE FROM actor.card WHERE usr = src_usr;
	DELETE FROM actor.stat_cat_entry_usr_map WHERE target_usr = src_usr;
	DELETE FROM actor.usr_privacy_waiver WHERE usr = src_usr;
	DELETE FROM actor.usr_message WHERE usr = src_usr;

	-- The following update is intended to avoid transient violations of a foreign
	-- key constraint, whereby actor.usr_address references itself.  It may not be
	-- necessary, but it does no harm.
	UPDATE actor.usr_address SET replaces = NULL
		WHERE usr = src_usr AND replaces IS NOT NULL;
	DELETE FROM actor.usr_address WHERE usr = src_usr;
	DELETE FROM actor.usr_org_unit_opt_in WHERE usr = src_usr;
	UPDATE actor.usr_org_unit_opt_in SET staff = dest_usr WHERE staff = src_usr;
	DELETE FROM actor.usr_setting WHERE usr = src_usr;
	DELETE FROM actor.usr_standing_penalty WHERE usr = src_usr;
	UPDATE actor.usr_message SET title = 'purged', message = 'purged', read_date = NOW() WHERE usr = src_usr;
	DELETE FROM actor.usr_message WHERE usr = src_usr;
	UPDATE actor.usr_standing_penalty SET staff = dest_usr WHERE staff = src_usr;
	UPDATE actor.usr_message SET editor = dest_usr WHERE editor = src_usr;

	-- asset.*
	UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
	UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
	UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
	UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
	UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
	UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;

	-- auditor.*
	DELETE FROM auditor.actor_usr_address_history WHERE id = src_usr;
	DELETE FROM auditor.actor_usr_history WHERE id = src_usr;
	UPDATE auditor.asset_call_number_history SET creator = dest_usr WHERE creator = src_usr;
	UPDATE auditor.asset_call_number_history SET editor  = dest_usr WHERE editor  = src_usr;
	UPDATE auditor.asset_copy_history SET creator = dest_usr WHERE creator = src_usr;
	UPDATE auditor.asset_copy_history SET editor  = dest_usr WHERE editor  = src_usr;
	UPDATE auditor.biblio_record_entry_history SET creator = dest_usr WHERE creator = src_usr;
	UPDATE auditor.biblio_record_entry_history SET editor  = dest_usr WHERE editor  = src_usr;

	-- biblio.*
	UPDATE biblio.record_entry SET creator = dest_usr WHERE creator = src_usr;
	UPDATE biblio.record_entry SET editor = dest_usr WHERE editor = src_usr;
	UPDATE biblio.record_note SET creator = dest_usr WHERE creator = src_usr;
	UPDATE biblio.record_note SET editor = dest_usr WHERE editor = src_usr;

	-- container.*
	-- Update buckets with a rename to avoid collisions
	FOR renamable_row in
		SELECT id, name
		FROM   container.biblio_record_entry_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.biblio_record_entry_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = renamable_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	FOR renamable_row in
		SELECT id, name
		FROM   container.call_number_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.call_number_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = renamable_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	FOR renamable_row in
		SELECT id, name
		FROM   container.copy_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.copy_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = renamable_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	FOR renamable_row in
		SELECT id, name
		FROM   container.user_bucket
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  container.user_bucket
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = renamable_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

	DELETE FROM container.user_bucket_item WHERE target_user = src_usr;

	-- money.*
	DELETE FROM money.billable_xact WHERE usr = src_usr;
	DELETE FROM money.collections_tracker WHERE usr = src_usr;
	UPDATE money.collections_tracker SET collector = dest_usr WHERE collector = src_usr;

	-- permission.*
	DELETE FROM permission.usr_grp_map WHERE usr = src_usr;
	DELETE FROM permission.usr_object_perm_map WHERE usr = src_usr;
	DELETE FROM permission.usr_perm_map WHERE usr = src_usr;
	DELETE FROM permission.usr_work_ou_map WHERE usr = src_usr;

	-- reporter.*
	-- Update with a rename to avoid collisions
	BEGIN
		FOR renamable_row in
			SELECT id, name
			FROM   reporter.output_folder
			WHERE  owner = src_usr
		LOOP
			suffix := ' (' || src_usr || ')';
			LOOP
				BEGIN
					UPDATE  reporter.output_folder
					SET     owner = dest_usr, name = name || suffix
					WHERE   id = renamable_row.id;
				EXCEPTION WHEN unique_violation THEN
					suffix := suffix || ' ';
					CONTINUE;
				END;
				EXIT;
			END LOOP;
		END LOOP;
	EXCEPTION WHEN undefined_table THEN
		-- do nothing
	END;

	BEGIN
		UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
	EXCEPTION WHEN undefined_table THEN
		-- do nothing
	END;

	-- Update with a rename to avoid collisions
	BEGIN
		FOR renamable_row in
			SELECT id, name
			FROM   reporter.report_folder
			WHERE  owner = src_usr
		LOOP
			suffix := ' (' || src_usr || ')';
			LOOP
				BEGIN
					UPDATE  reporter.report_folder
					SET     owner = dest_usr, name = name || suffix
					WHERE   id = renamable_row.id;
				EXCEPTION WHEN unique_violation THEN
					suffix := suffix || ' ';
					CONTINUE;
				END;
				EXIT;
			END LOOP;
		END LOOP;
	EXCEPTION WHEN undefined_table THEN
		-- do nothing
	END;

	BEGIN
		UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
	EXCEPTION WHEN undefined_table THEN
		-- do nothing
	END;

	BEGIN
		UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
	EXCEPTION WHEN undefined_table THEN
		-- do nothing
	END;

	-- Update with a rename to avoid collisions
	BEGIN
		FOR renamable_row in
			SELECT id, name
			FROM   reporter.template_folder
			WHERE  owner = src_usr
		LOOP
			suffix := ' (' || src_usr || ')';
			LOOP
				BEGIN
					UPDATE  reporter.template_folder
					SET     owner = dest_usr, name = name || suffix
					WHERE   id = renamable_row.id;
				EXCEPTION WHEN unique_violation THEN
					suffix := suffix || ' ';
					CONTINUE;
				END;
				EXIT;
			END LOOP;
		END LOOP;
	EXCEPTION WHEN undefined_table THEN
	-- do nothing
	END;

	-- vandelay.*
	-- Update with a rename to avoid collisions
	FOR renamable_row in
		SELECT id, name
		FROM   vandelay.queue
		WHERE  owner = src_usr
	LOOP
		suffix := ' (' || src_usr || ')';
		LOOP
			BEGIN
				UPDATE  vandelay.queue
				SET     owner = dest_usr, name = name || suffix
				WHERE   id = renamable_row.id;
			EXCEPTION WHEN unique_violation THEN
				suffix := suffix || ' ';
				CONTINUE;
			END;
			EXIT;
		END LOOP;
	END LOOP;

    UPDATE vandelay.session_tracker SET usr = dest_usr WHERE usr = src_usr;

    -- NULL-ify addresses last so other cleanup (e.g. circ anonymization)
    -- can access the information before deletion.
	UPDATE actor.usr SET
		active = FALSE,
		card = NULL,
		mailing_address = NULL,
		billing_address = NULL
	WHERE id = src_usr;

END;]]></definition>
         <parameters>
            <parameter mode="IN" name="src_usr" type="integer"/>
            <parameter mode="IN" name="specified_dest_usr" type="integer"/>
         </parameters>
      </routine>
      <routine dataAccess="MODIFIES" deterministic="false" name="verify_passwd(pw_usr integer, pw_type text, test_passwd text)" returnType="boolean" securityType="INVOKER" type="FUNCTION">
         <comment/>
         <definition language="plpgsql"><![CDATA[DECLARE
    pw_salt TEXT;
BEGIN
    /* Returns TRUE if the password provided matches the in-db password.  
     * If the password type is salted, we compare the output of CRYPT().
     * NOTE: test_passwd is MD5(salt || MD5(password)) for legacy 
     * 'main' passwords.
     */

    SELECT INTO pw_salt salt FROM actor.passwd 
        WHERE usr = pw_usr AND passwd_type = pw_type;

    IF NOT FOUND THEN
        -- no such password
        RETURN FALSE;
    END IF;

    IF pw_salt IS NULL THEN
        -- Password is unsalted, compare the un-CRYPT'ed values.
        RETURN EXISTS (
            SELECT TRUE FROM actor.passwd WHERE 
                usr = pw_usr AND
                passwd_type = pw_type AND
                passwd = test_passwd
        );
    END IF;

    RETURN EXISTS (
        SELECT TRUE FROM actor.passwd WHERE 
            usr = pw_usr AND
            passwd_type = pw_type AND
            passwd = CRYPT(test_passwd, pw_salt)
    );
END;]]></definition>
         <parameters>
            <parameter mode="IN" name="pw_usr" type="integer"/>
            <parameter mode="IN" name="pw_type" type="text"/>
            <parameter mode="IN" name="test_passwd" type="text"/>
         </parameters>
      </routine>
   </routines>
</database>
