Dumped on 2009-02-24

Index of database - evergreen


Schema _prod_replica_set


Table: _prod_replica_set.sl_archive_counter

_prod_replica_set.sl_archive_counter Structure
F-Key Name Type Description
ac_num bigint
ac_timestamp timestamp without time zone

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_config_lock

This table exists solely to prevent overlapping execution of configuration change procedures and the resulting possible deadlocks.

_prod_replica_set.sl_config_lock Structure
F-Key Name Type Description
dummy integer

 

Permissions which apply to _prod_replica_set.sl_config_lock
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_confirm

Holds confirmation of replication events. After a period of time, Slony removes old confirmed events from both this table and the sl_event table.

_prod_replica_set.sl_confirm Structure
F-Key Name Type Description
con_origin integer

The ID # (from sl_node.no_id) of the source node for this event
con_received integer
con_seqno bigint

The ID # for the event
con_timestamp timestamp without time zone DEFAULT (timeofday())::timestamp without time zone

When this event was confirmed
sl_confirm_idx1 con_origin, con_received, con_seqno sl_confirm_idx2 con_received, con_seqno

 

Permissions which apply to _prod_replica_set.sl_confirm
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_event

Holds information about replication events. After a period of time, Slony removes old confirmed events from both this table and the sl_confirm table.

_prod_replica_set.sl_event Structure
F-Key Name Type Description
ev_origin integer PRIMARY KEY

The ID # (from sl_node.no_id) of the source node for this event
ev_seqno bigint PRIMARY KEY

The ID # for the event
ev_timestamp timestamp without time zone

When this event record was created
ev_minxid _prod_replica_set.xxid

Earliest XID on provider node for this event
ev_maxxid _prod_replica_set.xxid

Latest XID on provider node for this event
ev_xip text

List of XIDs, in order, that are part of this event
ev_type text

The type of event this record is for. SYNC = Synchronise STORE_NODE = ENABLE_NODE = DROP_NODE = STORE_PATH = DROP_PATH = STORE_LISTEN = DROP_LISTEN = STORE_SET = DROP_SET = MERGE_SET = SET_ADD_TABLE = SET_ADD_SEQUENCE = STORE_TRIGGER = DROP_TRIGGER = MOVE_SET = ACCEPT_SET = SET_DROP_TABLE = SET_DROP_SEQUENCE = SET_MOVE_TABLE = SET_MOVE_SEQUENCE = FAILOVER_SET = SUBSCRIBE_SET = ENABLE_SUBSCRIPTION = UNSUBSCRIBE_SET = DDL_SCRIPT = ADJUST_SEQ = RESET_CONFIG =
ev_data1 text

Data field containing an argument needed to process the event
ev_data2 text

Data field containing an argument needed to process the event
ev_data3 text

Data field containing an argument needed to process the event
ev_data4 text

Data field containing an argument needed to process the event
ev_data5 text

Data field containing an argument needed to process the event
ev_data6 text

Data field containing an argument needed to process the event
ev_data7 text

Data field containing an argument needed to process the event
ev_data8 text

Data field containing an argument needed to process the event

 

Permissions which apply to _prod_replica_set.sl_event
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_listen

Indicates how nodes listen to events from other nodes in the Slony-I network.

_prod_replica_set.sl_listen Structure
F-Key Name Type Description
_prod_replica_set.sl_node.no_id li_origin integer PRIMARY KEY

The ID # (from sl_node.no_id) of the node this listener is operating on
_prod_replica_set.sl_path.pa_server#1 li_provider integer PRIMARY KEY

The ID # (from sl_node.no_id) of the source node for this listening event
_prod_replica_set.sl_path.pa_client#1 li_receiver integer PRIMARY KEY

The ID # (from sl_node.no_id) of the target node for this listening event

 

Permissions which apply to _prod_replica_set.sl_listen
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_log_1

Stores each change to be propagated to subscriber nodes

_prod_replica_set.sl_log_1 Structure
F-Key Name Type Description
log_origin integer

Origin node from which the change came
log_xid _prod_replica_set.xxid

Transaction ID on the origin node
log_tableid integer

The table ID (from sl_table.tab_id) that this log entry is to affect
log_actionseq bigint
log_cmdtype character(1)

Replication action to take. U = Update, I = Insert, D = DELETE
log_cmddata text

The data needed to perform the log action
PartInd_prod_replica_set_sl_log_1-node-1 log_xid _prod_replica_set.xxid_ops) WHERE (log_origin = 1 sl_log_1_idx1 log_origin, log_xid _prod_replica_set.xxid_ops, log_actionseq sl_log_1_idx2 log_xid _prod_replica_set.xxid_ops

 

Permissions which apply to _prod_replica_set.sl_log_1
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_log_2

Stores each change to be propagated to subscriber nodes

_prod_replica_set.sl_log_2 Structure
F-Key Name Type Description
log_origin integer

Origin node from which the change came
log_xid _prod_replica_set.xxid

Transaction ID on the origin node
log_tableid integer

The table ID (from sl_table.tab_id) that this log entry is to affect
log_actionseq bigint
log_cmdtype character(1)

Replication action to take. U = Update, I = Insert, D = DELETE
log_cmddata text

The data needed to perform the log action
PartInd_prod_replica_set_sl_log_2-node-1 log_xid _prod_replica_set.xxid_ops) WHERE (log_origin = 1 sl_log_2_idx1 log_origin, log_xid _prod_replica_set.xxid_ops, log_actionseq sl_log_2_idx2 log_xid _prod_replica_set.xxid_ops

 

Permissions which apply to _prod_replica_set.sl_log_2
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_node

Holds the list of nodes associated with this namespace.

_prod_replica_set.sl_node Structure
F-Key Name Type Description
no_id integer PRIMARY KEY

The unique ID number for the node
no_active boolean

Is the node active in replication yet?
no_comment text

A human-oriented description of the node
no_spool boolean

Is the node being used for log shipping?

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to _prod_replica_set.sl_node
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_nodelock

Used to prevent multiple slon instances and to identify the backends to kill in terminateNodeConnections().

_prod_replica_set.sl_nodelock Structure
F-Key Name Type Description
nl_nodeid integer PRIMARY KEY

Clients node_id
nl_conncnt serial PRIMARY KEY

Clients connection number
nl_backendpid integer

PID of database backend owning this lock

 

Permissions which apply to _prod_replica_set.sl_nodelock
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_path

Holds connection information for the paths between nodes, and the synchronisation delay

_prod_replica_set.sl_path Structure
F-Key Name Type Description
_prod_replica_set.sl_node.no_id pa_server integer PRIMARY KEY

The Node ID # (from sl_node.no_id) of the data source
_prod_replica_set.sl_node.no_id pa_client integer PRIMARY KEY

The Node ID # (from sl_node.no_id) of the data target
pa_conninfo text NOT NULL

The PostgreSQL connection string used to connect to the source node.
pa_connretry integer

The synchronisation delay, in seconds

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to _prod_replica_set.sl_path
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_registry

_prod_replica_set.sl_registry Structure
F-Key Name Type Description
reg_key text PRIMARY KEY
reg_int4 integer
reg_text text
reg_timestamp timestamp without time zone

Index - Schema _prod_replica_set


View: _prod_replica_set.sl_seqlastvalue

_prod_replica_set.sl_seqlastvalue Structure
F-Key Name Type Description
seq_id integer
seq_set integer
seq_reloid oid
seq_origin integer
seq_last_value bigint
SELECT sq.seq_id
, sq.seq_set
, sq.seq_reloid
, s.set_origin AS seq_origin
, _prod_replica_set.sequencelastvalue
(
     (
           (quote_ident
                 (
                       (pgn.nspname)::text
                 ) || '.'::text
           ) || quote_ident
           (
                 (pgc.relname)::text
           )
     )
) AS seq_last_value 
FROM _prod_replica_set.sl_sequence sq
, _prod_replica_set.sl_set s
, pg_class pgc
, pg_namespace pgn 
WHERE (
     (
           (s.set_id = sq.seq_set)
         AND (pgc.oid = sq.seq_reloid)
     )
   AND (pgn.oid = pgc.relnamespace)
);

 

Permissions which apply to _prod_replica_set.sl_seqlastvalue
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_seqlog

Log of Sequence updates

_prod_replica_set.sl_seqlog Structure
F-Key Name Type Description
seql_seqid integer

Sequence ID
seql_origin integer

Publisher node at which the sequence originates
seql_ev_seqno bigint

Slony-I Event with which this sequence update is associated
seql_last_value bigint

Last value published for this sequence
sl_seqlog_idx seql_origin, seql_ev_seqno, seql_seqid

 

Permissions which apply to _prod_replica_set.sl_seqlog
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_sequence

Similar to sl_table, each entry identifies a sequence being replicated.

_prod_replica_set.sl_sequence Structure
F-Key Name Type Description
seq_id integer PRIMARY KEY

An internally-used ID for Slony-I to use in its sequencing of updates
seq_reloid oid UNIQUE NOT NULL

The OID of the sequence object
seq_relname name NOT NULL

The name of the sdequence in pg_catalog.pg_class.relname used to recover from a dump/restore cycle
seq_nspname name NOT NULL

The name of the schema in pg_catalog.pg_namespace.nspname used to recover from a dump/restore cycle
_prod_replica_set.sl_set.set_id seq_set integer

Indicates which replication set the object is in
seq_comment text

A human-oriented comment

 

Permissions which apply to _prod_replica_set.sl_sequence
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_set

Holds definitions of replication sets.

_prod_replica_set.sl_set Structure
F-Key Name Type Description
set_id integer PRIMARY KEY

A unique ID number for the set.
_prod_replica_set.sl_node.no_id set_origin integer

The ID number of the source node for the replication set.
set_locked _prod_replica_set.xxid

Indicates whether or not the set is locked.
set_comment text

A human-oriented description of the set.

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to _prod_replica_set.sl_set
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_setsync

SYNC information

_prod_replica_set.sl_setsync Structure
F-Key Name Type Description
_prod_replica_set.sl_set.set_id ssy_setid integer PRIMARY KEY

ID number of the replication set
_prod_replica_set.sl_node.no_id ssy_origin integer

ID number of the node
ssy_seqno bigint

Slony-I sequence number
ssy_minxid _prod_replica_set.xxid

Earliest XID in provider system affected by SYNC
ssy_maxxid _prod_replica_set.xxid

Latest XID in provider system affected by SYNC
ssy_xip text

Contains the list of XIDs in progress at SYNC time
ssy_action_list text

action list used during the subscription process. At the time a subscriber copies over data from the origin, it sees all tables in a state somewhere between two SYNC events. Therefore this list must contains all XIDs that are visible at that time, whose operations have therefore already been included in the data copied at the time the initial data copy is done. Those actions may therefore be filtered out of the first SYNC done after subscribing.

 

Permissions which apply to _prod_replica_set.sl_setsync
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


View: _prod_replica_set.sl_status

View showing how far behind remote nodes are.

_prod_replica_set.sl_status Structure
F-Key Name Type Description
st_origin integer
st_received integer
st_last_event bigint
st_last_event_ts timestamp without time zone
st_last_received bigint
st_last_received_ts timestamp without time zone
st_last_received_event_ts timestamp without time zone
st_lag_num_events bigint
st_lag_time interval
SELECT e.ev_origin AS st_origin
, c.con_received AS st_received
, e.ev_seqno AS st_last_event
, e.ev_timestamp AS st_last_event_ts
, c.con_seqno AS st_last_received
, c.con_timestamp AS st_last_received_ts
, ce.ev_timestamp AS st_last_received_event_ts
, (e.ev_seqno - c.con_seqno) AS st_lag_num_events
, (now
     () - 
     (ce.ev_timestamp)::timestamp with time zone
) AS st_lag_time 
FROM _prod_replica_set.sl_event e
, _prod_replica_set.sl_confirm c
, _prod_replica_set.sl_event ce 
WHERE (
     (
           (
                 (
                       (e.ev_origin = c.con_origin)
                     AND (ce.ev_origin = e.ev_origin)
                 )
               AND (ce.ev_seqno = c.con_seqno)
           )
         AND (
                 (e.ev_origin
                       , e.ev_seqno
                 ) IN 
                 (
                  SELECT sl_event.ev_origin
                       , max
                       (sl_event.ev_seqno) AS max 
                    FROM _prod_replica_set.sl_event 
                   WHERE (sl_event.ev_origin = _prod_replica_set.getlocalnodeid
                             ('_prod_replica_set'::name)
                       )
                GROUP BY sl_event.ev_origin
                 )
           )
     )
   AND (
           (c.con_origin
                 , c.con_received
                 , c.con_seqno
           ) IN 
           (
            SELECT sl_confirm.con_origin
                 , sl_confirm.con_received
                 , max
                 (sl_confirm.con_seqno) AS max 
              FROM _prod_replica_set.sl_confirm 
             WHERE (sl_confirm.con_origin = _prod_replica_set.getlocalnodeid
                       ('_prod_replica_set'::name)
                 )
          GROUP BY sl_confirm.con_origin
                 , sl_confirm.con_received
           )
     )
);

 

Permissions which apply to _prod_replica_set.sl_status
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_subscribe

Holds a list of subscriptions on sets

_prod_replica_set.sl_subscribe Structure
F-Key Name Type Description
_prod_replica_set.sl_set.set_id sub_set integer PRIMARY KEY

ID # (from sl_set) of the set being subscribed to
_prod_replica_set.sl_path.pa_server#1 sub_provider integer

ID# (from sl_node) of the node providing data
_prod_replica_set.sl_path.pa_client#1 sub_receiver integer PRIMARY KEY

ID# (from sl_node) of the node receiving data from the provider
sub_forward boolean

Does this provider keep data in sl_log_1/sl_log_2 to allow it to be a provider for other nodes?
sub_active boolean

Has this subscription been activated? This is not set on the subscriber until AFTER the subscriber has received COPY data from the provider

 

Permissions which apply to _prod_replica_set.sl_subscribe
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_table

Holds information about the tables being replicated.

_prod_replica_set.sl_table Structure
F-Key Name Type Description
tab_id integer PRIMARY KEY

Unique key for Slony-I to use to identify the table
tab_reloid oid UNIQUE NOT NULL

The OID of the table in pg_catalog.pg_class.oid
tab_relname name NOT NULL

The name of the table in pg_catalog.pg_class.relname used to recover from a dump/restore cycle
tab_nspname name NOT NULL

The name of the schema in pg_catalog.pg_namespace.nspname used to recover from a dump/restore cycle
_prod_replica_set.sl_set.set_id tab_set integer

ID of the replication set the table is in
tab_idxname name NOT NULL

The name of the primary index of the table
tab_altered boolean NOT NULL

Has the table been modified for replication?
tab_comment text

Human-oriented description of the table

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to _prod_replica_set.sl_table
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Table: _prod_replica_set.sl_trigger

Holds information about triggers on tables managed using Slony-I

_prod_replica_set.sl_trigger Structure
F-Key Name Type Description
_prod_replica_set.sl_table.tab_id trig_tabid integer PRIMARY KEY

Slony-I ID number of table the trigger is on
trig_tgname name PRIMARY KEY

Indicates the name of a trigger

 

Permissions which apply to _prod_replica_set.sl_trigger
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema _prod_replica_set


Function: _prod_replica_set.add_empty_table_to_replication( integer, integer, text, text, text, text )

Returns: bigint

Language: PLPGSQL

Verify that a table is empty, and add it to replication. tab_idxname is optional - if NULL, then we use the primary key.

declare
  p_set_id alias for $1;
  p_tab_id alias for $2;
  p_nspname alias for $3;
  p_tabname alias for $4;
  p_idxname alias for $5;
  p_comment alias for $6;

  prec record;
  v_origin int4;
  v_isorigin boolean;
  v_fqname text;
  v_query text;
  v_rows integer;
  v_idxname text;

begin
-- Need to validate that the set exists; the set will tell us if this is the origin
  select set_origin into v_origin from "_prod_replica_set".sl_set where set_id = p_set_id;
  if not found then
	raise exception 'add_empty_table_to_replication: set % not found!', p_set_id;
  end if;

-- Need to be aware of whether or not this node is origin for the set
   v_isorigin := ( v_origin = "_prod_replica_set".getLocalNodeId('_prod_replica_set') );

   v_fqname := '"' || p_nspname || '"."' || p_tabname || '"';
-- Take out a lock on the table
   v_query := 'lock ' || v_fqname || ';';
   execute v_query;

   if v_isorigin then
	-- On the origin, verify that the table is empty, failing if it has any tuples
        v_query := 'select 1 as tuple from ' || v_fqname || ' limit 1;';
	execute v_query into prec;
        GET DIAGNOSTICS v_rows = ROW_COUNT;
	if v_rows = 0 then
		raise notice 'add_empty_table_to_replication: table % empty on origin - OK', v_fqname;
	else
		raise exception 'add_empty_table_to_replication: table % contained tuples on origin node %', v_fqname, v_origin;
	end if;
   else
	-- On other nodes, TRUNCATE the table
        v_query := 'truncate ' || v_fqname || ';';
	execute v_query;
   end if;
-- If p_idxname is NULL, then look up the PK index, and RAISE EXCEPTION if one does not exist
   if p_idxname is NULL then
	select c2.relname into prec from pg_catalog.pg_index i, pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_namespace n where i.indrelid = c1.oid and i.indexrelid = c2.oid and c1.relname = p_tabname and i.indisprimary and n.nspname = p_nspname and n.oid = c1.relnamespace;
	if not found then
		raise exception 'add_empty_table_to_replication: table % has no primary key and no candidate specified!', v_fqname;
	else
		v_idxname := prec.relname;
	end if;
   else
	v_idxname := p_idxname;
   end if;
   perform "_prod_replica_set".setAddTable_int(p_set_id, p_tab_id, v_fqname, v_idxname, p_comment);
   return "_prod_replica_set".alterTableRestore(p_tab_id);
end

Function: _prod_replica_set.add_missing_table_field( text, text, text, text )

Returns: boolean

Language: PLPGSQL

Add a column of a given type to a table if it is missing

DECLARE
  p_namespace alias for $1;
  p_table     alias for $2;
  p_field     alias for $3;
  p_type      alias for $4;
  v_row       record;
  v_query     text;
BEGIN
  select 1 into v_row from pg_namespace n, pg_class c, pg_attribute a
     where "_prod_replica_set".slon_quote_brute(n.nspname) = p_namespace and 
         c.relnamespace = n.oid and
         "_prod_replica_set".slon_quote_brute(c.relname) = p_table and
         a.attrelid = c.oid and
         "_prod_replica_set".slon_quote_brute(a.attname) = p_field;
  if not found then
    raise notice 'Upgrade table %.% - add field %', p_namespace, p_table, p_field;
    v_query := 'alter table ' || p_namespace || '.' || p_table || ' add column ';
    v_query := v_query || p_field || ' ' || p_type || ';';
    execute v_query;
    return 't';
  else
    return 'f';
  end if;
END;

Function: _prod_replica_set.addpartiallogindices( )

Returns: integer

Language: PLPGSQL

Add partial indexes, if possible, to the unused sl_log_? table for all origin nodes, and drop any that are no longer needed. This function presently gets run any time set origins are manipulated (FAILOVER, STORE SET, MOVE SET, DROP SET), as well as each time the system switches between sl_log_1 and sl_log_2.

DECLARE
	v_current_status	int4;
	v_log			int4;
	v_dummy		record;
	v_dummy2	record;
	idef 		text;
	v_count		int4;
        v_iname         text;
BEGIN
	v_count := 0;
	select last_value into v_current_status from "_prod_replica_set".sl_log_status;

	-- If status is 2 or 3 --> in process of cleanup --> unsafe to create indices
	if v_current_status in (2, 3) then
		return 0;
	end if;

	if v_current_status = 0 then   -- Which log should get indices?
		v_log := 2;
	else
		v_log := 1;
	end if;
--                                       PartInd_test_db_sl_log_2-node-1
	-- Add missing indices...
	for v_dummy in select distinct set_origin from "_prod_replica_set".sl_set loop
            v_iname := 'PartInd_prod_replica_set_sl_log_' || v_log || '-node-' || v_dummy.set_origin;
	    -- raise notice 'Consider adding partial index % on sl_log_%', v_iname, v_log;
	    -- raise notice 'schema: [_prod_replica_set] tablename:[sl_log_%]', v_log;
            select * into v_dummy2 from pg_catalog.pg_indexes where tablename = 'sl_log_' || v_log and  indexname = v_iname;
            if not found then
		-- raise notice 'index was not found - add it!';
		idef := 'create index "PartInd_prod_replica_set_sl_log_' || v_log || '-node-' || v_dummy.set_origin ||
                        '" on "_prod_replica_set".sl_log_' || v_log || ' USING btree(log_xid "_prod_replica_set".xxid_ops) where (log_origin = ' || v_dummy.set_origin || ');';
		execute idef;
		v_count := v_count + 1;
            else
                -- raise notice 'Index % already present - skipping', v_iname;
            end if;
	end loop;

	-- Remove unneeded indices...
	for v_dummy in select indexname from pg_catalog.pg_indexes i where i.tablename = 'sl_log_' || v_log and
                       i.indexname like ('PartInd_prod_replica_set_sl_log_' || v_log || '-node-%') and
                       not exists (select 1 from "_prod_replica_set".sl_set where
				i.indexname = 'PartInd_prod_replica_set_sl_log_' || v_log || '-node-' || set_origin)
	loop
		-- raise notice 'Dropping obsolete index %d', v_dummy.indexname;
		idef := 'drop index "_prod_replica_set"."' || v_dummy.indexname || '";';
		execute idef;
		v_count := v_count - 1;
	end loop;
	return v_count;
END

Function: _prod_replica_set.altertableforreplication( integer )

Returns: integer

Language: PLPGSQL

alterTableForReplication(tab_id) Sets up a table for replication. On the origin, this involves adding the "logTrigger()" trigger to the table. On a subscriber node, this involves disabling triggers and rules, and adding in the trigger that denies write access to replicated tables.

declare
	p_tab_id			alias for $1;
	v_no_id				int4;
	v_tab_row			record;
	v_tab_fqname		text;
	v_tab_attkind		text;
	v_n					int4;
	v_trec	record;
	v_tgbad	boolean;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get our local node ID
	-- ----
	v_no_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');

	-- ----
	-- Get the sl_table row and the current origin of the table. 
	-- Verify that the table currently is NOT in altered state.
	-- ----
	select T.tab_reloid, T.tab_set, T.tab_idxname, T.tab_altered,
			S.set_origin, PGX.indexrelid,
			"_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			"_prod_replica_set".slon_quote_brute(PGC.relname) as tab_fqname
			into v_tab_row
			from "_prod_replica_set".sl_table T, "_prod_replica_set".sl_set S,
				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN,
				"pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC
			where T.tab_id = p_tab_id
				and T.tab_set = S.set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
				and PGX.indrelid = T.tab_reloid
				and PGX.indexrelid = PGXC.oid
				and PGXC.relname = T.tab_idxname
				for update;
	if not found then
		raise exception 'Slony-I: alterTableForReplication(): Table with id % not found', p_tab_id;
	end if;
	v_tab_fqname = v_tab_row.tab_fqname;
	if v_tab_row.tab_altered then
		raise exception 'Slony-I: alterTableForReplication(): Table % is already in altered state',
				v_tab_fqname;
	end if;

	v_tab_attkind := "_prod_replica_set".determineAttKindUnique(v_tab_row.tab_fqname, 
						v_tab_row.tab_idxname);

	execute 'lock table ' || v_tab_fqname || ' in access exclusive mode';

	-- ----
	-- Procedures are different on origin and subscriber
	-- ----
	if v_no_id = v_tab_row.set_origin then
		-- ----
		-- On the Origin we add the log trigger to the table and done
		-- ----
		execute 'create trigger "_prod_replica_set_logtrigger_' || 
				p_tab_id || '" after insert or update or delete on ' ||
				v_tab_fqname || ' for each row execute procedure
				"_prod_replica_set".logTrigger (''_prod_replica_set'', ''' || 
					p_tab_id || ''', ''' || 
					v_tab_attkind || ''');';
	else
		-- ----
		-- On the subscriber the thing is a bit more difficult. We want
		-- to disable all user- and foreign key triggers and rules.
		-- ----


		-- ----
		-- Check to see if there are any trigger conflicts...
		-- ----
		v_tgbad := 'false';
		for v_trec in 
			select pc.relname, tg1.tgname from
			"pg_catalog".pg_trigger tg1, 
			"pg_catalog".pg_trigger tg2,
			"pg_catalog".pg_class pc,
			"pg_catalog".pg_index pi,
			"_prod_replica_set".sl_table tab
			where 
			 tg1.tgname = tg2.tgname and        -- Trigger names match
			 tg1.tgrelid = tab.tab_reloid and   -- trigger 1 is on the table
			 pi.indexrelid = tg2.tgrelid and    -- trigger 2 is on the index
			 pi.indrelid = tab.tab_reloid and   -- indexes table is this table
			 pc.oid = tab.tab_reloid
                loop
			raise notice 'Slony-I: alterTableForReplication(): multiple instances of trigger % on table %',
				v_trec.tgname, v_trec.relname;
			v_tgbad := 'true';
		end loop;
		if v_tgbad then
			raise exception 'Slony-I: Unable to disable triggers';
		end if;  		

		-- ----
		-- Disable all existing triggers
		-- ----
		update "pg_catalog".pg_trigger
				set tgrelid = v_tab_row.indexrelid
				where tgrelid = v_tab_row.tab_reloid
				and not exists (
						select true from "_prod_replica_set".sl_table TAB,
								"_prod_replica_set".sl_trigger TRIG
								where TAB.tab_reloid = tgrelid
								and TAB.tab_id = TRIG.trig_tabid
								and TRIG.trig_tgname = tgname
					);
		get diagnostics v_n = row_count;
		if v_n > 0 then
			update "pg_catalog".pg_class
					set reltriggers = reltriggers - v_n
					where oid = v_tab_row.tab_reloid;
		end if;

		-- ----
		-- Disable all existing rules
		-- ----
		update "pg_catalog".pg_rewrite
				set ev_class = v_tab_row.indexrelid
				where ev_class = v_tab_row.tab_reloid;
		get diagnostics v_n = row_count;
		if v_n > 0 then
			update "pg_catalog".pg_class
					set relhasrules = false
					where oid = v_tab_row.tab_reloid;
		end if;

		-- ----
		-- Add the trigger that denies write access to replicated tables
		-- ----
		execute 'create trigger "_prod_replica_set_denyaccess_' || 
				p_tab_id || '" before insert or update or delete on ' ||
				v_tab_fqname || ' for each row execute procedure
				"_prod_replica_set".denyAccess (''_prod_replica_set'');';
	end if;

	-- ----
	-- Mark the table altered in our configuration
	-- ----
	update "_prod_replica_set".sl_table
			set tab_altered = true where tab_id = p_tab_id;

	return p_tab_id;
end;

Function: _prod_replica_set.altertablerestore( integer )

Returns: integer

Language: PLPGSQL

alterTableRestore (tab_id) Restores table tab_id from being replicated. On the origin, this simply involves dropping the "logtrigger" trigger. On subscriber nodes, this involves dropping the "denyaccess" trigger, and restoring user triggers and rules.

declare
	p_tab_id			alias for $1;
	v_no_id				int4;
	v_tab_row			record;
	v_tab_fqname		text;
	v_n					int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get our local node ID
	-- ----
	v_no_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');

	-- ----
	-- Get the sl_table row and the current tables origin. Check
	-- that the table currently IS in altered state.
	-- ----
	select T.tab_reloid, T.tab_set, T.tab_altered,
			S.set_origin, PGX.indexrelid,
			"_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			"_prod_replica_set".slon_quote_brute(PGC.relname) as tab_fqname
			into v_tab_row
			from "_prod_replica_set".sl_table T, "_prod_replica_set".sl_set S,
				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN,
				"pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC
			where T.tab_id = p_tab_id
				and T.tab_set = S.set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
				and PGX.indrelid = T.tab_reloid
				and PGX.indexrelid = PGXC.oid
				and PGXC.relname = T.tab_idxname
				for update;
	if not found then
		raise exception 'Slony-I: alterTableRestore(): Table with id % not found', p_tab_id;
	end if;
	v_tab_fqname = v_tab_row.tab_fqname;
	if not v_tab_row.tab_altered then
		raise exception 'Slony-I: alterTableRestore(): Table % is not in altered state',
				v_tab_fqname;
	end if;

	execute 'lock table ' || v_tab_fqname || ' in access exclusive mode';

	-- ----
	-- Procedures are different on origin and subscriber
	-- ----
	if v_no_id = v_tab_row.set_origin then
		-- ----
		-- On the Origin we just drop the trigger we originally added
		-- ----
		execute 'drop trigger "_prod_replica_set_logtrigger_' || 
				p_tab_id || '" on ' || v_tab_fqname;
	else
		-- ----
		-- On the subscriber drop the denyAccess trigger
		-- ----
		execute 'drop trigger "_prod_replica_set_denyaccess_' || 
				p_tab_id || '" on ' || v_tab_fqname;
				
		-- ----
		-- Restore all original triggers
		-- ----
		update "pg_catalog".pg_trigger
				set tgrelid = v_tab_row.tab_reloid
				where tgrelid = v_tab_row.indexrelid;
		get diagnostics v_n = row_count;
		if v_n > 0 then
			update "pg_catalog".pg_class
					set reltriggers = reltriggers + v_n
					where oid = v_tab_row.tab_reloid;
		end if;

		-- ----
		-- Restore all original rewrite rules
		-- ----
		update "pg_catalog".pg_rewrite
				set ev_class = v_tab_row.tab_reloid
				where ev_class = v_tab_row.indexrelid;
		get diagnostics v_n = row_count;
		if v_n > 0 then
			update "pg_catalog".pg_class
					set relhasrules = true
					where oid = v_tab_row.tab_reloid;
		end if;

	end if;

	-- ----
	-- Mark the table not altered in our configuration
	-- ----
	update "_prod_replica_set".sl_table
			set tab_altered = false where tab_id = p_tab_id;

	return p_tab_id;
end;

Function: _prod_replica_set.btxxidcmp( _prod_replica_set.xxid, _prod_replica_set.xxid )

Returns: integer

Language: C

_Slony_I_btxxidcmp

Function: _prod_replica_set.checkmoduleversion( )

Returns: text

Language: PLPGSQL

Inline test function that verifies that slonik request for STORE NODE/INIT CLUSTER is being run against a conformant set of schema/functions.

declare
  moduleversion	text;
begin
  select into moduleversion "_prod_replica_set".getModuleVersion();
  if moduleversion <> '1.2.12' then
      raise exception 'Slonik version: 1.2.12 != Slony-I version in PG build %',
             moduleversion;
  end if;
  return null;
end;

Function: _prod_replica_set.cleanupevent( )

Returns: integer

Language: PLPGSQL

cleaning old data out of sl_confirm, sl_event. Removes all but the last sl_confirm row per (origin,receiver), and then removes all events that are confirmed by all nodes in the whole cluster up to the last SYNC.

declare
	v_max_row	record;
	v_min_row	record;
	v_max_sync	int8;
begin
	-- ----
	-- First remove all but the oldest confirm row per origin,receiver pair
	-- ----
	delete from "_prod_replica_set".sl_confirm
				where con_origin not in (select no_id from "_prod_replica_set".sl_node);
	delete from "_prod_replica_set".sl_confirm
				where con_received not in (select no_id from "_prod_replica_set".sl_node);
	-- ----
	-- Next remove all but the oldest confirm row per origin,receiver pair.
	-- Ignore confirmations that are younger than 10 minutes. We currently
	-- have an not confirmed suspicion that a possibly lost transaction due
	-- to a server crash might have been visible to another session, and
	-- that this led to log data that is needed again got removed.
	-- ----
	for v_max_row in select con_origin, con_received, max(con_seqno) as con_seqno
				from "_prod_replica_set".sl_confirm
				where con_timestamp < (CURRENT_TIMESTAMP - '10 min'::interval)
				group by con_origin, con_received
	loop
		delete from "_prod_replica_set".sl_confirm
				where con_origin = v_max_row.con_origin
				and con_received = v_max_row.con_received
				and con_seqno < v_max_row.con_seqno;
	end loop;

	-- ----
	-- Then remove all events that are confirmed by all nodes in the
	-- whole cluster up to the last SYNC
	-- ----
	for v_min_row in select con_origin, min(con_seqno) as con_seqno
				from "_prod_replica_set".sl_confirm
				group by con_origin
	loop
		select coalesce(max(ev_seqno), 0) into v_max_sync
				from "_prod_replica_set".sl_event
				where ev_origin = v_min_row.con_origin
				and ev_seqno <= v_min_row.con_seqno
				and ev_type = 'SYNC';
		if v_max_sync > 0 then
			delete from "_prod_replica_set".sl_event
					where ev_origin = v_min_row.con_origin
					and ev_seqno < v_max_sync;
		end if;
	end loop;

	-- ----
	-- If cluster has only one node, then remove all events up to
	-- the last SYNC - Bug #1538
        -- http://gborg.postgresql.org/project/slony1/bugs/bugupdate.php?1538
	-- ----

	select * into v_min_row from "_prod_replica_set".sl_node where
			no_id <> "_prod_replica_set".getLocalNodeId('_prod_replica_set') limit 1;
	if not found then
		select ev_origin, ev_seqno into v_min_row from "_prod_replica_set".sl_event
		where ev_origin = "_prod_replica_set".getLocalNodeId('_prod_replica_set')
		order by ev_origin desc, ev_seqno desc limit 1;
		raise notice 'Slony-I: cleanupEvent(): Single node - deleting events < %', v_min_row.ev_seqno;
			delete from "_prod_replica_set".sl_event
			where
				ev_origin = v_min_row.ev_origin and
				ev_seqno < v_min_row.ev_seqno;

        end if;

	if exists (select * from "pg_catalog".pg_class c, "pg_catalog".pg_namespace n, "pg_catalog".pg_attribute a where c.relname = 'sl_seqlog' and n.oid = c.relnamespace and a.attrelid = c.oid and a.attname = 'oid') then
                execute 'alter table "_prod_replica_set".sl_seqlog set without oids;';
	end if;		
	-- ----
	-- Also remove stale entries from the nodelock table.
	-- ----
	perform "_prod_replica_set".cleanupNodelock();

	return 0;
end;

Function: _prod_replica_set.cleanupnodelock( )

Returns: integer

Language: PLPGSQL

Clean up stale entries when restarting slon

declare
	v_row		record;
begin
	for v_row in select nl_nodeid, nl_conncnt, nl_backendpid
			from "_prod_replica_set".sl_nodelock
			for update
	loop
		if "_prod_replica_set".killBackend(v_row.nl_backendpid, 'NULL') < 0 then
			raise notice 'Slony-I: cleanup stale sl_nodelock entry for pid=%',
					v_row.nl_backendpid;
			delete from "_prod_replica_set".sl_nodelock where
					nl_nodeid = v_row.nl_nodeid and
					nl_conncnt = v_row.nl_conncnt;
		end if;
	end loop;

	return 0;
end;

Function: _prod_replica_set.copyfields( integer )

Returns: text

Language: PLPGSQL

Return a string consisting of what should be appended to a COPY statement to specify fields for the passed-in tab_id. In PG versions > 7.3, this looks like (field1,field2,...fieldn)

declare
	result text;
	prefix text;
	prec record;
begin
	result := '';
	prefix := '(';   -- Initially, prefix is the opening paren

	for prec in select "_prod_replica_set".slon_quote_input(a.attname) as column from "_prod_replica_set".sl_table t, pg_catalog.pg_attribute a where t.tab_id = $1 and t.tab_reloid = a.attrelid and a.attnum > 0 and a.attisdropped = false order by attnum
	loop
		result := result || prefix || prec.column;
		prefix := ',';   -- Subsequently, prepend columns with commas
	end loop;
	result := result || ')';
	return result;
end;

Function: _prod_replica_set.createevent( name, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text, text, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text, text, text, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text, text, text, text, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text, text, text, text, text, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.createevent( name, text, text, text, text, text, text, text, text, text )

Returns: bigint

Language: C

FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) Create an sl_event entry

_Slony_I_createEvent

Function: _prod_replica_set.ddlscript( integer, text, integer )

Returns: bigint

Language: PLPGSQL

ddlScript(set_id, script, only_on_node) Generates a SYNC event, runs the script on the origin, and then generates a DDL_SCRIPT event to request it to be run on replicated slaves.

declare
	p_set_id			alias for $1;
	p_script			alias for $2;
	p_only_on_node		alias for $3;
	v_set_origin		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that the set exists and originates here
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_set_origin <> "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: set % does not originate on local node',
				p_set_id;
	end if;

	-- ----
	-- Create a SYNC event, run the script and generate the DDL_SCRIPT event
	-- ----
	perform "_prod_replica_set".createEvent('_prod_replica_set', 'SYNC', NULL);
	perform "_prod_replica_set".ddlScript_int(p_set_id, p_script, p_only_on_node);
	perform "_prod_replica_set".updateRelname(p_set_id, p_only_on_node);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'DDL_SCRIPT', 
			p_set_id, p_script, p_only_on_node);
end;

Function: _prod_replica_set.ddlscript_complete( integer, text, integer )

Returns: integer

Language: PLPGSQL

ddlScript_complete(set_id, script, only_on_node) After script has run on origin, this fixes up relnames, restores triggers, and generates a DDL_SCRIPT event to request it to be run on replicated slaves.

declare
	p_set_id			alias for $1;
	p_script			alias for $2;
	p_only_on_node		alias for $3;
	v_set_origin		int4;
begin
	perform "_prod_replica_set".updateRelname(p_set_id, p_only_on_node);
	if p_only_on_node = -1 then
		perform "_prod_replica_set".alterTableForReplication(tab_id) from "_prod_replica_set".sl_table where tab_set in (select set_id from "_prod_replica_set".sl_set where set_origin = "_prod_replica_set".getLocalNodeId('_prod_replica_set'));

		return  "_prod_replica_set".createEvent('_prod_replica_set', 'DDL_SCRIPT', 
			p_set_id::text, p_script::text, p_only_on_node::text);
	else
		perform "_prod_replica_set".alterTableForReplication(tab_id) from "_prod_replica_set".sl_table;
	end if;
	return NULL;
end;

Function: _prod_replica_set.ddlscript_complete_int( integer, integer )

Returns: integer

Language: PLPGSQL

ddlScript_complete_int(set_id, script, only_on_node) Complete processing the DDL_SCRIPT event. This puts tables back into replicated mode.

declare
	p_set_id			alias for $1;
	p_only_on_node		alias for $2;
	v_row				record;
begin
	-- ----
	-- Put all tables back into replicated mode
	-- ----
	for v_row in select * from "_prod_replica_set".sl_table
	loop
		perform "_prod_replica_set".alterTableForReplication(v_row.tab_id);
	end loop;

	return p_set_id;
end;

Function: _prod_replica_set.ddlscript_int( integer, text, integer )

Returns: integer

Language: PLPGSQL

ddlScript_int(set_id, script, only_on_node) Processes the DDL_SCRIPT event. On slave nodes, this restores original triggers/rules, runs the script, and then puts tables back into replicated mode.

declare
	p_set_id			alias for $1;
	p_script			alias for $2;
	p_only_on_node		alias for $3;
	v_set_origin		int4;
	v_no_id				int4;
	v_row				record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that we either are the set origin or a current
	-- subscriber of the set.
	-- ----
	v_no_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_set_origin <> v_no_id
			and not exists (select 1 from "_prod_replica_set".sl_subscribe
						where sub_set = p_set_id
						and sub_receiver = v_no_id)
	then
		return 0;
	end if;

	-- ----
	-- If execution on only one node is requested, check that
	-- we are that node.
	-- ----
	if p_only_on_node > 0 and p_only_on_node <> v_no_id then
		return 0;
	end if;

	-- ----
	-- Restore all original triggers and rules of all sets
	-- ----
	for v_row in select * from "_prod_replica_set".sl_table
	loop
		perform "_prod_replica_set".alterTableRestore(v_row.tab_id);
	end loop;

	-- ----
	-- Run the script
	-- ----
	execute p_script;

	-- ----
	-- Put all tables back into replicated mode
	-- ----
	for v_row in select * from "_prod_replica_set".sl_table
	loop
		perform "_prod_replica_set".alterTableForReplication(v_row.tab_id);
	end loop;

	return p_set_id;
end;

Function: _prod_replica_set.ddlscript_prepare( integer, integer )

Returns: integer

Language: PLPGSQL

Prepare for DDL script execution on origin

declare
	p_set_id			alias for $1;
	p_only_on_node		alias for $2;
	v_set_origin		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	
	-- ----
	-- Check that the set exists and originates here
	-- unless only_on_node was specified (then it can be applied to
	-- that node because that is what the user wanted)
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;

	if p_only_on_node = -1 then
		if v_set_origin <> "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
			raise exception 'Slony-I: set % does not originate on local node',
				p_set_id;
		end if;
		-- ----
		-- Create a SYNC event, run the script and generate the DDL_SCRIPT event
		-- ----
		perform "_prod_replica_set".createEvent('_prod_replica_set', 'SYNC', NULL);
		perform "_prod_replica_set".alterTableRestore(tab_id) from "_prod_replica_set".sl_table where tab_set in (select set_id from "_prod_replica_set".sl_set where set_origin = "_prod_replica_set".getLocalNodeId('_prod_replica_set'));
	else
		-- ----
		-- If doing "only on one node" - restore ALL tables irrespective of set
		-- ----
		perform "_prod_replica_set".alterTableRestore(tab_id) from "_prod_replica_set".sl_table;
	end if;
	return 1;
end;

Function: _prod_replica_set.ddlscript_prepare_int( integer, integer )

Returns: integer

Language: PLPGSQL

ddlScript_prepare_int (set_id, only_on_node) Do preparatory work for a DDL script, restoring triggers/rules to original state.

declare
	p_set_id			alias for $1;
	p_only_on_node		alias for $2;
	v_set_origin		int4;
	v_no_id				int4;
	v_row				record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that we either are the set origin or a current
	-- subscriber of the set.
	-- ----
	v_no_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_set_origin <> v_no_id
			and not exists (select 1 from "_prod_replica_set".sl_subscribe
						where sub_set = p_set_id
						and sub_receiver = v_no_id)
	then
		return 0;
	end if;

	-- ----
	-- If execution on only one node is requested, check that
	-- we are that node.
	-- ----
	if p_only_on_node > 0 and p_only_on_node <> v_no_id then
		return 0;
	end if;

	-- ----
	-- Restore all original triggers and rules of all sets
	-- ----
	for v_row in select * from "_prod_replica_set".sl_table
	loop
		perform "_prod_replica_set".alterTableRestore(v_row.tab_id);
	end loop;
	return p_set_id;
end;

Function: _prod_replica_set.denyaccess( )

Returns: "trigger"

Language: C

Trigger function to prevent modifications to a table on a subscriber

_Slony_I_denyAccess

Function: _prod_replica_set.determineattkindserial( text )

Returns: text

Language: PLPGSQL

determineAttKindSerial (tab_fqname) A table was that was specified without a primary key is added to the replication. Assume that tableAddKey() was called before and finish the creation of the serial column. The return an attkind according to that.

declare
	p_tab_fqname	alias for $1;
	v_tab_fqname_quoted	text default '';
	v_attkind		text default '';
	v_attrow		record;
	v_have_serial	bool default 'f';
begin
	v_tab_fqname_quoted := "_prod_replica_set".slon_quote_input(p_tab_fqname);
	--
	-- Loop over the attributes of this relation
	-- and add a "v" for every user column, and a "k"
	-- if we find the Slony-I special serial column.
	--
	for v_attrow in select PGA.attnum, PGA.attname
			from "pg_catalog".pg_class PGC,
			    "pg_catalog".pg_namespace PGN,
				"pg_catalog".pg_attribute PGA
			where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			    "_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace
				and PGA.attrelid = PGC.oid
				and not PGA.attisdropped
				and PGA.attnum > 0
			order by attnum
	loop
		if v_attrow.attname = '_Slony-I_prod_replica_set_rowID' then
		    v_attkind := v_attkind || 'k';
			v_have_serial := 't';
		else
			v_attkind := v_attkind || 'v';
		end if;
	end loop;
	
	--
	-- A table must have at least one attribute, so not finding
	-- anything means the table does not exist.
	--
	if not found then
		raise exception 'Slony-I: table % not found', v_tab_fqname_quoted;
	end if;

	--
	-- If it does not have the special serial column, we
	-- should not have been called in the first place.
	--
	if not v_have_serial then
		raise exception 'Slony-I: table % does not have the serial key',
				v_tab_fqname_quoted;
	end if;

	execute 'update ' || v_tab_fqname_quoted ||
		' set "_Slony-I_prod_replica_set_rowID" =' ||
		' "pg_catalog".nextval(''"_prod_replica_set".sl_rowid_seq'');';
	execute 'alter table only ' || v_tab_fqname_quoted ||
		' add unique ("_Slony-I_prod_replica_set_rowID");';
	execute 'alter table only ' || v_tab_fqname_quoted ||
		' alter column "_Slony-I_prod_replica_set_rowID" ' ||
		' set not null;';

	--
	-- Return the resulting Slony-I attkind
	--
	return v_attkind;
end;

Function: _prod_replica_set.determineattkindunique( text, name )

Returns: text

Language: PLPGSQL

determineAttKindUnique (tab_fqname, indexname) Given a tablename, return the Slony-I specific attkind (used for the log trigger) of the table. Use the specified unique index or the primary key (if indexname is NULL).

declare
	p_tab_fqname	alias for $1;
	v_tab_fqname_quoted	text default '';
	p_idx_name		alias for $2;
	v_idx_name_quoted	text;
	v_idxrow		record;
	v_attrow		record;
	v_i				integer;
	v_attno			int2;
	v_attkind		text default '';
	v_attfound		bool;
begin
	v_tab_fqname_quoted := "_prod_replica_set".slon_quote_input(p_tab_fqname);
	v_idx_name_quoted := "_prod_replica_set".slon_quote_brute(p_idx_name);
	--
	-- Ensure that the table exists
	--
	if (select PGC.relname
				from "pg_catalog".pg_class PGC,
					"pg_catalog".pg_namespace PGN
				where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
					"_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace) is null then
		raise exception 'Slony-I: table % not found', v_tab_fqname_quoted;
	end if;

	--
	-- Lookup the tables primary key or the specified unique index
	--
	if p_idx_name isnull then
		raise exception 'Slony-I: index name must be specified';
	else
		select PGXC.relname, PGX.indexrelid, PGX.indkey
				into v_idxrow
				from "pg_catalog".pg_class PGC,
					"pg_catalog".pg_namespace PGN,
					"pg_catalog".pg_index PGX,
					"pg_catalog".pg_class PGXC
				where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
					"_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace
					and PGX.indrelid = PGC.oid
					and PGX.indexrelid = PGXC.oid
					and PGX.indisunique
					and "_prod_replica_set".slon_quote_brute(PGXC.relname) = v_idx_name_quoted;
		if not found then
			raise exception 'Slony-I: table % has no unique index %',
					v_tab_fqname_quoted, v_idx_name_quoted;
		end if;
	end if;

	--
	-- Loop over the tables attributes and check if they are
	-- index attributes. If so, add a "k" to the return value,
	-- otherwise add a "v".
	--
	for v_attrow in select PGA.attnum, PGA.attname
			from "pg_catalog".pg_class PGC,
			    "pg_catalog".pg_namespace PGN,
				"pg_catalog".pg_attribute PGA
			where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			    "_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace
				and PGA.attrelid = PGC.oid
				and not PGA.attisdropped
				and PGA.attnum > 0
			order by attnum
	loop
		v_attfound = 'f';

		v_i := 0;
		loop
			select indkey[v_i] into v_attno from "pg_catalog".pg_index
					where indexrelid = v_idxrow.indexrelid;
			if v_attno isnull or v_attno = 0 then
				exit;
			end if;
			if v_attrow.attnum = v_attno then
				v_attfound = 't';
				exit;
			end if;
			v_i := v_i + 1;
		end loop;

		if v_attfound then
			v_attkind := v_attkind || 'k';
		else
			v_attkind := v_attkind || 'v';
		end if;
	end loop;

	--
	-- Return the resulting attkind
	--
	return v_attkind;
end;

Function: _prod_replica_set.determineidxnameserial( text )

Returns: name

Language: PLPGSQL

determineIdxnameSerial (tab_fqname) Given a tablename, construct the index name of the serial column.

declare
	p_tab_fqname	alias for $1;
	v_tab_fqname_quoted	text default '';
	v_row			record;
begin
	v_tab_fqname_quoted := "_prod_replica_set".slon_quote_input(p_tab_fqname);
	--
	-- Lookup the table name alone
	--
	select PGC.relname
			into v_row
			from "pg_catalog".pg_class PGC,
				"pg_catalog".pg_namespace PGN
			where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
				"_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace;
	if not found then
		raise exception 'Slony-I: table % not found',
				v_tab_fqname_quoted;
	end if;

	--
	-- Return the found index name
	--
	return v_row.relname || '__Slony-I_prod_replica_set_rowID_key';
end;

Function: _prod_replica_set.determineidxnameunique( text, name )

Returns: name

Language: PLPGSQL

FUNCTION determineIdxnameUnique (tab_fqname, indexname) Given a tablename, tab_fqname, check that the unique index, indexname, exists or return the primary key index name for the table. If there is no unique index, it raises an exception.

declare
	p_tab_fqname	alias for $1;
	v_tab_fqname_quoted	text default '';
	p_idx_name		alias for $2;
	v_idxrow		record;
begin
	v_tab_fqname_quoted := "_prod_replica_set".slon_quote_input(p_tab_fqname);
	--
	-- Ensure that the table exists
	--
	if (select PGC.relname
				from "pg_catalog".pg_class PGC,
					"pg_catalog".pg_namespace PGN
				where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
					"_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace) is null then
		raise exception 'Slony-I: determineIdxnameUnique(): table % not found', v_tab_fqname_quoted;
	end if;

	--
	-- Lookup the tables primary key or the specified unique index
	--
	if p_idx_name isnull then
		select PGXC.relname
				into v_idxrow
				from "pg_catalog".pg_class PGC,
					"pg_catalog".pg_namespace PGN,
					"pg_catalog".pg_index PGX,
					"pg_catalog".pg_class PGXC
				where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
					"_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace
					and PGX.indrelid = PGC.oid
					and PGX.indexrelid = PGXC.oid
					and PGX.indisprimary;
		if not found then
			raise exception 'Slony-I: table % has no primary key',
					v_tab_fqname_quoted;
		end if;
	else
		select PGXC.relname
				into v_idxrow
				from "pg_catalog".pg_class PGC,
					"pg_catalog".pg_namespace PGN,
					"pg_catalog".pg_index PGX,
					"pg_catalog".pg_class PGXC
				where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
					"_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace
					and PGX.indrelid = PGC.oid
					and PGX.indexrelid = PGXC.oid
					and PGX.indisunique
					and "_prod_replica_set".slon_quote_brute(PGXC.relname) = "_prod_replica_set".slon_quote_input(p_idx_name);
		if not found then
			raise exception 'Slony-I: table % has no unique index %',
					v_tab_fqname_quoted, p_idx_name;
		end if;
	end if;

	--
	-- Return the found index name
	--
	return v_idxrow.relname;
end;

Function: _prod_replica_set.disablenode( integer )

Returns: bigint

Language: PLPGSQL

process DISABLE_NODE event for node no_id NOTE: This is not yet implemented!

declare
	p_no_id			alias for $1;
begin
	-- **** TODO ****
	raise exception 'Slony-I: disableNode() not implemented';
end;

Function: _prod_replica_set.disablenode_int( integer )

Returns: integer

Language: PLPGSQL

declare
	p_no_id			alias for $1;
begin
	-- **** TODO ****
	raise exception 'Slony-I: disableNode_int() not implemented';
end;

Function: _prod_replica_set.droplisten( integer, integer, integer )

Returns: bigint

Language: PLPGSQL

dropListen (li_origin, li_provider, li_receiver) Generate the DROP_LISTEN event.

declare
	p_li_origin		alias for $1;
	p_li_provider	alias for $2;
	p_li_receiver	alias for $3;
begin
	perform "_prod_replica_set".dropListen_int(p_li_origin, 
			p_li_provider, p_li_receiver);
	
	return  "_prod_replica_set".createEvent ('_prod_replica_set', 'DROP_LISTEN',
			p_li_origin::text, p_li_provider::text, p_li_receiver::text);
end;

Function: _prod_replica_set.droplisten_int( integer, integer, integer )

Returns: integer

Language: PLPGSQL

dropListen (li_origin, li_provider, li_receiver) Process the DROP_LISTEN event, deleting the sl_listen entry for the indicated (origin,provider,receiver) combination.

declare
	p_li_origin		alias for $1;
	p_li_provider	alias for $2;
	p_li_receiver	alias for $3;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	delete from "_prod_replica_set".sl_listen
			where li_origin = p_li_origin
			and li_provider = p_li_provider
			and li_receiver = p_li_receiver;
	if found then
		return 1;
	else
		return 0;
	end if;
end;

Function: _prod_replica_set.dropnode( integer )

Returns: bigint

Language: PLPGSQL

generate DROP_NODE event to drop node node_id from replication

declare
	p_no_id			alias for $1;
	v_node_row		record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that this got called on a different node
	-- ----
	if p_no_id = "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: DROP_NODE cannot initiate on the dropped node';
	end if;

	select * into v_node_row from "_prod_replica_set".sl_node
			where no_id = p_no_id
			for update;
	if not found then
		raise exception 'Slony-I: unknown node ID %', p_no_id;
	end if;

	-- ----
	-- Make sure we do not break other nodes subscriptions with this
	-- ----
	if exists (select true from "_prod_replica_set".sl_subscribe
			where sub_provider = p_no_id)
	then
		raise exception 'Slony-I: Node % is still configured as a data provider',
				p_no_id;
	end if;

	-- ----
	-- Make sure no set originates there any more
	-- ----
	if exists (select true from "_prod_replica_set".sl_set
			where set_origin = p_no_id)
	then
		raise exception 'Slony-I: Node % is still origin of one or more sets',
				p_no_id;
	end if;

	-- ----
	-- Call the internal drop functionality and generate the event
	-- ----
	perform "_prod_replica_set".dropNode_int(p_no_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'DROP_NODE',
									p_no_id::text);
end;

Function: _prod_replica_set.dropnode_int( integer )

Returns: integer

Language: PLPGSQL

internal function to process DROP_NODE event to drop node node_id from replication

declare
	p_no_id			alias for $1;
	v_tab_row		record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- If the dropped node is a remote node, clean the configuration
	-- from all traces for it.
	-- ----
	if p_no_id <> "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		delete from "_prod_replica_set".sl_subscribe
				where sub_receiver = p_no_id;
		delete from "_prod_replica_set".sl_listen
				where li_origin = p_no_id
					or li_provider = p_no_id
					or li_receiver = p_no_id;
		delete from "_prod_replica_set".sl_path
				where pa_server = p_no_id
					or pa_client = p_no_id;
		delete from "_prod_replica_set".sl_confirm
				where con_origin = p_no_id
					or con_received = p_no_id;
		delete from "_prod_replica_set".sl_event
				where ev_origin = p_no_id;
		delete from "_prod_replica_set".sl_node
				where no_id = p_no_id;

		return p_no_id;
	end if;

	-- ----
	-- This is us ... deactivate the node for now, the daemon
	-- will call uninstallNode() in a separate transaction.
	-- ----
	update "_prod_replica_set".sl_node
			set no_active = false
			where no_id = p_no_id;

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	return p_no_id;
end;

Function: _prod_replica_set.droppath( integer, integer )

Returns: bigint

Language: PLPGSQL

Generate DROP_PATH event to drop path from pa_server to pa_client

declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
	v_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- There should be no existing subscriptions. Auto unsubscribing
	-- is considered too dangerous. 
	-- ----
	for v_row in select sub_set, sub_provider, sub_receiver
			from "_prod_replica_set".sl_subscribe
			where sub_provider = p_pa_server
			and sub_receiver = p_pa_client
	loop
		raise exception 
			'Slony-I: Path cannot be dropped, subscription of set % needs it',
			v_row.sub_set;
	end loop;

	-- ----
	-- Drop all sl_listen entries that depend on this path
	-- ----
	for v_row in select li_origin, li_provider, li_receiver
			from "_prod_replica_set".sl_listen
			where li_provider = p_pa_server
			and li_receiver = p_pa_client
	loop
		perform "_prod_replica_set".dropListen(
				v_row.li_origin, v_row.li_provider, v_row.li_receiver);
	end loop;

	-- ----
	-- Now drop the path and create the event
	-- ----
	perform "_prod_replica_set".dropPath_int(p_pa_server, p_pa_client);

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	return  "_prod_replica_set".createEvent ('_prod_replica_set', 'DROP_PATH',
			p_pa_server::text, p_pa_client::text);
end;

Function: _prod_replica_set.droppath_int( integer, integer )

Returns: integer

Language: PLPGSQL

Process DROP_PATH event to drop path from pa_server to pa_client

declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Remove any dangling sl_listen entries with the server
	-- as provider and the client as receiver. This must have
	-- been cleared out before, but obviously was not.
	-- ----
	delete from "_prod_replica_set".sl_listen
			where li_provider = p_pa_server
			and li_receiver = p_pa_client;

	delete from "_prod_replica_set".sl_path
			where pa_server = p_pa_server
			and pa_client = p_pa_client;

	if found then
		-- Rewrite sl_listen table
		perform "_prod_replica_set".RebuildListenEntries();

		return 1;
	else
		-- Rewrite sl_listen table
		perform "_prod_replica_set".RebuildListenEntries();

		return 0;
	end if;
end;

Function: _prod_replica_set.dropset( integer )

Returns: bigint

Language: PLPGSQL

Process DROP_SET event to drop replication of set set_id. This involves: - Restoring original triggers and rules - Removing all traces of the set configuration, including sequences, tables, subscribers, syncs, and the set itself

declare
	p_set_id			alias for $1;
	v_origin			int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;
	
	-- ----
	-- Check that the set exists and originates here
	-- ----
	select set_origin into v_origin from "_prod_replica_set".sl_set
			where set_id = p_set_id;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: set % does not originate on local node',
				p_set_id;
	end if;

	-- ----
	-- Call the internal drop set functionality and generate the event
	-- ----
	perform "_prod_replica_set".dropSet_int(p_set_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'DROP_SET', 
			p_set_id::text);
end;

Function: _prod_replica_set.dropset_int( integer )

Returns: integer

Language: PLPGSQL

declare
	p_set_id			alias for $1;
	v_tab_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;
	
	-- ----
	-- Restore all tables original triggers and rules and remove
	-- our replication stuff.
	-- ----
	for v_tab_row in select tab_id from "_prod_replica_set".sl_table
			where tab_set = p_set_id
			order by tab_id
	loop
		perform "_prod_replica_set".alterTableRestore(v_tab_row.tab_id);
		perform "_prod_replica_set".tableDropKey(v_tab_row.tab_id);
	end loop;

	-- ----
	-- Remove all traces of the set configuration
	-- ----
	delete from "_prod_replica_set".sl_sequence
			where seq_set = p_set_id;
	delete from "_prod_replica_set".sl_table
			where tab_set = p_set_id;
	delete from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id;
	delete from "_prod_replica_set".sl_setsync
			where ssy_setid = p_set_id;
	delete from "_prod_replica_set".sl_set
			where set_id = p_set_id;

	-- Regenerate sl_listen since we revised the subscriptions
	perform "_prod_replica_set".RebuildListenEntries();

	-- Run addPartialLogIndices() to try to add indices to unused sl_log_? table
	perform "_prod_replica_set".addPartialLogIndices();

	return p_set_id;
end;

Function: _prod_replica_set.droptrigger( integer, name )

Returns: bigint

Language: PLPGSQL

dropTrigger (trig_tabid, trig_tgname) Submits DROP_TRIGGER event to indicate that trigger trig_tgname on replicated table trig_tabid WILL be disabled.

declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
begin
	perform "_prod_replica_set".dropTrigger_int(p_trig_tabid, p_trig_tgname);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'DROP_TRIGGER',
			p_trig_tabid::text, p_trig_tgname::text);
end;

Function: _prod_replica_set.droptrigger_int( integer, name )

Returns: integer

Language: PLPGSQL

dropTrigger_int (trig_tabid, trig_tgname) Processes DROP_TRIGGER event to make sure that trigger trig_tgname on replicated table trig_tabid IS disabled.

declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
	v_tab_altered		boolean;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get the current table status (altered or not)
	-- ----
	select tab_altered into v_tab_altered
			from "_prod_replica_set".sl_table where tab_id = p_trig_tabid;
	if not found then
		-- ----
		-- Not found is no hard error here, because that might
		-- mean that we are not subscribed to that set
		-- ----
		return 0;
	end if;

	-- ----
	-- If the table is modified for replication, restore the original state
	-- ----
	if v_tab_altered then
		perform "_prod_replica_set".alterTableRestore(p_trig_tabid);
	end if;

	-- ----
	-- Remove the entry from sl_trigger
	-- ----
	delete from "_prod_replica_set".sl_trigger
			where trig_tabid = p_trig_tabid
			  and trig_tgname = p_trig_tgname;

	-- ----
	-- Put the table back into replicated state if it was
	-- ----
	if v_tab_altered then
		perform "_prod_replica_set".alterTableForReplication(p_trig_tabid);
	end if;

	return p_trig_tabid;
end;

Function: _prod_replica_set.enablenode( integer )

Returns: bigint

Language: PLPGSQL

no_id - Node ID # Generate the ENABLE_NODE event for node no_id

declare
	p_no_id			alias for $1;
	v_local_node_id	int4;
	v_node_row		record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that we are the node to activate and that we are
	-- currently disabled.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select * into v_node_row
			from "_prod_replica_set".sl_node
			where no_id = p_no_id
			for update;
	if not found then 
		raise exception 'Slony-I: node % not found', p_no_id;
	end if;
	if v_node_row.no_active then
		raise exception 'Slony-I: node % is already active', p_no_id;
	end if;

	-- ----
	-- Activate this node and generate the ENABLE_NODE event
	-- ----
	perform "_prod_replica_set".enableNode_int (p_no_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'ENABLE_NODE',
									p_no_id::text);
end;

Function: _prod_replica_set.enablenode_int( integer )

Returns: integer

Language: PLPGSQL

no_id - Node ID # Internal function to process the ENABLE_NODE event for node no_id

declare
	p_no_id			alias for $1;
	v_local_node_id	int4;
	v_node_row		record;
	v_sub_row		record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that the node is inactive
	-- ----
	select * into v_node_row
			from "_prod_replica_set".sl_node
			where no_id = p_no_id
			for update;
	if not found then 
		raise exception 'Slony-I: node % not found', p_no_id;
	end if;
	if v_node_row.no_active then
		return p_no_id;
	end if;

	-- ----
	-- Activate the node and generate sl_confirm status rows for it.
	-- ----
	update "_prod_replica_set".sl_node
			set no_active = 't'
			where no_id = p_no_id;
	insert into "_prod_replica_set".sl_confirm
			(con_origin, con_received, con_seqno)
			select no_id, p_no_id, 0 from "_prod_replica_set".sl_node
				where no_id != p_no_id
				and no_active;
	insert into "_prod_replica_set".sl_confirm
			(con_origin, con_received, con_seqno)
			select p_no_id, no_id, 0 from "_prod_replica_set".sl_node
				where no_id != p_no_id
				and no_active;

	-- ----
	-- Generate ENABLE_SUBSCRIPTION events for all sets that
	-- origin here and are subscribed by the just enabled node.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	for v_sub_row in select SUB.sub_set, SUB.sub_provider from
			"_prod_replica_set".sl_set S,
			"_prod_replica_set".sl_subscribe SUB
			where S.set_origin = v_local_node_id
			and S.set_id = SUB.sub_set
			and SUB.sub_receiver = p_no_id
			for update of S
	loop
		perform "_prod_replica_set".enableSubscription (v_sub_row.sub_set,
				v_sub_row.sub_provider, p_no_id);
	end loop;

	return p_no_id;
end;

Function: _prod_replica_set.enablesubscription( integer, integer, integer )

Returns: integer

Language: PLPGSQL

enableSubscription (sub_set, sub_provider, sub_receiver) Indicates that sub_receiver intends subscribing to set sub_set from sub_provider. Work is all done by the internal function enableSubscription_int (sub_set, sub_provider, sub_receiver).

declare
	p_sub_set			alias for $1;
	p_sub_provider		alias for $2;
	p_sub_receiver		alias for $3;
begin
	return  "_prod_replica_set".enableSubscription_int (p_sub_set, 
			p_sub_provider, p_sub_receiver);
end;

Function: _prod_replica_set.enablesubscription_int( integer, integer, integer )

Returns: integer

Language: PLPGSQL

enableSubscription_int (sub_set, sub_provider, sub_receiver) Internal function to enable subscription of node sub_receiver to set sub_set via node sub_provider. slon does most of the work; all we need do here is to remember that it happened. The function updates sl_subscribe, indicating that the subscription has become active.

declare
	p_sub_set			alias for $1;
	p_sub_provider		alias for $2;
	p_sub_receiver		alias for $3;
	v_n					int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- The real work is done in the replication engine. All
	-- we have to do here is remembering that it happened.
	-- ----

	-- ----
	-- Well, not only ... we might be missing an important event here
	-- ----
	if not exists (select true from "_prod_replica_set".sl_path
			where pa_server = p_sub_provider
			and pa_client = p_sub_receiver)
	then
		insert into "_prod_replica_set".sl_path
				(pa_server, pa_client, pa_conninfo, pa_connretry)
				values 
				(p_sub_provider, p_sub_receiver, 
				'<event pending>', 10);
	end if;

	update "_prod_replica_set".sl_subscribe
			set sub_active = 't'
			where sub_set = p_sub_set
			and sub_receiver = p_sub_receiver;
	get diagnostics v_n = row_count;
	if v_n = 0 then
		insert into "_prod_replica_set".sl_subscribe
				(sub_set, sub_provider, sub_receiver,
				sub_forward, sub_active)
				values
				(p_sub_set, p_sub_provider, p_sub_receiver,
				false, true);
	end if;

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	return p_sub_set;
end;

Function: _prod_replica_set.failednode( integer, integer )

Returns: integer

Language: PLPGSQL

Initiate failover from failed_node to backup_node. This function must be called on all nodes, and then waited for the restart of all node daemons.

declare
	p_failed_node		alias for $1;
	p_backup_node		alias for $2;
	v_row				record;
	v_row2				record;
	v_n					int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- All consistency checks first
	-- Check that every node that has a path to the failed node
	-- also has a path to the backup node.
	-- ----
	for v_row in select P.pa_client
			from "_prod_replica_set".sl_path P
			where P.pa_server = p_failed_node
				and P.pa_client <> p_backup_node
				and not exists (select true from "_prod_replica_set".sl_path PP
							where PP.pa_server = p_backup_node
								and PP.pa_client = P.pa_client)
	loop
		raise exception 'Slony-I: cannot failover - node % has no path to the backup node',
				v_row.pa_client;
	end loop;

	-- ----
	-- Check all sets originating on the failed node
	-- ----
	for v_row in select set_id
			from "_prod_replica_set".sl_set
			where set_origin = p_failed_node
	loop
		-- ----
		-- Check that the backup node is subscribed to all sets
		-- that originate on the failed node
		-- ----
		select into v_row2 sub_forward, sub_active
				from "_prod_replica_set".sl_subscribe
				where sub_set = v_row.set_id
					and sub_receiver = p_backup_node;
		if not found then
			raise exception 'Slony-I: cannot failover - node % is not subscribed to set %',
					p_backup_node, v_row.set_id;
		end if;

		-- ----
		-- Check that the subscription is active
		-- ----
		if not v_row2.sub_active then
			raise exception 'Slony-I: cannot failover - subscription for set % is not active',
					v_row.set_id;
		end if;

		-- ----
		-- If there are other subscribers, the backup node needs to
		-- be a forwarder too.
		-- ----
		select into v_n count(*)
				from "_prod_replica_set".sl_subscribe
				where sub_set = v_row.set_id
					and sub_receiver <> p_backup_node;
		if v_n > 0 and not v_row2.sub_forward then
			raise exception 'Slony-I: cannot failover - node % is not a forwarder of set %',
					p_backup_node, v_row.set_id;
		end if;
	end loop;

	-- ----
	-- Terminate all connections of the failed node the hard way
	-- ----
	perform "_prod_replica_set".terminateNodeConnections(p_failed_node);

	-- ----
	-- Move the sets
	-- ----
	for v_row in select S.set_id, (select count(*)
					from "_prod_replica_set".sl_subscribe SUB
					where S.set_id = SUB.sub_set
						and SUB.sub_receiver <> p_backup_node
						and SUB.sub_provider = p_failed_node)
					as num_direct_receivers 
			from "_prod_replica_set".sl_set S
			where S.set_origin = p_failed_node
			for update
	loop
		-- ----
		-- If the backup node is the only direct subscriber ...
		-- ----
		if v_row.num_direct_receivers = 0 then
		        raise notice 'failedNode: set % has no other direct receivers - move now', v_row.set_id;
			-- ----
			-- backup_node is the only direct subscriber, move the set
			-- right now. On the backup node itself that includes restoring
			-- all user mode triggers, removing the protection trigger,
			-- adding the log trigger, removing the subscription and the
			-- obsolete setsync status.
			-- ----
			if p_backup_node = "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
				for v_row2 in select * from "_prod_replica_set".sl_table
						where tab_set = v_row.set_id
				loop
					perform "_prod_replica_set".alterTableRestore(v_row2.tab_id);
				end loop;

				update "_prod_replica_set".sl_set set set_origin = p_backup_node
						where set_id = v_row.set_id;

				delete from "_prod_replica_set".sl_setsync
						where ssy_setid = v_row.set_id;

				for v_row2 in select * from "_prod_replica_set".sl_table
						where tab_set = v_row.set_id
				loop
					perform "_prod_replica_set".alterTableForReplication(v_row2.tab_id);
				end loop;
			end if;

			delete from "_prod_replica_set".sl_subscribe
					where sub_set = v_row.set_id
						and sub_receiver = p_backup_node;
		else
			raise notice 'failedNode: set % has other direct receivers - change providers only', v_row.set_id;
			-- ----
			-- Backup node is not the only direct subscriber. This
			-- means that at this moment, we redirect all direct
			-- subscribers to receive from the backup node, and the
			-- backup node itself to receive from another one.
			-- The admin utility will wait for the slon engine to
			-- restart and then call failedNode2() on the node with
			-- the highest SYNC and redirect this to it on
			-- backup node later.
			-- ----
			update "_prod_replica_set".sl_subscribe
					set sub_provider = (select min(SS.sub_receiver)
							from "_prod_replica_set".sl_subscribe SS
							where SS.sub_set = v_row.set_id
								and SS.sub_provider = p_failed_node
								and SS.sub_receiver <> p_backup_node
								and SS.sub_forward)
					where sub_set = v_row.set_id
						and sub_receiver = p_backup_node;
			update "_prod_replica_set".sl_subscribe
					set sub_provider = p_backup_node
					where sub_set = v_row.set_id
						and sub_provider = p_failed_node
						and sub_receiver <> p_backup_node;
		end if;
	end loop;

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	-- Run addPartialLogIndices() to try to add indices to unused sl_log_? table
	perform "_prod_replica_set".addPartialLogIndices();

	-- ----
	-- Make sure the node daemon will restart
	-- ----
	notify "_prod_replica_set_Restart";

	-- ----
	-- That is it - so far.
	-- ----
	return p_failed_node;
end;

Function: _prod_replica_set.failednode2( integer, integer, integer, bigint, bigint )

Returns: bigint

Language: PLPGSQL

FUNCTION failedNode2 (failed_node, backup_node, set_id, ev_seqno, ev_seqfake) On the node that has the highest sequence number of the failed node, fake the FAILOVER_SET event.

declare
	p_failed_node		alias for $1;
	p_backup_node		alias for $2;
	p_set_id			alias for $3;
	p_ev_seqno			alias for $4;
	p_ev_seqfake		alias for $5;
	v_row				record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	select * into v_row
			from "_prod_replica_set".sl_event
			where ev_origin = p_failed_node
			and ev_seqno = p_ev_seqno;
	if not found then
		raise exception 'Slony-I: event %,% not found',
				p_failed_node, p_ev_seqno;
	end if;

	insert into "_prod_replica_set".sl_event
			(ev_origin, ev_seqno, ev_timestamp,
			ev_minxid, ev_maxxid, ev_xip,
			ev_type, ev_data1, ev_data2, ev_data3)
			values 
			(p_failed_node, p_ev_seqfake, CURRENT_TIMESTAMP,
			v_row.ev_minxid, v_row.ev_maxxid, v_row.ev_xip,
			'FAILOVER_SET', p_failed_node::text, p_backup_node::text,
			p_set_id::text);
	insert into "_prod_replica_set".sl_confirm
			(con_origin, con_received, con_seqno, con_timestamp)
			values
			(p_failed_node, "_prod_replica_set".getLocalNodeId('_prod_replica_set'),
			p_ev_seqfake, CURRENT_TIMESTAMP);
	notify "_prod_replica_set_Event";
	notify "_prod_replica_set_Confirm";
	notify "_prod_replica_set_Restart";

	perform "_prod_replica_set".failoverSet_int(p_failed_node,
			p_backup_node, p_set_id, p_ev_seqfake);

	return p_ev_seqfake;
end;

Function: _prod_replica_set.failoverset_int( integer, integer, integer )

Returns: integer

Language: PLPGSQL

FUNCTION failoverSet_int (failed_node, backup_node, set_id) Finish failover for one set.

declare
	p_failed_node		alias for $1;
	p_backup_node		alias for $2;
	p_set_id			alias for $3;
	v_row				record;
	v_last_sync			int8;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Change the origin of the set now to the backup node.
	-- On the backup node this includes changing all the
	-- trigger and protection stuff
	-- ----
	if p_backup_node = "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		for v_row in select * from "_prod_replica_set".sl_table
				where tab_set = p_set_id
		loop
			perform "_prod_replica_set".alterTableRestore(v_row.tab_id);
		end loop;

		delete from "_prod_replica_set".sl_setsync
				where ssy_setid = p_set_id;
		delete from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = p_backup_node;
		update "_prod_replica_set".sl_set
				set set_origin = p_backup_node
				where set_id = p_set_id;

		for v_row in select * from "_prod_replica_set".sl_table
				where tab_set = p_set_id
		loop
			perform "_prod_replica_set".alterTableForReplication(v_row.tab_id);
		end loop;
		insert into "_prod_replica_set".sl_event
				(ev_origin, ev_seqno, ev_timestamp,
				ev_minxid, ev_maxxid, ev_xip,
				ev_type, ev_data1, ev_data2, ev_data3)
				values 
				(p_backup_node, "pg_catalog".nextval('"_prod_replica_set".sl_event_seq'), CURRENT_TIMESTAMP,
				'0', '0', '',
				'ACCEPT_SET', p_set_id::text,
				p_failed_node::text, p_backup_node::text);
	else
		delete from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = p_backup_node;
		update "_prod_replica_set".sl_set
				set set_origin = p_backup_node
				where set_id = p_set_id;
	end if;

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	-- ----
	-- If we are a subscriber of the set ourself, change our
	-- setsync status to reflect the new set origin.
	-- ----
	if exists (select true from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id
				and sub_receiver = "_prod_replica_set".getLocalNodeId(
						'_prod_replica_set'))
	then
		delete from "_prod_replica_set".sl_setsync
				where ssy_setid = p_set_id;

		select coalesce(max(ev_seqno), 0) into v_last_sync
				from "_prod_replica_set".sl_event
				where ev_origin = p_backup_node
					and ev_type = 'SYNC';
		if v_last_sync > 0 then
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					select p_set_id, p_backup_node, v_last_sync,
					ev_minxid, ev_maxxid, ev_xip, NULL
					from "_prod_replica_set".sl_event
					where ev_origin = p_backup_node
						and ev_seqno = v_last_sync;
		else
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					values (p_set_id, p_backup_node, '0',
					'0', '0', '', NULL);
		end if;
				
	end if;

	return p_failed_node;
end;

Function: _prod_replica_set.failoverset_int( integer, integer, integer, bigint )

Returns: integer

Language: PLPGSQL

FUNCTION failoverSet_int (failed_node, backup_node, set_id, wait_seqno) Finish failover for one set.

declare
	p_failed_node		alias for $1;
	p_backup_node		alias for $2;
	p_set_id			alias for $3;
	p_wait_seqno		alias for $4;
	v_row				record;
	v_last_sync			int8;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Change the origin of the set now to the backup node.
	-- On the backup node this includes changing all the
	-- trigger and protection stuff
	-- ----
	if p_backup_node = "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		for v_row in select * from "_prod_replica_set".sl_table
				where tab_set = p_set_id
		loop
			perform "_prod_replica_set".alterTableRestore(v_row.tab_id);
		end loop;

		delete from "_prod_replica_set".sl_setsync
				where ssy_setid = p_set_id;
		delete from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = p_backup_node;
		update "_prod_replica_set".sl_set
				set set_origin = p_backup_node
				where set_id = p_set_id;

		for v_row in select * from "_prod_replica_set".sl_table
				where tab_set = p_set_id
		loop
			perform "_prod_replica_set".alterTableForReplication(v_row.tab_id);
		end loop;
		insert into "_prod_replica_set".sl_event
				(ev_origin, ev_seqno, ev_timestamp,
				ev_minxid, ev_maxxid, ev_xip,
				ev_type, ev_data1, ev_data2, ev_data3, ev_data4)
				values
				(p_backup_node, "pg_catalog".nextval('"_prod_replica_set".sl_event_seq'), CURRENT_TIMESTAMP,
				'0', '0', '',
				'ACCEPT_SET', p_set_id::text,
				p_failed_node::text, p_backup_node::text,
				p_wait_seqno::text);
	else
		delete from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = p_backup_node;
		update "_prod_replica_set".sl_set
				set set_origin = p_backup_node
				where set_id = p_set_id;
	end if;

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	-- ----
	-- If we are a subscriber of the set ourself, change our
	-- setsync status to reflect the new set origin.
	-- ----
	if exists (select true from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id
				and sub_receiver = "_prod_replica_set".getLocalNodeId(
						'_prod_replica_set'))
	then
		delete from "_prod_replica_set".sl_setsync
				where ssy_setid = p_set_id;

		select coalesce(max(ev_seqno), 0) into v_last_sync
				from "_prod_replica_set".sl_event
				where ev_origin = p_backup_node
					and ev_type = 'SYNC';
		if v_last_sync > 0 then
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					select p_set_id, p_backup_node, v_last_sync,
					ev_minxid, ev_maxxid, ev_xip, NULL
					from "_prod_replica_set".sl_event
					where ev_origin = p_backup_node
						and ev_seqno = v_last_sync;
		else
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					values (p_set_id, p_backup_node, '0',
					'0', '0', '', NULL);
		end if;
				
	end if;

	return p_failed_node;
end;

Function: _prod_replica_set.finishtableaftercopy( integer )

Returns: integer

Language: PLPGSQL

Reenable index maintenance and reindex the table

declare
	p_tab_id		alias for $1;
	v_tab_oid		oid;
	v_tab_fqname	text;
begin
	-- ----
	-- Get the tables OID and fully qualified name
	-- ---
	select	PGC.oid,
			"_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			"_prod_replica_set".slon_quote_brute(PGC.relname) as tab_fqname
		into v_tab_oid, v_tab_fqname
			from "_prod_replica_set".sl_table T,   
				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
				where T.tab_id = p_tab_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid;
	if not found then
		raise exception 'Table with ID % not found in sl_table', p_tab_id;
	end if;

	-- ----
	-- Reenable indexes and reindex the table.
	-- ----
	update pg_class set relhasindex = 't' where oid = v_tab_oid;
	execute 'reindex table ' || "_prod_replica_set".slon_quote_input(v_tab_fqname);

	return 1;
end;

Function: _prod_replica_set.forwardconfirm( integer, integer, bigint, timestamp without time zone )

Returns: bigint

Language: PLPGSQL

forwardConfirm (p_con_origin, p_con_received, p_con_seqno, p_con_timestamp) Confirms (recorded in sl_confirm) that items from p_con_origin up to p_con_seqno have been received by node p_con_received as of p_con_timestamp, and raises an event to forward this confirmation.

declare
	p_con_origin	alias for $1;
	p_con_received	alias for $2;
	p_con_seqno		alias for $3;
	p_con_timestamp	alias for $4;
	v_max_seqno		bigint;
begin
	select into v_max_seqno coalesce(max(con_seqno), 0)
			from "_prod_replica_set".sl_confirm
			where con_origin = p_con_origin
			and con_received = p_con_received;
	if v_max_seqno < p_con_seqno then
		insert into "_prod_replica_set".sl_confirm 
				(con_origin, con_received, con_seqno, con_timestamp)
				values (p_con_origin, p_con_received, p_con_seqno,
					p_con_timestamp);
		notify "_prod_replica_set_Confirm";
		v_max_seqno = p_con_seqno;
	end if;

	return v_max_seqno;
end;

Function: _prod_replica_set.generate_sync_event( interval )

Returns: integer

Language: PLPGSQL

Generate a sync event if there has not been one in the requested interval.

declare
	p_interval     alias for $1;
	v_node_row     record;

BEGIN
	select 1 into v_node_row from "_prod_replica_set".sl_event 
       	  where ev_type = 'SYNC' and ev_origin = "_prod_replica_set".getLocalNodeId('_prod_replica_set')
          and ev_timestamp > now() - p_interval limit 1;
	if not found then
		-- If there has been no SYNC in the last interval, then push one
		perform "_prod_replica_set".createEvent('_prod_replica_set', 'SYNC', NULL);
		return 1;
	else
		return 0;
	end if;
end;

Function: _prod_replica_set.getcurrentxid( )

Returns: xxid

Language: C

_Slony_I_getCurrentXid

Function: _prod_replica_set.getlocalnodeid( name )

Returns: integer

Language: C

Returns the node ID of the node being serviced on the local database

_Slony_I_getLocalNodeId

Function: _prod_replica_set.getmaxxid( )

Returns: xxid

Language: C

_Slony_I_getMaxXid

Function: _prod_replica_set.getminxid( )

Returns: xxid

Language: C

_Slony_I_getMinXid

Function: _prod_replica_set.getmoduleversion( )

Returns: text

Language: C

Returns the compiled-in version number of the Slony-I shared object

_Slony_I_getModuleVersion

Function: _prod_replica_set.getsessionrole( name )

Returns: text

Language: C

not yet documented

_Slony_I_getSessionRole

Function: _prod_replica_set.initializelocalnode( integer, text )

Returns: integer

Language: PLPGSQL

no_id - Node ID # no_comment - Human-oriented comment Initializes the new node, no_id

declare
	p_local_node_id		alias for $1;
	p_comment			alias for $2;
	v_old_node_id		int4;
	v_first_log_no		int4;
	v_event_seq			int8;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Make sure this node is uninitialized or got reset
	-- ----
	select last_value::int4 into v_old_node_id from "_prod_replica_set".sl_local_node_id;
	if v_old_node_id != -1 then
		raise exception 'Slony-I: This node is already initialized';
	end if;

	-- ----
	-- Set sl_local_node_id to the requested value and add our
	-- own system to sl_node.
	-- ----
	perform setval('"_prod_replica_set".sl_local_node_id', p_local_node_id);
	perform setval('"_prod_replica_set".sl_rowid_seq', 
			p_local_node_id::int8 * '1000000000000000'::int8);
	perform "_prod_replica_set".storeNode_int (p_local_node_id, p_comment, false);
	
	return p_local_node_id;
end;

Function: _prod_replica_set.killbackend( integer, text )

Returns: integer

Language: C

Send a signal to a postgres process. Requires superuser rights

_Slony_I_killBackend

Function: _prod_replica_set.lockedset( )

Returns: "trigger"

Language: C

Trigger function to prevent modifications to a table before and after a moveSet()

_Slony_I_lockedSet

Function: _prod_replica_set.lockset( integer )

Returns: integer

Language: PLPGSQL

lockSet(set_id) Add a special trigger to all tables of a set that disables access to it.

declare
	p_set_id			alias for $1;
	v_local_node_id		int4;
	v_set_row			record;
	v_tab_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that the set exists and that we are the origin
	-- and that it is not already locked.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select * into v_set_row from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_set_row.set_origin <> v_local_node_id then
		raise exception 'Slony-I: set % does not originate on local node',
				p_set_id;
	end if;
	if v_set_row.set_locked notnull then
		raise exception 'Slony-I: set % is already locked', p_set_id;
	end if;

	-- ----
	-- Place the lockedSet trigger on all tables in the set.
	-- ----
	for v_tab_row in select T.tab_id,
			"_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			"_prod_replica_set".slon_quote_brute(PGC.relname) as tab_fqname
			from "_prod_replica_set".sl_table T,
				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
			where T.tab_set = p_set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
			order by tab_id
	loop
		execute 'create trigger "_prod_replica_set_lockedset_' || 
				v_tab_row.tab_id || 
				'" before insert or update or delete on ' ||
				v_tab_row.tab_fqname || ' for each row execute procedure
				"_prod_replica_set".lockedSet (''_prod_replica_set'');';
	end loop;

	-- ----
	-- Remember our snapshots xmax as for the set locking
	-- ----
	update "_prod_replica_set".sl_set
			set set_locked = "_prod_replica_set".getMaxXid()
			where set_id = p_set_id;

	return p_set_id;
end;

Function: _prod_replica_set.logswitch_finish( )

Returns: integer

Language: PLPGSQL

logswitch_finish() Attempt to finalize a log table switch in progress

DECLARE
	v_current_status	int4;
	v_dummy				record;
BEGIN
	-- ----
	-- Grab the central configuration lock to prevent race conditions
	-- while changing the sl_log_status sequence value.
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get the current log status.
	-- ----
	select last_value into v_current_status from "_prod_replica_set".sl_log_status;

	-- ----
	-- status value 0 or 1 means that there is no log switch in progress
	-- ----
	if v_current_status = 0 or v_current_status = 1 then
		return 0;
	end if;

	-- ----
	-- status = 2: sl_log_1 active, cleanup sl_log_2
	-- ----
	if v_current_status = 2 then
		-- ----
		-- The cleanup thread calls us after it did the delete and
		-- vacuum of both log tables. If sl_log_2 is empty now, we
		-- can truncate it and the log switch is done.
		-- ----
		for v_dummy in select 1 from "_prod_replica_set".sl_log_2 loop
			-- ----
			-- Found a row ... log switch is still in progress.
			-- ----
			raise notice 'Slony-I: log switch to sl_log_1 still in progress - sl_log_2 not truncated';
			return -1;
		end loop;

		raise notice 'Slony-I: log switch to sl_log_1 complete - truncate sl_log_2';
		truncate "_prod_replica_set".sl_log_2;
		if exists (select * from "pg_catalog".pg_class c, "pg_catalog".pg_namespace n, "pg_catalog".pg_attribute a where c.relname = 'sl_log_2' and n.oid = c.relnamespace and a.attrelid = c.oid and a.attname = 'oid') then
	                execute 'alter table "_prod_replica_set".sl_log_2 set without oids;';
		end if;		
		perform "pg_catalog".setval('"_prod_replica_set".sl_log_status', 0);
		-- Run addPartialLogIndices() to try to add indices to unused sl_log_? table
		perform "_prod_replica_set".addPartialLogIndices();

		return 1;
	end if;

	-- ----
	-- status = 3: sl_log_2 active, cleanup sl_log_1
	-- ----
	if v_current_status = 3 then
		-- ----
		-- The cleanup thread calls us after it did the delete and
		-- vacuum of both log tables. If sl_log_2 is empty now, we
		-- can truncate it and the log switch is done.
		-- ----
		for v_dummy in select 1 from "_prod_replica_set".sl_log_1 loop
			-- ----
			-- Found a row ... log switch is still in progress.
			-- ----
			raise notice 'Slony-I: log switch to sl_log_2 still in progress - sl_log_1 not truncated';
			return -1;
		end loop;

		raise notice 'Slony-I: log switch to sl_log_2 complete - truncate sl_log_1';
		truncate "_prod_replica_set".sl_log_1;
		if exists (select * from "pg_catalog".pg_class c, "pg_catalog".pg_namespace n, "pg_catalog".pg_attribute a where c.relname = 'sl_log_1' and n.oid = c.relnamespace and a.attrelid = c.oid and a.attname = 'oid') then
	                execute 'alter table "_prod_replica_set".sl_log_1 set without oids;';
		end if;		
		perform "pg_catalog".setval('"_prod_replica_set".sl_log_status', 1);
		-- Run addPartialLogIndices() to try to add indices to unused sl_log_? table
		perform "_prod_replica_set".addPartialLogIndices();
		return 2;
	end if;
END;

Function: _prod_replica_set.logswitch_start( )

Returns: integer

Language: PLPGSQL

logswitch_start() Initiate a log table switch if none is in progress

DECLARE
	v_current_status	int4;
BEGIN
	-- ----
	-- Grab the central configuration lock to prevent race conditions
	-- while changing the sl_log_status sequence value.
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get the current log status.
	-- ----
	select last_value into v_current_status from "_prod_replica_set".sl_log_status;

	-- ----
	-- status = 0: sl_log_1 active, sl_log_2 clean
	-- Initiate a switch to sl_log_2.
	-- ----
	if v_current_status = 0 then
		perform "pg_catalog".setval('"_prod_replica_set".sl_log_status', 3);
		perform "_prod_replica_set".registry_set_timestamp(
				'logswitch.laststart', now()::timestamp);
		raise notice 'Slony-I: Logswitch to sl_log_2 initiated';
		return 2;
	end if;

	-- ----
	-- status = 1: sl_log_2 active, sl_log_1 clean
	-- Initiate a switch to sl_log_1.
	-- ----
	if v_current_status = 1 then
		perform "pg_catalog".setval('"_prod_replica_set".sl_log_status', 2);
		perform "_prod_replica_set".registry_set_timestamp(
				'logswitch.laststart', now()::timestamp);
		raise notice 'Slony-I: Logswitch to sl_log_1 initiated';
		return 1;
	end if;

	raise exception 'Previous logswitch still in progress';
END;

Function: _prod_replica_set.logswitch_weekly( )

Returns: integer

Language: PLPGSQL

logswitch_weekly() Ensure a logswitch is done at least weekly

DECLARE
	v_now			timestamp;
	v_now_dow		int4;
	v_auto_dow		int4;
	v_auto_time		time;
	v_auto_ts		timestamp;
	v_lastrun		timestamp;
	v_laststart		timestamp;
	v_days_since	int4;
BEGIN
	-- ----
	-- Check that today is the day to run at all
	-- ----
	v_auto_dow := "_prod_replica_set".registry_get_int4(
			'logswitch_weekly.dow', 0);
	v_now := "pg_catalog".now();
	v_now_dow := extract (DOW from v_now);
	if v_now_dow <> v_auto_dow then
		perform "_prod_replica_set".registry_set_timestamp(
				'logswitch_weekly.lastrun', v_now);
		return 0;
	end if;

	-- ----
	-- Check that the last run of this procedure was before and now is
	-- after the time we should automatically switch logs.
	-- ----
	v_auto_time := "_prod_replica_set".registry_get_text(
			'logswitch_weekly.time', '02:00');
	v_auto_ts := current_date + v_auto_time;
	v_lastrun := "_prod_replica_set".registry_get_timestamp(
			'logswitch_weekly.lastrun', 'epoch');
	if v_lastrun >= v_auto_ts or v_now < v_auto_ts then
		perform "_prod_replica_set".registry_set_timestamp(
				'logswitch_weekly.lastrun', v_now);
		return 0;
	end if;

	-- ----
	-- This is the moment configured in dow+time. Check that the
	-- last logswitch was done more than 2 days ago.
	-- ----
	v_laststart := "_prod_replica_set".registry_get_timestamp(
			'logswitch.laststart', 'epoch');
	v_days_since := extract (days from (v_now - v_laststart));
	if v_days_since < 2 then
		perform "_prod_replica_set".registry_set_timestamp(
				'logswitch_weekly.lastrun', v_now);
		return 0;
	end if;

	-- ----
	-- Fire off an automatic logswitch
	-- ----
	perform "_prod_replica_set".logswitch_start();
	perform "_prod_replica_set".registry_set_timestamp(
			'logswitch_weekly.lastrun', v_now);
	return 1;
END;

Function: _prod_replica_set.logtrigger( )

Returns: "trigger"

Language: C

This is the trigger that is executed on the origin node that causes updates to be recorded in sl_log_1/sl_log_2.

_Slony_I_logTrigger

Function: _prod_replica_set.make_function_strict( text, text )

Returns: void

Language: PLPGSQL

Equivalent to 8.1+ ALTER FUNCTION ... STRICT

declare
   fun alias for $1;
   parms alias for $2;
   stmt text;
begin
   stmt := 'ALTER FUNCTION "_prod_replica_set".' || fun || ' ' || parms || ' STRICT;';
   execute stmt;
   return;
end

Function: _prod_replica_set.mergeset( integer, integer )

Returns: bigint

Language: PLPGSQL

Generate MERGE_SET event to request that sets be merged together. Both sets must exist, and originate on the same node. They must be subscribed by the same set of nodes.

declare
	p_set_id			alias for $1;
	p_add_id			alias for $2;
	v_origin			int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;
	
	-- ----
	-- Check that both sets exist and originate here
	-- ----
	if p_set_id = p_add_id then
		raise exception 'Slony-I: merged set ids cannot be identical';
	end if;
	select set_origin into v_origin from "_prod_replica_set".sl_set
			where set_id = p_set_id;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: set % does not originate on local node',
				p_set_id;
	end if;

	select set_origin into v_origin from "_prod_replica_set".sl_set
			where set_id = p_add_id;
	if not found then
		raise exception 'Slony-I: set % not found', p_add_id;
	end if;
	if v_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: set % does not originate on local node',
				p_add_id;
	end if;

	-- ----
	-- Check that both sets are subscribed by the same set of nodes
	-- ----
	if exists (select true from "_prod_replica_set".sl_subscribe SUB1
				where SUB1.sub_set = p_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from "_prod_replica_set".sl_subscribe SUB2
						where SUB2.sub_set = p_add_id))
	then
		raise exception 'Slony-I: subscriber lists of set % and % are different',
				p_set_id, p_add_id;
	end if;

	if exists (select true from "_prod_replica_set".sl_subscribe SUB1
				where SUB1.sub_set = p_add_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from "_prod_replica_set".sl_subscribe SUB2
						where SUB2.sub_set = p_set_id))
	then
		raise exception 'Slony-I: subscriber lists of set % and % are different',
				p_add_id, p_set_id;
	end if;

	-- ----
	-- Check that all ENABLE_SUBSCRIPTION events for the set are confirmed
	-- ----
	if exists (select true from "_prod_replica_set".sl_event
			where ev_type = 'ENABLE_SUBSCRIPTION'
			and ev_data1 = p_add_id::text
			and ev_seqno > (select max(con_seqno) from "_prod_replica_set".sl_confirm
					where con_origin = ev_origin
					and con_received::text = ev_data3))
	then
		raise exception 'Slony-I: set % has subscriptions in progress - cannot merge',
				p_add_id;
	end if;
			  

	-- ----
	-- Create a SYNC event, merge the sets, create a MERGE_SET event
	-- ----
	perform "_prod_replica_set".createEvent('_prod_replica_set', 'SYNC', NULL);
	perform "_prod_replica_set".mergeSet_int(p_set_id, p_add_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'MERGE_SET', 
			p_set_id::text, p_add_id::text);
end;

Function: _prod_replica_set.mergeset_int( integer, integer )

Returns: integer

Language: PLPGSQL

mergeSet_int(set_id, add_id) - Perform MERGE_SET event, merging all objects from set add_id into set set_id.

declare
	p_set_id			alias for $1;
	p_add_id			alias for $2;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;
	
	update "_prod_replica_set".sl_sequence
			set seq_set = p_set_id
			where seq_set = p_add_id;
	update "_prod_replica_set".sl_table
			set tab_set = p_set_id
			where tab_set = p_add_id;
	delete from "_prod_replica_set".sl_subscribe
			where sub_set = p_add_id;
	delete from "_prod_replica_set".sl_setsync
			where ssy_setid = p_add_id;
	delete from "_prod_replica_set".sl_set
			where set_id = p_add_id;

	return p_set_id;
end;

Function: _prod_replica_set.moveset( integer, integer )

Returns: bigint

Language: PLPGSQL

moveSet(set_id, new_origin) Generate MOVE_SET event to request that the origin for set set_id be moved to node new_origin

declare
	p_set_id			alias for $1;
	p_new_origin		alias for $2;
	v_local_node_id		int4;
	v_set_row			record;
	v_sub_row			record;
	v_sync_seqno		int8;
	v_lv_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that the set is locked and that this locking
	-- happened long enough ago.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select * into v_set_row from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_set_row.set_origin <> v_local_node_id then
		raise exception 'Slony-I: set % does not originate on local node',
				p_set_id;
	end if;
	if v_set_row.set_locked isnull then
		raise exception 'Slony-I: set % is not locked', p_set_id;
	end if;
	if v_set_row.set_locked > "_prod_replica_set".getMinXid() then
		raise exception 'Slony-I: cannot move set % yet, transactions < % are still in progress',
				p_set_id, v_set_row.set_locked;
	end if;

	-- ----
	-- Unlock the set
	-- ----
	perform "_prod_replica_set".unlockSet(p_set_id);

	-- ----
	-- Check that the new_origin is an active subscriber of the set
	-- ----
	select * into v_sub_row from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;
	if not found then
		raise exception 'Slony-I: set % is not subscribed by node %',
				p_set_id, p_new_origin;
	end if;
	if not v_sub_row.sub_active then
		raise exception 'Slony-I: subsctiption of node % for set % is inactive',
				p_new_origin, p_set_id;
	end if;

	-- ----
	-- Reconfigure everything
	-- ----
	perform "_prod_replica_set".moveSet_int(p_set_id, v_local_node_id,
			p_new_origin, 0);

	perform "_prod_replica_set".RebuildListenEntries();

	-- ----
	-- At this time we hold access exclusive locks for every table
	-- in the set. But we did move the set to the new origin, so the
	-- createEvent() we are doing now will not record the sequences.
	-- ----
	v_sync_seqno := "_prod_replica_set".createEvent('_prod_replica_set', 'SYNC');
	insert into "_prod_replica_set".sl_seqlog 
			(seql_seqid, seql_origin, seql_ev_seqno, seql_last_value)
			select seq_id, v_local_node_id, v_sync_seqno, seq_last_value
			from "_prod_replica_set".sl_seqlastvalue
			where seq_set = p_set_id;
					
	-- ----
	-- Finally we generate the real event
	-- ----
	return "_prod_replica_set".createEvent('_prod_replica_set', 'MOVE_SET', 
			p_set_id::text, v_local_node_id::text, p_new_origin::text);
end;

Function: _prod_replica_set.moveset_int( integer, integer, integer )

Returns: integer

Language: PLPGSQL

moveSet(set_id, old_origin, new_origin) Process MOVE_SET event to request that the origin for set set_id be moved from old_origin to node new_origin

declare
	p_set_id			alias for $1;
	p_old_origin		alias for $2;
	p_new_origin		alias for $3;
	v_local_node_id		int4;
	v_tab_row			record;
	v_sub_row			record;
	v_sub_node			int4;
	v_sub_last			int4;
	v_sub_next			int4;
	v_last_sync			int8;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get our local node ID
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');

	-- ----
	-- If we are the old or new origin of the set, we need to
	-- remove the log trigger from all tables first.
	-- ----
	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
		for v_tab_row in select tab_id from "_prod_replica_set".sl_table
				where tab_set = p_set_id
				order by tab_id
		loop
			perform "_prod_replica_set".alterTableRestore(v_tab_row.tab_id);
		end loop;
	end if;

	-- On the new origin, raise an event - ACCEPT_SET
	if v_local_node_id = p_new_origin then
		
		perform "_prod_replica_set".createEvent('_prod_replica_set', 'ACCEPT_SET', 
			p_set_id, p_old_origin, p_new_origin);
	end if;

	-- ----
	-- Next we have to reverse the subscription path
	-- ----
	v_sub_last = p_new_origin;
	select sub_provider into v_sub_node
			from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;
	if not found then
		raise exception 'Slony-I: subscription path broken in moveSet_int';
	end if;
	while v_sub_node <> p_old_origin loop
		-- ----
		-- Tracing node by node, the old receiver is now in
		-- v_sub_last and the old provider is in v_sub_node.
		-- ----

		-- ----
		-- Get the current provider of this node as next
		-- and change the provider to the previous one in
		-- the reverse chain.
		-- ----
		select sub_provider into v_sub_next
				from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = v_sub_node
				for update;
		if not found then
			raise exception 'Slony-I: subscription path broken in moveSet_int';
		end if;
		update "_prod_replica_set".sl_subscribe
				set sub_provider = v_sub_last
				where sub_set = p_set_id
					and sub_receiver = v_sub_node;

		v_sub_last = v_sub_node;
		v_sub_node = v_sub_next;
	end loop;

	-- ----
	-- This includes creating a subscription for the old origin
	-- ----
	insert into "_prod_replica_set".sl_subscribe
			(sub_set, sub_provider, sub_receiver,
			sub_forward, sub_active)
			values (p_set_id, v_sub_last, p_old_origin, true, true);
	if v_local_node_id = p_old_origin then
		select coalesce(max(ev_seqno), 0) into v_last_sync 
				from "_prod_replica_set".sl_event
				where ev_origin = p_new_origin
					and ev_type = 'SYNC';
		if v_last_sync > 0 then
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					select p_set_id, p_new_origin, v_last_sync,
					ev_minxid, ev_maxxid, ev_xip, NULL
					from "_prod_replica_set".sl_event
					where ev_origin = p_new_origin
						and ev_seqno = v_last_sync;
		else
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					values (p_set_id, p_new_origin, '0',
					'0', '0', '', NULL);
		end if;
	end if;

	-- ----
	-- Now change the ownership of the set.
	-- ----
	update "_prod_replica_set".sl_set
			set set_origin = p_new_origin
			where set_id = p_set_id;

	-- ----
	-- On the new origin, delete the obsolete setsync information
	-- and the subscription.
	-- ----
	if v_local_node_id = p_new_origin then
		delete from "_prod_replica_set".sl_setsync
				where ssy_setid = p_set_id;
	else
		if v_local_node_id <> p_old_origin then
			--
			-- On every other node, change the setsync so that it will
			-- pick up from the new origins last known sync.
			--
			delete from "_prod_replica_set".sl_setsync
					where ssy_setid = p_set_id;
			select coalesce(max(ev_seqno), 0) into v_last_sync
					from "_prod_replica_set".sl_event
					where ev_origin = p_new_origin
						and ev_type = 'SYNC';
			if v_last_sync > 0 then
				insert into "_prod_replica_set".sl_setsync
						(ssy_setid, ssy_origin, ssy_seqno,
						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
						select p_set_id, p_new_origin, v_last_sync,
						ev_minxid, ev_maxxid, ev_xip, NULL
						from "_prod_replica_set".sl_event
						where ev_origin = p_new_origin
							and ev_seqno = v_last_sync;
			else
				insert into "_prod_replica_set".sl_setsync
						(ssy_setid, ssy_origin, ssy_seqno,
						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
						values (p_set_id, p_new_origin, '0',
						'0', '0', '', NULL);
			end if;
		end if;
	end if;
	delete from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;

	-- Regenerate sl_listen since we revised the subscriptions
	perform "_prod_replica_set".RebuildListenEntries();

	-- ----
	-- If we are the new or old origin, we have to
	-- put all the tables into altered state again.
	-- ----
	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
		for v_tab_row in select tab_id from "_prod_replica_set".sl_table
				where tab_set = p_set_id
				order by tab_id
		loop
			perform "_prod_replica_set".alterTableForReplication(v_tab_row.tab_id);
		end loop;
	end if;

	return p_set_id;
end;

Function: _prod_replica_set.moveset_int( integer, integer, integer, bigint )

Returns: integer

Language: PLPGSQL

moveSet(set_id, old_origin, new_origin, wait_seqno) Process MOVE_SET event to request that the origin for set set_id be moved from old_origin to node new_origin

declare
	p_set_id			alias for $1;
	p_old_origin		alias for $2;
	p_new_origin		alias for $3;
	p_wait_seqno		alias for $4;
	v_local_node_id		int4;
	v_tab_row			record;
	v_sub_row			record;
	v_sub_node			int4;
	v_sub_last			int4;
	v_sub_next			int4;
	v_last_sync			int8;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get our local node ID
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');

	-- ----
	-- If we are the old or new origin of the set, we need to
	-- remove the log trigger from all tables first.
	-- ----
	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
		for v_tab_row in select tab_id from "_prod_replica_set".sl_table
				where tab_set = p_set_id
				order by tab_id
		loop
			perform "_prod_replica_set".alterTableRestore(v_tab_row.tab_id);
		end loop;
	end if;

	-- On the new origin, raise an event - ACCEPT_SET
	if v_local_node_id = p_new_origin then
		-- Create a SYNC event as well so that the ACCEPT_SET has
		-- the same snapshot as the last SYNC generated by the new
		-- origin. This snapshot will be used by other nodes to
		-- finalize the setsync status.
		perform "_prod_replica_set".createEvent('_prod_replica_set', 'SYNC', NULL);
		perform "_prod_replica_set".createEvent('_prod_replica_set', 'ACCEPT_SET', 
			p_set_id::text, p_old_origin::text, 
			p_new_origin::text, p_wait_seqno::text);
	end if;

	-- ----
	-- Next we have to reverse the subscription path
	-- ----
	v_sub_last = p_new_origin;
	select sub_provider into v_sub_node
			from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;
	if not found then
		raise exception 'Slony-I: subscription path broken in moveSet_int';
	end if;
	while v_sub_node <> p_old_origin loop
		-- ----
		-- Tracing node by node, the old receiver is now in
		-- v_sub_last and the old provider is in v_sub_node.
		-- ----

		-- ----
		-- Get the current provider of this node as next
		-- and change the provider to the previous one in
		-- the reverse chain.
		-- ----
		select sub_provider into v_sub_next
				from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = v_sub_node
				for update;
		if not found then
			raise exception 'Slony-I: subscription path broken in moveSet_int';
		end if;
		update "_prod_replica_set".sl_subscribe
				set sub_provider = v_sub_last
				where sub_set = p_set_id
					and sub_receiver = v_sub_node;

		v_sub_last = v_sub_node;
		v_sub_node = v_sub_next;
	end loop;

	-- ----
	-- This includes creating a subscription for the old origin
	-- ----
	insert into "_prod_replica_set".sl_subscribe
			(sub_set, sub_provider, sub_receiver,
			sub_forward, sub_active)
			values (p_set_id, v_sub_last, p_old_origin, true, true);
	if v_local_node_id = p_old_origin then
		select coalesce(max(ev_seqno), 0) into v_last_sync 
				from "_prod_replica_set".sl_event
				where ev_origin = p_new_origin
					and ev_type = 'SYNC';
		if v_last_sync > 0 then
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					select p_set_id, p_new_origin, v_last_sync,
					ev_minxid, ev_maxxid, ev_xip, NULL
					from "_prod_replica_set".sl_event
					where ev_origin = p_new_origin
						and ev_seqno = v_last_sync;
		else
			insert into "_prod_replica_set".sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					values (p_set_id, p_new_origin, '0',
					'0', '0', '', NULL);
		end if;
	end if;

	-- ----
	-- Now change the ownership of the set.
	-- ----
	update "_prod_replica_set".sl_set
			set set_origin = p_new_origin
			where set_id = p_set_id;

	-- ----
	-- On the new origin, delete the obsolete setsync information
	-- and the subscription.
	-- ----
	if v_local_node_id = p_new_origin then
		delete from "_prod_replica_set".sl_setsync
				where ssy_setid = p_set_id;
	else
		if v_local_node_id <> p_old_origin then
			--
			-- On every other node, change the setsync so that it will
			-- pick up from the new origins last known sync.
			--
			delete from "_prod_replica_set".sl_setsync
					where ssy_setid = p_set_id;
			select coalesce(max(ev_seqno), 0) into v_last_sync
					from "_prod_replica_set".sl_event
					where ev_origin = p_new_origin
						and ev_type = 'SYNC';
			if v_last_sync > 0 then
				insert into "_prod_replica_set".sl_setsync
						(ssy_setid, ssy_origin, ssy_seqno,
						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
						select p_set_id, p_new_origin, v_last_sync,
						ev_minxid, ev_maxxid, ev_xip, NULL
						from "_prod_replica_set".sl_event
						where ev_origin = p_new_origin
							and ev_seqno = v_last_sync;
			else
				insert into "_prod_replica_set".sl_setsync
						(ssy_setid, ssy_origin, ssy_seqno,
						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
						values (p_set_id, p_new_origin, '0',
						'0', '0', '', NULL);
			end if;
		end if;
	end if;
	delete from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;

	-- Regenerate sl_listen since we revised the subscriptions
	perform "_prod_replica_set".RebuildListenEntries();

	-- Run addPartialLogIndices() to try to add indices to unused sl_log_? table
	perform "_prod_replica_set".addPartialLogIndices();

	-- ----
	-- If we are the new or old origin, we have to
	-- put all the tables into altered state again.
	-- ----
	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
		for v_tab_row in select tab_id from "_prod_replica_set".sl_table
				where tab_set = p_set_id
				order by tab_id
		loop
			perform "_prod_replica_set".alterTableForReplication(v_tab_row.tab_id);
		end loop;
	end if;

	return p_set_id;
end;

Function: _prod_replica_set.pre74( )

Returns: integer

Language: SQL

Returns 1/0 based on whether or not the DB is running a version earlier than 7.4

select 0

Function: _prod_replica_set.preparetableforcopy( integer )

Returns: integer

Language: PLPGSQL

Delete all data and suppress index maintenance

declare
	p_tab_id		alias for $1;
	v_tab_oid		oid;
	v_tab_fqname	text;
begin
	-- ----
	-- Get the OID and fully qualified name for the table
	-- ---
	select	PGC.oid,
			"_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			"_prod_replica_set".slon_quote_brute(PGC.relname) as tab_fqname
		into v_tab_oid, v_tab_fqname
			from "_prod_replica_set".sl_table T,   
				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
				where T.tab_id = p_tab_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid;
	if not found then
		raise exception 'Table with ID % not found in sl_table', p_tab_id;
	end if;

	-- ----
	-- Try using truncate to empty the table and fallback to
	-- delete on error.
	-- ----
	execute 'truncate ' || "_prod_replica_set".slon_quote_input(v_tab_fqname);
	raise notice 'truncate of % succeeded', v_tab_fqname;

	-- ----
	-- Setting pg_class.relhasindex to false will cause copy not to
	-- maintain any indexes. At the end of the copy we will reenable
	-- them and reindex the table. This bulk creating of indexes is
	-- faster.
	-- ----
	update pg_class set relhasindex = 'f' where oid = v_tab_oid;

	return 1;
	exception when others then
		raise notice 'truncate of % failed - doing delete', v_tab_fqname;
		update pg_class set relhasindex = 'f' where oid = v_tab_oid;
		execute 'delete from only ' || "_prod_replica_set".slon_quote_input(v_tab_fqname);
		return 0;
end;

Function: _prod_replica_set.reachablefromnode( integer, integer[] )

Returns: SET OF integer

Language: PLPGSQL

ReachableFromNode(receiver, blacklist) Find all nodes that <receiver> can receive events from without using nodes in <blacklist> as a relay.

declare
	v_node alias for $1 ;
	v_blacklist alias for $2 ;
	v_ignore int4[] ;
	v_reachable_edge_last int4[] ;
	v_reachable_edge_new int4[] default '{}' ;
	v_server record ;
begin
	v_reachable_edge_last := array[v_node] ;
	v_ignore := v_blacklist || array[v_node] ;
	return next v_node ;
	while v_reachable_edge_last != '{}' loop
		v_reachable_edge_new := '{}' ;
		for v_server in select pa_server as no_id
			from "_prod_replica_set".sl_path
			where pa_client = ANY(v_reachable_edge_last) and pa_server != ALL(v_ignore)
		loop
			if v_server.no_id != ALL(v_ignore) then
				v_ignore := v_ignore || array[v_server.no_id] ;
				v_reachable_edge_new := v_reachable_edge_new || array[v_server.no_id] ;
				return next v_server.no_id ;
			end if ;
		end loop ;
		v_reachable_edge_last := v_reachable_edge_new ;
	end loop ;
	return ;
end ;

Function: _prod_replica_set.rebuildlistenentries( )

Returns: integer

Language: PLPGSQL

RebuildListenEntries() Invoked by various subscription and path modifying functions, this rewrites the sl_listen entries, adding in all the ones required to allow communications between nodes in the Slony-I cluster.

declare
	v_row	record;
	skip    boolean;
begin
	-- First remove the entire configuration
	delete from "_prod_replica_set".sl_listen;

	-- Second populate the sl_listen configuration with a full
	-- network of all possible paths.
	insert into "_prod_replica_set".sl_listen
				(li_origin, li_provider, li_receiver)
			select pa_server, pa_server, pa_client from "_prod_replica_set".sl_path;
	while true loop
		insert into "_prod_replica_set".sl_listen
					(li_origin, li_provider, li_receiver)
			select distinct li_origin, pa_server, pa_client
				from "_prod_replica_set".sl_listen, "_prod_replica_set".sl_path
				where li_receiver = pa_server
				  and li_origin <> pa_client
			except
			select li_origin, li_provider, li_receiver
				from "_prod_replica_set".sl_listen;

		if not found then
			exit;
		end if;
	end loop;

	-- We now replace specific event-origin,receiver combinations
	-- with a configuration that tries to avoid events arriving at
	-- a node before the data provider actually has the data ready.

	-- Loop over every possible pair of receiver and event origin
	for v_row in select N1.no_id as receiver, N2.no_id as origin
			from "_prod_replica_set".sl_node as N1, "_prod_replica_set".sl_node as N2
			where N1.no_id <> N2.no_id
	loop
		skip := 'f';
		-- 1st choice:
		-- If we use the event origin as a data provider for any
		-- set that originates on that very node, we are a direct
		-- subscriber to that origin and listen there only.
		if exists (select true from "_prod_replica_set".sl_set, "_prod_replica_set".sl_subscribe
				where set_origin = v_row.origin
				  and sub_set = set_id
				  and sub_provider = v_row.origin
				  and sub_receiver = v_row.receiver
				  and sub_active)
		then
			delete from "_prod_replica_set".sl_listen
				where li_origin = v_row.origin
				  and li_receiver = v_row.receiver;
			insert into "_prod_replica_set".sl_listen (li_origin, li_provider, li_receiver)
				values (v_row.origin, v_row.origin, v_row.receiver);
			skip := 't';
		end if;

		if skip then
			skip := 'f';
		else
		-- 2nd choice:
		-- If we are subscribed to any set originating on this
		-- event origin, we want to listen on all data providers
		-- we use for this origin. We are a cascaded subscriber
		-- for sets from this node.
			if exists (select true from "_prod_replica_set".sl_set, "_prod_replica_set".sl_subscribe
						where set_origin = v_row.origin
						  and sub_set = set_id
						  and sub_receiver = v_row.receiver
						  and sub_active)
			then
				delete from "_prod_replica_set".sl_listen
					where li_origin = v_row.origin
					  and li_receiver = v_row.receiver;
				insert into "_prod_replica_set".sl_listen (li_origin, li_provider, li_receiver)
					select distinct set_origin, sub_provider, v_row.receiver
						from "_prod_replica_set".sl_set, "_prod_replica_set".sl_subscribe
						where set_origin = v_row.origin
						  and sub_set = set_id
						  and sub_receiver = v_row.receiver
						  and sub_active;
			end if;
		end if;

	end loop ;

	return null ;
end ;

Function: _prod_replica_set.rebuildlistenentriesone( integer, integer )

Returns: integer

Language: PLPGSQL

RebuildListenEntriesOne(p_origin, p_receiver) Rebuilding of sl_listen entries for one origin, receiver pair.

declare
	p_origin		alias for $1;
	p_receiver		alias for $2;
	v_row			record;
begin
	-- 1. If the receiver is subscribed to any set from the origin,
	--    listen on the same provider(s).
	for v_row in select distinct sub_provider
			from "_prod_replica_set".sl_subscribe, "_prod_replica_set".sl_set,
				"_prod_replica_set".sl_path
			where sub_set = set_id
			and set_origin = p_origin
			and sub_receiver = p_receiver
			and sub_provider = pa_server
			and sub_receiver = pa_client
	loop
		perform "_prod_replica_set".storeListen_int(p_origin, 
				v_row.sub_provider, p_receiver);
	end loop;
	if found then
		return 1;
	end if;

	-- 2. If the receiver has a direct path to the provider,
	--    use that.
	if exists (select true
			from "_prod_replica_set".sl_path
			where pa_server = p_origin
			and pa_client = p_receiver)
	then
		perform "_prod_replica_set".storeListen_int(p_origin, p_origin, p_receiver);
		return 1;
	end if;

	-- 3. Listen on every node that is either provider for the
	--    receiver or is using the receiver as provider (follow the
	--    normal subscription routes).
	for v_row in select distinct provider from (
			select sub_provider as provider
					from "_prod_replica_set".sl_subscribe
					where sub_receiver = p_receiver
			union
			select sub_receiver as provider
					from "_prod_replica_set".sl_subscribe
					where sub_provider = p_receiver
					and exists (select true from "_prod_replica_set".sl_path
								where pa_server = sub_receiver
								and pa_client = sub_provider)
			) as S
	loop
		perform "_prod_replica_set".storeListen_int(p_origin,
				v_row.provider, p_receiver);
	end loop;
	if found then
		return 1;
	end if;

	-- 4. If all else fails - meaning there are no subscriptions to
	--    guide us to the right path - use every node we have a path
	--    to as provider. This normally only happens when the cluster
	--    is built or a new node added. This brute force fallback
	--    ensures that events will propagate if possible at all.
	for v_row in select pa_server as provider
			from "_prod_replica_set".sl_path
			where pa_client = p_receiver
	loop
		perform "_prod_replica_set".storeListen_int(p_origin, 
				v_row.provider, p_receiver);
	end loop;
	if found then
		return 1;
	end if;

	return 0;
end;

Function: _prod_replica_set.registernodeconnection( integer )

Returns: integer

Language: PLPGSQL

Register (uniquely) the node connection so that only one slon can service the node

declare
	p_nodeid	alias for $1;
begin
	insert into "_prod_replica_set".sl_nodelock
		(nl_nodeid, nl_backendpid)
		values
		(p_nodeid, pg_backend_pid());

	return 0;
end;

Function: _prod_replica_set.registry_get_int4( text, integer )

Returns: integer

Language: PLPGSQL

registry_get_int4(key, value) Get a registry value. If not present, set and return the default.

DECLARE
	p_key		alias for $1;
	p_default	alias for $2;
	v_value		int4;
BEGIN
	select reg_int4 into v_value from "_prod_replica_set".sl_registry
			where reg_key = p_key;
	if not found then 
		v_value = p_default;
		if p_default notnull then
			perform "_prod_replica_set".registry_set_int4(p_key, p_default);
		end if;
	else
		if v_value is null then
			raise exception 'Slony-I: registry key % is not an int4 value',
					p_key;
		end if;
	end if;
	return v_value;
END;

Function: _prod_replica_set.registry_get_text( text, text )

Returns: text

Language: PLPGSQL

registry_get_text(key, value) Get a registry value. If not present, set and return the default.

DECLARE
	p_key		alias for $1;
	p_default	alias for $2;
	v_value		text;
BEGIN
	select reg_text into v_value from "_prod_replica_set".sl_registry
			where reg_key = p_key;
	if not found then 
		v_value = p_default;
		if p_default notnull then
			perform "_prod_replica_set".registry_set_text(p_key, p_default);
		end if;
	else
		if v_value is null then
			raise exception 'Slony-I: registry key % is not a text value',
					p_key;
		end if;
	end if;
	return v_value;
END;

Function: _prod_replica_set.registry_get_timestamp( text, timestamp without time zone )

Returns: timestamp without time zone

Language: PLPGSQL

registry_get_timestamp(key, value) Get a registry value. If not present, set and return the default.

DECLARE
	p_key		alias for $1;
	p_default	alias for $2;
	v_value		timestamp;
BEGIN
	select reg_timestamp into v_value from "_prod_replica_set".sl_registry
			where reg_key = p_key;
	if not found then 
		v_value = p_default;
		if p_default notnull then
			perform "_prod_replica_set".registry_set_timestamp(p_key, p_default);
		end if;
	else
		if v_value is null then
			raise exception 'Slony-I: registry key % is not an timestamp value',
					p_key;
		end if;
	end if;
	return v_value;
END;

Function: _prod_replica_set.registry_set_int4( text, integer )

Returns: integer

Language: PLPGSQL

registry_set_int4(key, value) Set or delete a registry value

DECLARE
	p_key		alias for $1;
	p_value		alias for $2;
BEGIN
	if p_value is null then
		delete from "_prod_replica_set".sl_registry
				where reg_key = p_key;
	else
		lock table "_prod_replica_set".sl_registry;
		update "_prod_replica_set".sl_registry
				set reg_int4 = p_value
				where reg_key = p_key;
		if not found then
			insert into "_prod_replica_set".sl_registry (reg_key, reg_int4)
					values (p_key, p_value);
		end if;
	end if;
	return p_value;
END;

Function: _prod_replica_set.registry_set_text( text, text )

Returns: text

Language: PLPGSQL

registry_set_text(key, value) Set or delete a registry value

DECLARE
	p_key		alias for $1;
	p_value		alias for $2;
BEGIN
	if p_value is null then
		delete from "_prod_replica_set".sl_registry
				where reg_key = p_key;
	else
		lock table "_prod_replica_set".sl_registry;
		update "_prod_replica_set".sl_registry
				set reg_text = p_value
				where reg_key = p_key;
		if not found then
			insert into "_prod_replica_set".sl_registry (reg_key, reg_text)
					values (p_key, p_value);
		end if;
	end if;
	return p_value;
END;

Function: _prod_replica_set.registry_set_timestamp( text, timestamp without time zone )

Returns: timestamp without time zone

Language: PLPGSQL

registry_set_timestamp(key, value) Set or delete a registry value

DECLARE
	p_key		alias for $1;
	p_value		alias for $2;
BEGIN
	if p_value is null then
		delete from "_prod_replica_set".sl_registry
				where reg_key = p_key;
	else
		lock table "_prod_replica_set".sl_registry;
		update "_prod_replica_set".sl_registry
				set reg_timestamp = p_value
				where reg_key = p_key;
		if not found then
			insert into "_prod_replica_set".sl_registry (reg_key, reg_timestamp)
					values (p_key, p_value);
		end if;
	end if;
	return p_value;
END;

Function: _prod_replica_set.replicate_partition( integer, text, text, text, text )

Returns: bigint

Language: PLPGSQL

Add a partition table to replication. tab_idxname is optional - if NULL, then we use the primary key. This function looks up replication configuration via the parent table.

declare
  p_tab_id alias for $1;
  p_nspname alias for $2;
  p_tabname alias for $3;
  p_idxname alias for $4;
  p_comment alias for $5;

  prec record;
  prec2 record;
  v_set_id int4;

begin
-- Look up the parent table; fail if it does not exist
   select c1.oid into prec from pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_inherits i, pg_catalog.pg_namespace n where c1.oid = i.inhparent  and c2.oid = i.inhrelid and n.oid = c2.relnamespace and n.nspname = p_nspname and c2.relname = p_tabname;
   if not found then
	raise exception 'replicate_partition: No parent table found for %.%!', p_nspname, p_tabname;
   end if;

-- The parent table tells us what replication set to use
   select tab_set into prec2 from "_prod_replica_set".sl_table where tab_reloid = prec.oid;
   if not found then
	raise exception 'replicate_partition: Parent table % for new partition %.% is not replicated!', prec.oid, p_nspname, p_tabname;
   end if;

   v_set_id := prec2.tab_set;

-- Now, we have all the parameters necessary to run add_empty_table_to_replication...
   return "_prod_replica_set".add_empty_table_to_replication(v_set_id, p_tab_id, p_nspname, p_tabname, p_idxname, p_comment);
end

Function: _prod_replica_set.sequencelastvalue( text )

Returns: bigint

Language: PLPGSQL

sequenceLastValue(p_seqname) Utility function used in sl_seqlastvalue view to compactly get the last value from the requested sequence.

declare
	p_seqname	alias for $1;
	v_seq_row	record;
begin
	for v_seq_row in execute 'select last_value from ' || "_prod_replica_set".slon_quote_input(p_seqname)
	loop
		return v_seq_row.last_value;
	end loop;

	-- not reached
end;

Function: _prod_replica_set.sequencesetvalue( integer, integer, bigint, bigint )

Returns: integer

Language: PLPGSQL

sequenceSetValue (seq_id, seq_origin, ev_seqno, last_value) Set sequence seq_id to have new value last_value.

declare
	p_seq_id			alias for $1;
	p_seq_origin		alias for $2;
	p_ev_seqno			alias for $3;
	p_last_value		alias for $4;
	v_fqname			text;
begin
	-- ----
	-- Get the sequences fully qualified name
	-- ----
	select "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			"_prod_replica_set".slon_quote_brute(PGC.relname) into v_fqname
		from "_prod_replica_set".sl_sequence SQ,
			"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
		where SQ.seq_id = p_seq_id
			and SQ.seq_reloid = PGC.oid
			and PGC.relnamespace = PGN.oid;
	if not found then
		raise exception 'Slony-I: sequenceSetValue(): sequence % not found', p_seq_id;
	end if;

	-- ----
	-- Update it to the new value
	-- ----
	execute 'select setval(''' || v_fqname ||
			''', ''' || p_last_value || ''')';

	insert into "_prod_replica_set".sl_seqlog
			(seql_seqid, seql_origin, seql_ev_seqno, seql_last_value)
			values (p_seq_id, p_seq_origin, p_ev_seqno, p_last_value);

	return p_seq_id;
end;

Function: _prod_replica_set.setaddsequence( integer, integer, text, text )

Returns: bigint

Language: PLPGSQL

setAddSequence (set_id, seq_id, seq_fqname, seq_comment) On the origin node for set set_id, add sequence seq_fqname to the replication set, and raise SET_ADD_SEQUENCE to cause this to replicate to subscriber nodes.

declare
	p_set_id			alias for $1;
	p_seq_id			alias for $2;
	p_fqname			alias for $3;
	p_seq_comment		alias for $4;
	v_set_origin		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that we are the origin of the set
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id;
	if not found then
		raise exception 'Slony-I: setAddSequence(): set % not found', p_set_id;
	end if;
	if v_set_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: setAddSequence(): set % has remote origin - submit to origin node', p_set_id;
	end if;

	if exists (select true from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id)
	then
		raise exception 'Slony-I: cannot add sequence to currently subscribed set %',
				p_set_id;
	end if;

	-- ----
	-- Add the sequence to the set and generate the SET_ADD_SEQUENCE event
	-- ----
	perform "_prod_replica_set".setAddSequence_int(p_set_id, p_seq_id, p_fqname,
			p_seq_comment);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'SET_ADD_SEQUENCE',
						p_set_id::text, p_seq_id::text, 
						p_fqname::text, p_seq_comment::text);
end;

Function: _prod_replica_set.setaddsequence_int( integer, integer, text, text )

Returns: integer

Language: PLPGSQL

setAddSequence_int (set_id, seq_id, seq_fqname, seq_comment) This processes the SET_ADD_SEQUENCE event. On remote nodes that subscribe to set_id, add the sequence to the replication set.

declare
	p_set_id			alias for $1;
	p_seq_id			alias for $2;
	p_fqname			alias for $3;
	p_seq_comment		alias for $4;
	v_local_node_id		int4;
	v_set_origin		int4;
	v_sub_provider		int4;
	v_relkind			char;
	v_seq_reloid		oid;
	v_seq_relname		name;
	v_seq_nspname		name;
	v_sync_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- For sets with a remote origin, check that we are subscribed 
	-- to that set. Otherwise we ignore the sequence because it might 
	-- not even exist in our database.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id;
	if not found then
		raise exception 'Slony-I: setAddSequence_int(): set % not found',
				p_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
				and sub_receiver = "_prod_replica_set".getLocalNodeId('_prod_replica_set');
		if not found then
			return 0;
		end if;
	end if;
	
	-- ----
	-- Get the sequences OID and check that it is a sequence
	-- ----
	select PGC.oid, PGC.relkind, PGC.relname, PGN.nspname 
		into v_seq_reloid, v_relkind, v_seq_relname, v_seq_nspname
			from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
			where PGC.relnamespace = PGN.oid
			and "_prod_replica_set".slon_quote_input(p_fqname) = "_prod_replica_set".slon_quote_brute(PGN.nspname) ||
					'.' || "_prod_replica_set".slon_quote_brute(PGC.relname);
	if not found then
		raise exception 'Slony-I: setAddSequence_int(): sequence % not found', 
				p_fqname;
	end if;
	if v_relkind != 'S' then
		raise exception 'Slony-I: setAddSequence_int(): % is not a sequence',
				p_fqname;
	end if;

        select 1 into v_sync_row from "_prod_replica_set".sl_sequence where seq_id = p_seq_id;
	if not found then
               v_relkind := 'o';   -- all is OK
        else
                raise exception 'Slony-I: setAddSequence_int(): sequence ID % has already been assigned', p_seq_id;
        end if;

	-- ----
	-- Add the sequence to sl_sequence
	-- ----
	insert into "_prod_replica_set".sl_sequence
		(seq_id, seq_reloid, seq_relname, seq_nspname, seq_set, seq_comment) 
		values
		(p_seq_id, v_seq_reloid, v_seq_relname, v_seq_nspname,  p_set_id, p_seq_comment);

	-- ----
	-- On the set origin, fake a sl_seqlog row for the last sync event
	-- ----
	if v_set_origin = v_local_node_id then
		for v_sync_row in select coalesce (max(ev_seqno), 0) as ev_seqno
				from "_prod_replica_set".sl_event
				where ev_origin = v_local_node_id
					and ev_type = 'SYNC'
		loop
			insert into "_prod_replica_set".sl_seqlog
					(seql_seqid, seql_origin, seql_ev_seqno, 
					seql_last_value) values
					(p_seq_id, v_local_node_id, v_sync_row.ev_seqno,
					"_prod_replica_set".sequenceLastValue(p_fqname));
		end loop;
	end if;

	return p_seq_id;
end;

Function: _prod_replica_set.setaddtable( integer, integer, text, name, text )

Returns: bigint

Language: PLPGSQL

setAddTable (set_id, tab_id, tab_fqname, tab_idxname, tab_comment) Add table tab_fqname to replication set on origin node, and generate SET_ADD_TABLE event to allow this to propagate to other nodes. Note that the table id, tab_id, must be unique ACROSS ALL SETS.

declare
	p_set_id			alias for $1;
	p_tab_id			alias for $2;
	p_fqname			alias for $3;
	p_tab_idxname		alias for $4;
	p_tab_comment		alias for $5;
	v_set_origin		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that we are the origin of the set
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id;
	if not found then
		raise exception 'Slony-I: setAddTable(): set % not found', p_set_id;
	end if;
	if v_set_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: setAddTable(): set % has remote origin', p_set_id;
	end if;

	if exists (select true from "_prod_replica_set".sl_subscribe
			where sub_set = p_set_id)
	then
		raise exception 'Slony-I: cannot add table to currently subscribed set %',
				p_set_id;
	end if;

	-- ----
	-- Add the table to the set and generate the SET_ADD_TABLE event
	-- ----
	perform "_prod_replica_set".setAddTable_int(p_set_id, p_tab_id, p_fqname,
			p_tab_idxname, p_tab_comment);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'SET_ADD_TABLE',
			p_set_id::text, p_tab_id::text, p_fqname::text,
			p_tab_idxname::text, p_tab_comment::text);
end;

Function: _prod_replica_set.setaddtable_int( integer, integer, text, name, text )

Returns: integer

Language: PLPGSQL

setAddTable_int (set_id, tab_id, tab_fqname, tab_idxname, tab_comment) This function processes the SET_ADD_TABLE event on remote nodes, adding a table to replication if the remote node is subscribing to its replication set.

declare

	p_set_id		alias for $1;
	p_tab_id		alias for $2;
	p_fqname		alias for $3;
	p_tab_idxname		alias for $4;
	p_tab_comment		alias for $5;
	v_tab_relname		name;
	v_tab_nspname		name;
	v_local_node_id		int4;
	v_set_origin		int4;
	v_sub_provider		int4;
	v_relkind		char;
	v_tab_reloid		oid;
	v_pkcand_nn		boolean;
	v_prec			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- For sets with a remote origin, check that we are subscribed 
	-- to that set. Otherwise we ignore the table because it might 
	-- not even exist in our database.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_set_id;
	if not found then
		raise exception 'Slony-I: setAddTable_int(): set % not found',
				p_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from "_prod_replica_set".sl_subscribe
				where sub_set = p_set_id
				and sub_receiver = "_prod_replica_set".getLocalNodeId('_prod_replica_set');
		if not found then
			return 0;
		end if;
	end if;
	
	-- ----
	-- Get the tables OID and check that it is a real table
	-- ----
	select PGC.oid, PGC.relkind, PGC.relname, PGN.nspname into v_tab_reloid, v_relkind, v_tab_relname, v_tab_nspname
			from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
			where PGC.relnamespace = PGN.oid
			and "_prod_replica_set".slon_quote_input(p_fqname) = "_prod_replica_set".slon_quote_brute(PGN.nspname) ||
					'.' || "_prod_replica_set".slon_quote_brute(PGC.relname);
	if not found then
		raise exception 'Slony-I: setAddTable_int(): table % not found', 
				p_fqname;
	end if;
	if v_relkind != 'r' then
		raise exception 'Slony-I: setAddTable_int(): % is not a regular table',
				p_fqname;
	end if;

	if not exists (select indexrelid
			from "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGC
			where PGX.indrelid = v_tab_reloid
				and PGX.indexrelid = PGC.oid
				and PGC.relname = p_tab_idxname)
	then
		raise exception 'Slony-I: setAddTable_int(): table % has no index %',
				p_fqname, p_tab_idxname;
	end if;

	-- ----
	-- Verify that the columns in the PK (or candidate) are not NULLABLE
	-- ----

	v_pkcand_nn := 'f';
	for v_prec in select attname from "pg_catalog".pg_attribute where attrelid = 
                        (select oid from "pg_catalog".pg_class where oid = v_tab_reloid) 
                    and attname in (select attname from "pg_catalog".pg_attribute where 
                                    attrelid = (select oid from "pg_catalog".pg_class PGC, 
                                    "pg_catalog".pg_index PGX where 
                                    PGC.relname = p_tab_idxname and PGX.indexrelid=PGC.oid and
                                    PGX.indrelid = v_tab_reloid)) and attnotnull <> 't'
	loop
		raise notice 'Slony-I: setAddTable_int: table % PK column % nullable', p_fqname, v_prec.attname;
		v_pkcand_nn := 't';
	end loop;
	if v_pkcand_nn then
		raise exception 'Slony-I: setAddTable_int: table % not replicable!', p_fqname;
	end if;

	select * into v_prec from "_prod_replica_set".sl_table where tab_id = p_tab_id;
	if not found then
		v_pkcand_nn := 't';  -- No-op -- All is well
	else
		raise exception 'Slony-I: setAddTable_int: table id % has already been assigned!', p_tab_id;
	end if;

	-- ----
	-- Add the table to sl_table and create the trigger on it.
	-- ----
	insert into "_prod_replica_set".sl_table
			(tab_id, tab_reloid, tab_relname, tab_nspname, 
			tab_set, tab_idxname, tab_altered, tab_comment) 
			values
			(p_tab_id, v_tab_reloid, v_tab_relname, v_tab_nspname,
			p_set_id, p_tab_idxname, false, p_tab_comment);
	perform "_prod_replica_set".alterTableForReplication(p_tab_id);

	return p_tab_id;
end;

Function: _prod_replica_set.setdropsequence( integer )

Returns: bigint

Language: PLPGSQL

setDropSequence (seq_id) On the origin node for the set, drop sequence seq_id from replication set, and raise SET_DROP_SEQUENCE to cause this to replicate to subscriber nodes.

declare
	p_seq_id		alias for $1;
	v_set_id		int4;
	v_set_origin		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Determine set id for this sequence
	-- ----
	select seq_set into v_set_id from "_prod_replica_set".sl_sequence where seq_id = p_seq_id;

	-- ----
	-- Ensure sequence exists
	-- ----
	if not found then
		raise exception 'Slony-I: setDropSequence_int(): sequence % not found',
			p_seq_id;
	end if;

	-- ----
	-- Check that we are the origin of the set
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = v_set_id;
	if not found then
		raise exception 'Slony-I: setDropSequence(): set % not found', v_set_id;
	end if;
	if v_set_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: setDropSequence(): set % has origin at another node - submit this to that node', v_set_id;
	end if;

	-- ----
	-- Add the sequence to the set and generate the SET_ADD_SEQUENCE event
	-- ----
	perform "_prod_replica_set".setDropSequence_int(p_seq_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'SET_DROP_SEQUENCE',
					p_seq_id::text);
end;

Function: _prod_replica_set.setdropsequence_int( integer )

Returns: integer

Language: PLPGSQL

setDropSequence_int (seq_id) This processes the SET_DROP_SEQUENCE event. On remote nodes that subscribe to the set containing sequence seq_id, drop the sequence from the replication set.

declare
	p_seq_id		alias for $1;
	v_set_id		int4;
	v_local_node_id		int4;
	v_set_origin		int4;
	v_sub_provider		int4;
	v_relkind			char;
	v_sync_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Determine set id for this sequence
	-- ----
	select seq_set into v_set_id from "_prod_replica_set".sl_sequence where seq_id = p_seq_id;

	-- ----
	-- Ensure sequence exists
	-- ----
	if not found then
		return 0;
	end if;

	-- ----
	-- For sets with a remote origin, check that we are subscribed 
	-- to that set. Otherwise we ignore the sequence because it might 
	-- not even exist in our database.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = v_set_id;
	if not found then
		raise exception 'Slony-I: setDropSequence_int(): set % not found',
				v_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from "_prod_replica_set".sl_subscribe
				where sub_set = v_set_id
				and sub_receiver = "_prod_replica_set".getLocalNodeId('_prod_replica_set');
		if not found then
			return 0;
		end if;
	end if;

	-- ----
	-- drop the sequence from sl_sequence, sl_seqlog
	-- ----
	delete from "_prod_replica_set".sl_seqlog where seql_seqid = p_seq_id;
	delete from "_prod_replica_set".sl_sequence where seq_id = p_seq_id;

	return p_seq_id;
end;

Function: _prod_replica_set.setdroptable( integer )

Returns: bigint

Language: PLPGSQL

setDropTable (tab_id) Drop table tab_id from set on origin node, and generate SET_DROP_TABLE event to allow this to propagate to other nodes.

declare
	p_tab_id		alias for $1;
	v_set_id		int4;
	v_set_origin		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

        -- ----
	-- Determine the set_id
        -- ----
	select tab_set into v_set_id from "_prod_replica_set".sl_table where tab_id = p_tab_id;

	-- ----
	-- Ensure table exists
	-- ----
	if not found then
		raise exception 'Slony-I: setDropTable_int(): table % not found',
			p_tab_id;
	end if;

	-- ----
	-- Check that we are the origin of the set
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = v_set_id;
	if not found then
		raise exception 'Slony-I: setDropTable(): set % not found', v_set_id;
	end if;
	if v_set_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: setDropTable(): set % has remote origin', v_set_id;
	end if;

	-- ----
	-- Drop the table from the set and generate the SET_ADD_TABLE event
	-- ----
	perform "_prod_replica_set".setDropTable_int(p_tab_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'SET_DROP_TABLE', 
				p_tab_id::text);
end;

Function: _prod_replica_set.setdroptable_int( integer )

Returns: integer

Language: PLPGSQL

setDropTable_int (tab_id) This function processes the SET_DROP_TABLE event on remote nodes, dropping a table from replication if the remote node is subscribing to its replication set.

declare
	p_tab_id		alias for $1;
	v_set_id		int4;
	v_local_node_id		int4;
	v_set_origin		int4;
	v_sub_provider		int4;
	v_tab_reloid		oid;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

        -- ----
	-- Determine the set_id
        -- ----
	select tab_set into v_set_id from "_prod_replica_set".sl_table where tab_id = p_tab_id;

	-- ----
	-- Ensure table exists
	-- ----
	if not found then
		return 0;
	end if;

	-- ----
	-- For sets with a remote origin, check that we are subscribed 
	-- to that set. Otherwise we ignore the table because it might 
	-- not even exist in our database.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = v_set_id;
	if not found then
		raise exception 'Slony-I: setDropTable_int(): set % not found',
				v_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from "_prod_replica_set".sl_subscribe
				where sub_set = v_set_id
				and sub_receiver = "_prod_replica_set".getLocalNodeId('_prod_replica_set');
		if not found then
			return 0;
		end if;
	end if;
	
	-- ----
	-- Drop the table from sl_table and drop trigger from it.
	-- ----
	perform "_prod_replica_set".alterTableRestore(p_tab_id);
	perform "_prod_replica_set".tableDropKey(p_tab_id);
	delete from "_prod_replica_set".sl_table where tab_id = p_tab_id;
	return p_tab_id;
end;

Function: _prod_replica_set.setmovesequence( integer, integer )

Returns: bigint

Language: PLPGSQL

setMoveSequence(p_seq_id, p_new_set_id) - This generates the SET_MOVE_SEQUENCE event, after validation, notably that both sets exist, are distinct, and have exactly the same subscription lists

declare
	p_seq_id			alias for $1;
	p_new_set_id		alias for $2;
	v_old_set_id		int4;
	v_origin			int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get the sequences current set
	-- ----
	select seq_set into v_old_set_id from "_prod_replica_set".sl_sequence
			where seq_id = p_seq_id;
	if not found then
		raise exception 'Slony-I: setMoveSequence(): sequence %d not found', p_seq_id;
	end if;
	
	-- ----
	-- Check that both sets exist and originate here
	-- ----
	if p_new_set_id = v_old_set_id then
		raise exception 'Slony-I: setMoveSequence(): set ids cannot be identical';
	end if;
	select set_origin into v_origin from "_prod_replica_set".sl_set
			where set_id = p_new_set_id;
	if not found then
		raise exception 'Slony-I: setMoveSequence(): set % not found', p_new_set_id;
	end if;
	if v_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: setMoveSequence(): set % does not originate on local node',
				p_new_set_id;
	end if;

	select set_origin into v_origin from "_prod_replica_set".sl_set
			where set_id = v_old_set_id;
	if not found then
		raise exception 'Slony-I: set % not found', v_old_set_id;
	end if;
	if v_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: set % does not originate on local node',
				v_old_set_id;
	end if;

	-- ----
	-- Check that both sets are subscribed by the same set of nodes
	-- ----
	if exists (select true from "_prod_replica_set".sl_subscribe SUB1
				where SUB1.sub_set = p_new_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from "_prod_replica_set".sl_subscribe SUB2
						where SUB2.sub_set = v_old_set_id))
	then
		raise exception 'Slony-I: subscriber lists of set % and % are different',
				p_new_set_id, v_old_set_id;
	end if;

	if exists (select true from "_prod_replica_set".sl_subscribe SUB1
				where SUB1.sub_set = v_old_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from "_prod_replica_set".sl_subscribe SUB2
						where SUB2.sub_set = p_new_set_id))
	then
		raise exception 'Slony-I: subscriber lists of set % and % are different',
				v_old_set_id, p_new_set_id;
	end if;

	-- ----
	-- Change the set the sequence belongs to
	-- ----
	perform "_prod_replica_set".setMoveSequence_int(p_seq_id, p_new_set_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'SET_MOVE_SEQUENCE', 
			p_seq_id::text, p_new_set_id::text);
end;

Function: _prod_replica_set.setmovesequence_int( integer, integer )

Returns: integer

Language: PLPGSQL

setMoveSequence_int(p_seq_id, p_new_set_id) - processes the SET_MOVE_SEQUENCE event, moving a sequence to another replication set.

declare
	p_seq_id			alias for $1;
	p_new_set_id		alias for $2;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;
	
	-- ----
	-- Move the sequence to the new set
	-- ----
	update "_prod_replica_set".sl_sequence
			set seq_set = p_new_set_id
			where seq_id = p_seq_id;

	return p_seq_id;
end;

Function: _prod_replica_set.setmovetable( integer, integer )

Returns: bigint

Language: PLPGSQL

This processes the SET_MOVE_TABLE event. The table is moved to the destination set.

declare
	p_tab_id			alias for $1;
	p_new_set_id		alias for $2;
	v_old_set_id		int4;
	v_origin			int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get the tables current set
	-- ----
	select tab_set into v_old_set_id from "_prod_replica_set".sl_table
			where tab_id = p_tab_id;
	if not found then
		raise exception 'Slony-I: table %d not found', p_tab_id;
	end if;
	
	-- ----
	-- Check that both sets exist and originate here
	-- ----
	if p_new_set_id = v_old_set_id then
		raise exception 'Slony-I: set ids cannot be identical';
	end if;
	select set_origin into v_origin from "_prod_replica_set".sl_set
			where set_id = p_new_set_id;
	if not found then
		raise exception 'Slony-I: set % not found', p_new_set_id;
	end if;
	if v_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: set % does not originate on local node',
				p_new_set_id;
	end if;

	select set_origin into v_origin from "_prod_replica_set".sl_set
			where set_id = v_old_set_id;
	if not found then
		raise exception 'Slony-I: set % not found', v_old_set_id;
	end if;
	if v_origin != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: set % does not originate on local node',
				v_old_set_id;
	end if;

	-- ----
	-- Check that both sets are subscribed by the same set of nodes
	-- ----
	if exists (select true from "_prod_replica_set".sl_subscribe SUB1
				where SUB1.sub_set = p_new_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from "_prod_replica_set".sl_subscribe SUB2
						where SUB2.sub_set = v_old_set_id))
	then
		raise exception 'Slony-I: subscriber lists of set % and % are different',
				p_new_set_id, v_old_set_id;
	end if;

	if exists (select true from "_prod_replica_set".sl_subscribe SUB1
				where SUB1.sub_set = v_old_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from "_prod_replica_set".sl_subscribe SUB2
						where SUB2.sub_set = p_new_set_id))
	then
		raise exception 'Slony-I: subscriber lists of set % and % are different',
				v_old_set_id, p_new_set_id;
	end if;

	-- ----
	-- Change the set the table belongs to
	-- ----
	perform "_prod_replica_set".createEvent('_prod_replica_set', 'SYNC', NULL);
	perform "_prod_replica_set".setMoveTable_int(p_tab_id, p_new_set_id);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'SET_MOVE_TABLE', 
			p_tab_id::text, p_new_set_id::text);
end;

Function: _prod_replica_set.setmovetable_int( integer, integer )

Returns: integer

Language: PLPGSQL

declare
	p_tab_id			alias for $1;
	p_new_set_id		alias for $2;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;
	
	-- ----
	-- Move the table to the new set
	-- ----
	update "_prod_replica_set".sl_table
			set tab_set = p_new_set_id
			where tab_id = p_tab_id;

	return p_tab_id;
end;

Function: _prod_replica_set.setsessionrole( name, text )

Returns: text

Language: C

setSessionRole(username, role) - set role for session. role can be "normal" or "slon"; setting the latter is necessary, on subscriber nodes, in order to override the denyaccess() trigger attached to subscribing tables.

_Slony_I_setSessionRole

Function: _prod_replica_set.slon_quote_brute( text )

Returns: text

Language: PLPGSQL

Brutally quote the given text

declare	
    p_tab_fqname alias for $1;
    v_fqname text default '';
begin
    v_fqname := '"' || replace(p_tab_fqname,'"','""') || '"';
    return v_fqname;
end;

Function: _prod_replica_set.slon_quote_input( text )

Returns: text

Language: PLPGSQL

quote all words that aren't quoted yet

  declare
     p_tab_fqname alias for $1;
     v_nsp_name text;
     v_tab_name text;
	 v_i integer;
	 v_l integer;
     v_pq2 integer;
begin
	v_l := length(p_tab_fqname);

	-- Let us search for the dot
	if p_tab_fqname like '"%' then
		-- if the first part of the ident starts with a double quote, search
		-- for the closing double quote, skipping over double double quotes.
		v_i := 2;
		while v_i <= v_l loop
			if substr(p_tab_fqname, v_i, 1) != '"' then
				v_i := v_i + 1;
			else
				v_i := v_i + 1;
				if substr(p_tab_fqname, v_i, 1) != '"' then
					exit;
				end if;
				v_i := v_i + 1;
			end if;
		end loop;
	else
		-- first part of ident is not quoted, search for the dot directly
		v_i := 1;
		while v_i <= v_l loop
			if substr(p_tab_fqname, v_i, 1) = '.' then
				exit;
			end if;
			v_i := v_i + 1;
		end loop;
	end if;

	-- v_i now points at the dot or behind the string.

	if substr(p_tab_fqname, v_i, 1) = '.' then
		-- There is a dot now, so split the ident into its namespace
		-- and objname parts and make sure each is quoted
		v_nsp_name := substr(p_tab_fqname, 1, v_i - 1);
		v_tab_name := substr(p_tab_fqname, v_i + 1);
		if v_nsp_name not like '"%' then
			v_nsp_name := '"' || replace(v_nsp_name, '"', '""') ||
						  '"';
		end if;
		if v_tab_name not like '"%' then
			v_tab_name := '"' || replace(v_tab_name, '"', '""') ||
						  '"';
		end if;

		return v_nsp_name || '.' || v_tab_name;
	else
		-- No dot ... must be just an ident without schema
		if p_tab_fqname like '"%' then
			return p_tab_fqname;
		else
			return '"' || replace(p_tab_fqname, '"', '""') || '"';
		end if;
	end if;

end;

Function: _prod_replica_set.slonyversion( )

Returns: text

Language: PLPGSQL

Returns the version number of the slony schema

begin
	return ''	|| "_prod_replica_set".slonyVersionMajor() || '.'
				|| "_prod_replica_set".slonyVersionMinor() || '.'
				|| "_prod_replica_set".slonyVersionPatchlevel();
end;

Function: _prod_replica_set.slonyversionmajor( )

Returns: integer

Language: PLPGSQL

Returns the major version number of the slony schema

begin
	return 1;
end;

Function: _prod_replica_set.slonyversionminor( )

Returns: integer

Language: PLPGSQL

Returns the minor version number of the slony schema

begin
	return 2;
end;

Function: _prod_replica_set.slonyversionpatchlevel( )

Returns: integer

Language: PLPGSQL

Returns the version patch level of the slony schema

begin
	return 12;
end;

Function: _prod_replica_set.storelisten( integer, integer, integer )

Returns: bigint

Language: PLPGSQL

FUNCTION storeListen (li_origin, li_provider, li_receiver) generate STORE_LISTEN event, indicating that receiver node li_receiver listens to node li_provider in order to get messages coming from node li_origin.

declare
	p_origin		alias for $1;
	p_provider	alias for $2;
	p_receiver	alias for $3;
begin
	perform "_prod_replica_set".storeListen_int (p_origin, p_provider, p_receiver);
	return  "_prod_replica_set".createEvent ('_prod_replica_set', 'STORE_LISTEN',
			p_origin::text, p_provider::text, p_receiver::text);
end;

Function: _prod_replica_set.storelisten_int( integer, integer, integer )

Returns: integer

Language: PLPGSQL

FUNCTION storeListen_int (li_origin, li_provider, li_receiver) Process STORE_LISTEN event, indicating that receiver node li_receiver listens to node li_provider in order to get messages coming from node li_origin.

declare
	p_li_origin		alias for $1;
	p_li_provider	alias for $2;
	p_li_receiver	alias for $3;
	v_exists		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	select 1 into v_exists
			from "_prod_replica_set".sl_listen
			where li_origin = p_li_origin
			and li_provider = p_li_provider
			and li_receiver = p_li_receiver;
	if not found then
		-- ----
		-- In case we receive STORE_LISTEN events before we know
		-- about the nodes involved in this, we generate those nodes
		-- as pending.
		-- ----
		if not exists (select 1 from "_prod_replica_set".sl_node
						where no_id = p_li_origin) then
			perform "_prod_replica_set".storeNode_int (p_li_origin, '<event pending>', 'f');
		end if;
		if not exists (select 1 from "_prod_replica_set".sl_node
						where no_id = p_li_provider) then
			perform "_prod_replica_set".storeNode_int (p_li_provider, '<event pending>', 'f');
		end if;
		if not exists (select 1 from "_prod_replica_set".sl_node
						where no_id = p_li_receiver) then
			perform "_prod_replica_set".storeNode_int (p_li_receiver, '<event pending>', 'f');
		end if;

		insert into "_prod_replica_set".sl_listen
				(li_origin, li_provider, li_receiver) values
				(p_li_origin, p_li_provider, p_li_receiver);
	end if;

	return 0;
end;

Function: _prod_replica_set.storenode( integer, text, boolean )

Returns: bigint

Language: PLPGSQL

no_id - Node ID # no_comment - Human-oriented comment no_spool - Flag for virtual spool nodes Generate the STORE_NODE event for node no_id

declare
	p_no_id			alias for $1;
	p_no_comment	alias for $2;
	p_no_spool		alias for $3;
	v_no_spool_txt	text;
begin
	if p_no_spool then
		v_no_spool_txt = 't';
	else
		v_no_spool_txt = 'f';
	end if;
	perform "_prod_replica_set".storeNode_int (p_no_id, p_no_comment, p_no_spool);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'STORE_NODE',
									p_no_id::text, p_no_comment::text, 
									v_no_spool_txt::text);
end;

Function: _prod_replica_set.storenode_int( integer, text, boolean )

Returns: integer

Language: PLPGSQL

no_id - Node ID # no_comment - Human-oriented comment no_spool - Flag for virtual spool nodes Internal function to process the STORE_NODE event for node no_id

declare
	p_no_id			alias for $1;
	p_no_comment	alias for $2;
	p_no_spool		alias for $3;
	v_old_row		record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check if the node exists
	-- ----
	select * into v_old_row
			from "_prod_replica_set".sl_node
			where no_id = p_no_id
			for update;
	if found then 
		-- ----
		-- Node exists, update the existing row.
		-- ----
		update "_prod_replica_set".sl_node
				set no_comment = p_no_comment,
				no_spool = p_no_spool
				where no_id = p_no_id;
	else
		-- ----
		-- New node, insert the sl_node row
		-- ----
		insert into "_prod_replica_set".sl_node
				(no_id, no_active, no_comment, no_spool) values
				(p_no_id, 'f', p_no_comment, p_no_spool);
	end if;

	return p_no_id;
end;

Function: _prod_replica_set.storepath( integer, integer, text, integer )

Returns: bigint

Language: PLPGSQL

FUNCTION storePath (pa_server, pa_client, pa_conninfo, pa_connretry) Generate the STORE_PATH event indicating that node pa_client can access node pa_server using DSN pa_conninfo

declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
	p_pa_conninfo	alias for $3;
	p_pa_connretry	alias for $4;
begin
	perform "_prod_replica_set".storePath_int(p_pa_server, p_pa_client,
			p_pa_conninfo, p_pa_connretry);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'STORE_PATH', 
			p_pa_server::text, p_pa_client::text, 
			p_pa_conninfo::text, p_pa_connretry::text);
end;

Function: _prod_replica_set.storepath_int( integer, integer, text, integer )

Returns: integer

Language: PLPGSQL

FUNCTION storePath (pa_server, pa_client, pa_conninfo, pa_connretry) Process the STORE_PATH event indicating that node pa_client can access node pa_server using DSN pa_conninfo

declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
	p_pa_conninfo	alias for $3;
	p_pa_connretry	alias for $4;
	v_dummy			int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check if the path already exists
	-- ----
	select 1 into v_dummy
			from "_prod_replica_set".sl_path
			where pa_server = p_pa_server
			and pa_client = p_pa_client
			for update;
	if found then
		-- ----
		-- Path exists, update pa_conninfo
		-- ----
		update "_prod_replica_set".sl_path
				set pa_conninfo = p_pa_conninfo,
					pa_connretry = p_pa_connretry
				where pa_server = p_pa_server
				and pa_client = p_pa_client;
	else
		-- ----
		-- New path
		--
		-- In case we receive STORE_PATH events before we know
		-- about the nodes involved in this, we generate those nodes
		-- as pending.
		-- ----
		if not exists (select 1 from "_prod_replica_set".sl_node
						where no_id = p_pa_server) then
			perform "_prod_replica_set".storeNode_int (p_pa_server, '<event pending>', 'f');
		end if;
		if not exists (select 1 from "_prod_replica_set".sl_node
						where no_id = p_pa_client) then
			perform "_prod_replica_set".storeNode_int (p_pa_client, '<event pending>', 'f');
		end if;
		insert into "_prod_replica_set".sl_path
				(pa_server, pa_client, pa_conninfo, pa_connretry) values
				(p_pa_server, p_pa_client, p_pa_conninfo, p_pa_connretry);
	end if;

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	return 0;
end;

Function: _prod_replica_set.storeset( integer, text )

Returns: bigint

Language: PLPGSQL

Generate STORE_SET event for set set_id with human readable comment set_comment

declare
	p_set_id			alias for $1;
	p_set_comment		alias for $2;
	v_local_node_id		int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');

	insert into "_prod_replica_set".sl_set
			(set_id, set_origin, set_comment) values
			(p_set_id, v_local_node_id, p_set_comment);

	return "_prod_replica_set".createEvent('_prod_replica_set', 'STORE_SET', 
			p_set_id::text, v_local_node_id::text, p_set_comment::text);
end;

Function: _prod_replica_set.storeset_int( integer, integer, text )

Returns: integer

Language: PLPGSQL

storeSet_int (set_id, set_origin, set_comment) Process the STORE_SET event, indicating the new set with given ID, origin node, and human readable comment.

declare
	p_set_id			alias for $1;
	p_set_origin		alias for $2;
	p_set_comment		alias for $3;
	v_dummy				int4;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	select 1 into v_dummy
			from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if found then 
		update "_prod_replica_set".sl_set
				set set_comment = p_set_comment
				where set_id = p_set_id;
	else
		if not exists (select 1 from "_prod_replica_set".sl_node
						where no_id = p_set_origin) then
			perform "_prod_replica_set".storeNode_int (p_set_origin, '<event pending>', 'f');
		end if;
		insert into "_prod_replica_set".sl_set
				(set_id, set_origin, set_comment) values
				(p_set_id, p_set_origin, p_set_comment);
	end if;

	-- Run addPartialLogIndices() to try to add indices to unused sl_log_? table
	perform "_prod_replica_set".addPartialLogIndices();

	return p_set_id;
end;

Function: _prod_replica_set.storetrigger( integer, name )

Returns: bigint

Language: PLPGSQL

storeTrigger (trig_tabid, trig_tgname) Submits STORE_TRIGGER event to indicate that trigger trig_tgname on replicated table trig_tabid will NOT be disabled.

declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
begin
	perform "_prod_replica_set".storeTrigger_int(p_trig_tabid, p_trig_tgname);
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'STORE_TRIGGER',
			p_trig_tabid::text, p_trig_tgname::text);
end;

Function: _prod_replica_set.storetrigger_int( integer, name )

Returns: integer

Language: PLPGSQL

storeTrigger_int (trig_tabid, trig_tgname) Processes STORE_TRIGGER event to make sure that trigger trig_tgname on replicated table trig_tabid is NOT disabled.

declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
	v_tab_altered		boolean;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Get the current table status (altered or not)
	-- ----
	select tab_altered into v_tab_altered
			from "_prod_replica_set".sl_table where tab_id = p_trig_tabid;
	if not found then
		-- ----
		-- Not found is no hard error here, because that might
		-- mean that we are not subscribed to that set
		-- ----
		return 0;
	end if;

	-- ----
	-- If the table is modified for replication, restore the original state
	-- ----
	if v_tab_altered then
		perform "_prod_replica_set".alterTableRestore(p_trig_tabid);
	end if;

	-- ----
	-- Make sure that an entry for this trigger exists
	-- ----
	delete from "_prod_replica_set".sl_trigger
			where trig_tabid = p_trig_tabid
			  and trig_tgname = p_trig_tgname;
	insert into "_prod_replica_set".sl_trigger (
				trig_tabid, trig_tgname
			) values (
				p_trig_tabid, p_trig_tgname
			);

	-- ----
	-- Put the table back into replicated state if it was
	-- ----
	if v_tab_altered then
		perform "_prod_replica_set".alterTableForReplication(p_trig_tabid);
	end if;

	return p_trig_tabid;
end;

Function: _prod_replica_set.subscribeset( integer, integer, integer, boolean )

Returns: bigint

Language: PLPGSQL

subscribeSet (sub_set, sub_provider, sub_receiver, sub_forward) Makes sure that the receiver is not the provider, then stores the subscription, and publishes the SUBSCRIBE_SET event to other nodes.

declare
	p_sub_set			alias for $1;
	p_sub_provider		alias for $2;
	p_sub_receiver		alias for $3;
	p_sub_forward		alias for $4;
	v_set_origin		int4;
	v_ev_seqno			int8;
	v_rec			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that this is called on the provider node
	-- ----
	if p_sub_provider != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: subscribeSet() must be called on provider';
	end if;

	-- ----
	-- Check that the origin and provider of the set are remote
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_sub_set;
	if not found then
		raise exception 'Slony-I: subscribeSet(): set % not found', p_sub_set;
	end if;
	if v_set_origin = p_sub_receiver then
		raise exception 
				'Slony-I: subscribeSet(): set origin and receiver cannot be identical';
	end if;
	if p_sub_receiver = p_sub_provider then
		raise exception 
				'Slony-I: subscribeSet(): set provider and receiver cannot be identical';
	end if;

	-- ---
	-- Verify that the provider is either the origin or an active subscriber
	-- Bug report #1362
	-- ---
	if v_set_origin <> p_sub_provider then
		if not exists (select 1 from "_prod_replica_set".sl_subscribe
			where sub_set = p_sub_set and 
                              sub_receiver = p_sub_provider and
			      sub_forward and sub_active) then
			raise exception 'Slony-I: subscribeSet(): provider % is not an active forwarding node for replication set %', p_sub_provider, p_sub_set;
		end if;
	end if;

	-- ----
	-- Create the SUBSCRIBE_SET event
	-- ----
	v_ev_seqno :=  "_prod_replica_set".createEvent('_prod_replica_set', 'SUBSCRIBE_SET', 
			p_sub_set::text, p_sub_provider::text, p_sub_receiver::text, 
			case p_sub_forward when true then 't' else 'f' end);

	-- ----
	-- Call the internal procedure to store the subscription
	-- ----
	perform "_prod_replica_set".subscribeSet_int(p_sub_set, p_sub_provider,
			p_sub_receiver, p_sub_forward);

	return v_ev_seqno;
end;

Function: _prod_replica_set.subscribeset_int( integer, integer, integer, boolean )

Returns: integer

Language: PLPGSQL

subscribeSet_int (sub_set, sub_provider, sub_receiver, sub_forward) Internal actions for subscribing receiver sub_receiver to subscription set sub_set.

declare
	p_sub_set			alias for $1;
	p_sub_provider		alias for $2;
	p_sub_receiver		alias for $3;
	p_sub_forward		alias for $4;
	v_set_origin		int4;
	v_sub_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Provider change is only allowed for active sets
	-- ----
	if p_sub_receiver = "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		select sub_active into v_sub_row from "_prod_replica_set".sl_subscribe
				where sub_set = p_sub_set
				and sub_receiver = p_sub_receiver;
		if found then
			if not v_sub_row.sub_active then
				raise exception 'Slony-I: subscribeSet_int(): set % is not active, cannot change provider',
						p_sub_set;
			end if;
		end if;
	end if;

	-- ----
	-- Try to change provider and/or forward for an existing subscription
	-- ----
	update "_prod_replica_set".sl_subscribe
			set sub_provider = p_sub_provider,
				sub_forward = p_sub_forward
			where sub_set = p_sub_set
			and sub_receiver = p_sub_receiver;
	if found then
		-- ----
		-- Rewrite sl_listen table
		-- ----
		perform "_prod_replica_set".RebuildListenEntries();

		return p_sub_set;
	end if;

	-- ----
	-- Not found, insert a new one
	-- ----
	if not exists (select true from "_prod_replica_set".sl_path
			where pa_server = p_sub_provider
			and pa_client = p_sub_receiver)
	then
		insert into "_prod_replica_set".sl_path
				(pa_server, pa_client, pa_conninfo, pa_connretry)
				values 
				(p_sub_provider, p_sub_receiver, 
				'<event pending>', 10);
	end if;
	insert into "_prod_replica_set".sl_subscribe
			(sub_set, sub_provider, sub_receiver, sub_forward, sub_active)
			values (p_sub_set, p_sub_provider, p_sub_receiver,
				p_sub_forward, false);

	-- ----
	-- If the set origin is here, then enable the subscription
	-- ----
	select set_origin into v_set_origin
			from "_prod_replica_set".sl_set
			where set_id = p_sub_set;
	if not found then
		raise exception 'Slony-I: subscribeSet_int(): set % not found', p_sub_set;
	end if;

	if v_set_origin = "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		perform "_prod_replica_set".createEvent('_prod_replica_set', 'ENABLE_SUBSCRIPTION', 
				p_sub_set::text, p_sub_provider::text, p_sub_receiver::text, 
				case p_sub_forward when true then 't' else 'f' end);
		perform "_prod_replica_set".enableSubscription(p_sub_set, 
				p_sub_provider, p_sub_receiver);
	end if;

	-- ----
	-- Rewrite sl_listen table
	-- ----
	perform "_prod_replica_set".RebuildListenEntries();

	return p_sub_set;
end;

Function: _prod_replica_set.tableaddkey( text )

Returns: text

Language: PLPGSQL

tableAddKey (tab_fqname) - if the table has not got a column of the form _Slony-I_<clustername>_rowID, then add it as a bigint, defaulted to nextval() for a sequence created for the cluster.

declare
	p_tab_fqname	alias for $1;
	v_tab_fqname_quoted	text default '';
	v_attkind		text default '';
	v_attrow		record;
	v_have_serial	bool default 'f';
begin
	v_tab_fqname_quoted := "_prod_replica_set".slon_quote_input(p_tab_fqname);
	--
	-- Loop over the attributes of this relation
	-- and add a "v" for every user column, and a "k"
	-- if we find the Slony-I special serial column.
	--
	for v_attrow in select PGA.attnum, PGA.attname
			from "pg_catalog".pg_class PGC,
			    "pg_catalog".pg_namespace PGN,
				"pg_catalog".pg_attribute PGA
			where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			    "_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace
				and PGA.attrelid = PGC.oid
				and not PGA.attisdropped
				and PGA.attnum > 0
			order by attnum
	loop
		if v_attrow.attname = '_Slony-I_prod_replica_set_rowID' then
		    v_attkind := v_attkind || 'k';
			v_have_serial := 't';
		else
			v_attkind := v_attkind || 'v';
		end if;
	end loop;
	
	--
	-- A table must have at least one attribute, so not finding
	-- anything means the table does not exist.
	--
	if not found then
		raise exception 'Slony-I: tableAddKey(): table % not found', v_tab_fqname_quoted;
	end if;

	--
	-- If it does not have the special serial column, we
	-- have to add it. This will be only half way done.
	-- The function to add the table to the set must finish
	-- these definitions with NOT NULL and UNIQUE after
	-- updating all existing rows.
	--
	if not v_have_serial then
		execute 'lock table ' || v_tab_fqname_quoted ||
			' in access exclusive mode';
		execute 'alter table only ' || v_tab_fqname_quoted ||
			' add column "_Slony-I_prod_replica_set_rowID" bigint;';
		execute 'alter table only ' || v_tab_fqname_quoted ||
			' alter column "_Slony-I_prod_replica_set_rowID" ' ||
			' set default "pg_catalog".nextval(''"_prod_replica_set".sl_rowid_seq'');';

		v_attkind := v_attkind || 'k';
	end if;

	--
	-- Return the resulting Slony-I attkind
	--
	return v_attkind;
end;

Function: _prod_replica_set.tabledropkey( integer )

Returns: integer

Language: PLPGSQL

tableDropKey (tab_id) If the specified table has a column "_Slony-I_<clustername>_rowID", then drop it.

declare
	p_tab_id		alias for $1;
	v_tab_fqname	text;
	v_tab_oid		oid;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Construct the tables fully qualified name and get its oid
	-- ----
	select "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
				"_prod_replica_set".slon_quote_brute(PGC.relname),
				PGC.oid into v_tab_fqname, v_tab_oid
			from "_prod_replica_set".sl_table T,
				"pg_catalog".pg_class PGC,
				"pg_catalog".pg_namespace PGN
			where T.tab_id = p_tab_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid;
	if not found then
		raise exception 'Slony-I: tableDropKey(): table with ID % not found', p_tab_id;
	end if;

	-- ----
	-- Drop the special serial ID column if the table has it
	-- ----
	if exists (select true from "pg_catalog".pg_attribute
			where attrelid = v_tab_oid
				and attname = '_Slony-I_prod_replica_set_rowID')
	then
		execute 'lock table ' || v_tab_fqname ||
				' in access exclusive mode';
		execute 'alter table ' || v_tab_fqname ||
				' drop column "_Slony-I_prod_replica_set_rowID"';
	end if;

	return p_tab_id;
end;

Function: _prod_replica_set.tablehasserialkey( text )

Returns: boolean

Language: PLPGSQL

tableHasSerialKey (tab_fqname) Checks if a table has our special serial key column that is used if the table has no natural unique constraint.

declare
	p_tab_fqname	alias for $1;
	v_tab_fqname_quoted	text default '';
	v_attnum		int2;
begin
	v_tab_fqname_quoted := "_prod_replica_set".slon_quote_input(p_tab_fqname);
	select PGA.attnum into v_attnum
			from "pg_catalog".pg_class PGC,
				"pg_catalog".pg_namespace PGN,
				"pg_catalog".pg_attribute PGA
			where "_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
				"_prod_replica_set".slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGC.relnamespace = PGN.oid
				and PGA.attrelid = PGC.oid
				and PGA.attname = '_Slony-I_prod_replica_set_rowID'
				and not PGA.attisdropped;
	return found;
end;

Function: _prod_replica_set.terminatenodeconnections( integer )

Returns: integer

Language: PLPGSQL

terminates all backends that have registered to be from the given node

declare
	p_failed_node	alias for $1;
	v_row			record;
begin
	for v_row in select nl_nodeid, nl_conncnt,
			nl_backendpid from "_prod_replica_set".sl_nodelock
			where nl_nodeid = p_failed_node for update
	loop
		perform "_prod_replica_set".killBackend(v_row.nl_backendpid, 'TERM');
		delete from "_prod_replica_set".sl_nodelock
			where nl_nodeid = v_row.nl_nodeid
			and nl_conncnt = v_row.nl_conncnt;
	end loop;

	return 0;
end;

Function: _prod_replica_set.uninstallnode( )

Returns: integer

Language: PLPGSQL

Reset the whole database to standalone by removing the whole replication system.

declare
	v_tab_row		record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- This is us ... time for suicide! Restore all tables to
	-- their original status.
	-- ----
	for v_tab_row in select * from "_prod_replica_set".sl_table loop
		perform "_prod_replica_set".alterTableRestore(v_tab_row.tab_id);
		perform "_prod_replica_set".tableDropKey(v_tab_row.tab_id);
	end loop;

	raise notice 'Slony-I: Please drop schema "_prod_replica_set"';
	return 0;
end;

Function: _prod_replica_set.unlockset( integer )

Returns: integer

Language: PLPGSQL

Remove the special trigger from all tables of a set that disables access to it.

declare
	p_set_id			alias for $1;
	v_local_node_id		int4;
	v_set_row			record;
	v_tab_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that the set exists and that we are the origin
	-- and that it is not already locked.
	-- ----
	v_local_node_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
	select * into v_set_row from "_prod_replica_set".sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception 'Slony-I: set % not found', p_set_id;
	end if;
	if v_set_row.set_origin <> v_local_node_id then
		raise exception 'Slony-I: set % does not originate on local node',
				p_set_id;
	end if;
	if v_set_row.set_locked isnull then
		raise exception 'Slony-I: set % is not locked', p_set_id;
	end if;

	-- ----
	-- Drop the lockedSet trigger from all tables in the set.
	-- ----
	for v_tab_row in select T.tab_id,
			"_prod_replica_set".slon_quote_brute(PGN.nspname) || '.' ||
			"_prod_replica_set".slon_quote_brute(PGC.relname) as tab_fqname
			from "_prod_replica_set".sl_table T,
				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
			where T.tab_set = p_set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
			order by tab_id
	loop
		execute 'drop trigger "_prod_replica_set_lockedset_' || 
				v_tab_row.tab_id || '" on ' || v_tab_row.tab_fqname;
	end loop;

	-- ----
	-- Clear out the set_locked field
	-- ----
	update "_prod_replica_set".sl_set
			set set_locked = NULL
			where set_id = p_set_id;

	return p_set_id;
end;

Function: _prod_replica_set.unsubscribeset( integer, integer )

Returns: bigint

Language: PLPGSQL

unsubscribeSet (sub_set, sub_receiver) Unsubscribe node sub_receiver from subscription set sub_set. This is invoked on the receiver node. It verifies that this does not break any chains (e.g. - where sub_receiver is a provider for another node), then restores tables, drops Slony-specific keys, drops table entries for the set, drops the subscription, and generates an UNSUBSCRIBE_SET node to publish that the node is being dropped.

declare
	p_sub_set			alias for $1;
	p_sub_receiver		alias for $2;
	v_tab_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- Check that this is called on the receiver node
	-- ----
	if p_sub_receiver != "_prod_replica_set".getLocalNodeId('_prod_replica_set') then
		raise exception 'Slony-I: unsubscribeSet() must be called on receiver';
	end if;

	-- ----
	-- Check that this does not break any chains
	-- ----
	if exists (select true from "_prod_replica_set".sl_subscribe
			where sub_set = p_sub_set
				and sub_provider = p_sub_receiver)
	then
		raise exception 'Slony-I: Cannot unsubscribe set % while being provider',
				p_sub_set;
	end if;

	-- ----
	-- Restore all tables original triggers and rules and remove
	-- our replication stuff.
	-- ----
	for v_tab_row in select tab_id from "_prod_replica_set".sl_table
			where tab_set = p_sub_set
			order by tab_id
	loop
		perform "_prod_replica_set".alterTableRestore(v_tab_row.tab_id);
		perform "_prod_replica_set".tableDropKey(v_tab_row.tab_id);
	end loop;

	-- ----
	-- Remove the setsync status. This will also cause the
	-- worker thread to ignore the set and stop replicating
	-- right now.
	-- ----
	delete from "_prod_replica_set".sl_setsync
			where ssy_setid = p_sub_set;

	-- ----
	-- Remove all sl_table and sl_sequence entries for this set.
	-- Should we ever subscribe again, the initial data
	-- copy process will create new ones.
	-- ----
	delete from "_prod_replica_set".sl_table
			where tab_set = p_sub_set;
	delete from "_prod_replica_set".sl_sequence
			where seq_set = p_sub_set;

	-- ----
	-- Call the internal procedure to drop the subscription
	-- ----
	perform "_prod_replica_set".unsubscribeSet_int(p_sub_set, p_sub_receiver);

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	-- ----
	-- Create the UNSUBSCRIBE_SET event
	-- ----
	return  "_prod_replica_set".createEvent('_prod_replica_set', 'UNSUBSCRIBE_SET', 
			p_sub_set::text, p_sub_receiver::text);
end;

Function: _prod_replica_set.unsubscribeset_int( integer, integer )

Returns: integer

Language: PLPGSQL

unsubscribeSet_int (sub_set, sub_receiver) All the REAL work of removing the subscriber is done before the event is generated, so this function just has to drop the references to the subscription in sl_subscribe.

declare
	p_sub_set			alias for $1;
	p_sub_receiver		alias for $2;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table "_prod_replica_set".sl_config_lock;

	-- ----
	-- All the real work is done before event generation on the
	-- subscriber.
	-- ----
	delete from "_prod_replica_set".sl_subscribe
			where sub_set = p_sub_set
				and sub_receiver = p_sub_receiver;

	-- Rewrite sl_listen table
	perform "_prod_replica_set".RebuildListenEntries();

	return p_sub_set;
end;

Function: _prod_replica_set.updaterelname( integer, integer )

Returns: integer

Language: PLPGSQL

updateRelname(set_id, only_on_node)

declare
        p_set_id                alias for $1;
        p_only_on_node          alias for $2;
        v_no_id                 int4;
        v_set_origin            int4;
begin
        -- ----
        -- Grab the central configuration lock
        -- ----
        lock table "_prod_replica_set".sl_config_lock;

        -- ----
        -- Check that we either are the set origin or a current
        -- subscriber of the set.
        -- ----
        v_no_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
        select set_origin into v_set_origin
                        from "_prod_replica_set".sl_set
                        where set_id = p_set_id
                        for update;
        if not found then
                raise exception 'Slony-I: set % not found', p_set_id;
        end if;
        if v_set_origin <> v_no_id
                and not exists (select 1 from "_prod_replica_set".sl_subscribe
                        where sub_set = p_set_id
                        and sub_receiver = v_no_id)
        then
                return 0;
        end if;
    
        -- ----
        -- If execution on only one node is requested, check that
        -- we are that node.
        -- ----
        if p_only_on_node > 0 and p_only_on_node <> v_no_id then
                return 0;
        end if;
        update "_prod_replica_set".sl_table set 
                tab_relname = PGC.relname, tab_nspname = PGN.nspname
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN 
                where "_prod_replica_set".sl_table.tab_reloid = PGC.oid
                        and PGC.relnamespace = PGN.oid;
        update "_prod_replica_set".sl_sequence set
                seq_relname = PGC.relname, seq_nspname = PGN.nspname
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
                where "_prod_replica_set".sl_sequence.seq_reloid = PGC.oid
                and PGC.relnamespace = PGN.oid;
        return p_set_id;
end;

Function: _prod_replica_set.updatereloid( integer, integer )

Returns: integer

Language: PLPGSQL

updateReloid(set_id, only_on_node) Updates the respective reloids in sl_table and sl_seqeunce based on their respective FQN

declare
        p_set_id                alias for $1;
        p_only_on_node          alias for $2;
        v_no_id                 int4;
        v_set_origin            int4;
begin
        -- ----
        -- Grab the central configuration lock
        -- ----
        lock table "_prod_replica_set".sl_config_lock;

        -- ----
        -- Check that we either are the set origin or a current
        -- subscriber of the set.
        -- ----
        v_no_id := "_prod_replica_set".getLocalNodeId('_prod_replica_set');
        select set_origin into v_set_origin
                        from "_prod_replica_set".sl_set
                        where set_id = p_set_id
                        for update;
        if not found then
                raise exception 'Slony-I: set % not found', p_set_id;
        end if;
        if v_set_origin <> v_no_id
                and not exists (select 1 from "_prod_replica_set".sl_subscribe
                        where sub_set = p_set_id
                        and sub_receiver = v_no_id)
        then
                return 0;
        end if;

        -- ----
        -- If execution on only one node is requested, check that
        -- we are that node.
        -- ----
        if p_only_on_node > 0 and p_only_on_node <> v_no_id then
                return 0;
        end if;
        update "_prod_replica_set".sl_table set
                tab_reloid = PGC.oid
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
                where "_prod_replica_set".slon_quote_brute("_prod_replica_set".sl_table.tab_relname) = "_prod_replica_set".slon_quote_brute(PGC.relname)
                        and PGC.relnamespace = PGN.oid
			and "_prod_replica_set".slon_quote_brute(PGN.nspname) = "_prod_replica_set".slon_quote_brute("_prod_replica_set".sl_table.tab_nspname);

        update "_prod_replica_set".sl_sequence set
                seq_reloid = PGC.oid
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
                where "_prod_replica_set".slon_quote_brute("_prod_replica_set".sl_sequence.seq_relname) = "_prod_replica_set".slon_quote_brute(PGC.relname)
                	and PGC.relnamespace = PGN.oid
			and "_prod_replica_set".slon_quote_brute(PGN.nspname) = "_prod_replica_set".slon_quote_brute("_prod_replica_set".sl_sequence.seq_nspname);

        return  "_prod_replica_set".createEvent('_prod_replica_set', 'RESET_CONFIG',
                        p_set_id::text, p_only_on_node::text);
end;

Function: _prod_replica_set.upgradeschema( text )

Returns: text

Language: PLPGSQL

Called during "update functions" by slonik to perform schema changes


declare
        p_old   alias for $1;
begin
	-- upgrade sl_table
	if p_old IN ('1.0.2', '1.0.5', '1.0.6') then
		-- Add new column(s) sl_table.tab_relname, sl_table.tab_nspname
		execute 'alter table "_prod_replica_set".sl_table add column tab_relname name';
		execute 'alter table "_prod_replica_set".sl_table add column tab_nspname name';

		-- populate the colums with data
		update "_prod_replica_set".sl_table set
			tab_relname = PGC.relname, tab_nspname = PGN.nspname
			from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
			where "_prod_replica_set".sl_table.tab_reloid = PGC.oid
			and PGC.relnamespace = PGN.oid;

		-- constrain the colums
		execute 'alter table "_prod_replica_set".sl_table alter column tab_relname set NOT NULL';
		execute 'alter table "_prod_replica_set".sl_table alter column tab_nspname set NOT NULL';

	end if;

	-- upgrade sl_sequence
	if p_old IN ('1.0.2', '1.0.5', '1.0.6') then
		-- Add new column(s) sl_sequence.seq_relname, sl_sequence.seq_nspname
		execute 'alter table "_prod_replica_set".sl_sequence add column seq_relname name';
		execute 'alter table "_prod_replica_set".sl_sequence add column seq_nspname name';

		-- populate the columns with data
		update "_prod_replica_set".sl_sequence set
			seq_relname = PGC.relname, seq_nspname = PGN.nspname
			from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
			where "_prod_replica_set".sl_sequence.seq_reloid = PGC.oid
			and PGC.relnamespace = PGN.oid;

		-- constrain the data
		execute 'alter table "_prod_replica_set".sl_sequence alter column seq_relname set NOT NULL';
		execute 'alter table "_prod_replica_set".sl_sequence alter column seq_nspname set NOT NULL';
	end if;

	-- ----
	-- Changes from 1.0.x to 1.1.0
	-- ----
	if p_old IN ('1.0.2', '1.0.5', '1.0.6') then
		-- Add new column sl_node.no_spool for virtual spool nodes
		execute 'alter table "_prod_replica_set".sl_node add column no_spool boolean';
		update "_prod_replica_set".sl_node set no_spool = false;
	end if;

	-- ----
	-- Changes for 1.1.3
	-- ----
	if p_old IN ('1.0.2', '1.0.5', '1.0.6', '1.1.0', '1.1.1', '1.1.2') then
		-- Add new table sl_nodelock
		execute 'create table "_prod_replica_set".sl_nodelock (
						nl_nodeid		int4,
						nl_conncnt		serial,
						nl_backendpid	int4,

						CONSTRAINT "sl_nodelock-pkey"
						PRIMARY KEY (nl_nodeid, nl_conncnt)
					)';
		-- Drop obsolete functions
		execute 'drop function "_prod_replica_set".terminateNodeConnections(name)';
		execute 'drop function "_prod_replica_set".cleanupListener()';
		execute 'drop function "_prod_replica_set".truncateTable(text)';
	end if;

	-- ----
	-- Changes for 1.2
	-- ----
	if p_old IN ('1.0.2', '1.0.5', '1.0.6', '1.1.0', '1.1.1', '1.1.2', '1.1.3','1.1.5', '1.1.6', '1.1.7', '1.1.8', '1.1.9') then
		-- Add new table sl_registry
		execute 'create table "_prod_replica_set".sl_registry (
						reg_key			text primary key,
						reg_int4		int4,
						reg_text		text,
						reg_timestamp	timestamp
					) without oids';
                execute 'alter table "_prod_replica_set".sl_config_lock set without oids;';
                execute 'alter table "_prod_replica_set".sl_confirm set without oids;';
                execute 'alter table "_prod_replica_set".sl_event set without oids;';
                execute 'alter table "_prod_replica_set".sl_listen set without oids;';
                execute 'alter table "_prod_replica_set".sl_node set without oids;';
                execute 'alter table "_prod_replica_set".sl_nodelock set without oids;';
                execute 'alter table "_prod_replica_set".sl_path set without oids;';
                execute 'alter table "_prod_replica_set".sl_sequence set without oids;';
                execute 'alter table "_prod_replica_set".sl_set set without oids;';
                execute 'alter table "_prod_replica_set".sl_setsync set without oids;';
                execute 'alter table "_prod_replica_set".sl_subscribe set without oids;';
                execute 'alter table "_prod_replica_set".sl_table set without oids;';
                execute 'alter table "_prod_replica_set".sl_trigger set without oids;';
	end if;

	-- ----
	-- Changes for 1.2.11
	-- ----
	if p_old IN ('1.0.2', '1.0.5', '1.0.6', '1.1.0', '1.1.1', '1.1.2', '1.1.3','1.1.5', '1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.2.0', '1.2.1', '1.2.2', '1.2.3', '1.2.4', '1.2.5', '1.2.6', '1.2.7', '1.2.8', '1.2.9', '1.2.10') then
		-- Add new table sl_archive_counter
		execute 'create table "_prod_replica_set".sl_archive_counter (
						ac_num			bigint,
						ac_timestamp	timestamp
					) without oids';
		execute 'insert into "_prod_replica_set".sl_archive_counter
					(ac_num, ac_timestamp) values (0, ''epoch''::timestamp)';
	end if;

	-- In any version, make sure that the xxidin() functions are defined STRICT
	perform "_prod_replica_set".make_function_strict ('xxidin', '(cstring)');
	return p_old;
end;

Function: _prod_replica_set.xxid_ge_snapshot( _prod_replica_set.xxid, _prod_replica_set.xxid_snapshot )

Returns: boolean

Language: C

_Slony_I_xxid_ge_snapshot

Function: _prod_replica_set.xxid_lt_snapshot( _prod_replica_set.xxid, _prod_replica_set.xxid_snapshot )

Returns: boolean

Language: C

_Slony_I_xxid_lt_snapshot

Function: _prod_replica_set.xxid_snapshot_in( cstring )

Returns: xxid_snapshot

Language: C

_Slony_I_xxid_snapshot_in

Function: _prod_replica_set.xxid_snapshot_out( _prod_replica_set.xxid_snapshot )

Returns: cstring

Language: C

_Slony_I_xxid_snapshot_out

Function: _prod_replica_set.xxideq( _prod_replica_set.xxid, _prod_replica_set.xxid )

Returns: boolean

Language: C

_Slony_I_xxideq

Function: _prod_replica_set.xxidge( _prod_replica_set.xxid, _prod_replica_set.xxid )

Returns: boolean

Language: C

_Slony_I_xxidge

Function: _prod_replica_set.xxidgt( _prod_replica_set.xxid, _prod_replica_set.xxid )

Returns: boolean

Language: C

_Slony_I_xxidgt

Function: _prod_replica_set.xxidin( cstring )

Returns: xxid

Language: C

_Slony_I_xxidin

Function: _prod_replica_set.xxidle( _prod_replica_set.xxid, _prod_replica_set.xxid )

Returns: boolean

Language: C

_Slony_I_xxidle

Function: _prod_replica_set.xxidlt( _prod_replica_set.xxid, _prod_replica_set.xxid )

Returns: boolean

Language: C

_Slony_I_xxidlt

Function: _prod_replica_set.xxidne( _prod_replica_set.xxid, _prod_replica_set.xxid )

Returns: boolean

Language: C

_Slony_I_xxidne

Function: _prod_replica_set.xxidout( _prod_replica_set.xxid )

Returns: cstring

Language: C

_Slony_I_xxidout

Schema action


View: action.billable_cirulations

action.billable_cirulations Structure
F-Key Name Type Description
id bigint
usr integer
xact_start timestamp with time zone
xact_finish timestamp with time zone
target_copy bigint
circ_lib integer
circ_staff integer
checkin_staff integer
checkin_lib integer
renewal_remaining integer
due_date timestamp with time zone
stop_fines_time timestamp with time zone
checkin_time timestamp with time zone
duration interval
fine_interval interval
recuring_fine numeric(6,2)
max_fine numeric(6,2)
phone_renewal boolean
desk_renewal boolean
opac_renewal boolean
duration_rule text
recuring_fine_rule text
max_fine_rule text
stop_fines text
SELECT circulation.id
, circulation.usr
, circulation.xact_start
, circulation.xact_finish
, circulation.target_copy
, circulation.circ_lib
, circulation.circ_staff
, circulation.checkin_staff
, circulation.checkin_lib
, circulation.renewal_remaining
, circulation.due_date
, circulation.stop_fines_time
, circulation.checkin_time
, circulation.duration
, circulation.fine_interval
, circulation.recuring_fine
, circulation.max_fine
, circulation.phone_renewal
, circulation.desk_renewal
, circulation.opac_renewal
, circulation.duration_rule
, circulation.recuring_fine_rule
, circulation.max_fine_rule
, circulation.stop_fines 
FROM"action".circulation 
WHERE (circulation.xact_finish IS NULL);

 

Permissions which apply to action.billable_cirulations
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.circulation

action.circulation Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('money.billable_xact_id_seq'::regclass)
actor.usr.id usr integer NOT NULL
xact_start timestamp with time zone NOT NULL DEFAULT now()
xact_finish timestamp with time zone
asset.copy.id target_copy bigint NOT NULL
actor.org_unit.id circ_lib integer NOT NULL
circ_staff integer NOT NULL
checkin_staff integer
checkin_lib integer
renewal_remaining integer NOT NULL
due_date timestamp with time zone
stop_fines_time timestamp with time zone
checkin_time timestamp with time zone
duration interval
fine_interval interval NOT NULL DEFAULT '1 day'::interval
recuring_fine numeric(6,2)
max_fine numeric(6,2)
phone_renewal boolean NOT NULL DEFAULT false
desk_renewal boolean NOT NULL DEFAULT false
opac_renewal boolean NOT NULL DEFAULT false
duration_rule text NOT NULL
recuring_fine_rule text NOT NULL
max_fine_rule text NOT NULL
stop_fines text

Table action.circulation Inherits billable_xact,

 

action.circulation Constraints
Name Constraint
circulation_stop_fines_check CHECK (((((((stop_fines = 'CHECKIN'::text) OR (stop_fines = 'CLAIMSRETURNED'::text)) OR (stop_fines = 'LOST'::text)) OR (stop_fines = 'MAXFINES'::text)) OR (stop_fines = 'RENEW'::text)) OR (stop_fines = 'LONGOVERDUE'::text)))
circ_checkin_time checkin_time) WHERE (checkin_time IS NOT NULL circ_circ_lib_idx circ_lib circ_copy_idx target_copy circ_open_date_idx xact_start) WHERE (xact_finish IS NULL circ_open_xacts_idx usr) WHERE (xact_finish IS NULL circ_outstanding_idx usr) WHERE (checkin_time IS NULL circ_usr_idx usr

 

Permissions which apply to action.circulation
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.hold_copy_map

action.hold_copy_map Structure
F-Key Name Type Description
id serial PRIMARY KEY
action.hold_request.id hold integer UNIQUE#1 NOT NULL
asset.copy.id target_copy bigint UNIQUE#1 NOT NULL
acm_copy_idx target_copy

 

Permissions which apply to action.hold_copy_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.hold_notification

action.hold_notification Structure
F-Key Name Type Description
id serial PRIMARY KEY
action.hold_request.id hold integer NOT NULL
actor.usr.id notify_staff integer
notify_time timestamp with time zone NOT NULL DEFAULT now()
method text NOT NULL
note text
ahn_hold_idx "hold"

 

Permissions which apply to action.hold_notification
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.hold_request

action.hold_request Structure
F-Key Name Type Description
id serial PRIMARY KEY
request_time timestamp with time zone NOT NULL DEFAULT now()
capture_time timestamp with time zone
fulfillment_time timestamp with time zone
checkin_time timestamp with time zone
return_time timestamp with time zone
prev_check_time timestamp with time zone
expire_time timestamp with time zone
cancel_time timestamp with time zone
target bigint NOT NULL
asset.copy.id current_copy bigint
actor.usr.id fulfillment_staff integer
actor.org_unit.id fulfillment_lib integer
actor.org_unit.id request_lib integer NOT NULL
actor.usr.id requestor integer NOT NULL
actor.usr.id usr integer NOT NULL
selection_ou integer NOT NULL
selection_depth integer NOT NULL
actor.org_unit.id pickup_lib integer NOT NULL
hold_type text NOT NULL
holdable_formats text
phone_notify text
email_notify boolean NOT NULL DEFAULT true
frozen boolean NOT NULL DEFAULT false
thaw_date timestamp with time zone

 

action.hold_request Constraints
Name Constraint
hold_request_hold_type_check CHECK (((((hold_type = 'M'::text) OR (hold_type = 'T'::text)) OR (hold_type = 'V'::text)) OR (hold_type = 'C'::text)))

Tables referencing this one via Foreign Key Constraints:

hold_request_current_copy_idx current_copy hold_request_pickup_lib_idx pickup_lib hold_request_prev_check_time_idx prev_check_time hold_request_target_idx target hold_request_usr_idx usr

 

Permissions which apply to action.hold_request
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.hold_transit_copy

action.hold_transit_copy Structure
F-Key Name Type Description
id integer PRIMARY KEY DEFAULT nextval('transit_copy_id_seq'::regclass)
source_send_time timestamp with time zone
dest_recv_time timestamp with time zone
asset.copy.id target_copy bigint NOT NULL
source integer NOT NULL
dest integer NOT NULL
prev_hop integer
copy_status integer NOT NULL
persistant_transfer boolean NOT NULL DEFAULT false
action.hold_request.id hold integer

Table action.hold_transit_copy Inherits transit_copy,

active_hold_transit_cp_idx target_copy active_hold_transit_dest_idx dest active_hold_transit_source_idx source

 

Permissions which apply to action.hold_transit_copy
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.in_house_use

action.in_house_use Structure
F-Key Name Type Description
id serial PRIMARY KEY
asset.copy.id item bigint NOT NULL
actor.usr.id staff integer NOT NULL
actor.org_unit.id org_unit integer NOT NULL
use_time timestamp with time zone NOT NULL DEFAULT now()

 

Permissions which apply to action.in_house_use
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.non_cat_in_house_use

action.non_cat_in_house_use Structure
F-Key Name Type Description
id serial PRIMARY KEY
config.non_cataloged_type.id item_type bigint NOT NULL
actor.usr.id staff integer NOT NULL
actor.org_unit.id org_unit integer NOT NULL
use_time timestamp with time zone NOT NULL DEFAULT now()

 

Permissions which apply to action.non_cat_in_house_use
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.non_cataloged_circulation

action.non_cataloged_circulation Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id patron integer NOT NULL
actor.usr.id staff integer NOT NULL
actor.org_unit.id circ_lib integer NOT NULL
config.non_cataloged_type.id item_type integer NOT NULL
circ_time timestamp with time zone NOT NULL DEFAULT now()
action_non_cat_circ_patron_idx patron action_non_cat_circ_time_idx circ_time

 

Permissions which apply to action.non_cataloged_circulation
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


View: action.open_circ_count_by_circ_mod

action.open_circ_count_by_circ_mod Structure
F-Key Name Type Description
usr integer
circ_modifier text
count bigint
SELECT circ.usr
, cp.circ_modifier
, count
(circ.id) AS count 
FROM ("action".circulation circ 
  JOIN asset."copy" cp 
    ON (
           (circ.target_copy = cp.id)
     )
)
WHERE (
     (circ.checkin_time IS NULL)
   AND (
           (
                 (
                       (circ.stop_fines = 'LOST'::text)
                      OR (circ.stop_fines = 
                 'LONGOVERDUE'::text
                       )
                 )
                OR (circ.stop_fines = 'CLAIMSRETURNED'::text)
           )
          OR (circ.stop_fines IS NULL)
     )
)
GROUP BY circ.usr
, cp.circ_modifier;

Index - Schema action


View: action.open_circulation

action.open_circulation Structure
F-Key Name Type Description
id bigint
usr integer
xact_start timestamp with time zone
xact_finish timestamp with time zone
target_copy bigint
circ_lib integer
circ_staff integer
checkin_staff integer
checkin_lib integer
renewal_remaining integer
due_date timestamp with time zone
stop_fines_time timestamp with time zone
checkin_time timestamp with time zone
duration interval
fine_interval interval
recuring_fine numeric(6,2)
max_fine numeric(6,2)
phone_renewal boolean
desk_renewal boolean
opac_renewal boolean
duration_rule text
recuring_fine_rule text
max_fine_rule text
stop_fines text
SELECT circulation.id
, circulation.usr
, circulation.xact_start
, circulation.xact_finish
, circulation.target_copy
, circulation.circ_lib
, circulation.circ_staff
, circulation.checkin_staff
, circulation.checkin_lib
, circulation.renewal_remaining
, circulation.due_date
, circulation.stop_fines_time
, circulation.checkin_time
, circulation.duration
, circulation.fine_interval
, circulation.recuring_fine
, circulation.max_fine
, circulation.phone_renewal
, circulation.desk_renewal
, circulation.opac_renewal
, circulation.duration_rule
, circulation.recuring_fine_rule
, circulation.max_fine_rule
, circulation.stop_fines 
FROM"action".circulation 
WHERE (circulation.checkin_time IS NULL)
ORDER BY circulation.due_date;

 

Permissions which apply to action.open_circulation
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.survey

action.survey Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.org_unit.id owner integer NOT NULL
start_date timestamp with time zone NOT NULL DEFAULT now()
end_date timestamp with time zone NOT NULL DEFAULT (now() + '10 years'::interval)
usr_summary boolean NOT NULL DEFAULT false
opac boolean NOT NULL DEFAULT false
poll boolean NOT NULL DEFAULT false
required boolean NOT NULL DEFAULT false
name text NOT NULL
description text NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to action.survey
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.survey_answer

action.survey_answer Structure
F-Key Name Type Description
id serial PRIMARY KEY
action.survey_question.id question integer NOT NULL
answer text NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to action.survey_answer
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.survey_question

action.survey_question Structure
F-Key Name Type Description
id serial PRIMARY KEY
action.survey.id survey integer NOT NULL
question text NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to action.survey_question
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.survey_response

action.survey_response Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
response_group_id integer
usr integer
action.survey.id survey integer NOT NULL
action.survey_question.id question integer NOT NULL
action.survey_answer.id answer integer NOT NULL
answer_date timestamp with time zone
effective_date timestamp with time zone NOT NULL DEFAULT now()
action_survey_response_answer_idx answer action_survey_response_question_idx question action_survey_response_survey_idx survey action_survey_response_usr_idx usr

 

Permissions which apply to action.survey_response
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.transit_copy

action.transit_copy Structure
F-Key Name Type Description
id serial PRIMARY KEY
source_send_time timestamp with time zone
dest_recv_time timestamp with time zone
asset.copy.id target_copy bigint NOT NULL
actor.org_unit.id source integer NOT NULL
actor.org_unit.id dest integer NOT NULL
action.transit_copy.id prev_hop integer
config.copy_status.id copy_status integer NOT NULL
persistant_transfer boolean NOT NULL DEFAULT false

Tables referencing this one via Foreign Key Constraints:

active_transit_cp_idx target_copy active_transit_dest_idx dest active_transit_source_idx source

 

Permissions which apply to action.transit_copy
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Table: action.unfulfilled_hold_list

action.unfulfilled_hold_list Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
current_copy bigint NOT NULL
hold integer NOT NULL
circ_lib integer NOT NULL
fail_time timestamp with time zone NOT NULL DEFAULT now()

 

Permissions which apply to action.unfulfilled_hold_list
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema action


Function: action.circulation_claims_returned( )

Returns: "trigger"

Language: PLPGSQL

BEGIN
	IF OLD.stop_fines IS NULL OR OLD.stop_fines <> NEW.stop_fines THEN
		IF NEW.stop_fines = 'CLAIMSRETURNED' THEN
			UPDATE actor.usr SET claims_returned_count = claims_returned_count + 1 WHERE id = NEW.usr;
		END IF;
		IF NEW.stop_fines = 'LOST' THEN
			UPDATE asset.copy SET status = 3 WHERE id = NEW.target_copy;
		END IF;
	END IF;
	RETURN NEW;
END;

Function: action.survey_response_answer_date_fixup( )

Returns: "trigger"

Language: PLPGSQL

BEGIN
	NEW.answer_date := NOW();
	RETURN NEW;
END;

Schema actor

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander * * Schema: actor * * Holds all tables pertaining to users and libraries (org units). * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */


Table: actor.card

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Library Cards * * Each User has one or more library cards. The current "main" * card is linked to here from the actor.usr table, and it is up * to the consortium policy whether more than one card can be * active for any one user at a given time. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.card Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id usr integer NOT NULL
barcode text UNIQUE NOT NULL
active boolean NOT NULL DEFAULT true
actor_card_usr_idx usr

 

Permissions which apply to actor.card
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.hours_of_operation

actor.hours_of_operation Structure
F-Key Name Type Description
actor.org_unit.id id integer PRIMARY KEY
dow_0_open time without time zone NOT NULL DEFAULT '09:00:00'::time without time zone
dow_0_close time without time zone NOT NULL DEFAULT '17:00:00'::time without time zone
dow_1_open time without time zone NOT NULL DEFAULT '09:00:00'::time without time zone
dow_1_close time without time zone NOT NULL DEFAULT '17:00:00'::time without time zone
dow_2_open time without time zone NOT NULL DEFAULT '09:00:00'::time without time zone
dow_2_close time without time zone NOT NULL DEFAULT '17:00:00'::time without time zone
dow_3_open time without time zone NOT NULL DEFAULT '09:00:00'::time without time zone
dow_3_close time without time zone NOT NULL DEFAULT '17:00:00'::time without time zone
dow_4_open time without time zone NOT NULL DEFAULT '09:00:00'::time without time zone
dow_4_close time without time zone NOT NULL DEFAULT '17:00:00'::time without time zone
dow_5_open time without time zone NOT NULL DEFAULT '09:00:00'::time without time zone
dow_5_close time without time zone NOT NULL DEFAULT '17:00:00'::time without time zone
dow_6_open time without time zone NOT NULL DEFAULT '09:00:00'::time without time zone
dow_6_close time without time zone NOT NULL DEFAULT '17:00:00'::time without time zone

 

Permissions which apply to actor.hours_of_operation
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.org_address

actor.org_address Structure
F-Key Name Type Description
id serial PRIMARY KEY
valid boolean NOT NULL DEFAULT true
address_type text NOT NULL DEFAULT 'MAILING'::text
actor.org_unit.id org_unit integer NOT NULL
street1 text NOT NULL
street2 text
city text NOT NULL
county text
state text NOT NULL
country text NOT NULL
post_code text NOT NULL

Tables referencing this one via Foreign Key Constraints:

actor_org_address_org_unit_idx org_unit

 

Permissions which apply to actor.org_address
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.org_unit

actor.org_unit Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.org_unit.id parent_ou integer
actor.org_unit_type.id ou_type integer NOT NULL
actor.org_address.id ill_address integer
actor.org_address.id holds_address integer
actor.org_address.id mailing_address integer
actor.org_address.id billing_address integer
shortname text NOT NULL
name text NOT NULL
email text
phone text
opac_visible boolean NOT NULL DEFAULT true

Tables referencing this one via Foreign Key Constraints:

actor_org_unit_billing_address_idx billing_address actor_org_unit_holds_address_idx holds_address actor_org_unit_ill_address_idx ill_address actor_org_unit_mailing_address_idx mailing_address actor_org_unit_ou_type_idx ou_type actor_org_unit_parent_ou_idx parent_ou

 

Permissions which apply to actor.org_unit
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.org_unit_closed

actor.org_unit_closed Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.org_unit.id org_unit integer NOT NULL
close_start timestamp with time zone NOT NULL
close_end timestamp with time zone NOT NULL
reason text

 

Permissions which apply to actor.org_unit_closed
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.org_unit_proximity

actor.org_unit_proximity Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
from_org integer
to_org integer
prox integer
from_prox_idx from_org

 

Permissions which apply to actor.org_unit_proximity
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.org_unit_setting

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Org Unit settings * * This table contains any arbitrary settings that a client * program would like to save for an org unit. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.org_unit_setting Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.org_unit.id org_unit integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
value text NOT NULL
actor_org_unit_setting_usr_idx org_unit

 

Permissions which apply to actor.org_unit_setting
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.org_unit_type

actor.org_unit_type Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text NOT NULL
opac_label text NOT NULL
depth integer NOT NULL
actor.org_unit_type.id parent integer
can_have_vols boolean NOT NULL DEFAULT true
can_have_users boolean NOT NULL DEFAULT true

Tables referencing this one via Foreign Key Constraints:

actor_org_unit_type_parent_idx parent

 

Permissions which apply to actor.org_unit_type
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.stat_cat

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * User Statistical Catagories * * Local data collected about Users is placed into a Statistical * Catagory. Here's where those catagories are defined. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.stat_cat Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.org_unit.id owner integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
opac_visible boolean NOT NULL DEFAULT false

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to actor.stat_cat
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.stat_cat_entry

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * User Statistical Catagory Entries * * Local data collected about Users is placed into a Statistical * Catagory. Each library can create entries into any of it's own * stat_cats, it's anscestors stat_cats, or it's descendants' stat_cats. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.stat_cat_entry Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.stat_cat.id stat_cat integer UNIQUE#1 NOT NULL
actor.org_unit.id owner integer UNIQUE#1 NOT NULL
value text UNIQUE#1 NOT NULL

 

Permissions which apply to actor.stat_cat_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.stat_cat_entry_usr_map

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Statistical Catagory Entry to User map * * Records the stat_cat entries for each user. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.stat_cat_entry_usr_map Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
stat_cat_entry text NOT NULL
actor.stat_cat.id stat_cat integer UNIQUE#1 NOT NULL
actor.usr.id target_usr integer UNIQUE#1 NOT NULL
actor_stat_cat_entry_usr_idx target_usr

 

Permissions which apply to actor.stat_cat_entry_usr_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.usr

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * User objects * * This table contains the core User objects that describe both * staff members and patrons. The difference between the two * types of users is based on the user's permissions. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.usr Structure
F-Key Name Type Description
id serial PRIMARY KEY
card integer UNIQUE
profile integer NOT NULL
usrname text UNIQUE NOT NULL
email text
passwd text NOT NULL
standing integer NOT NULL DEFAULT 1
config.identification_type.id ident_type integer NOT NULL
ident_value text
config.identification_type.id ident_type2 integer
ident_value2 text
config.net_access_level.id net_access_level integer NOT NULL DEFAULT 1
photo_url text
prefix text
first_given_name text NOT NULL
second_given_name text
family_name text NOT NULL
suffix text
day_phone text
evening_phone text
other_phone text
actor.usr_address.id mailing_address integer
actor.usr_address.id billing_address integer
actor.org_unit.id home_ou integer NOT NULL
dob timestamp with time zone
active boolean NOT NULL DEFAULT true
master_account boolean NOT NULL DEFAULT false
super_user boolean NOT NULL DEFAULT false
barred boolean NOT NULL DEFAULT false
deleted boolean NOT NULL DEFAULT false
usrgroup serial NOT NULL
claims_returned_count integer NOT NULL
credit_forward_balance numeric(6,2) NOT NULL DEFAULT 0.00
last_xact_id text NOT NULL DEFAULT 'none'::text
alert_message text
create_date timestamp with time zone NOT NULL DEFAULT now()
expire_date timestamp with time zone NOT NULL DEFAULT (now() + '3 years'::interval)

Tables referencing this one via Foreign Key Constraints:

actor_usr_billing_address_idx billing_address actor_usr_day_phone_idx lower(day_phone) actor_usr_email_idx lower(email) actor_usr_evening_phone_idx lower(evening_phone) actor_usr_family_name_idx lower(family_name) actor_usr_first_given_name_idx lower(first_given_name) actor_usr_home_ou_idx home_ou actor_usr_ident_value2_idx lower(ident_value2) actor_usr_ident_value_idx lower(ident_value) actor_usr_mailing_address_idx mailing_address actor_usr_other_phone_idx lower(other_phone) actor_usr_second_given_name_idx lower(second_given_name)

 

Permissions which apply to actor.usr
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.usr_address

actor.usr_address Structure
F-Key Name Type Description
id serial PRIMARY KEY
valid boolean NOT NULL DEFAULT true
within_city_limits boolean NOT NULL DEFAULT true
address_type text NOT NULL DEFAULT 'MAILING'::text
actor.usr.id usr integer NOT NULL
street1 text NOT NULL
street2 text
city text NOT NULL
county text
state text NOT NULL
country text NOT NULL
post_code text NOT NULL

Tables referencing this one via Foreign Key Constraints:

actor_usr_addr_city_idx lower(city) actor_usr_addr_county_idx lower(county) actor_usr_addr_post_code_idx lower(post_code) actor_usr_addr_state_idx lower(state) actor_usr_addr_street1_idx lower(street1) actor_usr_addr_street2_idx lower(street2) actor_usr_addr_usr_idx usr

 

Permissions which apply to actor.usr_address
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.usr_note

actor.usr_note Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.usr.id usr bigint NOT NULL
actor.usr.id creator bigint NOT NULL
create_date timestamp with time zone DEFAULT now()
pub boolean NOT NULL DEFAULT false
title text NOT NULL
value text NOT NULL
actor_usr_note_usr_idx usr

 

Permissions which apply to actor.usr_note
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.usr_org_unit_opt_in

actor.usr_org_unit_opt_in Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.org_unit.id org_unit integer UNIQUE#1 NOT NULL
actor.usr.id usr integer UNIQUE#1 NOT NULL
actor.usr.id staff integer NOT NULL
opt_in_ts timestamp with time zone NOT NULL DEFAULT now()
actor.workstation.id opt_in_ws integer NOT NULL

Index - Schema actor


Table: actor.usr_setting

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * User settings * * This table contains any arbitrary settings that a client * program would like to save for a user. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.usr_setting Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.usr.id usr integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
value text NOT NULL
actor_usr_setting_usr_idx usr

 

Permissions which apply to actor.usr_setting
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.usr_standing_penalty

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * User standing penalties * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

actor.usr_standing_penalty Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id usr integer NOT NULL
penalty_type text NOT NULL
actor_usr_standing_penalty_usr_idx usr

 

Permissions which apply to actor.usr_standing_penalty
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Table: actor.workstation

actor.workstation Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL
actor.org_unit.id owning_lib integer NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to actor.workstation
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema actor


Function: actor.crypt_pw_insert( )

Returns: "trigger"

Language: PLPGSQL

	BEGIN
		NEW.passwd = MD5( NEW.passwd );
		RETURN NEW;
	END;

Function: actor.crypt_pw_update( )

Returns: "trigger"

Language: PLPGSQL

	BEGIN
		IF NEW.passwd <> OLD.passwd THEN
			NEW.passwd = MD5( NEW.passwd );
		END IF;
		RETURN NEW;
	END;

Function: actor.org_unit_ancestor_at_depth( integer, integer )

Returns: org_unit

Language: SQL

	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);

Function: actor.org_unit_ancestors( integer )

Returns: SET OF org_unit

Language: SQL

	SELECT	a.*
	  FROM	connectby('actor.org_unit','parent_ou','id','name',$1,'100','.')
	  		AS t(keyid text, parent_keyid text, level int, branch text,pos int)
		JOIN actor.org_unit a ON a.id = t.keyid
	  ORDER BY  CASE WHEN a.parent_ou IS NULL THEN 0 ELSE 1 END, a.name;

Function: actor.org_unit_combined_ancestors( integer, integer )

Returns: SET OF org_unit

Language: SQL

	SELECT	*
	  FROM	actor.org_unit_ancestors($1)
			UNION
	SELECT	*
	  FROM	actor.org_unit_ancestors($2);

Function: actor.org_unit_common_ancestors( integer, integer )

Returns: SET OF org_unit

Language: SQL

	SELECT	*
	  FROM	actor.org_unit_ancestors($1)
			INTERSECT
	SELECT	*
	  FROM	actor.org_unit_ancestors($2);

Function: actor.org_unit_descendants( integer )

Returns: SET OF org_unit

Language: SQL

	SELECT	a.*
	  FROM	connectby('actor.org_unit','id','parent_ou','name',$1,'100','.')
	  		AS t(keyid text, parent_keyid text, level int, branch text,pos int)
		JOIN actor.org_unit a ON a.id = t.keyid
	  ORDER BY  CASE WHEN a.parent_ou IS NULL THEN 0 ELSE 1 END, a.name;

Function: actor.org_unit_descendants( integer, integer )

Returns: SET OF org_unit

Language: SQL

	SELECT	a.*
	  FROM	connectby('actor.org_unit','id','parent_ou','name',
	  			(SELECT	x.id
				   FROM	actor.org_unit_ancestors($1) x
				   	JOIN actor.org_unit_type y ON x.ou_type = y.id
				  WHERE	y.depth = $2)
		,'100','.')
	  		AS t(keyid text, parent_keyid text, level int, branch text,pos int)
		JOIN actor.org_unit a ON a.id = t.keyid
	  ORDER BY  CASE WHEN a.parent_ou IS NULL THEN 0 ELSE 1 END, a.name;

Function: actor.org_unit_full_path( integer )

Returns: SET OF org_unit

Language: SQL

	SELECT	*
	  FROM	actor.org_unit_ancestors($1)
			UNION
	SELECT	*
	  FROM	actor.org_unit_descendants($1);

Function: actor.org_unit_full_path( integer, integer )

Returns: SET OF org_unit

Language: SQL

	SELECT	* FROM actor.org_unit_full_path((actor.org_unit_ancestor_at_depth($1, $2)).id)

Function: actor.org_unit_proximity( integer, integer )

Returns: integer

Language: SQL

	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;

Schema asset


Table: asset.call_number

asset.call_number Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.usr.id creator bigint NOT NULL
create_date timestamp with time zone DEFAULT now()
actor.usr.id editor bigint NOT NULL
edit_date timestamp with time zone DEFAULT now()
biblio.record_entry.id record bigint NOT NULL
actor.org_unit.id owning_lib integer NOT NULL
label text NOT NULL
deleted boolean NOT NULL DEFAULT false

Tables referencing this one via Foreign Key Constraints:

asset_call_number_creator_idx creator asset_call_number_dewey_idx call_number_dewey(label) asset_call_number_editor_idx editor asset_call_number_record_idx record asset_call_number_upper_label_id_owning_lib_idx upper(label), id, owning_lib

 

Permissions which apply to asset.call_number
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.call_number_note

asset.call_number_note Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
asset.call_number.id call_number bigint NOT NULL
actor.usr.id creator bigint NOT NULL
create_date timestamp with time zone DEFAULT now()
pub boolean NOT NULL DEFAULT false
title text NOT NULL
value text NOT NULL

 

Permissions which apply to asset.call_number_note
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.copy

asset.copy Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.org_unit.id circ_lib integer NOT NULL
actor.usr.id creator bigint NOT NULL
asset.call_number.id call_number bigint NOT NULL
actor.usr.id editor bigint NOT NULL
create_date timestamp with time zone DEFAULT now()
edit_date timestamp with time zone DEFAULT now()
copy_number integer
config.copy_status.id status integer NOT NULL
asset.copy_location.id location integer NOT NULL DEFAULT 1
loan_duration integer NOT NULL
fine_level integer NOT NULL
age_protect integer
circulate boolean NOT NULL DEFAULT true
deposit boolean NOT NULL DEFAULT false
ref boolean NOT NULL DEFAULT false
holdable boolean NOT NULL DEFAULT true
deposit_amount numeric(6,2) NOT NULL DEFAULT 0.00
price numeric(8,2) NOT NULL DEFAULT 0.00
barcode text NOT NULL
circ_modifier text
circ_as_type text
dummy_title text
dummy_author text
alert_message text
opac_visible boolean NOT NULL DEFAULT true
deleted boolean NOT NULL DEFAULT false

 

asset.copy Constraints
Name Constraint
copy_fine_level_check CHECK ((((fine_level = 1) OR (fine_level = 2)) OR (fine_level = 3)))
copy_loan_duration_check CHECK ((((loan_duration = 1) OR (loan_duration = 2)) OR (loan_duration = 3)))

Tables referencing this one via Foreign Key Constraints:

cp_avail_cn_idx call_number cp_barcode_all_idx barcode

 

Permissions which apply to asset.copy
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.copy_location

asset.copy_location Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text NOT NULL
actor.org_unit.id owning_lib integer NOT NULL
holdable boolean NOT NULL DEFAULT true
opac_visible boolean NOT NULL DEFAULT true
circulate boolean NOT NULL DEFAULT true

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to asset.copy_location
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.copy_note

asset.copy_note Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
asset.copy.id owning_copy bigint NOT NULL
actor.usr.id creator bigint NOT NULL
create_date timestamp with time zone DEFAULT now()
pub boolean NOT NULL DEFAULT false
title text NOT NULL
value text NOT NULL
circ_copy_idx owning_copy

 

Permissions which apply to asset.copy_note
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.copy_tranparency_map

asset.copy_tranparency_map Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
asset.copy_transparency.id tansparency integer NOT NULL
asset.copy.id target_copy integer UNIQUE NOT NULL
cp_tr_cp_idx tansparency

 

Permissions which apply to asset.copy_tranparency_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.copy_transparency

asset.copy_transparency Structure
F-Key Name Type Description
id serial PRIMARY KEY
deposit_amount numeric(6,2)
actor.org_unit.id owner integer UNIQUE#1 NOT NULL
actor.org_unit.id circ_lib integer
loan_duration integer
fine_level integer
holdable boolean
circulate boolean
deposit boolean
ref boolean
opac_visible boolean
circ_modifier text
circ_as_type text
name text UNIQUE#1 NOT NULL

 

asset.copy_transparency Constraints
Name Constraint
copy_transparency_fine_level_check CHECK ((((fine_level = 1) OR (fine_level = 2)) OR (fine_level = 3)))
copy_transparency_loan_duration_check CHECK ((((loan_duration = 1) OR (loan_duration = 2)) OR (loan_duration = 3)))

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to asset.copy_transparency
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.stat_cat

asset.stat_cat Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.org_unit.id owner integer UNIQUE#1 NOT NULL
opac_visible boolean NOT NULL DEFAULT false
name text UNIQUE#1 NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to asset.stat_cat
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.stat_cat_entry

asset.stat_cat_entry Structure
F-Key Name Type Description
id serial PRIMARY KEY
asset.stat_cat.id stat_cat integer UNIQUE#1 NOT NULL
actor.org_unit.id owner integer UNIQUE#1 NOT NULL
value text UNIQUE#1 NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to asset.stat_cat_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.stat_cat_entry_copy_map

asset.stat_cat_entry_copy_map Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
asset.stat_cat.id stat_cat integer UNIQUE#1 NOT NULL
asset.stat_cat_entry.id stat_cat_entry integer NOT NULL
asset.copy.id owning_copy bigint UNIQUE#1 NOT NULL

 

Permissions which apply to asset.stat_cat_entry_copy_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Table: asset.stat_cat_entry_transparency_map

asset.stat_cat_entry_transparency_map Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
stat_cat integer UNIQUE#1 NOT NULL
stat_cat_entry integer NOT NULL
owning_transparency integer UNIQUE#1 NOT NULL

 

Permissions which apply to asset.stat_cat_entry_transparency_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema asset


Schema auditor


Table: auditor.actor_org_unit_history

auditor.actor_org_unit_history Structure
F-Key Name Type Description
audit_time timestamp with time zone NOT NULL
audit_action text NOT NULL
id integer NOT NULL
parent_ou integer
ou_type integer NOT NULL
ill_address integer
holds_address integer
mailing_address integer
billing_address integer
shortname text NOT NULL
name text NOT NULL
email text
phone text

 

Permissions which apply to auditor.actor_org_unit_history
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


View: auditor.actor_org_unit_lifecycle

auditor.actor_org_unit_lifecycle Structure
F-Key Name Type Description
audit_time timestamp with time zone
audit_action text
id integer
parent_ou integer
ou_type integer
ill_address integer
holds_address integer
mailing_address integer
billing_address integer
shortname text
name text
email text
phone text
SELECT now
() AS audit_time
,'C' AS audit_action
, org_unit.id
, org_unit.parent_ou
, org_unit.ou_type
, org_unit.ill_address
, org_unit.holds_address
, org_unit.mailing_address
, org_unit.billing_address
, org_unit.shortname
, org_unit.name
, org_unit.email
, org_unit.phone 
FROM actor.org_unit 
UNION ALLSELECT actor_org_unit_history.audit_time
, actor_org_unit_history.audit_action
, actor_org_unit_history.id
, actor_org_unit_history.parent_ou
, actor_org_unit_history.ou_type
, actor_org_unit_history.ill_address
, actor_org_unit_history.holds_address
, actor_org_unit_history.mailing_address
, actor_org_unit_history.billing_address
, actor_org_unit_history.shortname
, actor_org_unit_history.name
, actor_org_unit_history.email
, actor_org_unit_history.phone 
FROM auditor.actor_org_unit_history;

 

Permissions which apply to auditor.actor_org_unit_lifecycle
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


Table: auditor.actor_usr_address_history

auditor.actor_usr_address_history Structure
F-Key Name Type Description
audit_time timestamp with time zone NOT NULL
audit_action text NOT NULL
id integer NOT NULL
valid boolean NOT NULL
within_city_limits boolean NOT NULL
address_type text NOT NULL
usr integer NOT NULL
street1 text NOT NULL
street2 text
city text NOT NULL
county text
state text NOT NULL
country text NOT NULL
post_code text NOT NULL

 

Permissions which apply to auditor.actor_usr_address_history
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


View: auditor.actor_usr_address_lifecycle

auditor.actor_usr_address_lifecycle Structure
F-Key Name Type Description
audit_time timestamp with time zone
audit_action text
id integer
valid boolean
within_city_limits boolean
address_type text
usr integer
street1 text
street2 text
city text
county text
state text
country text
post_code text
SELECT now
() AS audit_time
,'C' AS audit_action
, usr_address.id
, usr_address."valid"
, usr_address.within_city_limits
, usr_address.address_type
, usr_address.usr
, usr_address.street1
, usr_address.street2
, usr_address.city
, usr_address.county
, usr_address.state
, usr_address.country
, usr_address.post_code 
FROM actor.usr_address 
UNION ALLSELECT actor_usr_address_history.audit_time
, actor_usr_address_history.audit_action
, actor_usr_address_history.id
, actor_usr_address_history."valid"
, actor_usr_address_history.within_city_limits
, actor_usr_address_history.address_type
, actor_usr_address_history.usr
, actor_usr_address_history.street1
, actor_usr_address_history.street2
, actor_usr_address_history.city
, actor_usr_address_history.county
, actor_usr_address_history.state
, actor_usr_address_history.country
, actor_usr_address_history.post_code 
FROM auditor.actor_usr_address_history;

 

Permissions which apply to auditor.actor_usr_address_lifecycle
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


Table: auditor.actor_usr_history

auditor.actor_usr_history Structure
F-Key Name Type Description
audit_time timestamp with time zone NOT NULL
audit_action text NOT NULL
id integer NOT NULL
card integer
profile integer NOT NULL
usrname text NOT NULL
email text
passwd text NOT NULL
standing integer NOT NULL
ident_type integer NOT NULL
ident_value text
ident_type2 integer
ident_value2 text
net_access_level integer NOT NULL
photo_url text
prefix text
first_given_name text NOT NULL
second_given_name text
family_name text NOT NULL
suffix text
day_phone text
evening_phone text
other_phone text
mailing_address integer
billing_address integer
home_ou integer NOT NULL
dob timestamp with time zone
active boolean NOT NULL
master_account boolean NOT NULL
super_user boolean NOT NULL
barred boolean NOT NULL
deleted boolean NOT NULL
usrgroup integer NOT NULL
claims_returned_count integer NOT NULL
credit_forward_balance numeric(6,2) NOT NULL
last_xact_id text NOT NULL
alert_message text
create_date timestamp with time zone NOT NULL
expire_date timestamp with time zone NOT NULL

 

Permissions which apply to auditor.actor_usr_history
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


View: auditor.actor_usr_lifecycle

auditor.actor_usr_lifecycle Structure
F-Key Name Type Description
audit_time timestamp with time zone
audit_action text
id integer
card integer
profile integer
usrname text
email text
passwd text
standing integer
ident_type integer
ident_value text
ident_type2 integer
ident_value2 text
net_access_level integer
photo_url text
prefix text
first_given_name text
second_given_name text
family_name text
suffix text
day_phone text
evening_phone text
other_phone text
mailing_address integer
billing_address integer
home_ou integer
dob timestamp with time zone
active boolean
master_account boolean
super_user boolean
barred boolean
deleted boolean
usrgroup integer
claims_returned_count integer
credit_forward_balance numeric
last_xact_id text
alert_message text
create_date timestamp with time zone
expire_date timestamp with time zone
SELECT now
() AS audit_time
,'C' AS audit_action
, usr.id
, usr.card
, usr.profile
, usr.usrname
, usr.email
, usr.passwd
, usr.standing
, usr.ident_type
, usr.ident_value
, usr.ident_type2
, usr.ident_value2
, usr.net_access_level
, usr.photo_url
, usr.prefix
, usr.first_given_name
, usr.second_given_name
, usr.family_name
, usr.suffix
, usr.day_phone
, usr.evening_phone
, usr.other_phone
, usr.mailing_address
, usr.billing_address
, usr.home_ou
, usr.dob
, usr.active
, usr.master_account
, usr.super_user
, usr.barred
, usr.deleted
, usr.usrgroup
, usr.claims_returned_count
, usr.credit_forward_balance
, usr.last_xact_id
, usr.alert_message
, usr.create_date
, usr.expire_date 
FROM actor.usr 
UNION ALLSELECT actor_usr_history.audit_time
, actor_usr_history.audit_action
, actor_usr_history.id
, actor_usr_history.card
, actor_usr_history.profile
, actor_usr_history.usrname
, actor_usr_history.email
, actor_usr_history.passwd
, actor_usr_history.standing
, actor_usr_history.ident_type
, actor_usr_history.ident_value
, actor_usr_history.ident_type2
, actor_usr_history.ident_value2
, actor_usr_history.net_access_level
, actor_usr_history.photo_url
, actor_usr_history.prefix
, actor_usr_history.first_given_name
, actor_usr_history.second_given_name
, actor_usr_history.family_name
, actor_usr_history.suffix
, actor_usr_history.day_phone
, actor_usr_history.evening_phone
, actor_usr_history.other_phone
, actor_usr_history.mailing_address
, actor_usr_history.billing_address
, actor_usr_history.home_ou
, actor_usr_history.dob
, actor_usr_history.active
, actor_usr_history.master_account
, actor_usr_history.super_user
, actor_usr_history.barred
, actor_usr_history.deleted
, actor_usr_history.usrgroup
, actor_usr_history.claims_returned_count
, actor_usr_history.credit_forward_balance
, actor_usr_history.last_xact_id
, actor_usr_history.alert_message
, actor_usr_history.create_date
, actor_usr_history.expire_date 
FROM auditor.actor_usr_history;

 

Permissions which apply to auditor.actor_usr_lifecycle
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


Table: auditor.asset_call_number_history

auditor.asset_call_number_history Structure
F-Key Name Type Description
audit_time timestamp with time zone NOT NULL
audit_action text NOT NULL
id bigint NOT NULL
creator bigint NOT NULL
create_date timestamp with time zone
editor bigint NOT NULL
edit_date timestamp with time zone
record bigint NOT NULL
owning_lib integer NOT NULL
label text NOT NULL
deleted boolean NOT NULL

 

Permissions which apply to auditor.asset_call_number_history
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


View: auditor.asset_call_number_lifecycle

auditor.asset_call_number_lifecycle Structure
F-Key Name Type Description
audit_time timestamp with time zone
audit_action text
id bigint
creator bigint
create_date timestamp with time zone
editor bigint
edit_date timestamp with time zone
record bigint
owning_lib integer
label text
deleted boolean
SELECT now
() AS audit_time
,'C' AS audit_action
, call_number.id
, call_number.creator
, call_number.create_date
, call_number.editor
, call_number.edit_date
, call_number.record
, call_number.owning_lib
, call_number.label
, call_number.deleted 
FROM asset.call_number 
UNION ALLSELECT asset_call_number_history.audit_time
, asset_call_number_history.audit_action
, asset_call_number_history.id
, asset_call_number_history.creator
, asset_call_number_history.create_date
, asset_call_number_history.editor
, asset_call_number_history.edit_date
, asset_call_number_history.record
, asset_call_number_history.owning_lib
, asset_call_number_history.label
, asset_call_number_history.deleted 
FROM auditor.asset_call_number_history;

 

Permissions which apply to auditor.asset_call_number_lifecycle
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


Table: auditor.asset_copy_history

auditor.asset_copy_history Structure
F-Key Name Type Description
audit_time timestamp with time zone NOT NULL
audit_action text NOT NULL
id bigint NOT NULL
circ_lib integer NOT NULL
creator bigint NOT NULL
call_number bigint NOT NULL
editor bigint NOT NULL
create_date timestamp with time zone
edit_date timestamp with time zone
copy_number integer
status integer NOT NULL
location integer NOT NULL
loan_duration integer NOT NULL
fine_level integer NOT NULL
age_protect integer
circulate boolean NOT NULL
deposit boolean NOT NULL
ref boolean NOT NULL
holdable boolean NOT NULL
deposit_amount numeric(6,2) NOT NULL
price numeric(8,2) NOT NULL
barcode text NOT NULL
circ_modifier text
circ_as_type text
dummy_title text
dummy_author text
alert_message text
opac_visible boolean NOT NULL
deleted boolean NOT NULL

 

Permissions which apply to auditor.asset_copy_history
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


View: auditor.asset_copy_lifecycle

auditor.asset_copy_lifecycle Structure
F-Key Name Type Description
audit_time timestamp with time zone
audit_action text
id bigint
circ_lib integer
creator bigint
call_number bigint
editor bigint
create_date timestamp with time zone
edit_date timestamp with time zone
copy_number integer
status integer
location integer
loan_duration integer
fine_level integer
age_protect integer
circulate boolean
deposit boolean
ref boolean
holdable boolean
deposit_amount numeric
price numeric
barcode text
circ_modifier text
circ_as_type text
dummy_title text
dummy_author text
alert_message text
opac_visible boolean
deleted boolean
SELECT now
() AS audit_time
,'C' AS audit_action
,"copy".id
,"copy".circ_lib
,"copy".creator
,"copy".call_number
,"copy".editor
,"copy".create_date
,"copy".edit_date
,"copy".copy_number
,"copy".status
,"copy"."location"
,"copy".loan_duration
,"copy".fine_level
,"copy".age_protect
,"copy".circulate
,"copy".deposit
,"copy".ref
,"copy".holdable
,"copy".deposit_amount
,"copy".price
,"copy".barcode
,"copy".circ_modifier
,"copy".circ_as_type
,"copy".dummy_title
,"copy".dummy_author
,"copy".alert_message
,"copy".opac_visible
,"copy".deleted 
FROM asset."copy"
UNION ALLSELECT asset_copy_history.audit_time
, asset_copy_history.audit_action
, asset_copy_history.id
, asset_copy_history.circ_lib
, asset_copy_history.creator
, asset_copy_history.call_number
, asset_copy_history.editor
, asset_copy_history.create_date
, asset_copy_history.edit_date
, asset_copy_history.copy_number
, asset_copy_history.status
, asset_copy_history."location"
, asset_copy_history.loan_duration
, asset_copy_history.fine_level
, asset_copy_history.age_protect
, asset_copy_history.circulate
, asset_copy_history.deposit
, asset_copy_history.ref
, asset_copy_history.holdable
, asset_copy_history.deposit_amount
, asset_copy_history.price
, asset_copy_history.barcode
, asset_copy_history.circ_modifier
, asset_copy_history.circ_as_type
, asset_copy_history.dummy_title
, asset_copy_history.dummy_author
, asset_copy_history.alert_message
, asset_copy_history.opac_visible
, asset_copy_history.deleted 
FROM auditor.asset_copy_history;

 

Permissions which apply to auditor.asset_copy_lifecycle
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


Table: auditor.biblio_record_entry_history

auditor.biblio_record_entry_history Structure
F-Key Name Type Description
audit_time timestamp with time zone NOT NULL
audit_action text NOT NULL
id bigint NOT NULL
creator integer NOT NULL
editor integer NOT NULL
source integer
quality integer
create_date timestamp with time zone NOT NULL
edit_date timestamp with time zone NOT NULL
active boolean NOT NULL
deleted boolean NOT NULL
fingerprint text
tcn_source text NOT NULL
tcn_value text NOT NULL
marc text NOT NULL
last_xact_id text NOT NULL

 

Permissions which apply to auditor.biblio_record_entry_history
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


View: auditor.biblio_record_entry_lifecycle

auditor.biblio_record_entry_lifecycle Structure
F-Key Name Type Description
audit_time timestamp with time zone
audit_action text
id bigint
creator integer
editor integer
source integer
quality integer
create_date timestamp with time zone
edit_date timestamp with time zone
active boolean
deleted boolean
fingerprint text
tcn_source text
tcn_value text
marc text
last_xact_id text
SELECT now
() AS audit_time
,'C' AS audit_action
, record_entry.id
, record_entry.creator
, record_entry.editor
, record_entry.source
, record_entry.quality
, record_entry.create_date
, record_entry.edit_date
, record_entry.active
, record_entry.deleted
, record_entry.fingerprint
, record_entry.tcn_source
, record_entry.tcn_value
, record_entry.marc
, record_entry.last_xact_id 
FROM biblio.record_entry 
UNION ALLSELECT biblio_record_entry_history.audit_time
, biblio_record_entry_history.audit_action
, biblio_record_entry_history.id
, biblio_record_entry_history.creator
, biblio_record_entry_history.editor
, biblio_record_entry_history.source
, biblio_record_entry_history.quality
, biblio_record_entry_history.create_date
, biblio_record_entry_history.edit_date
, biblio_record_entry_history.active
, biblio_record_entry_history.deleted
, biblio_record_entry_history.fingerprint
, biblio_record_entry_history.tcn_source
, biblio_record_entry_history.tcn_value
, biblio_record_entry_history.marc
, biblio_record_entry_history.last_xact_id 
FROM auditor.biblio_record_entry_history;

 

Permissions which apply to auditor.biblio_record_entry_lifecycle
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema auditor


Function: auditor.audit_actor_org_unit_func( )

Returns: "trigger"

Language: PLPGSQL

			BEGIN
				INSERT INTO auditor.actor_org_unit_history
					SELECT now(), SUBSTR(TG_OP,1,1), OLD.*;
				RETURN NULL;
			END;
			

Function: auditor.audit_actor_usr_address_func( )

Returns: "trigger"

Language: PLPGSQL

			BEGIN
				INSERT INTO auditor.actor_usr_address_history
					SELECT now(), SUBSTR(TG_OP,1,1), OLD.*;
				RETURN NULL;
			END;
			

Function: auditor.audit_actor_usr_func( )

Returns: "trigger"

Language: PLPGSQL

			BEGIN
				INSERT INTO auditor.actor_usr_history
					SELECT now(), SUBSTR(TG_OP,1,1), OLD.*;
				RETURN NULL;
			END;
			

Function: auditor.audit_asset_call_number_func( )

Returns: "trigger"

Language: PLPGSQL

			BEGIN
				INSERT INTO auditor.asset_call_number_history
					SELECT now(), SUBSTR(TG_OP,1,1), OLD.*;
				RETURN NULL;
			END;
			

Function: auditor.audit_asset_copy_func( )

Returns: "trigger"

Language: PLPGSQL

			BEGIN
				INSERT INTO auditor.asset_copy_history
					SELECT now(), SUBSTR(TG_OP,1,1), OLD.*;
				RETURN NULL;
			END;
			

Function: auditor.audit_biblio_record_entry_func( )

Returns: "trigger"

Language: PLPGSQL

			BEGIN
				INSERT INTO auditor.biblio_record_entry_history
					SELECT now(), SUBSTR(TG_OP,1,1), OLD.*;
				RETURN NULL;
			END;
			

Function: auditor.create_auditor( sch text, tbl text )

Returns: boolean

Language: PLPGSQL

BEGIN
	EXECUTE $$
			CREATE TABLE auditor.$$ || sch || $$_$$ || tbl || $$_history (
				audit_time	TIMESTAMP WITH TIME ZONE	NOT NULL,
				audit_action	TEXT				NOT NULL,
				LIKE $$ || sch || $$.$$ || tbl || $$
			);
	$$;

	EXECUTE $$
			CREATE FUNCTION auditor.audit_$$ || sch || $$_$$ || tbl || $$_func ()
			RETURNS TRIGGER AS $func$
			BEGIN
				INSERT INTO auditor.$$ || sch || $$_$$ || tbl || $$_history
					SELECT now(), SUBSTR(TG_OP,1,1), OLD.*;
				RETURN NULL;
			END;
			$func$ LANGUAGE 'plpgsql';
	$$;

	EXECUTE $$
			CREATE TRIGGER audit_$$ || sch || $$_$$ || tbl || $$_update_trigger
				AFTER UPDATE OR DELETE ON $$ || sch || $$.$$ || tbl || $$ FOR EACH ROW
				EXECUTE PROCEDURE auditor.audit_$$ || sch || $$_$$ || tbl || $$_func ();
	$$;

	EXECUTE $$
			CREATE VIEW auditor.$$ || sch || $$_$$ || tbl || $$_lifecycle AS
				SELECT	now() as audit_time, 'C' as audit_action, *
				  FROM	$$ || sch || $$.$$ || tbl || $$
				  	UNION ALL
				SELECT	*
				  FROM	auditor.$$ || sch || $$_$$ || tbl || $$_history;
	$$;
	RETURN TRUE;
END;

Schema authority


Table: authority.full_rec

authority.full_rec Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
record bigint NOT NULL
tag character(3) NOT NULL
ind1 text
ind2 text
subfield text
value text NOT NULL
index_vector tsvector NOT NULL
a_fr_tag_sf_idx tag, subfield authority_full_rec_index_vector_idx index_vector authority_full_rec_record_idx record authority_full_rec_value_idx value

 

Permissions which apply to authority.full_rec
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema authority


Table: authority.rec_descriptor

authority.rec_descriptor Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
record bigint
record_status text
char_encoding text
authority_rec_descriptor_record_idx record

 

Permissions which apply to authority.rec_descriptor
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema authority


Table: authority.record_entry

authority.record_entry Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
arn_source text NOT NULL DEFAULT 'AUTOGEN'::text
arn_value text NOT NULL
creator integer NOT NULL DEFAULT 1
editor integer NOT NULL DEFAULT 1
create_date timestamp with time zone NOT NULL DEFAULT now()
edit_date timestamp with time zone NOT NULL DEFAULT now()
active boolean NOT NULL DEFAULT true
deleted boolean NOT NULL DEFAULT false
source integer
marc text NOT NULL
last_xact_id text NOT NULL

Tables referencing this one via Foreign Key Constraints:

authority_record_entry_creator_idx creator authority_record_entry_editor_idx editor

 

Permissions which apply to authority.record_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema authority


Table: authority.record_note

authority.record_note Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
authority.record_entry.id record bigint NOT NULL
value text NOT NULL
creator integer NOT NULL DEFAULT 1
editor integer NOT NULL DEFAULT 1
create_date timestamp with time zone NOT NULL DEFAULT now()
edit_date timestamp with time zone NOT NULL DEFAULT now()
authority_record_note_creator_idx creator authority_record_note_editor_idx editor authority_record_note_record_idx record

 

Permissions which apply to authority.record_note
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema authority


View: authority.tracing_links

authority.tracing_links Structure
F-Key Name Type Description
record bigint
main_id bigint
main_tag character(3)
main_value text
relationship text
use_restriction text
deprecation text
display_restriction text
link_id bigint
link_tag character(3)
link_value text
SELECT main.record
, main.id AS main_id
, main.tag AS main_tag
, main.value AS main_value
, substr
(link.value
     , 1
     , 1
) AS relationship
, substr
(link.value
     , 2
     , 1
) AS use_restriction
, substr
(link.value
     , 3
     , 1
) AS deprecation
, substr
(link.value
     , 4
     , 1
) AS display_restriction
, link_value.id AS link_id
, link_value.tag AS link_tag
, link_value.value AS link_value 
FROM (
     (authority.full_rec main 
        JOIN authority.full_rec link 
          ON (
                 (
                       (
                             (link.record = main.record)
                           AND (
                                   (
                                         (link.tag)::text = 
                                         (
                                               (
                                                     (main.tag)::integer + 400
                                               )
                                         )::text
                                   )
                                  OR (
                                         (link.tag)::text = 
                                         (
                                               (
                                                     (main.tag)::integer + 300
                                               )
                                         )::text
                                   )
                             )
                       )
                     AND (link.subfield = 'w'::text)
                 )
           )
     )
  JOIN authority.full_rec link_value 
    ON (
           (
                 (
                       (link_value.record = main.record)
                     AND (link_value.tag = link.tag)
                 )
               AND (link_value.subfield = 'a'::text)
           )
     )
)
WHERE (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (
                                                     (
                                                           (
                                                                 (main.tag = '100'::bpchar)
                                                                OR (main.tag = '110'::bpchar)
                                                           )
                                                          OR (main.tag = '111'::bpchar)
                                                     )
                                                    OR (main.tag = '130'::bpchar)
                                               )
                                              OR (main.tag = '150'::bpchar)
                                         )
                                        OR (main.tag = '151'::bpchar)
                                   )
                                  OR (main.tag = '155'::bpchar)
                             )
                            OR (main.tag = '180'::bpchar)
                       )
                      OR (main.tag = '181'::bpchar)
                 )
                OR (main.tag = '182'::bpchar)
           )
          OR (main.tag = '185'::bpchar)
     )
   AND (main.subfield = 'a'::text)
);

 

Permissions which apply to authority.tracing_links
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema authority


Schema biblio


Table: biblio.record_entry

biblio.record_entry Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.usr.id creator integer NOT NULL DEFAULT 1
actor.usr.id editor integer NOT NULL DEFAULT 1
source integer
quality integer
create_date timestamp with time zone NOT NULL DEFAULT now()
edit_date timestamp with time zone NOT NULL DEFAULT now()
active boolean NOT NULL DEFAULT true
deleted boolean NOT NULL DEFAULT false
fingerprint text
tcn_source text NOT NULL DEFAULT 'AUTOGEN'::text
tcn_value text NOT NULL DEFAULT next_autogen_tcn_value()
marc text NOT NULL
last_xact_id text NOT NULL

Tables referencing this one via Foreign Key Constraints:

bib_rec_create_date_idx create_date bib_rec_edit_date_idx edit_date biblio_record_entry_creator_idx creator biblio_record_entry_editor_idx editor biblio_record_entry_fp_idx fingerprint

 

Permissions which apply to biblio.record_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema biblio


Table: biblio.record_note

biblio.record_note Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
biblio.record_entry.id record bigint NOT NULL
value text NOT NULL
actor.usr.id creator integer NOT NULL DEFAULT 1
actor.usr.id editor integer NOT NULL DEFAULT 1
pub boolean NOT NULL DEFAULT false
create_date timestamp with time zone NOT NULL DEFAULT now()
edit_date timestamp with time zone NOT NULL DEFAULT now()
biblio_record_note_creator_idx creator biblio_record_note_editor_idx editor biblio_record_note_record_idx record

 

Permissions which apply to biblio.record_note
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema biblio


Function: biblio.next_autogen_tcn_value( )

Returns: text

Language: PLPGSQL

    BEGIN RETURN 'AUTOGENERATED_' || nextval('biblio.autogen_tcn_value_seq'::TEXT); END;

Schema config

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander * * The config schema holds static configuration data for the * Open-ILS installation. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */


Table: config.audience_map

config.audience_map Structure
F-Key Name Type Description
code text PRIMARY KEY
value text NOT NULL
description text

 

Permissions which apply to config.audience_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.bib_source

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Valid sources of MARC records * * This is table is used to set up the relative "quality" of each * MARC source, such as OCLC. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.bib_source Structure
F-Key Name Type Description
id serial PRIMARY KEY
quality integer
source text UNIQUE NOT NULL
transcendant boolean NOT NULL DEFAULT false

 

config.bib_source Constraints
Name Constraint
bib_source_quality_check CHECK (((quality >= 0) AND (quality <= 100)))

 

Permissions which apply to config.bib_source
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.copy_status

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Copy Statuses * * The available copy statuses, and whether a copy in that * status is available for hold request capture. 0 (zero) is * the only special number in this set, meaning that the item * is available for imediate checkout, and is counted as available * in the OPAC. * * Statuses with an ID below 100 are not removable, and have special * meaning in the code. Do not change them except to translate the * textual name. * * You may add and remove statuses above 100, and these can be used * to remove items from normal circulation without affecting the rest * of the copy's values or it's location. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.copy_status Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL
holdable boolean NOT NULL DEFAULT false

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to config.copy_status
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.identification_type

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Types of valid patron identification. * * Each patron must display at least one valid form of identification * in order to get a library card. This table lists those forms. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.identification_type Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to config.identification_type
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.item_form_map

config.item_form_map Structure
F-Key Name Type Description
code text PRIMARY KEY
value text NOT NULL

 

Permissions which apply to config.item_form_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.item_type_map

config.item_type_map Structure
F-Key Name Type Description
code text PRIMARY KEY
value text NOT NULL

 

Permissions which apply to config.item_type_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.language_map

config.language_map Structure
F-Key Name Type Description
code text PRIMARY KEY
value text NOT NULL

 

Permissions which apply to config.language_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.lit_form_map

config.lit_form_map Structure
F-Key Name Type Description
code text PRIMARY KEY
value text NOT NULL
description text

 

Permissions which apply to config.lit_form_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.metabib_field

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * XPath used for WoRMing * * This table contains the XPath used to chop up MODS into it's * indexable parts. Each XPath entry is named and assigned to * a "class" of either title, subject, author, keyword or series. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.metabib_field Structure
F-Key Name Type Description
id serial PRIMARY KEY
field_class text NOT NULL
name text NOT NULL
xpath text NOT NULL
weight integer NOT NULL DEFAULT 1
format text NOT NULL DEFAULT 'mods'::text
search_field boolean NOT NULL DEFAULT true
facet_field boolean NOT NULL DEFAULT false

 

config.metabib_field Constraints
Name Constraint
metabib_field_field_class_check CHECK ((((((lower(field_class) = 'title'::text) OR (lower(field_class) = 'author'::text)) OR (lower(field_class) = 'subject'::text)) OR (lower(field_class) = 'keyword'::text)) OR (lower(field_class) = 'series'::text)))

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to config.metabib_field
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.net_access_level

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Patron Network Access level * * This will be used to inform the in-library firewall of how much * internet access the using patron should be allowed. * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.net_access_level Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to config.net_access_level
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.non_cataloged_type

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Types of valid non-cataloged items. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.non_cataloged_type Structure
F-Key Name Type Description
id serial PRIMARY KEY
owning_lib integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
circ_duration interval NOT NULL DEFAULT '14 days'::interval
in_house boolean NOT NULL DEFAULT false

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to config.non_cataloged_type
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.rule_age_hold_protect

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Hold Item Age Protection rules * * A hold request can only capture new(ish) items when they are * within a particular proximity of the home_ou of the requesting * user. The proximity ('prox' column) is calculated by counting * the number of tree edges beween the user's home_ou and the owning_lib * of the copy that could fulfill the hold. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.rule_age_hold_protect Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL
age interval NOT NULL
prox integer NOT NULL

 

config.rule_age_hold_protect Constraints
Name Constraint
rule_age_hold_protect_name_check CHECK ((name ~ E'^\\w+$'::text))

 

Permissions which apply to config.rule_age_hold_protect
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.rule_circ_duration

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Circulation Duration rules * * Each circulation is given a duration based on one of these rules. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.rule_circ_duration Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL
extended interval NOT NULL
normal interval NOT NULL
shrt interval NOT NULL
max_renewals integer NOT NULL

 

config.rule_circ_duration Constraints
Name Constraint
rule_circ_duration_name_check CHECK ((name ~ E'^\\w+$'::text))

 

Permissions which apply to config.rule_circ_duration
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.rule_max_fine

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Circulation Max Fine rules * * Each circulation is given a maximum fine based on one of * these rules. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.rule_max_fine Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL
amount numeric(6,2) NOT NULL
is_percent boolean NOT NULL DEFAULT false

 

config.rule_max_fine Constraints
Name Constraint
rule_max_fine_name_check CHECK ((name ~ E'^\\w+$'::text))

 

Permissions which apply to config.rule_max_fine
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.rule_recuring_fine

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Circulation Recuring Fine rules * * Each circulation is given a recuring fine amount based on one of * these rules. The recurance_interval should not be any shorter * than the interval between runs of the fine_processor.pl script * (which is run from CRON), or you could miss fines. * * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.rule_recuring_fine Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL
high numeric(6,2) NOT NULL
normal numeric(6,2) NOT NULL
low numeric(6,2) NOT NULL
recurance_interval interval NOT NULL DEFAULT '1 day'::interval

 

config.rule_recuring_fine Constraints
Name Constraint
rule_recuring_fine_name_check CHECK ((name ~ E'^\\w+$'::text))

 

Permissions which apply to config.rule_recuring_fine
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.standing

/* * Copyright (C) 2005 Georgia Public Library Service * Mike Rylander <mrylander@gmail.com> * * Patron Standings * * This table contains the values that can be applied to a patron * by a staff member. These values should not be changed, other * that for translation, as the ID column is currently a "magic * number" in the source. :( * * **** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */

config.standing Structure
F-Key Name Type Description
id serial PRIMARY KEY
value text UNIQUE NOT NULL

 

Permissions which apply to config.standing
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema config


Table: config.xml_transform

config.xml_transform Structure
F-Key Name Type Description
name text PRIMARY KEY
namespace_uri text UNIQUE NOT NULL
prefix text NOT NULL
xslt text NOT NULL

Index - Schema config


Schema container


Table: container.biblio_record_entry_bucket

container.biblio_record_entry_bucket Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id owner integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
btype text UNIQUE#1 NOT NULL DEFAULT 'misc'::text
pub boolean NOT NULL DEFAULT false
create_time timestamp with time zone NOT NULL DEFAULT now()

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to container.biblio_record_entry_bucket
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Table: container.biblio_record_entry_bucket_item

container.biblio_record_entry_bucket_item Structure
F-Key Name Type Description
id serial PRIMARY KEY
container.biblio_record_entry_bucket.id bucket integer NOT NULL
biblio.record_entry.id target_biblio_record_entry integer NOT NULL
create_time timestamp with time zone NOT NULL DEFAULT now()

 

Permissions which apply to container.biblio_record_entry_bucket_item
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Table: container.call_number_bucket

container.call_number_bucket Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id owner integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
btype text UNIQUE#1 NOT NULL DEFAULT 'misc'::text
pub boolean NOT NULL DEFAULT false
create_time timestamp with time zone NOT NULL DEFAULT now()

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to container.call_number_bucket
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Table: container.call_number_bucket_item

container.call_number_bucket_item Structure
F-Key Name Type Description
id serial PRIMARY KEY
container.call_number_bucket.id bucket integer NOT NULL
asset.call_number.id target_call_number integer NOT NULL
create_time timestamp with time zone NOT NULL DEFAULT now()

 

Permissions which apply to container.call_number_bucket_item
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Table: container.copy_bucket

container.copy_bucket Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id owner integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
btype text UNIQUE#1 NOT NULL DEFAULT 'misc'::text
pub boolean NOT NULL DEFAULT false
create_time timestamp with time zone NOT NULL DEFAULT now()

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to container.copy_bucket
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Table: container.copy_bucket_item

container.copy_bucket_item Structure
F-Key Name Type Description
id serial PRIMARY KEY
container.copy_bucket.id bucket integer NOT NULL
asset.copy.id target_copy integer NOT NULL
create_time timestamp with time zone NOT NULL DEFAULT now()

 

Permissions which apply to container.copy_bucket_item
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Table: container.user_bucket

container.user_bucket Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id owner integer UNIQUE#1 NOT NULL
name text UNIQUE#1 NOT NULL
btype text UNIQUE#1 NOT NULL DEFAULT 'misc'::text
pub boolean NOT NULL DEFAULT false
create_time timestamp with time zone NOT NULL DEFAULT now()

Tables referencing this one via Foreign Key Constraints:

 

Permissions which apply to container.user_bucket
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Table: container.user_bucket_item

container.user_bucket_item Structure
F-Key Name Type Description
id serial PRIMARY KEY
container.user_bucket.id bucket integer NOT NULL
actor.usr.id target_user integer NOT NULL
create_time timestamp with time zone NOT NULL DEFAULT now()

 

Permissions which apply to container.user_bucket_item
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema container


Schema extend_reporter


View: extend_reporter.full_circ_count

extend_reporter.full_circ_count Structure
F-Key Name Type Description
id bigint
circ_count bigint
SELECT cp.id
, (COALESCE
     (sum
           (c.circ_count)
           , (0)::bigint
     ) + COALESCE
     (count
           (circ.id)
           , (0)::bigint
     )
) AS circ_count 
FROM (
     (asset."copy" cp 
   LEFT JOIN extend_reporter.legacy_circ_count c 
       USING (id)
     )
LEFT JOIN"action".circulation circ 
    ON (
           (circ.target_copy = c.id)
     )
)
GROUP BY cp.id;

Index - Schema extend_reporter


Table: extend_reporter.legacy_circ_count

extend_reporter.legacy_circ_count Structure
F-Key Name Type Description
asset.copy.id id bigserial PRIMARY KEY
circ_count integer NOT NULL

Index - Schema extend_reporter


Schema metabib


Table: metabib.author_field_entry

metabib.author_field_entry Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
biblio.record_entry.id source bigint NOT NULL
config.metabib_field.id field integer NOT NULL
value text NOT NULL
index_vector tsvector NOT NULL
author_field_entry_source_idx source metabib_author_field_entry_index_vector_idx index_vector

 

Permissions which apply to metabib.author_field_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.full_rec

metabib.full_rec Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
biblio.record_entry.id record bigint NOT NULL
tag character(3) NOT NULL
ind1 text
ind2 text
subfield text
value text NOT NULL
index_vector tsvector NOT NULL
metabib_full_rec_index_vector_idx index_vector metabib_full_rec_record_idx record metabib_full_rec_tac_subfield_idx tag, subfield metabib_full_rec_value_idx value

 

Permissions which apply to metabib.full_rec
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.keyword_field_entry

metabib.keyword_field_entry Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
biblio.record_entry.id source bigint NOT NULL
config.metabib_field.id field integer NOT NULL
value text NOT NULL
index_vector tsvector NOT NULL
keyword_field_entry_source_idx source metabib_keyword_field_entry_index_vector_idx index_vector

 

Permissions which apply to metabib.keyword_field_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.metarecord

metabib.metarecord Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
fingerprint text NOT NULL
biblio.record_entry.id master_record bigint
mods text

Tables referencing this one via Foreign Key Constraints:

metabib_metarecord_fingerprint_idx fingerprint metabib_metarecord_master_record_idx master_record

 

Permissions which apply to metabib.metarecord
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.metarecord_source_map

metabib.metarecord_source_map Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
metabib.metarecord.id metarecord bigint NOT NULL
biblio.record_entry.id source bigint NOT NULL
metabib_metarecord_source_map_metarecord_idx metarecord metabib_metarecord_source_map_source_record_idx source

 

Permissions which apply to metabib.metarecord_source_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.rec_descriptor

metabib.rec_descriptor Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
biblio.record_entry.id record bigint
item_type text
item_form text
bib_level text
control_type text
char_encoding text
enc_level text
audience text
lit_form text
type_mat text
cat_form text
pub_status text
item_lang text
vr_format text
metabib_rec_descriptor_record_idx record

 

Permissions which apply to metabib.rec_descriptor
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.series_field_entry

metabib.series_field_entry Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
source bigint NOT NULL
field integer NOT NULL
value text NOT NULL
index_vector tsvector NOT NULL
metabib_series_field_entry_index_vector_idx index_vector series_field_entry_source_idx source

 

Permissions which apply to metabib.series_field_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.subject_field_entry

metabib.subject_field_entry Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
biblio.record_entry.id source bigint NOT NULL
config.metabib_field.id field integer NOT NULL
value text NOT NULL
index_vector tsvector NOT NULL
metabib_subject_field_entry_index_vector_idx index_vector subject_field_entry_source_idx source

 

Permissions which apply to metabib.subject_field_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Table: metabib.title_field_entry

metabib.title_field_entry Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
biblio.record_entry.id source bigint NOT NULL
config.metabib_field.id field integer NOT NULL
value text NOT NULL
index_vector tsvector NOT NULL
metabib_title_field_entry_index_vector_idx index_vector title_field_entry_source_idx source

 

Permissions which apply to metabib.title_field_entry
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema metabib


Schema money


Table: money.billable_xact

money.billable_xact Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.usr.id usr integer NOT NULL
xact_start timestamp with time zone NOT NULL DEFAULT now()
xact_finish timestamp with time zone
m_b_x_open_xacts_idx usr

 

Permissions which apply to money.billable_xact
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.billable_xact_summary

money.billable_xact_summary Structure
F-Key Name Type Description
id bigint
usr integer
xact_start timestamp with time zone
xact_finish timestamp with time zone
total_paid numeric
last_payment_ts timestamp with time zone
last_payment_note text
last_payment_type name
total_owed numeric
last_billing_ts timestamp with time zone
last_billing_note text
last_billing_type text
balance_owed numeric
xact_type name
SELECT xact.id
, xact.usr
, xact.xact_start
, xact.xact_finish
, credit.amount AS total_paid
, credit.payment_ts AS last_payment_ts
, credit.note AS last_payment_note
, credit.payment_type AS last_payment_type
, debit.amount AS total_owed
, debit.billing_ts AS last_billing_ts
, debit.note AS last_billing_note
, debit.billing_type AS last_billing_type
, (COALESCE
     (debit.amount
           , (0)::numeric
     ) - COALESCE
     (credit.amount
           , (0)::numeric
     )
) AS balance_owed
, p.relname AS xact_type 
FROM (
     (
           (money.billable_xact xact 
              JOIN pg_class p 
                ON (
                       (xact.tableoid = p.oid)
                 )
           )
   LEFT JOIN (
            SELECT billing.xact
                 , sum
                 (billing.amount) AS amount
                 , max
                 (billing.billing_ts) AS billing_ts
                 ,"last"
                 (billing.note) AS note
                 ,"last"
                 (billing.billing_type) AS billing_type 
              FROM money.billing 
             WHERE (billing.voided IS FALSE)
          GROUP BY billing.xact
           ) debit 
          ON (
                 (xact.id = debit.xact)
           )
     )
LEFT JOIN (
      SELECT payment_view.xact
           , sum
           (payment_view.amount) AS amount
           , max
           (payment_view.payment_ts) AS payment_ts
           ,"last"
           (payment_view.note) AS note
           ,"last"
           (payment_view.payment_type) AS payment_type 
        FROM money.payment_view 
       WHERE (payment_view.voided IS FALSE)
    GROUP BY payment_view.xact
     ) credit 
    ON (
           (xact.id = credit.xact)
     )
)
ORDER BY debit.billing_ts
, credit.payment_ts;

 

Permissions which apply to money.billable_xact_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.billable_xact_with_void_summary

money.billable_xact_with_void_summary Structure
F-Key Name Type Description
id bigint
usr integer
xact_start timestamp with time zone
xact_finish timestamp with time zone
total_paid numeric
last_payment_ts timestamp with time zone
last_payment_note text
last_payment_type name
total_owed numeric
last_billing_ts timestamp with time zone
last_billing_note text
last_billing_type text
balance_owed numeric
xact_type name
SELECT xact.id
, xact.usr
, xact.xact_start
, xact.xact_finish
, credit.amount AS total_paid
, credit.payment_ts AS last_payment_ts
, credit.note AS last_payment_note
, credit.payment_type AS last_payment_type
, debit.amount AS total_owed
, debit.billing_ts AS last_billing_ts
, debit.note AS last_billing_note
, debit.billing_type AS last_billing_type
, (COALESCE
     (debit.amount
           , (0)::numeric
     ) - COALESCE
     (credit.amount
           , (0)::numeric
     )
) AS balance_owed
, p.relname AS xact_type 
FROM (
     (
           (money.billable_xact xact 
              JOIN pg_class p 
                ON (
                       (xact.tableoid = p.oid)
                 )
           )
   LEFT JOIN (
            SELECT billing.xact
                 , sum
                 (billing.amount) AS amount
                 , max
                 (billing.billing_ts) AS billing_ts
                 ,"last"
                 (billing.note) AS note
                 ,"last"
                 (billing.billing_type) AS billing_type 
              FROM money.billing 
          GROUP BY billing.xact
           ) debit 
          ON (
                 (xact.id = debit.xact)
           )
     )
LEFT JOIN (
      SELECT payment_view.xact
           , sum
           (payment_view.amount) AS amount
           , max
           (payment_view.payment_ts) AS payment_ts
           ,"last"
           (payment_view.note) AS note
           ,"last"
           (payment_view.payment_type) AS payment_type 
        FROM money.payment_view 
    GROUP BY payment_view.xact
     ) credit 
    ON (
           (xact.id = credit.xact)
     )
)
ORDER BY debit.billing_ts
, credit.payment_ts;

 

Permissions which apply to money.billable_xact_with_void_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.billing

money.billing Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
xact bigint NOT NULL
billing_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
voider integer
void_time timestamp with time zone
amount numeric(6,2) NOT NULL
billing_type text NOT NULL
note text
m_b_time_idx billing_ts m_b_xact_idx xact

 

Permissions which apply to money.billing
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.bnm_desk_payment

money.bnm_desk_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL
actor.workstation.id cash_drawer integer

Table money.bnm_desk_payment Inherits bnm_payment,

 

Permissions which apply to money.bnm_desk_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.bnm_payment

money.bnm_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL

Table money.bnm_payment Inherits payment,

 

Permissions which apply to money.bnm_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.bnm_payment_view

money.bnm_payment_view Structure
F-Key Name Type Description
id bigint
xact bigint
payment_ts timestamp with time zone
voided boolean
amount numeric(6,2)
note text
amount_collected numeric(6,2)
accepting_usr integer
payment_type name
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, p.amount_collected
, p.accepting_usr
, c.relname AS payment_type 
FROM (money.bnm_payment p 
  JOIN pg_class c 
    ON (
           (p.tableoid = c.oid)
     )
);

 

Permissions which apply to money.bnm_payment_view
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.cash_payment

money.cash_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL
cash_drawer integer

Table money.cash_payment Inherits bnm_desk_payment,

money_cash_id_idx id money_cash_payment_accepting_usr_idx accepting_usr money_cash_payment_cash_drawer_idx cash_drawer money_cash_payment_ts_idx payment_ts money_cash_payment_xact_idx xact

 

Permissions which apply to money.cash_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.cashdrawer_payment_view

money.cashdrawer_payment_view Structure
F-Key Name Type Description
org_unit integer
cashdrawer integer
payment_type name
payment_ts timestamp with time zone
amount numeric(6,2)
voided boolean
note text
SELECT ou.id AS org_unit
, ws.id AS cashdrawer
, t.payment_type
, p.payment_ts
, p.amount
, p.voided
, p.note 
FROM (
     (
           (actor.org_unit ou 
              JOIN actor.workstation ws 
                ON (
                       (ou.id = ws.owning_lib)
                 )
           )
   LEFT JOIN money.bnm_desk_payment p 
          ON (
                 (ws.id = p.cash_drawer)
           )
     )
LEFT JOIN money.payment_view t 
    ON (
           (p.id = t.id)
     )
);

 

Permissions which apply to money.cashdrawer_payment_view
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.check_payment

money.check_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL
cash_drawer integer
check_number text NOT NULL

Table money.check_payment Inherits bnm_desk_payment,

money_check_id_idx id money_check_payment_accepting_usr_idx accepting_usr money_check_payment_cash_drawer_idx cash_drawer money_check_payment_ts_idx payment_ts money_check_payment_xact_idx xact

 

Permissions which apply to money.check_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.collections_tracker

money.collections_tracker Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
actor.usr.id usr integer NOT NULL
actor.usr.id collector integer NOT NULL
actor.org_unit.id location integer NOT NULL
enter_time timestamp with time zone

 

Permissions which apply to money.collections_tracker
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.credit_card_payment

money.credit_card_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL
cash_drawer integer
cc_type text NOT NULL
cc_number text NOT NULL
expire_month integer NOT NULL
expire_year integer NOT NULL
approval_code text NOT NULL

Table money.credit_card_payment Inherits bnm_desk_payment,

money_credit_card_id_idx id money_credit_card_payment_accepting_usr_idx accepting_usr money_credit_card_payment_cash_drawer_idx cash_drawer money_credit_card_payment_ts_idx payment_ts money_credit_card_payment_xact_idx xact

 

Permissions which apply to money.credit_card_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.credit_payment

money.credit_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL

Table money.credit_payment Inherits bnm_payment,

money_credit_id_idx id money_credit_payment_accepting_usr_idx accepting_usr money_credit_payment_payment_ts_idx payment_ts money_credit_payment_xact_idx xact

 

Permissions which apply to money.credit_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.desk_payment_view

money.desk_payment_view Structure
F-Key Name Type Description
id bigint
xact bigint
payment_ts timestamp with time zone
voided boolean
amount numeric(6,2)
note text
amount_collected numeric(6,2)
accepting_usr integer
cash_drawer integer
payment_type name
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, p.amount_collected
, p.accepting_usr
, p.cash_drawer
, c.relname AS payment_type 
FROM (money.bnm_desk_payment p 
  JOIN pg_class c 
    ON (
           (p.tableoid = c.oid)
     )
);

 

Permissions which apply to money.desk_payment_view
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.forgive_payment

money.forgive_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL

Table money.forgive_payment Inherits bnm_payment,

money_forgive_id_idx id money_forgive_payment_accepting_usr_idx accepting_usr money_forgive_payment_payment_ts_idx payment_ts money_forgive_payment_xact_idx xact

 

Permissions which apply to money.forgive_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.goods_payment

money.goods_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('money.payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL

Table money.goods_payment Inherits bnm_payment,

money_goods_id_idx id money_goods_payment_accepting_usr_idx accepting_usr money_goods_payment_payment_ts_idx payment_ts money_goods_payment_xact_idx xact

 

Permissions which apply to money.goods_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.grocery

money.grocery Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('billable_xact_id_seq'::regclass)
usr integer NOT NULL
xact_start timestamp with time zone NOT NULL DEFAULT now()
xact_finish timestamp with time zone
billing_location integer NOT NULL
note text

Table money.grocery Inherits billable_xact,

groc_open_date_idx xact_start) WHERE (xact_finish IS NULL m_g_usr_idx usr

 

Permissions which apply to money.grocery
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.live_billing_total

money.live_billing_total Structure
F-Key Name Type Description
xact bigint
amount numeric
last_billing_ts timestamp with time zone
last_note text
SELECT billing.xact
, sum
(billing.amount) AS amount
, max
(billing.billing_ts) AS last_billing_ts
,"last"
(billing.note) AS last_note 
FROM money.billing 
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact;

 

Permissions which apply to money.live_billing_total
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.live_payment_total

money.live_payment_total Structure
F-Key Name Type Description
xact bigint
amount numeric
last_payment_ts timestamp with time zone
last_note text
SELECT payment.xact
, sum
(payment.amount) AS amount
, max
(payment.payment_ts) AS last_payment_ts
,"last"
(payment.note) AS last_note 
FROM money.payment 
WHERE (payment.voided IS FALSE)
GROUP BY payment.xact;

 

Permissions which apply to money.live_payment_total
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.non_drawer_payment_view

money.non_drawer_payment_view Structure
F-Key Name Type Description
id bigint
xact bigint
payment_ts timestamp with time zone
voided boolean
amount numeric(6,2)
note text
amount_collected numeric(6,2)
accepting_usr integer
payment_type name
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, p.amount_collected
, p.accepting_usr
, c.relname AS payment_type 
FROM (money.bnm_payment p 
  JOIN pg_class c 
    ON (
           (p.tableoid = c.oid)
     )
)
WHERE (
     (
           (c.relname <> 'cash_payment'::name)
         AND (c.relname <> 'check_payment'::name)
     )
   AND (c.relname <> 'credit_card_payment'::name)
);

 

Permissions which apply to money.non_drawer_payment_view
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.open_balance_by_circ_and_owning_lib

money.open_balance_by_circ_and_owning_lib Structure
F-Key Name Type Description
circ_lib integer
owning_lib integer
billing_types text
balance numeric
SELECT x.circ_lib
, x.owning_lib
, array_to_string
(array_accum
     (DISTINCT x.billing_type)
     ,', '::text
) AS billing_types
, (sum
     (x.billed) - sum
     (COALESCE
           (
                 (
                  SELECT sum
                       (payment.amount) AS paid 
                    FROM money.payment 
                   WHERE (
                             (NOT payment.voided)
                           AND (payment.xact = x.id)
                       )
                 )
                 , (0)::numeric
           )
     )
) AS balance 
FROM money.open_circ_balance_by_circ_and_owning_lib x 
GROUP BY x.circ_lib
, x.owning_lib;

Index - Schema money


View: money.open_balance_by_owning_lib

money.open_balance_by_owning_lib Structure
F-Key Name Type Description
owning_lib integer
billing_types text
balance numeric
SELECT x.owning_lib
, array_to_string
(array_accum
     (DISTINCT x.billing_type)
     ,', '::text
) AS billing_types
, (sum
     (x.billed) - sum
     (COALESCE
           (
                 (
                  SELECT sum
                       (payment.amount) AS paid 
                    FROM money.payment 
                   WHERE (
                             (NOT payment.voided)
                           AND (payment.xact = x.id)
                       )
                 )
                 , (0)::numeric
           )
     )
) AS balance 
FROM money.open_circ_balance_by_owning_lib x 
GROUP BY x.owning_lib;

Index - Schema money


View: money.open_balance_by_usr_home_and_owning_lib

money.open_balance_by_usr_home_and_owning_lib Structure
F-Key Name Type Description
home_ou integer
owning_lib integer
billing_types text
balance numeric
SELECT x.home_ou
, x.owning_lib
, array_to_string
(array_accum
     (DISTINCT x.billing_type)
     ,', '::text
) AS billing_types
, (sum
     (x.billed) - sum
     (COALESCE
           (
                 (
                  SELECT sum
                       (payment.amount) AS paid 
                    FROM money.payment 
                   WHERE (
                             (NOT payment.voided)
                           AND (payment.xact = x.id)
                       )
                 )
                 , (0)::numeric
           )
     )
) AS balance 
FROM money.open_circ_balance_by_usr_home_and_owning_lib x 
GROUP BY x.home_ou
, x.owning_lib;

Index - Schema money


View: money.open_billable_xact_summary

money.open_billable_xact_summary Structure
F-Key Name Type Description
id bigint
usr integer
billing_location integer
xact_start timestamp with time zone
xact_finish timestamp with time zone
total_paid numeric
last_payment_ts timestamp with time zone
last_payment_note text
last_payment_type name
total_owed numeric
last_billing_ts timestamp with time zone
last_billing_note text
last_billing_type text
balance_owed numeric
xact_type name
SELECT xact.id
, xact.usr
, COALESCE
(circ.circ_lib
     , groc.billing_location
) AS billing_location
, xact.xact_start
, xact.xact_finish
, sum
(credit.amount) AS total_paid
, max
(credit.payment_ts) AS last_payment_ts
,"last"
(credit.note) AS last_payment_note
,"last"
(credit.payment_type) AS last_payment_type
, sum
(debit.amount) AS total_owed
, max
(debit.billing_ts) AS last_billing_ts
,"last"
(debit.note) AS last_billing_note
,"last"
(debit.billing_type) AS last_billing_type
, (COALESCE
     (sum
           (debit.amount)
           , (0)::numeric
     ) - COALESCE
     (sum
           (credit.amount)
           , (0)::numeric
     )
) AS balance_owed
, p.relname AS xact_type 
FROM (
     (
           (
                 (
                       (money.billable_xact xact 
                          JOIN pg_class p 
                            ON (
                                   (xact.tableoid = p.oid)
                             )
                       )
               LEFT JOIN"action".circulation circ 
                      ON (
                             (circ.id = xact.id)
                       )
                 )
         LEFT JOIN money.grocery groc 
                ON (
                       (groc.id = xact.id)
                 )
           )
   LEFT JOIN (
            SELECT billing.xact
                 , billing.voided
                 , sum
                 (billing.amount) AS amount
                 , max
                 (billing.billing_ts) AS billing_ts
                 ,"last"
                 (billing.note) AS note
                 ,"last"
                 (billing.billing_type) AS billing_type 
              FROM money.billing 
             WHERE (billing.voided IS FALSE)
          GROUP BY billing.xact
                 , billing.voided
           ) debit 
          ON (
                 (
                       (xact.id = debit.xact)
                     AND (debit.voided IS FALSE)
                 )
           )
     )
LEFT JOIN (
      SELECT payment_view.xact
           , payment_view.voided
           , sum
           (payment_view.amount) AS amount
           , max
           (payment_view.payment_ts) AS payment_ts
           ,"last"
           (payment_view.note) AS note
           ,"last"
           (payment_view.payment_type) AS payment_type 
        FROM money.payment_view 
       WHERE (payment_view.voided IS FALSE)
    GROUP BY payment_view.xact
           , payment_view.voided
     ) credit 
    ON (
           (
                 (xact.id = credit.xact)
               AND (credit.voided IS FALSE)
           )
     )
)
WHERE (xact.xact_finish IS NULL)
GROUP BY xact.id
, xact.usr
, COALESCE
(circ.circ_lib
     , groc.billing_location
)
, xact.xact_start
, xact.xact_finish
, p.relname 
ORDER BY max
(debit.billing_ts)
, max
(credit.payment_ts);

 

Permissions which apply to money.open_billable_xact_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.open_circ_balance

money.open_circ_balance Structure
F-Key Name Type Description
id bigint
billing_types text
balance numeric
SELECT x.id
, x.billing_types
, (x.billed - COALESCE
     (
           (
            SELECT sum
                 (payment.amount) AS paid 
              FROM money.payment 
             WHERE (
                       (NOT payment.voided)
                     AND (payment.xact = x.id)
                 )
           )
           , (0)::numeric
     )
) AS balance 
FROM (
SELECT circ.id
     , array_to_string
     (array_accum
           (DISTINCT bill.billing_type)
           ,', '::text
     ) AS billing_types
     , sum
     (bill.amount) AS billed 
  FROM ("action".circulation circ 
        JOIN money.billing bill 
          ON (
                 (circ.id = bill.xact)
           )
     )
 WHERE (
           (circ.xact_finish IS NULL)
         AND (NOT bill.voided)
     )
GROUP BY circ.id 
ORDER BY circ.id
     , array_to_string
     (array_accum
           (DISTINCT bill.billing_type)
           ,', '::text
     )
) x 
WHERE (
     (x.billed - COALESCE
           (
                 (
                  SELECT sum
                       (payment.amount) AS paid 
                    FROM money.payment 
                   WHERE (
                             (NOT payment.voided)
                           AND (payment.xact = x.id)
                       )
                 )
                 , (0)::numeric
           )
     ) > 
     (0)::numeric
);

Index - Schema money


View: money.open_circ_balance_by_circ_and_owning_lib

money.open_circ_balance_by_circ_and_owning_lib Structure
F-Key Name Type Description
id bigint
circ_lib integer
owning_lib integer
billing_type text
billed numeric
SELECT circ.id
, circ.circ_lib
, cn.owning_lib
, bill.billing_type
, sum
(bill.amount) AS billed 
FROM (
     (
           ("action".circulation circ 
              JOIN money.billing bill 
                ON (
                       (circ.id = bill.xact)
                 )
           )
        JOIN asset."copy" cp 
          ON (
                 (circ.target_copy = cp.id)
           )
     )
  JOIN asset.call_number cn 
    ON (
           (cn.id = cp.call_number)
     )
)
WHERE (
     (circ.xact_finish IS NULL)
   AND (NOT bill.voided)
)
GROUP BY circ.id
, circ.circ_lib
, cn.owning_lib
, bill.billing_type 
ORDER BY circ.id
, circ.circ_lib
, cn.owning_lib
, bill.billing_type;

Index - Schema money


View: money.open_circ_balance_by_owning_lib

money.open_circ_balance_by_owning_lib Structure
F-Key Name Type Description
id bigint
owning_lib integer
billing_type text
billed numeric
SELECT circ.id
, cn.owning_lib
, bill.billing_type
, sum
(bill.amount) AS billed 
FROM (
     (
           ("action".circulation circ 
              JOIN money.billing bill 
                ON (
                       (circ.id = bill.xact)
                 )
           )
        JOIN asset."copy" cp 
          ON (
                 (circ.target_copy = cp.id)
           )
     )
  JOIN asset.call_number cn 
    ON (
           (cn.id = cp.call_number)
     )
)
WHERE (
     (circ.xact_finish IS NULL)
   AND (NOT bill.voided)
)
GROUP BY circ.id
, cn.owning_lib
, bill.billing_type 
ORDER BY circ.id
, cn.owning_lib
, bill.billing_type;

Index - Schema money


View: money.open_circ_balance_by_usr_home_and_owning_lib

money.open_circ_balance_by_usr_home_and_owning_lib Structure
F-Key Name Type Description
id bigint
home_ou integer
owning_lib integer
billing_type text
billed numeric
SELECT circ.id
, usr.home_ou
, cn.owning_lib
, bill.billing_type
, sum
(bill.amount) AS billed 
FROM (
     (
           (
                 ("action".circulation circ 
                    JOIN money.billing bill 
                      ON (
                             (circ.id = bill.xact)
                       )
                 )
              JOIN asset."copy" cp 
                ON (
                       (circ.target_copy = cp.id)
                 )
           )
        JOIN asset.call_number cn 
          ON (
                 (cn.id = cp.call_number)
           )
     )
  JOIN actor.usr usr 
    ON (
           (circ.usr = usr.id)
     )
)
WHERE (
     (circ.xact_finish IS NULL)
   AND (NOT bill.voided)
)
GROUP BY circ.id
, usr.home_ou
, cn.owning_lib
, bill.billing_type 
ORDER BY circ.id
, usr.home_ou
, cn.owning_lib
, bill.billing_type;

Index - Schema money


View: money.open_transaction_billing_summary

money.open_transaction_billing_summary Structure
F-Key Name Type Description
xact bigint
last_billing_type text
last_billing_note text
last_billing_ts timestamp with time zone
total_owed numeric
SELECT billing.xact
,"last"
(billing.billing_type) AS last_billing_type
,"last"
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
     (billing.amount
           , (0)::numeric
     )
) AS total_owed 
FROM money.billing 
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact 
ORDER BY max
(billing.billing_ts);

 

Permissions which apply to money.open_transaction_billing_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.open_transaction_billing_type_summary

money.open_transaction_billing_type_summary Structure
F-Key Name Type Description
xact bigint
last_billing_type text
last_billing_note text
last_billing_ts timestamp with time zone
total_owed numeric
SELECT billing.xact
, billing.billing_type AS last_billing_type
,"last"
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
     (billing.amount
           , (0)::numeric
     )
) AS total_owed 
FROM money.billing 
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
, billing.billing_type 
ORDER BY max
(billing.billing_ts);

 

Permissions which apply to money.open_transaction_billing_type_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.open_transaction_payment_summary

money.open_transaction_payment_summary Structure
F-Key Name Type Description
xact bigint
last_payment_type name
last_payment_note text
last_payment_ts timestamp with time zone
total_paid numeric
SELECT payment_view.xact
,"last"
(payment_view.payment_type) AS last_payment_type
,"last"
(payment_view.note) AS last_payment_note
, max
(payment_view.payment_ts) AS last_payment_ts
, sum
(COALESCE
     (payment_view.amount
           , (0)::numeric
     )
) AS total_paid 
FROM money.payment_view 
WHERE (payment_view.voided IS FALSE)
GROUP BY payment_view.xact 
ORDER BY max
(payment_view.payment_ts);

 

Permissions which apply to money.open_transaction_payment_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.open_transaction_type_class_location_summary

money.open_transaction_type_class_location_summary Structure
F-Key Name Type Description
xact bigint
last_billing_type text
transactions_class name
location integer
last_billing_note text
last_billing_ts timestamp with time zone
total_owed numeric
SELECT billing.xact
, billing.billing_type AS last_billing_type
, p.relname AS transactions_class
, COALESCE
(g.billing_location
     , c.circ_lib
) AS "location"
,"last"
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
     (billing.amount
           , (0)::numeric
     )
) AS total_owed 
FROM (
     (
           (
                 (money.billing 
                    JOIN money.billable_xact x 
                      ON (
                             (x.id = billing.xact)
                       )
                 )
              JOIN pg_class p 
                ON (
                       (x.tableoid = p.oid)
                 )
           )
   LEFT JOIN money.grocery g 
          ON (
                 (g.id = x.id)
           )
     )
LEFT JOIN"action".circulation c 
    ON (
           (c.id = x.id)
     )
)
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
, billing.billing_type
, p.relname
, COALESCE
(g.billing_location
     , c.circ_lib
)
ORDER BY max
(billing.billing_ts);

Index - Schema money


View: money.open_transaction_type_class_summary

money.open_transaction_type_class_summary Structure
F-Key Name Type Description
xact bigint
last_billing_type text
transactions_class name
last_billing_note text
last_billing_ts timestamp with time zone
total_owed numeric
SELECT billing.xact
, billing.billing_type AS last_billing_type
, p.relname AS transactions_class
,"last"
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
     (billing.amount
           , (0)::numeric
     )
) AS total_owed 
FROM (
     (money.billing 
        JOIN money.billable_xact x 
          ON (
                 (x.id = billing.xact)
           )
     )
  JOIN pg_class p 
    ON (
           (x.tableoid = p.oid)
     )
)
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
, billing.billing_type
, p.relname 
ORDER BY max
(billing.billing_ts);

Index - Schema money


View: money.open_usr_circulation_summary

money.open_usr_circulation_summary Structure
F-Key Name Type Description
usr integer
total_paid numeric
total_owed numeric
balance_owed numeric
SELECT open_billable_xact_summary.usr
, sum
(open_billable_xact_summary.total_paid) AS total_paid
, sum
(open_billable_xact_summary.total_owed) AS total_owed
, sum
(open_billable_xact_summary.balance_owed) AS balance_owed 
FROM money.open_billable_xact_summary 
WHERE (open_billable_xact_summary.xact_type = 'circulation'::name)
GROUP BY open_billable_xact_summary.usr;

 

Permissions which apply to money.open_usr_circulation_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.open_usr_summary

money.open_usr_summary Structure
F-Key Name Type Description
usr integer
total_paid numeric
total_owed numeric
balance_owed numeric
SELECT open_billable_xact_summary.usr
, sum
(open_billable_xact_summary.total_paid) AS total_paid
, sum
(open_billable_xact_summary.total_owed) AS total_owed
, sum
(open_billable_xact_summary.balance_owed) AS balance_owed 
FROM money.open_billable_xact_summary 
GROUP BY open_billable_xact_summary.usr;

 

Permissions which apply to money.open_usr_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.payment

money.payment Structure
F-Key Name Type Description
id bigserial PRIMARY KEY
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
m_p_time_idx payment_ts m_p_xact_idx xact

 

Permissions which apply to money.payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.payment_view

money.payment_view Structure
F-Key Name Type Description
id bigint
xact bigint
payment_ts timestamp with time zone
voided boolean
amount numeric(6,2)
note text
payment_type name
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, c.relname AS payment_type 
FROM (money.payment p 
  JOIN pg_class c 
    ON (
           (p.tableoid = c.oid)
     )
);

 

Permissions which apply to money.payment_view
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.transaction_billing_summary

money.transaction_billing_summary Structure
F-Key Name Type Description
xact bigint
last_billing_type text
last_billing_note text
last_billing_ts timestamp with time zone
total_owed numeric
SELECT billing.xact
,"last"
(billing.billing_type) AS last_billing_type
,"last"
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
     (billing.amount
           , (0)::numeric
     )
) AS total_owed 
FROM money.billing 
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact 
ORDER BY max
(billing.billing_ts);

 

Permissions which apply to money.transaction_billing_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.transaction_billing_type_summary

money.transaction_billing_type_summary Structure
F-Key Name Type Description
xact bigint
last_billing_type text
last_billing_note text
last_billing_ts timestamp with time zone
total_owed numeric
SELECT billing.xact
, billing.billing_type AS last_billing_type
,"last"
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
     (billing.amount
           , (0)::numeric
     )
) AS total_owed 
FROM money.billing 
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
, billing.billing_type 
ORDER BY max
(billing.billing_ts);

 

Permissions which apply to money.transaction_billing_type_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.transaction_billing_with_void_summary

money.transaction_billing_with_void_summary Structure
F-Key Name Type Description
xact bigint
last_billing_type text
last_billing_note text
last_billing_ts timestamp with time zone
total_owed numeric
SELECT billing.xact
,"last"
(billing.billing_type) AS last_billing_type
,"last"
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(CASE WHEN billing.voided THEN 
     (0)::numeric ELSE COALESCE
     (billing.amount
           , (0)::numeric
     ) END
) AS total_owed 
FROM money.billing 
GROUP BY billing.xact 
ORDER BY max
(billing.billing_ts);

 

Permissions which apply to money.transaction_billing_with_void_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.transaction_payment_summary

money.transaction_payment_summary Structure
F-Key Name Type Description
xact bigint
last_payment_type name
last_payment_note text
last_payment_ts timestamp with time zone
total_paid numeric
SELECT payment_view.xact
,"last"
(payment_view.payment_type) AS last_payment_type
,"last"
(payment_view.note) AS last_payment_note
, max
(payment_view.payment_ts) AS last_payment_ts
, sum
(COALESCE
     (payment_view.amount
           , (0)::numeric
     )
) AS total_paid 
FROM money.payment_view 
WHERE (payment_view.voided IS FALSE)
GROUP BY payment_view.xact 
ORDER BY max
(payment_view.payment_ts);

 

Permissions which apply to money.transaction_payment_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.transaction_payment_with_void_summary

money.transaction_payment_with_void_summary Structure
F-Key Name Type Description
xact bigint
last_payment_type name
last_payment_note text
last_payment_ts timestamp with time zone
total_paid numeric
SELECT payment_view.xact
,"last"
(payment_view.payment_type) AS last_payment_type
,"last"
(payment_view.note) AS last_payment_note
, max
(payment_view.payment_ts) AS last_payment_ts
, sum
(CASE WHEN payment_view.voided THEN 
     (0)::numeric ELSE COALESCE
     (payment_view.amount
           , (0)::numeric
     ) END
) AS total_paid 
FROM money.payment_view 
GROUP BY payment_view.xact 
ORDER BY max
(payment_view.payment_ts);

 

Permissions which apply to money.transaction_payment_with_void_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.usr_circulation_summary

money.usr_circulation_summary Structure
F-Key Name Type Description
usr integer
total_paid numeric
total_owed numeric
balance_owed numeric
SELECT billable_xact_summary.usr
, sum
(billable_xact_summary.total_paid) AS total_paid
, sum
(billable_xact_summary.total_owed) AS total_owed
, sum
(billable_xact_summary.balance_owed) AS balance_owed 
FROM money.billable_xact_summary 
WHERE (billable_xact_summary.xact_type = 'circulation'::name)
GROUP BY billable_xact_summary.usr;

 

Permissions which apply to money.usr_circulation_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


View: money.usr_summary

money.usr_summary Structure
F-Key Name Type Description
usr integer
total_paid numeric
total_owed numeric
balance_owed numeric
SELECT billable_xact_summary.usr
, sum
(billable_xact_summary.total_paid) AS total_paid
, sum
(billable_xact_summary.total_owed) AS total_owed
, sum
(billable_xact_summary.balance_owed) AS balance_owed 
FROM money.billable_xact_summary 
GROUP BY billable_xact_summary.usr;

 

Permissions which apply to money.usr_summary
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Table: money.work_payment

money.work_payment Structure
F-Key Name Type Description
id bigint PRIMARY KEY DEFAULT nextval('payment_id_seq'::regclass)
xact bigint NOT NULL
payment_ts timestamp with time zone NOT NULL DEFAULT now()
voided boolean NOT NULL DEFAULT false
amount numeric(6,2) NOT NULL
note text
amount_collected numeric(6,2) NOT NULL
accepting_usr integer NOT NULL

Table money.work_payment Inherits bnm_payment,

money_work_id_idx id money_work_payment_accepting_usr_idx accepting_usr money_work_payment_payment_ts_idx payment_ts money_work_payment_xact_idx xact

 

Permissions which apply to money.work_payment
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema money


Function: money.payment_by_billing_type( range_start timestamp with time zone, range_end timestamp with time zone, location integer )

Returns: SET OF payment_by_billing_type

Language: PLPGSQL

DECLARE
    current_transaction RECORD;
    current_result      money.payment_by_billing_type;
BEGIN
    -- first, we find transactions at specified locations involivng
    -- payments within the specified range
    FOR current_transaction IN
        SELECT  DISTINCT x.id
          FROM  action.circulation x
                JOIN money.payment p ON (x.id = p.xact)
                JOIN actor.org_unit_descendants(location) d ON (d.id = x.circ_lib)
          WHERE p.payment_ts BETWEEN range_start AND range_end
            UNION ALL
        SELECT  DISTINCT x.id
          FROM  money.grocery x
                JOIN money.payment p ON (x.id = p.xact)
                JOIN actor.org_unit_descendants(location) d ON (d.id = x.billing_location)
          WHERE p.payment_ts BETWEEN range_start AND range_end
    LOOP
        FOR current_result IN
            SELECT * FROM money.payment_by_billing_type( current_transaction.id )
        LOOP
            IF current_result.payment_ts BETWEEN range_start AND range_end THEN
                RETURN NEXT current_result;
            END IF;
        END LOOP;
    END LOOP;
END;

Function: money.payment_by_billing_type( tid bigint )

Returns: SET OF payment_by_billing_type

Language: PLPGSQL

DECLARE
    current_result      money.payment_by_billing_type;
    current_payment     money.payment_view%ROWTYPE;
    current_billing     money.billing%ROWTYPE;
    payment_remainder   NUMERIC(8,2) := 0.0;
    billing_remainder   NUMERIC(8,2) := 0.0;
    payment_offset      INT := 0;
    billing_offset      INT := 0;
BEGIN


    payment_remainder   = 0.0;
    billing_remainder   = 0.0;
    payment_offset      = 0;
    billing_offset      = 0;

    -- Now the fun part ...
    -- Loop through the payments
    FOR current_payment IN
        SELECT  *
          FROM  money.payment_view
          WHERE xact = tid
                AND NOT voided
          ORDER BY payment_ts
          LIMIT 1
          OFFSET payment_offset
    LOOP
        payment_remainder = current_payment.amount;

        -- and apply them to billings
        IF billing_remainder > 0.0 THEN

            current_result.transaction = tid;
            current_result.payment = current_payment.id;
            current_result.billing = current_billing.id;
            current_result.payment_ts = current_payment.payment_ts;
            current_result.billing_ts = current_billing.billing_ts;
            current_result.payment_type = current_payment.payment_type;
            current_result.billing_type = current_billing.billing_type;

            IF billing_remainder >= payment_remainder THEN
                current_result.amount = payment_remainder;
                billing_remainder = billing_remainder - payment_remainder;
                payment_remainder = 0.0;
                payment_offset = payment_offset + 1;
            ELSE
                current_result.amount = billing_remainder;
                payment_remainder = payment_remainder - billing_remainder;
                billing_remainder = 0.0;
            END IF;

            RETURN NEXT current_result;

        END IF;

        CONTINUE WHEN payment_remainder = 0.0;

        -- next billing, please

        LOOP
            SELECT  * INTO current_billing
              FROM  money.billing
              WHERE xact = tid
                    AND NOT voided
              ORDER BY billing_ts
              LIMIT 1
              OFFSET payment_offset;

            billing_remainder = current_billing.amount;

            current_result.transaction = tid;
            current_result.payment = current_payment.id;
            current_result.billing = current_billing.id;
            current_result.payment_ts = current_payment.payment_ts;
            current_result.billing_ts = current_billing.billing_ts;
            current_result.payment_type = current_payment.payment_type;
            current_result.billing_type = current_billing.billing_type;

            IF billing_remainder >= payment_remainder THEN
                current_result.amount = payment_remainder;
                billing_remainder = billing_remainder - payment_remainder;
                payment_remainder = 0.0;
            ELSE
                current_result.amount = billing_remainder;
                payment_remainder = payment_remainder - billing_remainder;
                billing_remainder = 0.0;
                billing_offset = billing_offset + 1;
            END IF;

            RETURN NEXT current_result;

            EXIT WHEN payment_remainder = 0.0;

        END LOOP;

        payment_offset = payment_offset + 1;

    END LOOP;

END;

Schema offline


Table: offline.script

offline.script Structure
F-Key Name Type Description
id serial PRIMARY KEY
session text NOT NULL
requestor integer NOT NULL
create_time integer NOT NULL
workstation text NOT NULL
logfile text NOT NULL
time_delta integer NOT NULL
count integer NOT NULL
offline_script_pkey id offline_script_session "session" offline_script_ws workstation

 

Permissions which apply to offline.script
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema offline


Table: offline.session

offline.session Structure
F-Key Name Type Description
key text PRIMARY KEY
org integer NOT NULL
description text
creator integer NOT NULL
create_time integer NOT NULL
in_process integer NOT NULL
start_time integer
end_time integer
num_complete integer NOT NULL
offline_session_creation create_time offline_session_org org offline_session_pkey "key"

 

Permissions which apply to offline.session
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema offline


Schema permission


Table: permission.grp_perm_map

permission.grp_perm_map Structure
F-Key Name Type Description
id serial PRIMARY KEY
permission.grp_tree.id grp integer UNIQUE#1 NOT NULL
permission.perm_list.id perm integer UNIQUE#1 NOT NULL
depth integer NOT NULL
grantable boolean NOT NULL DEFAULT false

 

Permissions which apply to permission.grp_perm_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema permission


Table: permission.grp_tree

permission.grp_tree Structure
F-Key Name Type Description
id serial PRIMARY KEY
name text UNIQUE NOT NULL
permission.grp_tree.id parent integer
usergroup boolean NOT NULL DEFAULT true
perm_interval interval NOT NULL DEFAULT '3 years'::interval
description text
application_perm text

Tables referencing this one via Foreign Key Constraints:

grp_tree_parent_idx parent

 

Permissions which apply to permission.grp_tree
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema permission


Table: permission.perm_list

permission.perm_list Structure
F-Key Name Type Description
id serial PRIMARY KEY
code text UNIQUE NOT NULL
description text

Tables referencing this one via Foreign Key Constraints:

perm_list_code_idx code

 

Permissions which apply to permission.perm_list
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema permission


Table: permission.usr_grp_map

permission.usr_grp_map Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id usr integer UNIQUE#1 NOT NULL
permission.grp_tree.id grp integer UNIQUE#1 NOT NULL

 

Permissions which apply to permission.usr_grp_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema permission


Table: permission.usr_perm_map

permission.usr_perm_map Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id usr integer UNIQUE#1 NOT NULL
permission.perm_list.id perm integer UNIQUE#1 NOT NULL
depth integer NOT NULL
grantable boolean NOT NULL DEFAULT false

 

Permissions which apply to permission.usr_perm_map
User
Select
Insert
Update
Delete
Reference
Rule
Trigger
PUBLIC
postgres

Index - Schema permission


Table: permission.usr_work_ou_map

permission.usr_work_ou_map Structure
F-Key Name Type Description
id serial PRIMARY KEY
actor.usr.id usr integer UNIQUE#1 NOT NULL
actor.org_unit.id work_ou integer UNIQUE#1 NOT NULL

Index - Schema permission


Function: permission.grp_ancestors( integer )

Returns: SET OF grp_tree

Language: SQL

	SELECT	a.*
	FROM	connectby('permission.grp_tree','parent','id','name',$1,'100','.')
			AS t(keyid text, parent_keyid text, level int, branch text,pos int)
		JOIN permission.grp_tree a ON a.id = t.keyid
	ORDER BY
		CASE WHEN a.parent IS NULL
			THEN 0
			ELSE 1
		END, a.name;

Function: permission.grp_descendants( integer )

Returns: SET OF grp_tree

Language: SQL

    SELECT  a.*
      FROM  connectby('permission.grp_tree'::text,'id'::text,'parent'::text,'name'::text,$1::text,100,'.'::text)
            AS t(keyid text, parent_keyid text, level int, branch text,pos int)
        JOIN permission.grp_tree a ON a.id::text = t.keyid::text
      ORDER BY  CASE WHEN a.parent IS NULL THEN 0 ELSE 1 END, a.name;

Function: permission.usr_can_grant_perm( iuser integer, tperm text, target_ou integer )

Returns: boolean

Language: PLPGSQL

DECLARE
	r_usr	actor.usr%ROWTYPE;
	r_perm	permission.usr_perm_map%ROWTYPE;
BEGIN

	SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;

	IF r_usr.active = FALSE THEN
		RETURN FALSE;
	END IF;

	IF r_usr.super_user = TRUE THEN
		RETURN TRUE;
	END IF;


	FOR r_perm IN	SELECT	*
			  FROM	permission.usr_perms(iuser) p
				JOIN permission.perm_list l
					ON (l.id = p.perm)
			  WHERE	(l.code = tperm AND p.grantable IS TRUE)
		LOOP

		PERFORM	*
		  FROM	actor.org_unit_descendants(target_ou,r_perm.depth)
		  WHERE	id = r_usr.home_ou;

		IF FOUND THEN
			RETURN TRUE;
		ELSE
			RETURN FALSE;
		END IF;
	END LOOP;

	RETURN FALSE;
END;

Function: permission.usr_has_home_perm( iuser integer, tperm text, target_ou integer )

Returns: boolean

Language: PLPGSQL

DECLARE
	r_usr	actor.usr%ROWTYPE;
	r_perm	permission.usr_perm_map%ROWTYPE;
BEGIN

	SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;

	IF r_usr.active = FALSE THEN
		RETURN FALSE;
	END IF;

	IF r_usr.super_user = TRUE THEN
		RETURN TRUE;
	END IF;


	FOR r_perm IN	SELECT	*
			  FROM	permission.usr_perms(iuser) p
				JOIN permission.perm_list l
					ON (l.id = p.perm)
			  WHERE	l.code = tperm
			  	OR p.perm = -1 LOOP

		PERFORM	*
		  FROM	actor.org_unit_descendants(target_ou,r_perm.depth)
		  WHERE	id = r_usr.home_ou;

		IF FOUND THEN
			RETURN TRUE;
		ELSE
			RETURN FALSE;
		END IF;
	END LOOP;

	RETURN FALSE;
END;

Function: permission.usr_has_perm( integer, text, integer )

Returns: boolean

Language: SQL

        SELECT  CASE
                        WHEN permission.usr_has_home_perm( $1, $2, $3 ) THEN TRUE
                        WHEN permission.usr_has_work_perm( $1, $2, $3 ) THEN TRUE
                        ELSE FALSE
                END;

Function: permission.usr_has_work_perm( iuser integer, tperm text, target_ou integer )

Returns: boolean

Language: PLPGSQL

DECLARE
        r_woum  permission.usr_work_ou_map%ROWTYPE;
        r_usr   actor.usr%ROWTYPE;
        r_perm  permission.usr_perm_map%ROWTYPE;
BEGIN

        SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;

        IF r_usr.active = FALSE THEN
                RETURN FALSE;
        END IF;

        IF r_usr.super_user = TRUE THEN
                RETURN TRUE;
        END IF;

        FOR r_perm IN   SELECT  *
                          FROM  permission.usr_perms(iuser) p
                                JOIN permission.perm_list l
                                        ON (l.id = p.perm)
                          WHERE l.code = tperm
                                OR p.perm = -1
                LOOP

                FOR r_woum IN   SELECT  *
                                  FROM  permission.usr_work_ou_map
                                  WHERE usr = iuser
                        LOOP

                        PERFORM *
                          FROM  actor.org_unit_descendants(target_ou,r_perm.depth)
                          WHERE id = r_woum.work_ou;

                        IF FOUND THEN
                                RETURN TRUE;
                        END IF;

                END LOOP;

        END LOOP;

        RETURN FALSE;
END;

Function: permission.usr_perms( integer )

Returns: SET OF usr_perm_map

Language: SQL

	SELECT	DISTINCT ON (usr,perm) *
	  FROM	(
			(SELECT * FROM permission.usr_perm_map WHERE usr = $1)
        				UNION ALL
			(SELECT	-p.id, $1 AS usr, p.perm, p.depth, p.grantable
			  FROM	permission.grp_perm_map p
			  WHERE	p.grp IN (
			  	SELECT	(permission.grp_ancestors(
						(SELECT profile FROM actor.usr WHERE id = $1)
					)).id
				)
			)
        				UNION ALL
			(SELECT	-p.id, $1 AS usr, p.perm, p.depth, p.grantable
			  FROM	permission.grp_perm_map p 
			  WHERE	p.grp IN (SELECT (permission.grp_ancestors(m.grp)).id FROM permission.usr_grp_map m WHERE usr = $1))
		) AS x
	  ORDER BY 2, 3, 1 DESC, 5 DESC ;

Schema public

Standard public schema


Table: public.blackshear_fps

public.blackshear_fps Structure
F-Key Name Type Description
id integer
item_form text
date1 text
record_type text
bib_lvl text
title text

Index - Schema public


Table: public.blackshear_pines_fps

public.blackshear_pines_fps Structure
F-Key Name Type Description
id bigint
item_form text
date1 text
record_type text
bib_lvl text
title text

Index - Schema public


Table: public.catoosa_id_list

public.catoosa_id_list Structure
F-Key Name Type Description
id bigint

Index - Schema public


Table: public.circ_07

public.circ_07 Structure
F-Key Name Type Description
month text
type text
count bigint

 

Permissions which apply to public.circ_07
User
Select
Insert
Update