We no longer distribute slony SQL scripts. You need to point to the right location...
authorchriskl <chriskl>
Wed, 7 Sep 2005 08:09:21 +0000 (08:09 +0000)
committerchriskl <chriskl>
Wed, 7 Sep 2005 08:09:21 +0000 (08:09 +0000)
17 files changed:
classes/database/Postgres.php
classes/database/Postgres71.php
classes/database/Postgres72.php
classes/database/Postgres73.php
classes/database/Postgres74.php
classes/database/Postgres80.php
classes/database/Postgres81.php
classes/plugins/Slony.php
conf/config.inc.php-dist
sql/plugins/slony1_base.sql [deleted file]
sql/plugins/slony1_base.v73.sql [deleted file]
sql/plugins/slony1_base.v74.sql [deleted file]
sql/plugins/slony1_funcs.sql [deleted file]
sql/plugins/slony1_funcs.v73.sql [deleted file]
sql/plugins/slony1_funcs.v74.sql [deleted file]
sql/plugins/xxid.v73.sql [deleted file]
sql/plugins/xxid.v74.sql [deleted file]

index ccbc97ac6a56e4fc61ad06f7779dd774c2859186..cb943a77b4339cd2949ceac952210a7493071051 100755 (executable)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres.php,v 1.273 2005/08/15 17:15:36 xzilla Exp $
+ * $Id: Postgres.php,v 1.274 2005/09/07 08:09:21 chriskl Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -13,6 +13,8 @@ include_once('./classes/database/ADODB_base.php');
 
 class Postgres extends ADODB_base {
 
+       // Major version. MUST be numerically comparable to other versions.
+       var $major_version = 7.0;
        // Array of allowed type alignments
        var $typAligns = array('char', 'int2', 'int4', 'double');
        // The default type alignment
index 33af4133fe07772a942d6f4a80ac2b9b5fcc972a..ad03ae5e552a607a3dcb0601d2e1a14267c73c74 100644 (file)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres71.php,v 1.72 2005/07/31 09:15:06 chriskl Exp $
+ * $Id: Postgres71.php,v 1.73 2005/09/07 08:09:21 chriskl Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -13,6 +13,7 @@ include_once('./classes/database/Postgres.php');
 
 class Postgres71 extends Postgres {
 
+       var $major_version = 7.1;
        var $_lastSystemOID = 18539;
        var $_maxNameLen = 31;
 
index 57840fb8dd30374bc1218ccb2ae8957195ef0022..de45b9006db13fa1a03e7d14da54708586b54dae 100644 (file)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres72.php,v 1.83 2005/08/11 23:40:26 soranzo Exp $
+ * $Id: Postgres72.php,v 1.84 2005/09/07 08:09:21 chriskl Exp $
  */
 
 
@@ -12,6 +12,8 @@ include_once('./classes/database/Postgres71.php');
 
 class Postgres72 extends Postgres71 {
 
+       var $major_version = 7.2;
+
        // Set the maximum built-in ID.
        var $_lastSystemOID = 16554;
 
index ae328026af07fff01d4ecd9075ae052aea389702..ba7db9a900cd8ed78d2765d692343c0c3360b75b 100644 (file)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres73.php,v 1.152 2005/09/03 05:01:37 chriskl Exp $
+ * $Id: Postgres73.php,v 1.153 2005/09/07 08:09:21 chriskl Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -13,6 +13,8 @@ include_once('./classes/database/Postgres72.php');
 
 class Postgres73 extends Postgres72 {
 
+       var $major_version = 7.3;
+
        // Store the current schema
        var $_schema;
 
@@ -168,9 +170,11 @@ class Postgres73 extends Postgres72 {
                $sql = "CREATE SCHEMA \"{$schemaname}\"";
                if ($authorization != '') $sql .= " AUTHORIZATION \"{$authorization}\"";
                
-               $status = $this->beginTransaction();
-               if ($status != 0) return -1;
-
+               if ($comment != '') {
+                       $status = $this->beginTransaction();
+                       if ($status != 0) return -1;
+               }
+               
                // Create the new schema
                $status =  $this->execute($sql);
                if ($status != 0) {
@@ -185,8 +189,11 @@ class Postgres73 extends Postgres72 {
                                $this->rollbackTransaction();
                                return -1;
                        }
+                       
+                       return $this->endTransaction();
                }
-               return $this->endTransaction();
+               
+               return 0;
        }
        
        /**
index 0cf774a283025d5bc4e8cdf8143257e1f605319a..915e221e6f70ee87acd442eadd321a1d51f1e1ae 100644 (file)
@@ -4,13 +4,15 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres74.php,v 1.49 2005/08/31 20:49:10 xzilla Exp $
+ * $Id: Postgres74.php,v 1.50 2005/09/07 08:09:21 chriskl Exp $
  */
 
 include_once('./classes/database/Postgres73.php');
 
 class Postgres74 extends Postgres73 {
 
+       var $major_version = 7.4;
+
        // Last oid assigned to a system object
        var $_lastSystemOID = 17137;
 
index c246464b904b42c3327516d4d2c262d9beb8f874..b2385ef3936836febe928033ecbb9e3c5dd81e1e 100644 (file)
@@ -3,13 +3,15 @@
 /**
  * PostgreSQL 8.0 support
  *
- * $Id: Postgres80.php,v 1.17 2005/07/31 09:15:07 chriskl Exp $
+ * $Id: Postgres80.php,v 1.18 2005/09/07 08:09:21 chriskl Exp $
  */
 
 include_once('./classes/database/Postgres74.php');
 
 class Postgres80 extends Postgres74 {
 
+       var $major_version = 8.0;
+
        // List of all legal privileges that can be applied to different types
        // of objects.
        var $privlist = array(
index 8a4e3c403e186745ff560f5aefd4aef0b1c52a98..ab7081456c5542d953e09b7e64c325bae109ea21 100644 (file)
@@ -3,13 +3,15 @@
 /**
  * PostgreSQL 8.1 support
  *
- * $Id: Postgres81.php,v 1.2 2005/07/31 09:15:07 chriskl Exp $
+ * $Id: Postgres81.php,v 1.3 2005/09/07 08:09:21 chriskl Exp $
  */
 
 include_once('./classes/database/Postgres80.php');
 
 class Postgres81 extends Postgres80 {
 
+       var $major_version = 8.1;
+
        // Map of database encoding names to HTTP encoding names.  If a
        // database encoding does not appear in this list, then its HTTP
        // encoding name is the same as its database encoding name.
index 0be4165bdc899b61b2190e903b828958938f0956..44c551bfc6cc63be85db3dc26a004db61e4df7a7 100755 (executable)
@@ -3,7 +3,7 @@
 /**
  * A class that implements the Slony 1.0.x support plugin
  *
- * $Id: Slony.php,v 1.5 2005/07/06 14:46:24 chriskl Exp $
+ * $Id: Slony.php,v 1.6 2005/09/07 08:09:21 chriskl Exp $
  */
 
 include_once('./classes/plugins/Plugin.php');
@@ -126,14 +126,22 @@ class Slony extends Plugin {
        /**
         * Helper function to get a file into a string and replace
         * variables.
+        * @return The file contents, or FALSE on error.
         */
        function _getFile($file, $cluster) {
-               global $data;
+               global $data,$misc;
                $schema = '_' . $cluster;
                $data->fieldClean($cluster);
                
+               $server_info = $misc->getServerInfo();
+               $path = $server_info['slony_sql'] . '/' . $file;
+               
+               // Check that we can access the file
+               if (!file_exists($path) || !is_readable($path)) return false;
+
                $buffer = null;
-               $handle = fopen("./sql/plugins/{$file}", "r");\r
+               $handle = fopen($path, 'r');
+               if ($handle === false) return false;\r
                while (!feof($handle)) {\r
                   $temp = fgets($handle, 4096);
                   $temp = str_replace('@CLUSTERNAME@', $cluster, $temp);
@@ -160,10 +168,19 @@ class Slony extends Plugin {
                if (!$data->isSuperUser($server_info['username'])) {
                        return -10;
                }
-                               
+
+               // Determine Slony compatibility version.
+               if ($data->major_version == 7.3)
+                       $ver = '73';
+               elseif ($data->major_version >= 7.4)
+                       $ver = '74';
+               else {
+                       return -11;
+               }
+               
                $status = $data->beginTransaction();
                if ($status != 0) return -1;
-               
+
                // Create the schema
                $status = $data->createSchema('_' . $name);
                if ($status != 0) {
@@ -171,8 +188,11 @@ class Slony extends Plugin {
                        return -2;
                }
 
-               // XXX: Support only Postgresql 7.4+ at the moment              
-               $sql = $this->_getFile('xxid.v74.sql', $name);
+               $sql = $this->_getFile("xxid.v{$ver}.sql", $name);
+               if ($sql === false) {
+                       $data->rollbackTransaction();
+                       return -6;
+               }                       
                $status = $data->execute($sql);
                if ($status != 0) {
                        $data->rollbackTransaction();
@@ -180,6 +200,10 @@ class Slony extends Plugin {
                }
                
                $sql = $this->_getFile('slony1_base.sql', $name);
+               if ($sql === false) {
+                       $data->rollbackTransaction();
+                       return -6;
+               }                       
                $status = $data->execute($sql);
                if ($status != 0) {
                        $data->rollbackTransaction();
@@ -194,13 +218,21 @@ class Slony extends Plugin {
                }
 */
                $sql = $this->_getFile('slony1_funcs.sql', $name);
+               if ($sql === false) {
+                       $data->rollbackTransaction();
+                       return -6;
+               }                       
                $status = $data->execute($sql);
                if ($status != 0) {
                        $data->rollbackTransaction();
                        return -3;
                }
 
-               $sql = $this->_getFile('slony1_funcs.v74.sql', $name);
+               $sql = $this->_getFile("slony1_funcs.v{$ver}.sql", $name);
+               if ($sql === false) {
+                       $data->rollbackTransaction();
+                       return -6;
+               }                       
                $status = $data->execute($sql);
                if ($status != 0) {
                        $data->rollbackTransaction();
index 3ef8ab996aba35cacd8f27d6c9b4c3ecdfeab750..050f6039a4158aca809dcb10579a52fca180f4eb 100644 (file)
@@ -4,7 +4,7 @@
         * Central phpPgAdmin configuration.  As a user you may modify the
         * settings here for your particular configuration.
         *
-        * $Id: config.inc.php-dist,v 1.43 2005/08/01 05:54:22 chriskl Exp $
+        * $Id: config.inc.php-dist,v 1.44 2005/09/07 08:09:21 chriskl Exp $
         */
 
        // An example server.  Create as many of these as you wish,
@@ -30,6 +30,9 @@
 
        // Slony (www.slony.info) support?
        $conf['servers'][0]['slony_support'] = false;
+       // Specify the path to the Slony SQL scripts (where slony1_base.sql is located, etc.)
+       // No trailing slash.
+       $conf['servers'][0]['slony_sql'] = '/usr/share/pgsql';
 
        // Example for a second server (PostgreSQL for Windows)
        //$conf['servers'][1]['desc'] = 'Test Server';
@@ -39,6 +42,7 @@
        //$conf['servers'][1]['pg_dump_path'] = 'C:\\Program Files\\PostgreSQL\\8.0\\bin\\pg_dump.exe';
        //$conf['servers'][1]['pg_dumpall_path'] = 'C:\\Program Files\\PostgreSQL\\8.0\\bin\\pg_dumpall.exe';
        //$conf['servers'][1]['slony_support'] = false;
+       //$conf['servers'][1]['slony_sql'] = 'C:\\Program Files\\PostgreSQL\\8.0\\share';
 
        // Default language. Eg: 'english', 'polish', etc.  See lang/ directory
        // for all possibilities. If you specify 'auto' (the default) it will use 
diff --git a/sql/plugins/slony1_base.sql b/sql/plugins/slony1_base.sql
deleted file mode 100755 (executable)
index ce35e49..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
--- ----------------------------------------------------------------------\r
--- slony1_base.sql\r
---\r
---    Declaration of the basic replication schema.\r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: slony1_base.sql,v 1.2 2005/06/16 14:40:14 chriskl Exp $\r
--- ----------------------------------------------------------------------\r
-\r
-\r
--- **********************************************************************\r
--- * Tables\r
--- **********************************************************************\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_node\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_node (\r
-       no_id                           int4,\r
-       no_active                       bool,\r
-       no_comment                      text,\r
-\r
-       CONSTRAINT "sl_node-pkey"\r
-               PRIMARY KEY (no_id)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_set\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_set (\r
-       set_id                          int4,\r
-       set_origin                      int4,\r
-       set_locked                      @NAMESPACE@.xxid,\r
-       set_comment                     text,\r
-\r
-       CONSTRAINT "sl_set-pkey"\r
-               PRIMARY KEY (set_id),\r
-       CONSTRAINT "set_origin-no_id-ref"\r
-               FOREIGN KEY (set_origin)\r
-               REFERENCES @NAMESPACE@.sl_node (no_id)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_setsync\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_setsync (\r
-       ssy_setid                       int4,\r
-       ssy_origin                      int4,\r
-       ssy_seqno                       int8,\r
-       ssy_minxid                      @NAMESPACE@.xxid,\r
-       ssy_maxxid                      @NAMESPACE@.xxid,\r
-       ssy_xip                         text,\r
-       ssy_action_list         text,\r
-\r
-       CONSTRAINT "sl_setsync-pkey"\r
-               PRIMARY KEY (ssy_setid),\r
-       CONSTRAINT "ssy_setid-set_id-ref"\r
-               FOREIGN KEY (ssy_setid)\r
-               REFERENCES @NAMESPACE@.sl_set (set_id),\r
-       CONSTRAINT "ssy_origin-no_id-ref"\r
-               FOREIGN KEY (ssy_origin)\r
-               REFERENCES @NAMESPACE@.sl_node (no_id)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_table\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_table (\r
-       tab_id                          int4,\r
-       tab_reloid                      oid UNIQUE NOT NULL,\r
-       tab_set                         int4,\r
-       tab_idxname                     name NOT NULL,\r
-       tab_altered                     boolean NOT NULL,\r
-       tab_comment                     text,\r
-\r
-       CONSTRAINT "sl_table-pkey"\r
-               PRIMARY KEY (tab_id),\r
-       CONSTRAINT "tab_set-set_id-ref"\r
-               FOREIGN KEY (tab_set)\r
-               REFERENCES @NAMESPACE@.sl_set (set_id)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_trigger\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_trigger (\r
-       trig_tabid                      int4,\r
-       trig_tgname                     name,\r
-\r
-       CONSTRAINT "sl_trigger-pkey"\r
-               PRIMARY KEY (trig_tabid, trig_tgname),\r
-       CONSTRAINT "trig_tabid-tab_id-ref"\r
-               FOREIGN KEY (trig_tabid)\r
-               REFERENCES @NAMESPACE@.sl_table (tab_id)\r
-               ON DELETE CASCADE\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_sequence\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_sequence (\r
-       seq_id                          int4,\r
-       seq_reloid                      oid UNIQUE NOT NULL,\r
-       seq_set                         int4,\r
-       seq_comment                     text,\r
-\r
-       CONSTRAINT "sl_sequence-pkey"\r
-               PRIMARY KEY (seq_id),\r
-       CONSTRAINT "seq_set-set_id-ref"\r
-               FOREIGN KEY (seq_set)\r
-               REFERENCES @NAMESPACE@.sl_set (set_id)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_path\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_path (\r
-       pa_server                       int4,\r
-       pa_client                       int4,\r
-       pa_conninfo                     text NOT NULL,\r
-       pa_connretry            int4,\r
-\r
-       CONSTRAINT "sl_path-pkey"\r
-               PRIMARY KEY (pa_server, pa_client),\r
-       CONSTRAINT "pa_server-no_id-ref"\r
-               FOREIGN KEY (pa_server)\r
-               REFERENCES @NAMESPACE@.sl_node (no_id),\r
-       CONSTRAINT "pa_client-no_id-ref"\r
-               FOREIGN KEY (pa_client)\r
-               REFERENCES @NAMESPACE@.sl_node (no_id)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_listen\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_listen (\r
-       li_origin                       int4,\r
-       li_provider                     int4,\r
-       li_receiver                     int4,\r
-\r
-       CONSTRAINT "sl_listen-pkey"\r
-               PRIMARY KEY (li_origin, li_provider, li_receiver),\r
-       CONSTRAINT "li_origin-no_id-ref"\r
-               FOREIGN KEY (li_origin)\r
-               REFERENCES @NAMESPACE@.sl_node (no_id),\r
-       CONSTRAINT "sl_listen-sl_path-ref"\r
-               FOREIGN KEY (li_provider, li_receiver)\r
-               REFERENCES @NAMESPACE@.sl_path (pa_server, pa_client)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_subscribe\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_subscribe (\r
-       sub_set                         int4,\r
-       sub_provider            int4,\r
-       sub_receiver            int4,\r
-       sub_forward                     bool,\r
-       sub_active                      bool,\r
-\r
-       CONSTRAINT "sl_subscribe-pkey"\r
-               PRIMARY KEY (sub_receiver, sub_set),\r
-       CONSTRAINT "sl_subscribe-sl_path-ref"\r
-               FOREIGN KEY (sub_provider, sub_receiver)\r
-               REFERENCES @NAMESPACE@.sl_path (pa_server, pa_client),\r
-       CONSTRAINT "sub_set-set_id-ref"\r
-               FOREIGN KEY (sub_set)\r
-               REFERENCES @NAMESPACE@.sl_set (set_id)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_event\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_event (\r
-       ev_origin                       int4,\r
-       ev_seqno                        int8,\r
-       ev_timestamp            timestamp,\r
-       ev_minxid                       @NAMESPACE@.xxid,\r
-       ev_maxxid                       @NAMESPACE@.xxid,\r
-       ev_xip                          text,\r
-       ev_type                         text,\r
-       ev_data1                        text,\r
-       ev_data2                        text,\r
-       ev_data3                        text,\r
-       ev_data4                        text,\r
-       ev_data5                        text,\r
-       ev_data6                        text,\r
-       ev_data7                        text,\r
-       ev_data8                        text,\r
-\r
-       CONSTRAINT "sl_event-pkey"\r
-               PRIMARY KEY (ev_origin, ev_seqno)\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_confirm\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_confirm (\r
-       con_origin                      int4,\r
-       con_received            int4,\r
-       con_seqno                       int8,\r
-       con_timestamp           timestamp DEFAULT timeofday()::timestamp\r
-);\r
-create index sl_confirm_idx1 on @NAMESPACE@.sl_confirm\r
-       (con_origin, con_received, con_seqno);\r
-create index sl_confirm_idx2 on @NAMESPACE@.sl_confirm\r
-       (con_received, con_seqno);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_seqlog\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_seqlog (\r
-       seql_seqid                      int4,\r
-       seql_origin                     int4,\r
-       seql_ev_seqno           int8,\r
-       seql_last_value         int8\r
-);\r
-create index sl_seqlog_idx on @NAMESPACE@.sl_seqlog\r
-       (seql_origin, seql_ev_seqno, seql_seqid);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION sequenceLastValue (seqname)\r
---\r
---     Support function used in sl_seqlastvalue view\r
--- ----------------------------------------------------------------------\r
-create function @NAMESPACE@.sequenceLastValue(text) returns int8\r
-as '\r
-declare\r
-       p_seqname       alias for $1;\r
-       v_seq_row       record;\r
-begin\r
-       for v_seq_row in execute ''select last_value from '' || p_seqname\r
-       loop\r
-               return v_seq_row.last_value;\r
-       end loop;\r
-\r
-       -- not reached\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- VIEW sl_seqlastvalue\r
--- ----------------------------------------------------------------------\r
-create view @NAMESPACE@.sl_seqlastvalue as\r
-       select SQ.seq_id, SQ.seq_set, SQ.seq_reloid,\r
-                       S.set_origin as seq_origin,\r
-                       @NAMESPACE@.sequenceLastValue(\r
-                                       "pg_catalog".quote_ident(PGN.nspname) || '.' ||\r
-                                       "pg_catalog".quote_ident(PGC.relname)) as seq_last_value\r
-               from @NAMESPACE@.sl_sequence SQ, @NAMESPACE@.sl_set S,\r
-                       "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN\r
-               where S.set_id = SQ.seq_set\r
-                       and PGC.oid = SQ.seq_reloid and PGN.oid = PGC.relnamespace;\r
-               \r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_log_1\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_log_1 (\r
-       log_origin                      int4,\r
-       log_xid                         @NAMESPACE@.xxid,\r
-       log_tableid                     int4,\r
-       log_actionseq           int8,\r
-       log_cmdtype                     char,\r
-       log_cmddata                     text\r
-);\r
-create index sl_log_1_idx1 on @NAMESPACE@.sl_log_1\r
-       (log_origin, log_xid @NAMESPACE@.xxid_ops, log_actionseq);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_log_2\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_log_2 (\r
-       log_origin                      int4,\r
-       log_xid                         @NAMESPACE@.xxid,\r
-       log_tableid                     int4,\r
-       log_actionseq           int8,\r
-       log_cmdtype                     char,\r
-       log_cmddata                     text\r
-);\r
-create index sl_log_2_idx1 on @NAMESPACE@.sl_log_2\r
-       (log_origin, log_xid @NAMESPACE@.xxid_ops, log_actionseq);\r
-\r
-\r
--- **********************************************************************\r
--- * Sequences\r
--- **********************************************************************\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- SEQUENCE sl_local_node_id\r
---\r
---     The local node ID is initialized to -1, meaning that this node\r
---     is not initialized yet.\r
--- ----------------------------------------------------------------------\r
-create sequence @NAMESPACE@.sl_local_node_id\r
-       MINVALUE -1;\r
-SELECT setval('@NAMESPACE@.sl_local_node_id', -1);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- SEQUENCE sl_event_seq\r
---\r
---     The sequence for numbering events originating from this node.\r
--- ----------------------------------------------------------------------\r
-create sequence @NAMESPACE@.sl_event_seq;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- SEQUENCE sl_action_seq\r
---\r
---     The sequence to number statements in the transaction logs, so that\r
---     the replication engines can figure out the "agreeable" order of\r
---     statements.\r
--- ----------------------------------------------------------------------\r
-create sequence @NAMESPACE@.sl_action_seq;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- SEQUENCE sl_rowid_seq\r
---\r
---     Application tables that do not have a natural primary key must\r
---     be modified and an int8 column added that serves as a rowid for us.\r
---     The values are assigned with a default from this sequence.\r
--- ----------------------------------------------------------------------\r
-create sequence @NAMESPACE@.sl_rowid_seq;\r
-grant select, update on @NAMESPACE@.sl_rowid_seq to public;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- SEQUENCE sl_log_status\r
---\r
---     Bit 0x01 determines the currently active log table\r
---     Bit 0x02 tells if the engine needs to read both logs\r
---     after switching until the old log is clean and truncated.\r
---\r
---     Possible values:\r
---             0               sl_log_1 active, sl_log_2 clean\r
---             1               sl_log_2 active, sl_log_1 clean\r
---             2               sl_log_1 active, sl_log_2 unknown - cleanup\r
---             3               sl_log_2 active, sl_log_1 unknown - cleanup\r
--- ----------------------------------------------------------------------\r
-create sequence @NAMESPACE@.sl_log_status\r
-       MINVALUE 0 MAXVALUE 3;\r
-SELECT setval('@NAMESPACE@.sl_log_status', 0);\r
-\r
-\r
--- **********************************************************************\r
--- * Misc\r
--- **********************************************************************\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- TABLE sl_config_lock\r
---\r
---     This table exists solely to prevent overlapping execution of\r
---     configuration change procedures and the resulting possible\r
---     deadlocks.\r
--- ----------------------------------------------------------------------\r
-create table @NAMESPACE@.sl_config_lock (\r
-       dummy                           integer\r
-);\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- Last but not least grant USAGE to the replication schema objects.\r
--- ----------------------------------------------------------------------\r
-grant usage on schema @NAMESPACE@ to public;\r
-\r
-\r
diff --git a/sql/plugins/slony1_base.v73.sql b/sql/plugins/slony1_base.v73.sql
deleted file mode 100755 (executable)
index 26a1cf1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
--- ----------------------------------------------------------------------\r
--- slony1_base.v73.sql\r
---\r
---    Version 7.3 specific parts of the basic replication schema.\r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: slony1_base.v73.sql,v 1.2 2005/06/16 14:40:14 chriskl Exp $\r
--- ----------------------------------------------------------------------\r
-\r
-\r
diff --git a/sql/plugins/slony1_base.v74.sql b/sql/plugins/slony1_base.v74.sql
deleted file mode 100755 (executable)
index fee05c2..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
--- ----------------------------------------------------------------------\r
--- slony1_base.v73.sql\r
---\r
---    Version 7.3 specific parts of the basic replication schema.\r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: slony1_base.v74.sql,v 1.2 2005/06/16 14:40:14 chriskl Exp $\r
--- ----------------------------------------------------------------------\r
-\r
-\r
diff --git a/sql/plugins/slony1_funcs.sql b/sql/plugins/slony1_funcs.sql
deleted file mode 100755 (executable)
index 0008466..0000000
+++ /dev/null
@@ -1,4271 +0,0 @@
--- ----------------------------------------------------------------------\r
--- slony1_funcs.sql\r
---\r
---    Declaration of replication support functions.\r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: slony1_funcs.sql,v 1.2 2005/06/16 14:40:14 chriskl Exp $\r
--- ----------------------------------------------------------------------\r
-\r
-\r
--- **********************************************************************\r
--- * C functions in src/backend/slony1_base.c\r
--- **********************************************************************\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])\r
---\r
---     Create an sl_event entry\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.createEvent (name, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text, text, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text, text, text, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text, text, text, text, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text, text, text, text, text, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-create or replace function @NAMESPACE@.createEvent (name, text, text, text, text, text, text, text, text, text)\r
-       returns bigint\r
-       as '$libdir/slony1_funcs', '_Slony_I_createEvent'\r
-       language C\r
-       called on null input;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION denyAccess (cluster_name)\r
---\r
---     Trigger function to prevent modifications to a table on\r
---     a subscriber.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.denyAccess ()\r
-       returns trigger\r
-       as '$libdir/slony1_funcs', '_Slony_I_denyAccess'\r
-       language C\r
-       security definer;\r
-grant execute on function @NAMESPACE@.denyAccess () to public;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION lockedSet (cluster_name)\r
---\r
---     Trigger function to prevent modifications to a table before\r
---     and after a moveSet().\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.lockedSet ()\r
-       returns trigger\r
-       as '$libdir/slony1_funcs', '_Slony_I_lockedSet'\r
-       language C;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION getLocalNodeId (name)\r
---\r
---     \r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.getLocalNodeId (name) returns int4\r
-    as '$libdir/slony1_funcs', '_Slony_I_getLocalNodeId'\r
-       language C\r
-       security definer;\r
-grant execute on function @NAMESPACE@.getLocalNodeId (name) to public;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION getModuleVersion ()\r
---\r
---     Returns the compiled in version number of the Slony-I shared\r
---     object.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.getModuleVersion () returns text\r
-    as '$libdir/slony1_funcs', '_Slony_I_getModuleVersion'\r
-       language C\r
-       security definer;\r
-grant execute on function @NAMESPACE@.getModuleVersion () to public;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setSessionRole (name, role)\r
---\r
---     \r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setSessionRole (name, text) returns text\r
-    as '$libdir/slony1_funcs', '_Slony_I_setSessionRole'\r
-       language C\r
-       security definer;\r
-grant execute on function @NAMESPACE@.setSessionRole (name, text) to public;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION getSessionRole (name, role)\r
---\r
---     \r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.getSessionRole (name) returns text\r
-    as '$libdir/slony1_funcs', '_Slony_I_getSessionRole'\r
-       language C\r
-       security definer;\r
-grant execute on function @NAMESPACE@.getSessionRole (name) to public;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION logTrigger ()\r
---\r
---     \r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.logTrigger () returns trigger\r
-    as '$libdir/slony1_funcs', '_Slony_I_logTrigger'\r
-       language C\r
-       security definer;\r
-grant execute on function @NAMESPACE@.logTrigger () to public;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION terminateNodeConnections (name)\r
---\r
---     \r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.terminateNodeConnections (name) returns int4\r
-    as '$libdir/slony1_funcs', '_Slony_I_terminateNodeConnections'\r
-       language C;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION cleanupListener ()\r
---\r
---     \r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.cleanupListener () returns int4\r
-    as '$libdir/slony1_funcs', '_Slony_I_cleanupListener'\r
-       language C;\r
-\r
-\r
--- **********************************************************************\r
--- * PL/pgSQL functions for administrative tasks\r
--- **********************************************************************\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION slonyVersionMajor()\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.slonyVersionMajor()\r
-returns int4\r
-as '\r
-begin\r
-       return 1;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION slonyVersionMinor()\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.slonyVersionMinor()\r
-returns int4\r
-as '\r
-begin\r
-       return 0;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION slonyVersionPatchlevel()\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.slonyVersionPatchlevel()\r
-returns int4\r
-as '\r
-begin\r
-       return 5;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION slonyVersion()\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.slonyVersion()\r
-returns text\r
-as '\r
-begin\r
-       return ''''     || @NAMESPACE@.slonyVersionMajor() || ''.''\r
-                               || @NAMESPACE@.slonyVersionMinor() || ''.''\r
-                               || @NAMESPACE@.slonyVersionPatchlevel();\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION initializeLocalNode (no_id, no_comment)\r
---\r
---     Initializes a new node.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.initializeLocalNode (int4, text)\r
-returns int4\r
-as '\r
-declare\r
-       p_local_node_id         alias for $1;\r
-       p_comment                       alias for $2;\r
-       v_old_node_id           int4;\r
-       v_first_log_no          int4;\r
-       v_event_seq                     int8;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Make sure this node is uninitialized or got reset\r
-       -- ----\r
-       select last_value::int4 into v_old_node_id from @NAMESPACE@.sl_local_node_id;\r
-       if v_old_node_id != -1 then\r
-               raise exception ''Slony-I: This node is already initialized'';\r
-       end if;\r
-\r
-       -- ----\r
-       -- Set sl_local_node_id to the requested value and add our\r
-       -- own system to sl_node.\r
-       -- ----\r
-       perform setval(''@NAMESPACE@.sl_local_node_id'', p_local_node_id);\r
-       perform setval(''@NAMESPACE@.sl_rowid_seq'', \r
-                       p_local_node_id::int8 * ''1000000000000000''::int8);\r
-       perform @NAMESPACE@.storeNode_int (p_local_node_id, p_comment);\r
-       \r
-       return p_local_node_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeNode (no_id, no_comment)\r
---\r
---     Generate the STORE_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeNode (int4, text)\r
-returns bigint\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-       p_no_comment    alias for $2;\r
-begin\r
-       perform @NAMESPACE@.storeNode_int (p_no_id, p_no_comment);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''STORE_NODE'',\r
-                                                                       p_no_id, p_no_comment);\r
-end;\r
-' language plpgsql\r
-       called on null input;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeNode_int (no_id, no_comment)\r
---\r
---     Process the STORE_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeNode_int (int4, text)\r
-returns int4\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-       p_no_comment    alias for $2;\r
-       v_old_row               record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check if the node exists\r
-       -- ----\r
-       select * into v_old_row\r
-                       from @NAMESPACE@.sl_node\r
-                       where no_id = p_no_id\r
-                       for update;\r
-       if found then \r
-               -- ----\r
-               -- Node exists, update the existing row.\r
-               -- ----\r
-               update @NAMESPACE@.sl_node\r
-                               set no_comment = p_no_comment\r
-                               where no_id = p_no_id;\r
-       else\r
-               -- ----\r
-               -- New node, insert the sl_node row\r
-               -- ----\r
-               insert into @NAMESPACE@.sl_node\r
-                               (no_id, no_active, no_comment) values\r
-                               (p_no_id, ''f'', p_no_comment);\r
-       end if;\r
-\r
-       return p_no_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION enableNode (no_id)\r
---\r
---     Generate the ENABLE_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.enableNode (int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-       v_local_node_id int4;\r
-       v_node_row              record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that we are the node to activate and that we are\r
-       -- currently disabled.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select * into v_node_row\r
-                       from @NAMESPACE@.sl_node\r
-                       where no_id = p_no_id\r
-                       for update;\r
-       if not found then \r
-               raise exception ''Slony-I: node % not found'', p_no_id;\r
-       end if;\r
-       if v_node_row.no_active then\r
-               raise exception ''Slony-I: node % is already active'', p_no_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Activate this node and generate the ENABLE_NODE event\r
-       -- ----\r
-       perform @NAMESPACE@.enableNode_int (p_no_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''ENABLE_NODE'',\r
-                                                                       p_no_id);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION enableNode_int (no_id)\r
---\r
---     Process the ENABLE_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.enableNode_int (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-       v_local_node_id int4;\r
-       v_node_row              record;\r
-       v_sub_row               record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that the node is inactive\r
-       -- ----\r
-       select * into v_node_row\r
-                       from @NAMESPACE@.sl_node\r
-                       where no_id = p_no_id\r
-                       for update;\r
-       if not found then \r
-               raise exception ''Slony-I: node % not found'', p_no_id;\r
-       end if;\r
-       if v_node_row.no_active then\r
-               return p_no_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Activate the node and generate sl_confirm status rows for it.\r
-       -- ----\r
-       update @NAMESPACE@.sl_node\r
-                       set no_active = ''t''\r
-                       where no_id = p_no_id;\r
-       insert into @NAMESPACE@.sl_confirm\r
-                       (con_origin, con_received, con_seqno)\r
-                       select no_id, p_no_id, 0 from @NAMESPACE@.sl_node\r
-                               where no_id != p_no_id\r
-                               and no_active;\r
-       insert into @NAMESPACE@.sl_confirm\r
-                       (con_origin, con_received, con_seqno)\r
-                       select p_no_id, no_id, 0 from @NAMESPACE@.sl_node\r
-                               where no_id != p_no_id\r
-                               and no_active;\r
-\r
-       -- ----\r
-       -- Generate ENABLE_SUBSCRIPTION events for all sets that\r
-       -- origin here and are subscribed by the just enabled node.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       for v_sub_row in select SUB.sub_set, SUB.sub_provider from\r
-                       @NAMESPACE@.sl_set S,\r
-                       @NAMESPACE@.sl_subscribe SUB\r
-                       where S.set_origin = v_local_node_id\r
-                       and S.set_id = SUB.sub_set\r
-                       and SUB.sub_receiver = p_no_id\r
-                       for update of S\r
-       loop\r
-               perform @NAMESPACE@.enableSubscription (v_sub_row.sub_set,,\r
-                               v_sub_row.sub_provider, p_no_id);\r
-       end loop;\r
-\r
-       return p_no_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION disableNode (no_id)\r
---\r
---     Generate the DISABLE_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.disableNode (int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-begin\r
-       -- **** TODO ****\r
-       raise exception ''Slony-I: disableNode() not implemented'';\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION disableNode_int (no_id)\r
---\r
---     Process the DISABLE_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.disableNode_int (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-begin\r
-       -- **** TODO ****\r
-       raise exception ''Slony-I: disableNode_int() not implemented'';\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropNode (no_id)\r
---\r
---     Generate the DROP_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropNode (int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-       v_node_row              record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that this got called on a different node\r
-       -- ----\r
-       if p_no_id = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: DROP_NODE cannot initiate on the dropped node'';\r
-       end if;\r
-\r
-       select * into v_node_row from @NAMESPACE@.sl_node\r
-                       where no_id = p_no_id\r
-                       for update;\r
-       if not found then\r
-               raise exception ''Slony-I: unknown node ID %'', p_no_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Make sure we do not break other nodes subscriptions with this\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_subscribe\r
-                       where sub_provider = p_no_id)\r
-       then\r
-               raise exception ''Slony-I: Node % is still configured as data provider'',\r
-                               p_no_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Make sure no set originates there any more\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_set\r
-                       where set_origin = p_no_id)\r
-       then\r
-               raise exception ''Slony-I: Node % is still origin of one or more sets'',\r
-                               p_no_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Call the internal drop functionality and generate the event\r
-       -- ----\r
-       perform @NAMESPACE@.dropNode_int(p_no_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''DROP_NODE'',\r
-                                                                       p_no_id);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropNode_int (no_id)\r
---\r
---     Process the DROP_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropNode_int (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_no_id                 alias for $1;\r
-       v_tab_row               record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- If the dropped node is a remote node, clean the configuration\r
-       -- from all traces for it.\r
-       -- ----\r
-       if p_no_id <> @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               delete from @NAMESPACE@.sl_subscribe\r
-                               where sub_receiver = p_no_id;\r
-               delete from @NAMESPACE@.sl_listen\r
-                               where li_origin = p_no_id\r
-                                       or li_provider = p_no_id\r
-                                       or li_receiver = p_no_id;\r
-               delete from @NAMESPACE@.sl_path\r
-                               where pa_server = p_no_id\r
-                                       or pa_client = p_no_id;\r
-               delete from @NAMESPACE@.sl_confirm\r
-                               where con_origin = p_no_id\r
-                                       or con_received = p_no_id;\r
-               delete from @NAMESPACE@.sl_event\r
-                               where ev_origin = p_no_id;\r
-               delete from @NAMESPACE@.sl_node\r
-                               where no_id = p_no_id;\r
-\r
-               return p_no_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- This is us ... deactivate the node for now, the daemon\r
-       -- will call uninstallNode() in a separate transaction.\r
-       -- ----\r
-       update @NAMESPACE@.sl_node\r
-                       set no_active = false\r
-                       where no_id = p_no_id;\r
-\r
-       return p_no_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION failedNode (failed_node, backup_node)\r
---\r
---     Initiate a failover. This function must be called on all nodes\r
---     and then waited for the restart of all node deamons.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.failedNode(int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_failed_node           alias for $1;\r
-       p_backup_node           alias for $2;\r
-       v_row                           record;\r
-       v_row2                          record;\r
-       v_n                                     int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- All consistency checks first\r
-       -- Check that every system that has a path to the failed node\r
-       -- also has a path to the backup node.\r
-       -- ----\r
-       for v_row in select P.pa_client\r
-                       from @NAMESPACE@.sl_path P\r
-                       where P.pa_server = p_failed_node\r
-                               and P.pa_client <> p_backup_node\r
-                               and not exists (select true from @NAMESPACE@.sl_path PP\r
-                                                       where PP.pa_server = p_backup_node\r
-                                                               and PP.pa_client = P.pa_client)\r
-       loop\r
-               raise exception ''Slony-I: cannot failover - node % has no path to the backup node'',\r
-                               v_row.pa_client;\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Check all sets originating on the failed node\r
-       -- ----\r
-       for v_row in select set_id\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_origin = p_failed_node\r
-       loop\r
-               -- ----\r
-               -- Check that the backup node is subscribed to all sets\r
-               -- that origin on the failed node\r
-               -- ----\r
-               select into v_row2 sub_forward, sub_active\r
-                               from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = v_row.set_id\r
-                                       and sub_receiver = p_backup_node;\r
-               if not found then\r
-                       raise exception ''Slony-I: cannot failover - node % is not subscribed to set %'',\r
-                                       p_backup_node, v_row.set_id;\r
-               end if;\r
-\r
-               -- ----\r
-               -- Check that the subscription is active\r
-               -- ----\r
-               if not v_row2.sub_active then\r
-                       raise exception ''Slony-I: cannot failover - subscription for set % is not active'',\r
-                                       v_row.set_id;\r
-               end if;\r
-\r
-               -- ----\r
-               -- If there are other subscribers, the backup node needs to\r
-               -- be a forwarder too.\r
-               -- ----\r
-               select into v_n count(*)\r
-                               from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = v_row.set_id\r
-                                       and sub_receiver <> p_backup_node;\r
-               if v_n > 0 and not v_row2.sub_forward then\r
-                       raise exception ''Slony-I: cannot failover - node % is not a forwarder of set %'',\r
-                                       p_backup_node, v_row.set_id;\r
-               end if;\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Terminate all connections of the failed node the hard way\r
-       -- ----\r
-       perform @NAMESPACE@.terminateNodeConnections(\r
-                       ''_@CLUSTERNAME@_Node_'' || p_failed_node);\r
-\r
-       -- ----\r
-       -- Let every node that listens for something on the failed node\r
-       -- listen for that on the backup node instead.\r
-       -- ----\r
-       for v_row in select * from @NAMESPACE@.sl_listen\r
-                       where li_provider = p_failed_node\r
-                               and li_receiver <> p_backup_node\r
-       loop\r
-               perform @NAMESPACE@.storeListen_int(v_row.li_origin,\r
-                               p_backup_node, v_row.li_receiver);\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Let the backup node listen for all events where the\r
-       -- failed node did listen for it.\r
-       -- ----\r
-       for v_row in select li_origin, li_provider\r
-                       from @NAMESPACE@.sl_listen\r
-                       where li_receiver = p_failed_node\r
-                               and li_provider <> p_backup_node\r
-       loop\r
-               perform @NAMESPACE@.storeListen_int(v_row.li_origin,\r
-                               v_row.li_provider, p_backup_node);\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Remove all sl_listen entries that receive anything from the\r
-       -- failed node.\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_listen\r
-                       where li_provider = p_failed_node\r
-                               or li_receiver = p_failed_node;\r
-\r
-       -- ----\r
-       -- Move the sets\r
-       -- ----\r
-       for v_row in select S.set_id, (select count(*)\r
-                                       from @NAMESPACE@.sl_subscribe SUB\r
-                                       where S.set_id = SUB.sub_set\r
-                                               and SUB.sub_receiver <> p_backup_node\r
-                                               and SUB.sub_provider = p_failed_node)\r
-                                       as num_direct_receivers \r
-                       from @NAMESPACE@.sl_set S\r
-                       where S.set_origin = p_failed_node\r
-                       for update\r
-       loop\r
-               -- ----\r
-               -- If the backup node is the only direct subscriber ...\r
-               -- ----\r
-               if v_row.num_direct_receivers = 0 then\r
-raise notice ''failedNode: set % has no other direct receivers - move now'', v_row.set_id;\r
-                       -- ----\r
-                       -- backup_node is the only direct subscriber, move the set\r
-                       -- right now. On the backup node itself that includes restoring\r
-                       -- all user mode triggers, removing the protection trigger,\r
-                       -- adding the log trigger, removing the subscription and the\r
-                       -- obsolete setsync status.\r
-                       -- ----\r
-                       if p_backup_node = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-                               for v_row2 in select * from @NAMESPACE@.sl_table\r
-                                               where tab_set = v_row.set_id\r
-                               loop\r
-                                       perform @NAMESPACE@.alterTableRestore(v_row2.tab_id);\r
-                               end loop;\r
-                       end if;\r
-\r
-                       update @NAMESPACE@.sl_set set set_origin = p_backup_node\r
-                                       where set_id = v_row.set_id;\r
-\r
-                       if p_backup_node = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-                               delete from @NAMESPACE@.sl_setsync\r
-                                               where ssy_setid = v_row.set_id;\r
-\r
-                               for v_row2 in select * from @NAMESPACE@.sl_table\r
-                                               where tab_set = v_row.set_id\r
-                               loop\r
-                                       perform @NAMESPACE@.alterTableForReplication(v_row2.tab_id);\r
-                               end loop;\r
-                       end if;\r
-\r
-                       delete from @NAMESPACE@.sl_subscribe\r
-                                       where sub_set = v_row.set_id\r
-                                               and sub_receiver = p_backup_node;\r
-               else\r
-raise notice ''failedNode: set % has other direct receivers - change providers only'', v_row.set_id;\r
-                       -- ----\r
-                       -- Backup node is not the only direct subscriber. This\r
-                       -- means that at this moment, we redirect all direct\r
-                       -- subscribers to receive from the backup node, and the\r
-                       -- backup node itself to receive from another one.\r
-                       -- The admin utility will wait for the slon engine to\r
-                       -- restart and then call failedNode2() on the node with\r
-                       -- the highest SYNC and redirect this to it on\r
-                       -- backup node later.\r
-                       -- ----\r
-                       update @NAMESPACE@.sl_subscribe\r
-                                       set sub_provider = (select min(SS.sub_receiver)\r
-                                                       from @NAMESPACE@.sl_subscribe SS\r
-                                                       where SS.sub_set = v_row.set_id\r
-                                                               and SS.sub_provider = p_failed_node\r
-                                                               and SS.sub_receiver <> p_backup_node\r
-                                                               and SS.sub_forward)\r
-                                       where sub_set = v_row.set_id\r
-                                               and sub_receiver = p_backup_node;\r
-                       update @NAMESPACE@.sl_subscribe\r
-                                       set sub_provider = p_backup_node\r
-                                       where sub_set = v_row.set_id\r
-                                               and sub_provider = p_failed_node\r
-                                               and sub_receiver <> p_backup_node;\r
-               end if;\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Make sure the node daemon will restart\r
-       -- ----\r
-       notify "_@CLUSTERNAME@_Restart";\r
-\r
-       -- ----\r
-       -- That is it - so far.\r
-       -- ----\r
-       return p_failed_node;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION failedNode2 (failed_node, backup_node, set_id, ev_seqno, ev_seqfake)\r
---\r
---     On the node that has the highest sequence number of the failed node,\r
---     fake the FAILED_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.failedNode2 (int4, int4, int4, int8, int8)\r
-returns bigint\r
-as '\r
-declare\r
-       p_failed_node           alias for $1;\r
-       p_backup_node           alias for $2;\r
-       p_set_id                        alias for $3;\r
-       p_ev_seqno                      alias for $4;\r
-       p_ev_seqfake            alias for $5;\r
-       v_row                           record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       select * into v_row\r
-                       from @NAMESPACE@.sl_event\r
-                       where ev_origin = p_failed_node\r
-                       and ev_seqno = p_ev_seqno;\r
-       if not found then\r
-               raise exception ''Slony-I: event %,% not found'',\r
-                               p_failed_node, p_ev_seqno;\r
-       end if;\r
-\r
-       insert into @NAMESPACE@.sl_event\r
-                       (ev_origin, ev_seqno, ev_timestamp,\r
-                       ev_minxid, ev_maxxid, ev_xip,\r
-                       ev_type, ev_data1, ev_data2, ev_data3)\r
-                       values \r
-                       (p_failed_node, p_ev_seqfake, CURRENT_TIMESTAMP,\r
-                       v_row.ev_minxid, v_row.ev_maxxid, v_row.ev_xip,\r
-                       ''FAILOVER_SET'', p_failed_node::text, p_backup_node::text,\r
-                       p_set_id::text);\r
-       insert into @NAMESPACE@.sl_confirm\r
-                       (con_origin, con_received, con_seqno, con_timestamp)\r
-                       values\r
-                       (p_failed_node, @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@''),\r
-                       p_ev_seqfake, CURRENT_TIMESTAMP);\r
-       notify "_@CLUSTERNAME@_Event";\r
-       notify "_@CLUSTERNAME@_Confirm";\r
-       notify "_@CLUSTERNAME@_Restart";\r
-\r
-       perform @NAMESPACE@.failoverSet_int(p_failed_node,\r
-                       p_backup_node, p_set_id);\r
-\r
-       return p_ev_seqfake;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION failoverSet_int (failed_node, backup_node, set_id)\r
---\r
---     Finish failover for one set.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.failoverSet_int (int4, int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_failed_node           alias for $1;\r
-       p_backup_node           alias for $2;\r
-       p_set_id                        alias for $3;\r
-       v_row                           record;\r
-       v_last_sync                     int8;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Change the origin of the set now to the backup node.\r
-       -- On the backup node this includes changing all the\r
-       -- trigger and protection stuff\r
-       -- ----\r
-       if p_backup_node = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               for v_row in select * from @NAMESPACE@.sl_table\r
-                               where tab_set = p_set_id\r
-               loop\r
-                       perform @NAMESPACE@.alterTableRestore(v_row.tab_id);\r
-               end loop;\r
-\r
-               delete from @NAMESPACE@.sl_setsync\r
-                               where ssy_setid = p_set_id;\r
-               delete from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = p_set_id\r
-                                       and sub_receiver = p_backup_node;\r
-               update @NAMESPACE@.sl_set\r
-                               set set_origin = p_backup_node\r
-                               where set_id = p_set_id;\r
-\r
-               for v_row in select * from @NAMESPACE@.sl_table\r
-                               where tab_set = p_set_id\r
-               loop\r
-                       perform @NAMESPACE@.alterTableForReplication(v_row.tab_id);\r
-               end loop;\r
-       else\r
-               delete from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = p_set_id\r
-                                       and sub_receiver = p_backup_node;\r
-               update @NAMESPACE@.sl_set\r
-                               set set_origin = p_backup_node\r
-                               where set_id = p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- If we are a subscriber of the set ourself, change our\r
-       -- setsync status to reflect the new set origin.\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_set_id\r
-                               and sub_receiver = @NAMESPACE@.getLocalNodeId(\r
-                                               ''_@CLUSTERNAME@''))\r
-       then\r
-               delete from @NAMESPACE@.sl_setsync\r
-                               where ssy_setid = p_set_id;\r
-\r
-               select coalesce(max(ev_seqno), 0) into v_last_sync\r
-                               from @NAMESPACE@.sl_event\r
-                               where ev_origin = p_backup_node\r
-                                       and ev_type = ''SYNC'';\r
-               if v_last_sync > 0 then\r
-                       insert into @NAMESPACE@.sl_setsync\r
-                                       (ssy_setid, ssy_origin, ssy_seqno,\r
-                                       ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)\r
-                                       select p_set_id, p_backup_node, v_last_sync,\r
-                                       ev_minxid, ev_maxxid, ev_xip, NULL\r
-                                       from @NAMESPACE@.sl_event\r
-                                       where ev_origin = p_backup_node\r
-                                               and ev_seqno = v_last_sync;\r
-               else\r
-                       insert into @NAMESPACE@.sl_setsync\r
-                                       (ssy_setid, ssy_origin, ssy_seqno,\r
-                                       ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)\r
-                                       values (p_set_id, p_backup_node, ''0'',\r
-                                       ''0'', ''0'', '''', NULL);\r
-               end if;\r
-                               \r
-       end if;\r
-\r
-       return p_failed_node;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION uninstallNode ()\r
---\r
---     Reset the whole database to standalone by removing the whole\r
---     replication system.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.uninstallNode ()\r
-returns int4\r
-as '\r
-declare\r
-       v_tab_row               record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- This is us ... time for suicide! Restore all tables to\r
-       -- their original status.\r
-       -- ----\r
-       for v_tab_row in select * from @NAMESPACE@.sl_table loop\r
-               perform @NAMESPACE@.alterTableRestore(v_tab_row.tab_id);\r
-               perform @NAMESPACE@.tableDropKey(v_tab_row.tab_id);\r
-       end loop;\r
-\r
-       raise notice ''Slony-I: Please drop schema "_@CLUSTERNAME@"'';\r
-       return 0;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storePath (pa_server, pa_client, pa_conninfo, pa_connretry)\r
---\r
---     Generate the STORE_PATH event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storePath (int4, int4, text, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_pa_server             alias for $1;\r
-       p_pa_client             alias for $2;\r
-       p_pa_conninfo   alias for $3;\r
-       p_pa_connretry  alias for $4;\r
-begin\r
-       perform @NAMESPACE@.storePath_int(p_pa_server, p_pa_client,\r
-                       p_pa_conninfo, p_pa_connretry);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''STORE_PATH'', \r
-                       p_pa_server, p_pa_client, p_pa_conninfo, p_pa_connretry);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storePath_int (pa_server, pa_client, pa_conninfo, pa_connretry)\r
---\r
---     Process the STORE_PATH event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storePath_int (int4, int4, text, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_pa_server             alias for $1;\r
-       p_pa_client             alias for $2;\r
-       p_pa_conninfo   alias for $3;\r
-       p_pa_connretry  alias for $4;\r
-       v_dummy                 int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check if the path already exists\r
-       -- ----\r
-       select 1 into v_dummy\r
-                       from @NAMESPACE@.sl_path\r
-                       where pa_server = p_pa_server\r
-                       and pa_client = p_pa_client\r
-                       for update;\r
-       if found then\r
-               -- ----\r
-               -- Path exists, update pa_conninfo\r
-               -- ----\r
-               update @NAMESPACE@.sl_path\r
-                               set pa_conninfo = p_pa_conninfo,\r
-                                       pa_connretry = p_pa_connretry\r
-                               where pa_server = p_pa_server\r
-                               and pa_client = p_pa_client;\r
-       else\r
-               -- ----\r
-               -- New path\r
-               --\r
-               -- In case we receive STORE_PATH events before we know\r
-               -- about the nodes involved in this, we generate those nodes\r
-               -- as pending.\r
-               -- ----\r
-               if not exists (select 1 from @NAMESPACE@.sl_node\r
-                                               where no_id = p_pa_server) then\r
-                       perform @NAMESPACE@.storeNode_int (p_pa_server, ''<event pending>'');\r
-               end if;\r
-               if not exists (select 1 from @NAMESPACE@.sl_node\r
-                                               where no_id = p_pa_client) then\r
-                       perform @NAMESPACE@.storeNode_int (p_pa_client, ''<event pending>'');\r
-               end if;\r
-               insert into @NAMESPACE@.sl_path\r
-                               (pa_server, pa_client, pa_conninfo, pa_connretry) values\r
-                               (p_pa_server, p_pa_client, p_pa_conninfo, p_pa_connretry);\r
-       end if;\r
-\r
-       return 0;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropPath (pa_server, pa_client)\r
---\r
---     Generate the DROP_PATH event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropPath (int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_pa_server             alias for $1;\r
-       p_pa_client             alias for $2;\r
-       v_row                   record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- There should be no existing subscriptions. Auto unsubscribing\r
-       -- is considered too dangerous. \r
-       -- ----\r
-       for v_row in select sub_set, sub_provider, sub_receiver\r
-                       from @NAMESPACE@.sl_subscribe\r
-                       where sub_provider = p_pa_server\r
-                       and sub_receiver = p_pa_client\r
-       loop\r
-               raise exception \r
-                       ''Slony-I: Path cannot be dropped, subscription of set % needs it'',\r
-                       v_row.sub_set;\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Drop all sl_listen entries that depend on this path\r
-       -- ----\r
-       for v_row in select li_origin, li_provider, li_receiver\r
-                       from @NAMESPACE@.sl_listen\r
-                       where li_provider = p_pa_server\r
-                       and li_receiver = p_pa_client\r
-       loop\r
-               perform @NAMESPACE@.dropListen(\r
-                               v_row.li_origin, v_row.li_provider, v_row.li_receiver);\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Now drop the path and create the event\r
-       -- ----\r
-       perform @NAMESPACE@.dropPath_int(p_pa_server, p_pa_client);\r
-       return  @NAMESPACE@.createEvent (''_@CLUSTERNAME@'', ''DROP_PATH'',\r
-                       p_pa_server, p_pa_client);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropPath_int (pa_server, pa_client)\r
---\r
---     Process the DROP_NODE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropPath_int (int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_pa_server             alias for $1;\r
-       p_pa_client             alias for $2;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Remove any dangling sl_listen entries with the server\r
-       -- as provider and the client as receiver. This must have\r
-       -- been cleared out before, but obviously was not.\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_listen\r
-                       where li_provider = p_pa_server\r
-                       and li_receiver = p_pa_client;\r
-\r
-       delete from @NAMESPACE@.sl_path\r
-                       where pa_server = p_pa_server\r
-                       and pa_client = p_pa_client;\r
-\r
-       if found then\r
-               return 1;\r
-       else\r
-               return 0;\r
-       end if;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeListen (li_origin, li_provider, li_receiver)\r
---\r
---     Generate the STORE_LISTEN event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeListen (int4, int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_li_origin             alias for $1;\r
-       p_li_provider   alias for $2;\r
-       p_li_receiver   alias for $3;\r
-begin\r
-       perform @NAMESPACE@.storeListen_int (p_li_origin, p_li_provider, p_li_receiver);\r
-       return  @NAMESPACE@.createEvent (''_@CLUSTERNAME@'', ''STORE_LISTEN'',\r
-                       p_li_origin, p_li_provider, p_li_receiver);\r
-end;\r
-' language plpgsql\r
-       called on null input;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeListen_int (li_origin, li_provider, li_receiver)\r
---\r
---     Process the STORE_LISTEN event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeListen_int (int4, int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_li_origin             alias for $1;\r
-       p_li_provider   alias for $2;\r
-       p_li_receiver   alias for $3;\r
-       v_exists                int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       select 1 into v_exists\r
-                       from @NAMESPACE@.sl_listen\r
-                       where li_origin = p_li_origin\r
-                       and li_provider = p_li_provider\r
-                       and li_receiver = p_li_receiver;\r
-       if not found then\r
-               -- ----\r
-               -- In case we receive STORE_LISTEN events before we know\r
-               -- about the nodes involved in this, we generate those nodes\r
-               -- as pending.\r
-               -- ----\r
-               if not exists (select 1 from @NAMESPACE@.sl_node\r
-                                               where no_id = p_li_origin) then\r
-                       perform @NAMESPACE@.storeNode_int (p_li_origin, ''<event pending>'');\r
-               end if;\r
-               if not exists (select 1 from @NAMESPACE@.sl_node\r
-                                               where no_id = p_li_provider) then\r
-                       perform @NAMESPACE@.storeNode_int (p_li_provider, ''<event pending>'');\r
-               end if;\r
-               if not exists (select 1 from @NAMESPACE@.sl_node\r
-                                               where no_id = p_li_receiver) then\r
-                       perform @NAMESPACE@.storeNode_int (p_li_receiver, ''<event pending>'');\r
-               end if;\r
-\r
-               insert into @NAMESPACE@.sl_listen\r
-                               (li_origin, li_provider, li_receiver) values\r
-                               (p_li_origin, p_li_provider, p_li_receiver);\r
-       end if;\r
-\r
-       return 0;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropListen (li_origin, li_provider, li_receiver)\r
---\r
---     Generate the DROP_LISTEN event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropListen (int4, int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_li_origin             alias for $1;\r
-       p_li_provider   alias for $2;\r
-       p_li_receiver   alias for $3;\r
-begin\r
-       perform @NAMESPACE@.dropListen_int(p_li_origin, \r
-                       p_li_provider, p_li_receiver);\r
-       \r
-       return  @NAMESPACE@.createEvent (''_@CLUSTERNAME@'', ''DROP_LISTEN'',\r
-                       p_li_origin, p_li_provider, p_li_receiver);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropListen_int (li_origin, li_provider, li_receiver)\r
---\r
---     Process the DROP_LISTEN event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropListen_int (int4, int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_li_origin             alias for $1;\r
-       p_li_provider   alias for $2;\r
-       p_li_receiver   alias for $3;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       delete from @NAMESPACE@.sl_listen\r
-                       where li_origin = p_li_origin\r
-                       and li_provider = p_li_provider\r
-                       and li_receiver = p_li_receiver;\r
-       if found then\r
-               return 1;\r
-       else\r
-               return 0;\r
-       end if;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeSet (set_id, set_comment)\r
---\r
---     Generate the STORE_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeSet (int4, text)\r
-returns bigint\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_set_comment           alias for $2;\r
-       v_local_node_id         int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-\r
-       insert into @NAMESPACE@.sl_set\r
-                       (set_id, set_origin, set_comment) values\r
-                       (p_set_id, v_local_node_id, p_set_comment);\r
-\r
-       return @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''STORE_SET'', \r
-                       p_set_id, v_local_node_id, p_set_comment);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeSet_int (set_id, set_origin, set_comment)\r
---\r
---     Process the STORE_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeSet_int (int4, int4, text)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_set_origin            alias for $2;\r
-       p_set_comment           alias for $3;\r
-       v_dummy                         int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       select 1 into v_dummy\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id\r
-                       for update;\r
-       if found then \r
-               update @NAMESPACE@.sl_set\r
-                               set set_comment = p_set_comment\r
-                               where set_id = p_set_id;\r
-       else\r
-               if not exists (select 1 from @NAMESPACE@.sl_node\r
-                                               where no_id = p_set_origin) then\r
-                       perform @NAMESPACE@.storeNode_int (p_set_origin, ''<event pending>'');\r
-               end if;\r
-               insert into @NAMESPACE@.sl_set\r
-                               (set_id, set_origin, set_comment) values\r
-                               (p_set_id, p_set_origin, p_set_comment);\r
-       end if;\r
-\r
-       return p_set_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION lockSet (set_id)\r
---\r
---     Add a special trigger to all tables of a set that disables\r
---     access to it.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.lockSet (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       v_local_node_id         int4;\r
-       v_set_row                       record;\r
-       v_tab_row                       record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that the set exists and that we are the origin\r
-       -- and that it is not already locked.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select * into v_set_row from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id\r
-                       for update;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_set_id;\r
-       end if;\r
-       if v_set_row.set_origin <> v_local_node_id then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_set_id;\r
-       end if;\r
-       if v_set_row.set_locked notnull then\r
-               raise exception ''Slony-I: set % is already locked'', p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Place the lockedSet trigger on all tables in the set.\r
-       -- ----\r
-       for v_tab_row in select T.tab_id,\r
-                       "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                       "pg_catalog".quote_ident(PGC.relname) as tab_fqname\r
-                       from @NAMESPACE@.sl_table T,\r
-                               "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN\r
-                       where T.tab_set = p_set_id\r
-                               and T.tab_reloid = PGC.oid\r
-                               and PGC.relnamespace = PGN.oid\r
-                       order by tab_id\r
-       loop\r
-               execute ''create trigger "_@CLUSTERNAME@_lockedset_'' || \r
-                               v_tab_row.tab_id || \r
-                               ''" before insert or update or delete on '' ||\r
-                               v_tab_row.tab_fqname || '' for each row execute procedure\r
-                               @NAMESPACE@.lockedSet (''''_@CLUSTERNAME@'''');'';\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Remember our snapshots xmax as for the set locking\r
-       -- ----\r
-       update @NAMESPACE@.sl_set\r
-                       set set_locked = @NAMESPACE@.getMaxXid()\r
-                       where set_id = p_set_id;\r
-\r
-       return p_set_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION unlockSet (set_id)\r
---\r
---     Remove the special trigger from all tables of a set that disables\r
---     access to it.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.unlockSet (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       v_local_node_id         int4;\r
-       v_set_row                       record;\r
-       v_tab_row                       record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that the set exists and that we are the origin\r
-       -- and that it is not already locked.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select * into v_set_row from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id\r
-                       for update;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_set_id;\r
-       end if;\r
-       if v_set_row.set_origin <> v_local_node_id then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_set_id;\r
-       end if;\r
-       if v_set_row.set_locked isnull then\r
-               raise exception ''Slony-I: set % is not locked'', p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Drop the lockedSet trigger from all tables in the set.\r
-       -- ----\r
-       for v_tab_row in select T.tab_id,\r
-                       "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                       "pg_catalog".quote_ident(PGC.relname) as tab_fqname\r
-                       from @NAMESPACE@.sl_table T,\r
-                               "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN\r
-                       where T.tab_set = p_set_id\r
-                               and T.tab_reloid = PGC.oid\r
-                               and PGC.relnamespace = PGN.oid\r
-                       order by tab_id\r
-       loop\r
-               execute ''drop trigger "_@CLUSTERNAME@_lockedset_'' || \r
-                               v_tab_row.tab_id || ''" on '' || v_tab_row.tab_fqname;\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Clear out the set_locked field\r
-       -- ----\r
-       update @NAMESPACE@.sl_set\r
-                       set set_locked = NULL\r
-                       where set_id = p_set_id;\r
-\r
-       return p_set_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION moveSet (set_id, new_origin)\r
---\r
---     Generate the MOVE_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.moveSet (int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_new_origin            alias for $2;\r
-       v_local_node_id         int4;\r
-       v_set_row                       record;\r
-       v_sub_row                       record;\r
-       v_sync_seqno            int8;\r
-       v_lv_row                        record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that the set is locked and that this locking\r
-       -- happened long enough ago.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select * into v_set_row from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id\r
-                       for update;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_set_id;\r
-       end if;\r
-       if v_set_row.set_origin <> v_local_node_id then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_set_id;\r
-       end if;\r
-       if v_set_row.set_locked isnull then\r
-               raise exception ''Slony-I: set % is not locked'', p_set_id;\r
-       end if;\r
-       if v_set_row.set_locked > @NAMESPACE@.getMinXid() then\r
-               raise exception ''Slony-I: cannot move set % yet, transactions < % are still in progress'',\r
-                               p_set_id, v_set_row.set_locked;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Unlock the set\r
-       -- ----\r
-       perform @NAMESPACE@.unlockSet(p_set_id);\r
-\r
-       -- ----\r
-       -- Check that the new_origin is an active subscriber of the set\r
-       -- ----\r
-       select * into v_sub_row from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_set_id\r
-                       and sub_receiver = p_new_origin;\r
-       if not found then\r
-               raise exception ''Slony-I: set % is not subscribed by node %'',\r
-                               p_set_id, p_new_origin;\r
-       end if;\r
-       if not v_sub_row.sub_active then\r
-               raise exception ''Slony-I: subsctiption of node % for set % is inactive'',\r
-                               p_new_origin, p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Reconfigure everything\r
-       -- ----\r
-       perform @NAMESPACE@.moveSet_int(p_set_id, v_local_node_id,\r
-                       p_new_origin);\r
-\r
-       -- ----\r
-       -- At this time we hold access exclusive locks for every table\r
-       -- in the set. But we did move the set to the new origin, so the\r
-       -- createEvent() we are doing now will not record the sequences.\r
-       -- ----\r
-       v_sync_seqno := @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SYNC'');\r
-       insert into @NAMESPACE@.sl_seqlog \r
-                       (seql_seqid, seql_origin, seql_ev_seqno, seql_last_value)\r
-                       select seq_id, v_local_node_id, v_sync_seqno, seq_last_value\r
-                       from @NAMESPACE@.sl_seqlastvalue\r
-                       where seq_set = p_set_id;\r
-                                       \r
-       -- ----\r
-       -- Finally we generate the real event\r
-       -- ----\r
-       return @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''MOVE_SET'', \r
-                       p_set_id, v_local_node_id, p_new_origin);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION moveSet_int (set_id, old_origin, new_origin)\r
---\r
---     Process the MOVE_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.moveSet_int (int4, int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_old_origin            alias for $2;\r
-       p_new_origin            alias for $3;\r
-       v_local_node_id         int4;\r
-       v_tab_row                       record;\r
-       v_sub_row                       record;\r
-       v_sub_node                      int4;\r
-       v_sub_last                      int4;\r
-       v_sub_next                      int4;\r
-       v_last_sync                     int8;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Get our local node ID\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-\r
-       -- ----\r
-       -- If we are the old or new origin of the set, we need to\r
-       -- remove the log trigger from all tables first.\r
-       -- ----\r
-       if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then\r
-               for v_tab_row in select tab_id from @NAMESPACE@.sl_table\r
-                               where tab_set = p_set_id\r
-                               order by tab_id\r
-               loop\r
-                       perform @NAMESPACE@.alterTableRestore(v_tab_row.tab_id);\r
-               end loop;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Next we have to reverse the subscription path\r
-       -- ----\r
-       v_sub_last = p_new_origin;\r
-       select sub_provider into v_sub_node\r
-                       from @NAMESPACE@.sl_subscribe\r
-                       where sub_receiver = p_new_origin;\r
-       if not found then\r
-               raise exception ''Slony-I: subscription path broken in moveSet_int'';\r
-       end if;\r
-       while v_sub_node <> p_old_origin loop\r
-               -- ----\r
-               -- Tracing node by node, the old receiver is now in\r
-               -- v_sub_last and the old provider is in v_sub_node.\r
-               -- ----\r
-\r
-               -- ----\r
-               -- Get the current provider of this node as next\r
-               -- and change the provider to the previous one in\r
-               -- the reverse chain.\r
-               -- ----\r
-               select sub_provider into v_sub_next\r
-                               from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = p_set_id\r
-                                       and sub_receiver = v_sub_node\r
-                               for update;\r
-               if not found then\r
-                       raise exception ''Slony-I: subscription path broken in moveSet_int'';\r
-               end if;\r
-               update @NAMESPACE@.sl_subscribe\r
-                               set sub_provider = v_sub_last\r
-                               where sub_set = p_set_id\r
-                                       and sub_receiver = v_sub_node;\r
-\r
-               v_sub_last = v_sub_node;\r
-               v_sub_node = v_sub_next;\r
-       end loop;\r
-\r
-       -- ----\r
-       -- This includes creating a subscription for the old origin\r
-       -- ----\r
-       insert into @NAMESPACE@.sl_subscribe\r
-                       (sub_set, sub_provider, sub_receiver,\r
-                       sub_forward, sub_active)\r
-                       values (p_set_id, v_sub_last, p_old_origin, true, true);\r
-       if v_local_node_id = p_old_origin then\r
-               select coalesce(max(ev_seqno), 0) into v_last_sync \r
-                               from @NAMESPACE@.sl_event\r
-                               where ev_origin = p_new_origin\r
-                                       and ev_type = ''SYNC'';\r
-               if v_last_sync > 0 then\r
-                       insert into @NAMESPACE@.sl_setsync\r
-                                       (ssy_setid, ssy_origin, ssy_seqno,\r
-                                       ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)\r
-                                       select p_set_id, p_new_origin, v_last_sync,\r
-                                       ev_minxid, ev_maxxid, ev_xip, NULL\r
-                                       from @NAMESPACE@.sl_event\r
-                                       where ev_origin = p_new_origin\r
-                                               and ev_seqno = v_last_sync;\r
-               else\r
-                       insert into @NAMESPACE@.sl_setsync\r
-                                       (ssy_setid, ssy_origin, ssy_seqno,\r
-                                       ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)\r
-                                       values (p_set_id, p_new_origin, ''0'',\r
-                                       ''0'', ''0'', '''', NULL);\r
-               end if;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Now change the ownership of the set.\r
-       -- ----\r
-       update @NAMESPACE@.sl_set\r
-                       set set_origin = p_new_origin\r
-                       where set_id = p_set_id;\r
-\r
-       -- ----\r
-       -- On the new origin, delete the obsolete setsync information\r
-       -- and the subscription.\r
-       -- ----\r
-       if v_local_node_id = p_new_origin then\r
-               delete from @NAMESPACE@.sl_setsync\r
-                               where ssy_setid = p_set_id;\r
-       else\r
-               if v_local_node_id <> p_old_origin then\r
-                       --\r
-                       -- On every other node, change the setsync so that it will\r
-                       -- pick up from the new origins last known sync.\r
-                       --\r
-                       delete from @NAMESPACE@.sl_setsync\r
-                                       where ssy_setid = p_set_id;\r
-                       select coalesce(max(ev_seqno), 0) into v_last_sync\r
-                                       from @NAMESPACE@.sl_event\r
-                                       where ev_origin = p_new_origin\r
-                                               and ev_type = ''SYNC'';\r
-                       if v_last_sync > 0 then\r
-                               insert into @NAMESPACE@.sl_setsync\r
-                                               (ssy_setid, ssy_origin, ssy_seqno,\r
-                                               ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)\r
-                                               select p_set_id, p_new_origin, v_last_sync,\r
-                                               ev_minxid, ev_maxxid, ev_xip, NULL\r
-                                               from @NAMESPACE@.sl_event\r
-                                               where ev_origin = p_new_origin\r
-                                                       and ev_seqno = v_last_sync;\r
-                       else\r
-                               insert into @NAMESPACE@.sl_setsync\r
-                                               (ssy_setid, ssy_origin, ssy_seqno,\r
-                                               ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)\r
-                                               values (p_set_id, p_new_origin, ''0'',\r
-                                               ''0'', ''0'', '''', NULL);\r
-                       end if;\r
-               end if;\r
-       end if;\r
-       delete from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_set_id\r
-                       and sub_receiver = p_new_origin;\r
-\r
-       -- ----\r
-       -- If we are the new or old origin, we have to\r
-       -- put all the tables into altered state again.\r
-       -- ----\r
-       if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then\r
-               for v_tab_row in select tab_id from @NAMESPACE@.sl_table\r
-                               where tab_set = p_set_id\r
-                               order by tab_id\r
-               loop\r
-                       perform @NAMESPACE@.alterTableForReplication(v_tab_row.tab_id);\r
-               end loop;\r
-       end if;\r
-\r
-       return p_set_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropSet (set_id)\r
---\r
---     Generate the DROP_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropSet (int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       v_origin                        int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-       \r
-       -- ----\r
-       -- Check that the set exists and originates here\r
-       -- ----\r
-       select set_origin into v_origin from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_set_id;\r
-       end if;\r
-       if v_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Call the internal drop set functionality and generate the event\r
-       -- ----\r
-       perform @NAMESPACE@.dropSet_int(p_set_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''DROP_SET'', \r
-                       p_set_id);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropSet_int (set_id)\r
---\r
---     Process the DROP_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropSet_int (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       v_tab_row                       record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-       \r
-       -- ----\r
-       -- Restore all tables original triggers and rules and remove\r
-       -- our replication stuff.\r
-       -- ----\r
-       for v_tab_row in select tab_id from @NAMESPACE@.sl_table\r
-                       where tab_set = p_set_id\r
-                       order by tab_id\r
-       loop\r
-               perform @NAMESPACE@.alterTableRestore(v_tab_row.tab_id);\r
-               perform @NAMESPACE@.tableDropKey(v_tab_row.tab_id);\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Remove all traces of the set configuration\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_sequence\r
-                       where seq_set = p_set_id;\r
-       delete from @NAMESPACE@.sl_table\r
-                       where tab_set = p_set_id;\r
-       delete from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_set_id;\r
-       delete from @NAMESPACE@.sl_setsync\r
-                       where ssy_setid = p_set_id;\r
-       delete from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id;\r
-\r
-       return p_set_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION mergeSet (set_id, add_id)\r
---\r
---     Generate the MERGE_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.mergeSet (int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_add_id                        alias for $2;\r
-       v_origin                        int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-       \r
-       -- ----\r
-       -- Check that both sets exist and originate here\r
-       -- ----\r
-       if p_set_id = p_add_id then\r
-               raise exception ''Slony-I: merged set ids cannot be identical'';\r
-       end if;\r
-       select set_origin into v_origin from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_set_id;\r
-       end if;\r
-       if v_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_set_id;\r
-       end if;\r
-\r
-       select set_origin into v_origin from @NAMESPACE@.sl_set\r
-                       where set_id = p_add_id;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_add_id;\r
-       end if;\r
-       if v_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_add_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Check that both sets are subscribed by the same set of nodes\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_subscribe SUB1\r
-                               where SUB1.sub_set = p_set_id\r
-                               and SUB1.sub_receiver not in (select SUB2.sub_receiver\r
-                                               from @NAMESPACE@.sl_subscribe SUB2\r
-                                               where SUB2.sub_set = p_add_id))\r
-       then\r
-               raise exception ''Slony-I: subscriber lists of set % and % are different'',\r
-                               p_set_id, p_add_id;\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_subscribe SUB1\r
-                               where SUB1.sub_set = p_add_id\r
-                               and SUB1.sub_receiver not in (select SUB2.sub_receiver\r
-                                               from @NAMESPACE@.sl_subscribe SUB2\r
-                                               where SUB2.sub_set = p_set_id))\r
-       then\r
-               raise exception ''Slony-I: subscriber lists of set % and % are different'',\r
-                               p_add_id, p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Also check that there are no unconfirmed enable subscriptions\r
-       -- still lingering (prevents bug 896)\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_origin\r
-                               and ev_type = ''ENABLE_SUBSCRIPTION''\r
-                               and ev_data1 = p_set_id\r
-                               and ev_seqno > (select min(max_con_seqno) from\r
-                                       (select con_received, max(con_seqno) as max_con_seqno\r
-                                                       from @NAMESPACE@.sl_confirm\r
-                                                       where con_origin = v_origin\r
-                                                       group by con_received) as CON\r
-                                       )\r
-                               )\r
-       then\r
-               raise exception ''Slony-I: set % cannot be merged because of pending subscription'',\r
-                               p_set_id;\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_origin\r
-                               and ev_type = ''ENABLE_SUBSCRIPTION''\r
-                               and ev_data1 = p_add_id\r
-                               and ev_seqno > (select min(max_con_seqno) from\r
-                                       (select con_received, max(con_seqno) as max_con_seqno\r
-                                                       from @NAMESPACE@.sl_confirm\r
-                                                       where con_origin = v_origin\r
-                                                       group by con_received) as CON\r
-                                       )\r
-                               )\r
-       then\r
-               raise exception ''Slony-I: set % cannot be merged because of pending subscription'',\r
-                               p_add_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Create a SYNC event, merge the sets, create a MERGE_SET event\r
-       -- ----\r
-       perform @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SYNC'', NULL);\r
-       perform @NAMESPACE@.mergeSet_int(p_set_id, p_add_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''MERGE_SET'', \r
-                       p_set_id, p_add_id);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION mergeSet_int (set_id, add_id)\r
---\r
---     Process the MERGE_SET event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.mergeSet_int (int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_add_id                        alias for $2;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-       \r
-       update @NAMESPACE@.sl_sequence\r
-                       set seq_set = p_set_id\r
-                       where seq_set = p_add_id;\r
-       update @NAMESPACE@.sl_table\r
-                       set tab_set = p_set_id\r
-                       where tab_set = p_add_id;\r
-       delete from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_add_id;\r
-       delete from @NAMESPACE@.sl_setsync\r
-                       where ssy_setid = p_add_id;\r
-       delete from @NAMESPACE@.sl_set\r
-                       where set_id = p_add_id;\r
-\r
-       return p_set_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setAddTable (set_id, tab_id, tab_fqname, tab_idxname,\r
---                                     tab_comment)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setAddTable(int4, int4, text, name, text)\r
-returns bigint\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_tab_id                        alias for $2;\r
-       p_fqname                        alias for $3;\r
-       p_tab_idxname           alias for $4;\r
-       p_tab_comment           alias for $5;\r
-       v_set_origin            int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that we are the origin of the set\r
-       -- ----\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setAddTable(): set % not found'', p_set_id;\r
-       end if;\r
-       if v_set_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: setAddTable(): set % has remote origin'', p_set_id;\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_set_id)\r
-       then\r
-               raise exception ''Slony-I: cannot add table to currently subscribed set %'',\r
-                               p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Add the table to the set and generate the SET_ADD_TABLE event\r
-       -- ----\r
-       perform @NAMESPACE@.setAddTable_int(p_set_id, p_tab_id, p_fqname,\r
-                       p_tab_idxname, p_tab_comment);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SET_ADD_TABLE'',\r
-                       p_set_id, p_tab_id, p_fqname,\r
-                       p_tab_idxname, p_tab_comment);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setAddTable_int (set_id, tab_id, tab_fqname, tab_idxname,\r
---                                             tab_comment)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setAddTable_int(int4, int4, text, name, text)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_tab_id                        alias for $2;\r
-       p_fqname                        alias for $3;\r
-       p_tab_idxname           alias for $4;\r
-       p_tab_comment           alias for $5;\r
-       v_local_node_id         int4;\r
-       v_set_origin            int4;\r
-       v_sub_provider          int4;\r
-       v_relkind                       char;\r
-       v_tab_reloid            oid;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- For sets with a remote origin, check that we are subscribed \r
-       -- to that set. Otherwise we ignore the table because it might \r
-       -- not even exist in our database.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setAddTable_int(): set % not found'',\r
-                               p_set_id;\r
-       end if;\r
-       if v_set_origin != v_local_node_id then\r
-               select sub_provider into v_sub_provider\r
-                               from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = p_set_id\r
-                               and sub_receiver = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-               if not found then\r
-                       return 0;\r
-               end if;\r
-       end if;\r
-       \r
-       -- ----\r
-       -- Get the tables OID and check that it is a real table\r
-       -- ----\r
-       select PGC.oid, PGC.relkind into v_tab_reloid, v_relkind\r
-                       from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN\r
-                       where PGC.relnamespace = PGN.oid\r
-                       and p_fqname = "pg_catalog".quote_ident(PGN.nspname) ||\r
-                                       ''.'' || "pg_catalog".quote_ident(PGC.relname);\r
-       if not found then\r
-               raise exception ''Slony-I: setAddTable(): table % not found'', \r
-                               p_fqname;\r
-       end if;\r
-       if v_relkind != ''r'' then\r
-               raise exception ''Slony-I: setAddTable(): % is not a regular table'',\r
-                               p_fqname;\r
-       end if;\r
-\r
-       if not exists (select indexrelid\r
-                       from "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGC\r
-                       where PGX.indrelid = v_tab_reloid\r
-                               and PGX.indexrelid = PGC.oid\r
-                               and PGC.relname = p_tab_idxname)\r
-       then\r
-               raise exception ''Slony-I: setAddTable(): table % has no index %'',\r
-                               p_fqname, p_tab_idxname;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Add the table to sl_table and create the trigger on it.\r
-       -- ----\r
-       insert into @NAMESPACE@.sl_table\r
-                       (tab_id, tab_reloid, tab_set, tab_idxname, \r
-                       tab_altered, tab_comment) values\r
-                       (p_tab_id, v_tab_reloid, p_set_id, p_tab_idxname,\r
-                       false, p_tab_comment);\r
-       perform @NAMESPACE@.alterTableForReplication(p_tab_id);\r
-\r
-       return p_tab_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setDropTable (tab_id)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setDropTable(int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_tab_id                alias for $1;\r
-       v_set_id                int4;\r
-       v_set_origin            int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-        -- ----\r
-       -- Determine the set_id\r
-        -- ----\r
-       select tab_set into v_set_id from @NAMESPACE@.sl_table where tab_id = p_tab_id;\r
-\r
-       -- ----\r
-       -- Ensure table exists\r
-       -- ----\r
-       if not found then\r
-               raise exception ''Slony-I: setDropTable_int(): table % not found'',\r
-                       p_tab_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Check that we are the origin of the set\r
-       -- ----\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = v_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setDropTable(): set % not found'', v_set_id;\r
-       end if;\r
-       if v_set_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: setDropTable(): set % has remote origin'', v_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Drop the table from the set and generate the SET_ADD_TABLE event\r
-       -- ----\r
-       perform @NAMESPACE@.setDropTable_int(p_tab_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SET_DROP_TABLE'', p_tab_id);\r
-end;\r
-' language plpgsql;\r
-comment on function @NAMESPACE@.setDropTable(int4) is\r
-'setDropTable (tab_id)\r
-\r
-Drop table tab_id from set on origin node, and generate SET_DROP_TABLE\r
-event to allow this to propagate to other nodes.';\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setDropTable_int (tab_id)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setDropTable_int(int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_tab_id                alias for $1;\r
-       v_set_id                int4;\r
-       v_local_node_id         int4;\r
-       v_set_origin            int4;\r
-       v_sub_provider          int4;\r
-       v_tab_reloid            oid;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-        -- ----\r
-       -- Determine the set_id\r
-        -- ----\r
-       select tab_set into v_set_id from @NAMESPACE@.sl_table where tab_id = p_tab_id;\r
-\r
-       -- ----\r
-       -- Ensure table exists\r
-       -- ----\r
-       if not found then\r
-               return 0;\r
-       end if;\r
-\r
-       -- ----\r
-       -- For sets with a remote origin, check that we are subscribed \r
-       -- to that set. Otherwise we ignore the table because it might \r
-       -- not even exist in our database.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = v_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setDropTable_int(): set % not found'',\r
-                               v_set_id;\r
-       end if;\r
-       if v_set_origin != v_local_node_id then\r
-               select sub_provider into v_sub_provider\r
-                               from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = v_set_id\r
-                               and sub_receiver = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-               if not found then\r
-                       return 0;\r
-               end if;\r
-       end if;\r
-       \r
-       -- ----\r
-       -- Drop the table from sl_table and drop trigger from it.\r
-       -- ----\r
-       perform @NAMESPACE@.alterTableRestore(p_tab_id);\r
-       perform @NAMESPACE@.tableDropKey(p_tab_id);\r
-       delete from @NAMESPACE@.sl_table where tab_id = p_tab_id;\r
-       return p_tab_id;\r
-end;\r
-' language plpgsql;\r
-comment on function @NAMESPACE@.setDropTable_int(int4) is\r
-'setDropTable_int (tab_id)\r
-\r
-This function processes the SET_DROP_TABLE event on remote nodes,\r
-dropping a table from replication if the remote node is subscribing to\r
-its replication set.';\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setAddSequence (set_id, seq_id, seq_fqname, seq_comment)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setAddSequence (int4, int4, text, text)\r
-returns bigint\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_seq_id                        alias for $2;\r
-       p_fqname                        alias for $3;\r
-       p_seq_comment           alias for $4;\r
-       v_set_origin            int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that we are the origin of the set\r
-       -- ----\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setAddSequence(): set % not found'', p_set_id;\r
-       end if;\r
-       if v_set_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: setAddSequence(): set % has remote origin'', p_set_id;\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_set_id)\r
-       then\r
-               raise exception ''Slony-I: cannot add sequence to currently subscribed set %'',\r
-                               p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Add the sequence to the set and generate the SET_ADD_SEQUENCE event\r
-       -- ----\r
-       perform @NAMESPACE@.setAddSequence_int(p_set_id, p_seq_id, p_fqname,\r
-                       p_seq_comment);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SET_ADD_SEQUENCE'',\r
-                       p_set_id, p_seq_id, p_fqname, p_seq_comment);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setAddSequence_int (set_id, seq_id, seq_fqname, seq_comment\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setAddSequence_int(int4, int4, text, text)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_seq_id                        alias for $2;\r
-       p_fqname                        alias for $3;\r
-       p_seq_comment           alias for $4;\r
-       v_local_node_id         int4;\r
-       v_set_origin            int4;\r
-       v_sub_provider          int4;\r
-       v_relkind                       char;\r
-       v_seq_reloid            oid;\r
-       v_sync_row                      record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- For sets with a remote origin, check that we are subscribed \r
-       -- to that set. Otherwise we ignore the sequence because it might \r
-       -- not even exist in our database.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setAddSequence_int(): set % not found'',\r
-                               p_set_id;\r
-       end if;\r
-       if v_set_origin != v_local_node_id then\r
-               select sub_provider into v_sub_provider\r
-                               from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = p_set_id\r
-                               and sub_receiver = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-               if not found then\r
-                       return 0;\r
-               end if;\r
-       end if;\r
-       \r
-       -- ----\r
-       -- Get the sequences OID and check that it is a sequence\r
-       -- ----\r
-       select PGC.oid, PGC.relkind into v_seq_reloid, v_relkind\r
-                       from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN\r
-                       where PGC.relnamespace = PGN.oid\r
-                       and p_fqname = "pg_catalog".quote_ident(PGN.nspname) ||\r
-                                       ''.'' || "pg_catalog".quote_ident(PGC.relname);\r
-       if not found then\r
-               raise exception ''Slony-I: setAddSequence_int(): sequence % not found'', \r
-                               p_fqname;\r
-       end if;\r
-       if v_relkind != ''S'' then\r
-               raise exception ''Slony-I: setAddSequence_int(): % is not a sequence'',\r
-                               p_fqname;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Add the sequence to sl_sequence\r
-       -- ----\r
-       insert into @NAMESPACE@.sl_sequence\r
-                       (seq_id, seq_reloid, seq_set, seq_comment) values\r
-                       (p_seq_id, v_seq_reloid, p_set_id, p_seq_comment);\r
-\r
-       -- ----\r
-       -- On the set origin, fake a sl_seqlog row for the last sync event\r
-       -- ----\r
-       if v_set_origin = v_local_node_id then\r
-               for v_sync_row in select coalesce (max(ev_seqno), 0) as ev_seqno\r
-                               from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_local_node_id\r
-                                       and ev_type = ''SYNC''\r
-               loop\r
-                       insert into @NAMESPACE@.sl_seqlog\r
-                                       (seql_seqid, seql_origin, seql_ev_seqno, \r
-                                       seql_last_value) values\r
-                                       (p_seq_id, v_local_node_id, v_sync_row.ev_seqno,\r
-                                       @NAMESPACE@.sequenceLastValue(p_fqname));\r
-               end loop;\r
-       end if;\r
-\r
-       return p_seq_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setDropSequence (seq_id)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setDropSequence (int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_seq_id                alias for $1;\r
-       v_set_id                int4;\r
-       v_set_origin            int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Determine set id for this sequence\r
-       -- ----\r
-       select seq_set into v_set_id from @NAMESPACE@.sl_sequence where seq_id = p_seq_id;\r
-\r
-       -- ----\r
-       -- Ensure sequence exists\r
-       -- ----\r
-       if not found then\r
-               raise exception ''Slony-I: setDropSequence_int(): sequence % not found'',\r
-                       p_seq_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Check that we are the origin of the set\r
-       -- ----\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = v_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setDropSequence(): set % not found'', v_set_id;\r
-       end if;\r
-       if v_set_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: setDropSequence(): set % has remote origin'', v_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Add the sequence to the set and generate the SET_ADD_SEQUENCE event\r
-       -- ----\r
-       perform @NAMESPACE@.setDropSequence_int(p_seq_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SET_DROP_SEQUENCE'',\r
-                       p_seq_id);\r
-end;\r
-' language plpgsql;\r
-comment on function @NAMESPACE@.setDropSequence (int4) is\r
-'setDropSequence (seq_id)\r
-\r
-On the origin node for the set, drop sequence seq_id from replication\r
-set, and raise SET_DROP_SEQUENCE to cause this to replicate to\r
-subscriber nodes.';\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setDropSequence_int (seq_id)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setDropSequence_int(int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_seq_id                alias for $1;\r
-       v_set_id                int4;\r
-       v_local_node_id         int4;\r
-       v_set_origin            int4;\r
-       v_sub_provider          int4;\r
-       v_relkind                       char;\r
-       v_sync_row                      record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Determine set id for this sequence\r
-       -- ----\r
-       select seq_set into v_set_id from @NAMESPACE@.sl_sequence where seq_id = p_seq_id;\r
-\r
-       -- ----\r
-       -- Ensure sequence exists\r
-       -- ----\r
-       if not found then\r
-               return 0;\r
-       end if;\r
-\r
-       -- ----\r
-       -- For sets with a remote origin, check that we are subscribed \r
-       -- to that set. Otherwise we ignore the sequence because it might \r
-       -- not even exist in our database.\r
-       -- ----\r
-       v_local_node_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = v_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: setDropSequence_int(): set % not found'',\r
-                               v_set_id;\r
-       end if;\r
-       if v_set_origin != v_local_node_id then\r
-               select sub_provider into v_sub_provider\r
-                               from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = v_set_id\r
-                               and sub_receiver = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-               if not found then\r
-                       return 0;\r
-               end if;\r
-       end if;\r
-\r
-       -- ----\r
-       -- drop the sequence from sl_sequence, sl_seqlog\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_seqlog where seql_seqid = p_seq_id;\r
-       delete from @NAMESPACE@.sl_sequence where seq_id = p_seq_id;\r
-\r
-       return p_seq_id;\r
-end;\r
-' language plpgsql;\r
-comment on function @NAMESPACE@.setDropSequence_int(int4) is\r
-'setDropSequence_int (seq_id)\r
-\r
-This processes the SET_DROP_SEQUENCE event.  On remote nodes that\r
-subscribe to the set containing sequence seq_id, drop the sequence\r
-from the replication set.';\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setMoveTable (tab_id, new_set_id)\r
---\r
---     Generate the SET_MOVE_TABLE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setMoveTable (int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_tab_id                        alias for $1;\r
-       p_new_set_id            alias for $2;\r
-       v_old_set_id            int4;\r
-       v_origin                        int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Get the tables current set\r
-       -- ----\r
-       select tab_set into v_old_set_id from @NAMESPACE@.sl_table\r
-                       where tab_id = p_tab_id;\r
-       if not found then\r
-               raise exception ''Slony-I: table %d not found'', p_tab_id;\r
-       end if;\r
-       \r
-       -- ----\r
-       -- Check that both sets exist and originate here\r
-       -- ----\r
-       if p_new_set_id = v_old_set_id then\r
-               raise exception ''Slony-I: set ids cannot be identical'';\r
-       end if;\r
-       select set_origin into v_origin from @NAMESPACE@.sl_set\r
-                       where set_id = p_new_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_new_set_id;\r
-       end if;\r
-       if v_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_new_set_id;\r
-       end if;\r
-\r
-       select set_origin into v_origin from @NAMESPACE@.sl_set\r
-                       where set_id = v_old_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', v_old_set_id;\r
-       end if;\r
-       if v_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               v_old_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Check that both sets are subscribed by the same set of nodes\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_subscribe SUB1\r
-                               where SUB1.sub_set = p_new_set_id\r
-                               and SUB1.sub_receiver not in (select SUB2.sub_receiver\r
-                                               from @NAMESPACE@.sl_subscribe SUB2\r
-                                               where SUB2.sub_set = v_old_set_id))\r
-       then\r
-               raise exception ''Slony-I: subscriber lists of set % and % are different'',\r
-                               p_new_set_id, v_old_set_id;\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_subscribe SUB1\r
-                               where SUB1.sub_set = v_old_set_id\r
-                               and SUB1.sub_receiver not in (select SUB2.sub_receiver\r
-                                               from @NAMESPACE@.sl_subscribe SUB2\r
-                                               where SUB2.sub_set = p_new_set_id))\r
-       then\r
-               raise exception ''Slony-I: subscriber lists of set % and % are different'',\r
-                               v_old_set_id, p_new_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Also check that there are no unconfirmed enable subscriptions\r
-       -- still lingering (prevents bug 896)\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_origin\r
-                               and ev_type = ''ENABLE_SUBSCRIPTION''\r
-                               and ev_data1 = v_old_set_id\r
-                               and ev_seqno > (select min(max_con_seqno) from\r
-                                       (select con_received, max(con_seqno) as max_con_seqno\r
-                                                       from @NAMESPACE@.sl_confirm\r
-                                                       where con_origin = v_origin\r
-                                                       group by con_received) as CON\r
-                                       )\r
-                               )\r
-       then\r
-               raise exception ''Slony-I: table cannot be moved because of pending subscription'';\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_origin\r
-                               and ev_type = ''ENABLE_SUBSCRIPTION''\r
-                               and ev_data1 = p_new_set_id\r
-                               and ev_seqno > (select min(max_con_seqno) from\r
-                                       (select con_received, max(con_seqno) as max_con_seqno\r
-                                                       from @NAMESPACE@.sl_confirm\r
-                                                       where con_origin = v_origin\r
-                                                       group by con_received) as CON\r
-                                       )\r
-                               )\r
-       then\r
-               raise exception ''Slony-I: table cannot be moved because of pending subscription'';\r
-       end if;\r
-\r
-       -- ----\r
-       -- Change the set the table belongs to\r
-       -- ----\r
-       perform @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SYNC'', NULL);\r
-       perform @NAMESPACE@.setMoveTable_int(p_tab_id, p_new_set_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SET_MOVE_TABLE'', \r
-                       p_tab_id, p_new_set_id);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setMoveTable_int (tab_id, new_set_id)\r
---\r
---     Process the SET_MOVE_TABLE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setMoveTable_int (int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_tab_id                        alias for $1;\r
-       p_new_set_id            alias for $2;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-       \r
-       -- ----\r
-       -- Move the table to the new set\r
-       -- ----\r
-       update @NAMESPACE@.sl_table\r
-                       set tab_set = p_new_set_id\r
-                       where tab_id = p_tab_id;\r
-\r
-       return p_tab_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setMoveSequence (seq_id, new_set_id)\r
---\r
---     Generate the SET_MOVE_SEQUENCE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setMoveSequence (int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_seq_id                        alias for $1;\r
-       p_new_set_id            alias for $2;\r
-       v_old_set_id            int4;\r
-       v_origin                        int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Get the sequences current set\r
-       -- ----\r
-       select seq_set into v_old_set_id from @NAMESPACE@.sl_sequence\r
-                       where seq_id = p_seq_id;\r
-       if not found then\r
-               raise exception ''Slony-I: sequence %d not found'', p_seq_id;\r
-       end if;\r
-       \r
-       -- ----\r
-       -- Check that both sets exist and originate here\r
-       -- ----\r
-       if p_new_set_id = v_old_set_id then\r
-               raise exception ''Slony-I: set ids cannot be identical'';\r
-       end if;\r
-       select set_origin into v_origin from @NAMESPACE@.sl_set\r
-                       where set_id = p_new_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_new_set_id;\r
-       end if;\r
-       if v_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_new_set_id;\r
-       end if;\r
-\r
-       select set_origin into v_origin from @NAMESPACE@.sl_set\r
-                       where set_id = v_old_set_id;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', v_old_set_id;\r
-       end if;\r
-       if v_origin != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               v_old_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Check that both sets are subscribed by the same set of nodes\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_subscribe SUB1\r
-                               where SUB1.sub_set = p_new_set_id\r
-                               and SUB1.sub_receiver not in (select SUB2.sub_receiver\r
-                                               from @NAMESPACE@.sl_subscribe SUB2\r
-                                               where SUB2.sub_set = v_old_set_id))\r
-       then\r
-               raise exception ''Slony-I: subscriber lists of set % and % are different'',\r
-                               p_new_set_id, v_old_set_id;\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_subscribe SUB1\r
-                               where SUB1.sub_set = v_old_set_id\r
-                               and SUB1.sub_receiver not in (select SUB2.sub_receiver\r
-                                               from @NAMESPACE@.sl_subscribe SUB2\r
-                                               where SUB2.sub_set = p_new_set_id))\r
-       then\r
-               raise exception ''Slony-I: subscriber lists of set % and % are different'',\r
-                               v_old_set_id, p_new_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Also check that there are no unconfirmed enable subscriptions\r
-       -- still lingering (prevents bug 896)\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_origin\r
-                               and ev_type = ''ENABLE_SUBSCRIPTION''\r
-                               and ev_data1 = v_old_set_id\r
-                               and ev_seqno > (select min(max_con_seqno) from\r
-                                       (select con_received, max(con_seqno) as max_con_seqno\r
-                                                       from @NAMESPACE@.sl_confirm\r
-                                                       where con_origin = v_origin\r
-                                                       group by con_received) as CON\r
-                                       )\r
-                               )\r
-       then\r
-               raise exception ''Slony-I: sequence cannot be moved because of pending subscription'';\r
-       end if;\r
-\r
-       if exists (select true from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_origin\r
-                               and ev_type = ''ENABLE_SUBSCRIPTION''\r
-                               and ev_data1 = p_new_set_id\r
-                               and ev_seqno > (select min(max_con_seqno) from\r
-                                       (select con_received, max(con_seqno) as max_con_seqno\r
-                                                       from @NAMESPACE@.sl_confirm\r
-                                                       where con_origin = v_origin\r
-                                                       group by con_received) as CON\r
-                                       )\r
-                               )\r
-       then\r
-               raise exception ''Slony-I: sequence cannot be moved because of pending subscription'';\r
-       end if;\r
-\r
-       -- ----\r
-       -- Change the set the sequence belongs to\r
-       -- ----\r
-       perform @NAMESPACE@.setMoveSequence_int(p_seq_id, p_new_set_id);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SET_MOVE_SEQUENCE'', \r
-                       p_seq_id, p_new_set_id);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION setMoveSequence_int (seq_id, new_set_id)\r
---\r
---     Process the SET_MOVE_SEQUENCE event.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.setMoveSequence_int (int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_seq_id                        alias for $1;\r
-       p_new_set_id            alias for $2;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-       \r
-       -- ----\r
-       -- Move the sequence to the new set\r
-       -- ----\r
-       update @NAMESPACE@.sl_sequence\r
-                       set seq_set = p_new_set_id\r
-                       where seq_id = p_seq_id;\r
-\r
-       return p_seq_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION sequenceSetValue (seq_id, seq_origin, ev_seqno, last_value)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.sequenceSetValue(int4, int4, int8, int8) returns int4\r
-as '\r
-declare\r
-       p_seq_id                        alias for $1;\r
-       p_seq_origin            alias for $2;\r
-       p_ev_seqno                      alias for $3;\r
-       p_last_value            alias for $4;\r
-       v_fqname                        text;\r
-begin\r
-       -- ----\r
-       -- Get the sequences fully qualified name\r
-       -- ----\r
-       select "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                       "pg_catalog".quote_ident(PGC.relname) into v_fqname\r
-               from @NAMESPACE@.sl_sequence SQ,\r
-                       "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN\r
-               where SQ.seq_id = p_seq_id\r
-                       and SQ.seq_reloid = PGC.oid\r
-                       and PGC.relnamespace = PGN.oid;\r
-       if not found then\r
-               raise exception ''Slony-I: sequence % not found'', p_seq_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Update it to the new value\r
-       -- ----\r
-       execute ''select setval('''''' || v_fqname ||\r
-                       '''''', '''''' || p_last_value || '''''')'';\r
-\r
-       insert into @NAMESPACE@.sl_seqlog\r
-                       (seql_seqid, seql_origin, seql_ev_seqno, seql_last_value)\r
-                       values (p_seq_id, p_seq_origin, p_ev_seqno, p_last_value);\r
-\r
-       return p_seq_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeTrigger (trig_tabid, trig_tgname)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeTrigger (int4, name)\r
-returns bigint\r
-as '\r
-declare\r
-       p_trig_tabid            alias for $1;\r
-       p_trig_tgname           alias for $2;\r
-begin\r
-       perform @NAMESPACE@.storeTrigger_int(p_trig_tabid, p_trig_tgname);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''STORE_TRIGGER'',\r
-                       p_trig_tabid, p_trig_tgname);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION storeTrigger_int (trig_tabid, trig_tgname)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.storeTrigger_int (int4, name)\r
-returns int4\r
-as '\r
-declare\r
-       p_trig_tabid            alias for $1;\r
-       p_trig_tgname           alias for $2;\r
-       v_tab_altered           boolean;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Get the current table status (altered or not)\r
-       -- ----\r
-       select tab_altered into v_tab_altered\r
-                       from @NAMESPACE@.sl_table where tab_id = p_trig_tabid;\r
-       if not found then\r
-               -- ----\r
-               -- Not found is no hard error here, because that might\r
-               -- mean that we are not subscribed to that set\r
-               -- ----\r
-               return 0;\r
-       end if;\r
-\r
-       -- ----\r
-       -- If the table is modified for replication, restore the original state\r
-       -- ----\r
-       if v_tab_altered then\r
-               perform @NAMESPACE@.alterTableRestore(p_trig_tabid);\r
-       end if;\r
-\r
-       -- ----\r
-       -- Make sure that an entry for this trigger exists\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_trigger\r
-                       where trig_tabid = p_trig_tabid\r
-                         and trig_tgname = p_trig_tgname;\r
-       insert into @NAMESPACE@.sl_trigger (\r
-                               trig_tabid, trig_tgname\r
-                       ) values (\r
-                               p_trig_tabid, p_trig_tgname\r
-                       );\r
-\r
-       -- ----\r
-       -- Put the table back into replicated state if it was\r
-       -- ----\r
-       if v_tab_altered then\r
-               perform @NAMESPACE@.alterTableForReplication(p_trig_tabid);\r
-       end if;\r
-\r
-       return p_trig_tabid;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropTrigger (trig_tabid, trig_tgname)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropTrigger (int4, name)\r
-returns bigint\r
-as '\r
-declare\r
-       p_trig_tabid            alias for $1;\r
-       p_trig_tgname           alias for $2;\r
-begin\r
-       perform @NAMESPACE@.dropTrigger_int(p_trig_tabid, p_trig_tgname);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''DROP_TRIGGER'',\r
-                       p_trig_tabid, p_trig_tgname);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION dropTrigger_int (trig_tabid, trig_tgname)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.dropTrigger_int (int4, name)\r
-returns int4\r
-as '\r
-declare\r
-       p_trig_tabid            alias for $1;\r
-       p_trig_tgname           alias for $2;\r
-       v_tab_altered           boolean;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Get the current table status (altered or not)\r
-       -- ----\r
-       select tab_altered into v_tab_altered\r
-                       from @NAMESPACE@.sl_table where tab_id = p_trig_tabid;\r
-       if not found then\r
-               -- ----\r
-               -- Not found is no hard error here, because that might\r
-               -- mean that we are not subscribed to that set\r
-               -- ----\r
-               return 0;\r
-       end if;\r
-\r
-       -- ----\r
-       -- If the table is modified for replication, restore the original state\r
-       -- ----\r
-       if v_tab_altered then\r
-               perform @NAMESPACE@.alterTableRestore(p_trig_tabid);\r
-       end if;\r
-\r
-       -- ----\r
-       -- Remove the entry from sl_trigger\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_trigger\r
-                       where trig_tabid = p_trig_tabid\r
-                         and trig_tgname = p_trig_tgname;\r
-\r
-       -- ----\r
-       -- Put the table back into replicated state if it was\r
-       -- ----\r
-       if v_tab_altered then\r
-               perform @NAMESPACE@.alterTableForReplication(p_trig_tabid);\r
-       end if;\r
-\r
-       return p_trig_tabid;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION ddlScript (set_id, script)\r
---\r
---     Generate the DDL_SCRIPT event\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.ddlScript (int4, text)\r
-returns bigint\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_script                        alias for $2;\r
-       v_set_origin            int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that the set exists and originates here\r
-       -- ----\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id\r
-                       for update;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_set_id;\r
-       end if;\r
-       if v_set_origin <> @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: set % does not originate on local node'',\r
-                               p_set_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Create a SYNC event, run the script and generate the DDL_SCRIPT event\r
-       -- ----\r
-       perform @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SYNC'', NULL);\r
-       perform @NAMESPACE@.ddlScript_int(p_set_id, p_script);\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''DDL_SCRIPT'', \r
-                       p_set_id, p_script);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION ddlScript_int (set_id, script)\r
---\r
---     Process the DDL_SCRIPT event\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.ddlScript_int (int4, text)\r
-returns int4\r
-as '\r
-declare\r
-       p_set_id                        alias for $1;\r
-       p_script                        alias for $2;\r
-       v_set_origin            int4;\r
-       v_no_id                         int4;\r
-       v_row                           record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that we either are the set origin or a current\r
-       -- subscriber of the set.\r
-       -- ----\r
-       v_no_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_set_id\r
-                       for update;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_set_id;\r
-       end if;\r
-       if v_set_origin <> v_no_id\r
-                       and not exists (select 1 from @NAMESPACE@.sl_subscribe\r
-                                               where sub_set = p_set_id\r
-                                               and sub_receiver = v_no_id)\r
-       then\r
-               return 0;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Restore all original triggers and rules\r
-       -- ----\r
-       for v_row in select * from @NAMESPACE@.sl_table\r
-                       where tab_set = p_set_id\r
-       loop\r
-               perform @NAMESPACE@.alterTableRestore(v_row.tab_id);\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Run the script\r
-       -- ----\r
-       execute p_script;\r
-\r
-       -- ----\r
-       -- Put all tables back into replicated mode\r
-       -- ----\r
-       for v_row in select * from @NAMESPACE@.sl_table\r
-                       where tab_set = p_set_id\r
-       loop\r
-               perform @NAMESPACE@.alterTableForReplication(v_row.tab_id);\r
-       end loop;\r
-\r
-       return p_set_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION alterTableForReplication (tab_id)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.alterTableForReplication (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_tab_id                        alias for $1;\r
-       v_no_id                         int4;\r
-       v_tab_row                       record;\r
-       v_tab_fqname            text;\r
-       v_tab_attkind           text;\r
-       v_n                                     int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Get our local node ID\r
-       -- ----\r
-       v_no_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-\r
-       -- ----\r
-       -- Get the sl_table row and the current tables origin. Check\r
-       -- that the table currently is NOT in altered state.\r
-       -- ----\r
-       select T.tab_reloid, T.tab_set, T.tab_idxname, T.tab_altered,\r
-                       S.set_origin, PGX.indexrelid,\r
-                       "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                       "pg_catalog".quote_ident(PGC.relname) as tab_fqname\r
-                       into v_tab_row\r
-                       from @NAMESPACE@.sl_table T, @NAMESPACE@.sl_set S,\r
-                               "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN,\r
-                               "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC\r
-                       where T.tab_id = p_tab_id\r
-                               and T.tab_set = S.set_id\r
-                               and T.tab_reloid = PGC.oid\r
-                               and PGC.relnamespace = PGN.oid\r
-                               and PGX.indrelid = T.tab_reloid\r
-                               and PGX.indexrelid = PGXC.oid\r
-                               and PGXC.relname = T.tab_idxname\r
-                               for update;\r
-       if not found then\r
-               raise exception ''Slony-I: Table with id % not found'', p_tab_id;\r
-       end if;\r
-       v_tab_fqname = v_tab_row.tab_fqname;\r
-       if v_tab_row.tab_altered then\r
-               raise exception ''Slony-I: Table % is already in altered state'',\r
-                               v_tab_fqname;\r
-       end if;\r
-\r
-       v_tab_attkind := @NAMESPACE@.determineAttKindUnique(v_tab_row.tab_fqname, \r
-                                               v_tab_row.tab_idxname);\r
-\r
-       execute ''lock table '' || v_tab_fqname || '' in access exclusive mode'';\r
-\r
-       -- ----\r
-       -- Procedures are different on origin and subscriber\r
-       -- ----\r
-       if v_no_id = v_tab_row.set_origin then\r
-               -- ----\r
-               -- On the Origin we add the log trigger to the table and done\r
-               -- ----\r
-               execute ''create trigger "_@CLUSTERNAME@_logtrigger_'' || \r
-                               p_tab_id || ''" after insert or update or delete on '' ||\r
-                               v_tab_fqname || '' for each row execute procedure\r
-                               @NAMESPACE@.logTrigger (''''_@CLUSTERNAME@'''', '''''' || \r
-                                       p_tab_id || '''''', '''''' || \r
-                                       v_tab_attkind || '''''');'';\r
-       else\r
-               -- ----\r
-               -- On the subscriber the thing is a bit more difficult. We want\r
-               -- to disable all user- and foreign key triggers and rules.\r
-               -- ----\r
-\r
-\r
-               -- ----\r
-               -- Disable all existing triggers\r
-               -- ----\r
-               update "pg_catalog".pg_trigger\r
-                               set tgrelid = v_tab_row.indexrelid\r
-                               where tgrelid = v_tab_row.tab_reloid\r
-                               and not exists (\r
-                                               select true from @NAMESPACE@.sl_table TAB,\r
-                                                               @NAMESPACE@.sl_trigger TRIG\r
-                                                               where TAB.tab_reloid = tgrelid\r
-                                                               and TAB.tab_id = TRIG.trig_tabid\r
-                                                               and TRIG.trig_tgname = tgname\r
-                                       );\r
-               get diagnostics v_n = row_count;\r
-               if v_n > 0 then\r
-                       update "pg_catalog".pg_class\r
-                                       set reltriggers = reltriggers - v_n\r
-                                       where oid = v_tab_row.tab_reloid;\r
-               end if;\r
-\r
-               -- ----\r
-               -- Disable all existing rules\r
-               -- ----\r
-               update "pg_catalog".pg_rewrite\r
-                               set ev_class = v_tab_row.indexrelid\r
-                               where ev_class = v_tab_row.tab_reloid;\r
-               get diagnostics v_n = row_count;\r
-               if v_n > 0 then\r
-                       update "pg_catalog".pg_class\r
-                                       set relhasrules = false\r
-                                       where oid = v_tab_row.tab_reloid;\r
-               end if;\r
-\r
-               -- ----\r
-               -- Add the trigger that denies write access to replicated tables\r
-               -- ----\r
-               execute ''create trigger "_@CLUSTERNAME@_denyaccess_'' || \r
-                               p_tab_id || ''" before insert or update or delete on '' ||\r
-                               v_tab_fqname || '' for each row execute procedure\r
-                               @NAMESPACE@.denyAccess (''''_@CLUSTERNAME@'''');'';\r
-       end if;\r
-\r
-       -- ----\r
-       -- Mark the table altered in our configuration\r
-       -- ----\r
-       update @NAMESPACE@.sl_table\r
-                       set tab_altered = true where tab_id = p_tab_id;\r
-\r
-       return p_tab_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION alterTableRestore (tab_id)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.alterTableRestore (int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_tab_id                        alias for $1;\r
-       v_no_id                         int4;\r
-       v_tab_row                       record;\r
-       v_tab_fqname            text;\r
-       v_n                                     int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Get our local node ID\r
-       -- ----\r
-       v_no_id := @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'');\r
-\r
-       -- ----\r
-       -- Get the sl_table row and the current tables origin. Check\r
-       -- that the table currently IS in altered state.\r
-       -- ----\r
-       select T.tab_reloid, T.tab_set, T.tab_altered,\r
-                       S.set_origin, PGX.indexrelid,\r
-                       "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                       "pg_catalog".quote_ident(PGC.relname) as tab_fqname\r
-                       into v_tab_row\r
-                       from @NAMESPACE@.sl_table T, @NAMESPACE@.sl_set S,\r
-                               "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN,\r
-                               "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC\r
-                       where T.tab_id = p_tab_id\r
-                               and T.tab_set = S.set_id\r
-                               and T.tab_reloid = PGC.oid\r
-                               and PGC.relnamespace = PGN.oid\r
-                               and PGX.indrelid = T.tab_reloid\r
-                               and PGX.indexrelid = PGXC.oid\r
-                               and PGXC.relname = T.tab_idxname\r
-                               for update;\r
-       if not found then\r
-               raise exception ''Slony-I: Table with id % not found'', p_tab_id;\r
-       end if;\r
-       v_tab_fqname = v_tab_row.tab_fqname;\r
-       if not v_tab_row.tab_altered then\r
-               raise exception ''Slony-I: Table % is not in altered state'',\r
-                               v_tab_fqname;\r
-       end if;\r
-\r
-       execute ''lock table '' || v_tab_fqname || '' in access exclusive mode'';\r
-\r
-       -- ----\r
-       -- Procedures are different on origin and subscriber\r
-       -- ----\r
-       if v_no_id = v_tab_row.set_origin then\r
-               -- ----\r
-               -- On the Origin we just drop the trigger we originally added\r
-               -- ----\r
-               execute ''drop trigger "_@CLUSTERNAME@_logtrigger_'' || \r
-                               p_tab_id || ''" on '' || v_tab_fqname;\r
-       else\r
-               -- ----\r
-               -- On the subscriber drop the denyAccess trigger\r
-               -- ----\r
-               execute ''drop trigger "_@CLUSTERNAME@_denyaccess_'' || \r
-                               p_tab_id || ''" on '' || v_tab_fqname;\r
-                               \r
-               -- ----\r
-               -- Restore all original triggers\r
-               -- ----\r
-               update "pg_catalog".pg_trigger\r
-                               set tgrelid = v_tab_row.tab_reloid\r
-                               where tgrelid = v_tab_row.indexrelid;\r
-               get diagnostics v_n = row_count;\r
-               if v_n > 0 then\r
-                       update "pg_catalog".pg_class\r
-                                       set reltriggers = reltriggers + v_n\r
-                                       where oid = v_tab_row.tab_reloid;\r
-               end if;\r
-\r
-               -- ----\r
-               -- Restore all original rewrite rules\r
-               -- ----\r
-               update "pg_catalog".pg_rewrite\r
-                               set ev_class = v_tab_row.tab_reloid\r
-                               where ev_class = v_tab_row.indexrelid;\r
-               get diagnostics v_n = row_count;\r
-               if v_n > 0 then\r
-                       update "pg_catalog".pg_class\r
-                                       set relhasrules = true\r
-                                       where oid = v_tab_row.tab_reloid;\r
-               end if;\r
-\r
-       end if;\r
-\r
-       -- ----\r
-       -- Mark the table not altered in our configuration\r
-       -- ----\r
-       update @NAMESPACE@.sl_table\r
-                       set tab_altered = false where tab_id = p_tab_id;\r
-\r
-       return p_tab_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION subscribeSet (sub_set, sub_provider, sub_receiver, sub_forward)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.subscribeSet (int4, int4, int4, bool)\r
-returns bigint\r
-as '\r
-declare\r
-       p_sub_set                       alias for $1;\r
-       p_sub_provider          alias for $2;\r
-       p_sub_receiver          alias for $3;\r
-       p_sub_forward           alias for $4;\r
-       v_set_origin            int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that this is called on the receiver node\r
-       -- ----\r
-       if p_sub_receiver != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: subscribeSet() must be called on receiver'';\r
-       end if;\r
-\r
-       -- ----\r
-       -- Check that the origin and provider of the set are remote\r
-       -- ----\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_sub_set;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_sub_set;\r
-       end if;\r
-       if v_set_origin = p_sub_receiver then\r
-               raise exception \r
-                               ''Slony-I: set origin and receiver cannot be identical'';\r
-       end if;\r
-       if p_sub_receiver = p_sub_provider then\r
-               raise exception \r
-                               ''Slony-I: set provider and receiver cannot be identical'';\r
-       end if;\r
-\r
-       -- ----\r
-       -- Call the internal procedure to store the subscription\r
-       -- ----\r
-       perform @NAMESPACE@.subscribeSet_int(p_sub_set, p_sub_provider,\r
-                       p_sub_receiver, p_sub_forward);\r
-\r
-       -- ----\r
-       -- Create the SUBSCRIBE_SET event\r
-       -- ----\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''SUBSCRIBE_SET'', \r
-                       p_sub_set, p_sub_provider, p_sub_receiver, \r
-                       case p_sub_forward when true then ''t'' else ''f'' end);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION subscribeSet_int (sub_set, sub_provider, sub_receiver, sub_forward)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.subscribeSet_int (int4, int4, int4, bool)\r
-returns int4\r
-as '\r
-declare\r
-       p_sub_set                       alias for $1;\r
-       p_sub_provider          alias for $2;\r
-       p_sub_receiver          alias for $3;\r
-       p_sub_forward           alias for $4;\r
-       v_set_origin            int4;\r
-       v_sub_row                       record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Provider change is only allowed for active sets\r
-       -- ----\r
-       if p_sub_receiver = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               select sub_active into v_sub_row from @NAMESPACE@.sl_subscribe\r
-                               where sub_set = p_sub_set\r
-                               and sub_receiver = p_sub_receiver;\r
-               if found then\r
-                       if not v_sub_row.sub_active then\r
-                               raise exception ''Slony-I: set % is not active, cannot change provider'',\r
-                                               p_sub_set;\r
-                       end if;\r
-               end if;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Try to change provider and/or forward for an existing subscription\r
-       -- ----\r
-       update @NAMESPACE@.sl_subscribe\r
-                       set sub_provider = p_sub_provider,\r
-                               sub_forward = p_sub_forward\r
-                       where sub_set = p_sub_set\r
-                       and sub_receiver = p_sub_receiver;\r
-       if found then\r
-               return p_sub_set;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Not found, insert a new one\r
-       -- ----\r
-       if not exists (select true from @NAMESPACE@.sl_path\r
-                       where pa_server = p_sub_provider\r
-                       and pa_client = p_sub_receiver)\r
-       then\r
-               insert into @NAMESPACE@.sl_path\r
-                               (pa_server, pa_client, pa_conninfo, pa_connretry)\r
-                               values \r
-                               (p_sub_provider, p_sub_receiver, \r
-                               ''<event pending>'', 10);\r
-       end if;\r
-       insert into @NAMESPACE@.sl_subscribe\r
-                       (sub_set, sub_provider, sub_receiver, sub_forward, sub_active)\r
-                       values (p_sub_set, p_sub_provider, p_sub_receiver,\r
-                               p_sub_forward, false);\r
-\r
-       -- ----\r
-       -- If the set origin is here, then enable the subscription\r
-       -- ----\r
-       select set_origin into v_set_origin\r
-                       from @NAMESPACE@.sl_set\r
-                       where set_id = p_sub_set;\r
-       if not found then\r
-               raise exception ''Slony-I: set % not found'', p_sub_set;\r
-       end if;\r
-\r
-       if v_set_origin = @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               perform @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''ENABLE_SUBSCRIPTION'', \r
-                               p_sub_set, p_sub_provider, p_sub_receiver, \r
-                               case p_sub_forward when true then ''t'' else ''f'' end);\r
-               perform @NAMESPACE@.enableSubscription(p_sub_set, \r
-                               p_sub_provider, p_sub_receiver);\r
-       end if;\r
-\r
-       return p_sub_set;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION unsubscribeSet (sub_set, sub_receiver)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.unsubscribeSet (int4, int4)\r
-returns bigint\r
-as '\r
-declare\r
-       p_sub_set                       alias for $1;\r
-       p_sub_receiver          alias for $2;\r
-       v_tab_row                       record;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Check that this is called on the receiver node\r
-       -- ----\r
-       if p_sub_receiver != @NAMESPACE@.getLocalNodeId(''_@CLUSTERNAME@'') then\r
-               raise exception ''Slony-I: unsubscribeSet() must be called on receiver'';\r
-       end if;\r
-\r
-       -- ----\r
-       -- Check that this does not break any chains\r
-       -- ----\r
-       if exists (select true from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_sub_set\r
-                               and sub_provider = p_sub_receiver)\r
-       then\r
-               raise exception ''Slony-I: Cannot unsubscibe set % while being provider'',\r
-                               p_sub_set;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Restore all tables original triggers and rules and remove\r
-       -- our replication stuff.\r
-       -- ----\r
-       for v_tab_row in select tab_id from @NAMESPACE@.sl_table\r
-                       where tab_set = p_sub_set\r
-                       order by tab_id\r
-       loop\r
-               perform @NAMESPACE@.alterTableRestore(v_tab_row.tab_id);\r
-               perform @NAMESPACE@.tableDropKey(v_tab_row.tab_id);\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Remove the setsync status. This will also cause the\r
-       -- worker thread to ignore the set and stop replicating\r
-       -- right now.\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_setsync\r
-                       where ssy_setid = p_sub_set;\r
-\r
-       -- ----\r
-       -- Remove all sl_table and sl_sequence entries for this set.\r
-       -- Should we ever subscribe again, the initial data\r
-       -- copy process will create new ones.\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_table\r
-                       where tab_set = p_sub_set;\r
-       delete from @NAMESPACE@.sl_sequence\r
-                       where seq_set = p_sub_set;\r
-\r
-       -- ----\r
-       -- Call the internal procedure to drop the subscription\r
-       -- ----\r
-       perform @NAMESPACE@.unsubscribeSet_int(p_sub_set, p_sub_receiver);\r
-\r
-       -- ----\r
-       -- Create the UNSUBSCRIBE_SET event\r
-       -- ----\r
-       return  @NAMESPACE@.createEvent(''_@CLUSTERNAME@'', ''UNSUBSCRIBE_SET'', \r
-                       p_sub_set, p_sub_receiver);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION unsubscribeSet_int (sub_set, sub_receiver)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.unsubscribeSet_int (int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_sub_set                       alias for $1;\r
-       p_sub_receiver          alias for $2;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- All the real work is done before event generation on the\r
-       -- subscriber.\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_subscribe\r
-                       where sub_set = p_sub_set\r
-                               and sub_receiver = p_sub_receiver;\r
-\r
-       return p_sub_set;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION enableSubscription (sub_set, sub_provider, sub_receiver)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.enableSubscription (int4, int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_sub_set                       alias for $1;\r
-       p_sub_provider          alias for $2;\r
-       p_sub_receiver          alias for $3;\r
-begin\r
-       return  @NAMESPACE@.enableSubscription_int (p_sub_set, \r
-                       p_sub_provider, p_sub_receiver);\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION enableSubscription_int (sub_set, sub_provider, sub_receiver)\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.enableSubscription_int (int4, int4, int4)\r
-returns int4\r
-as '\r
-declare\r
-       p_sub_set                       alias for $1;\r
-       p_sub_provider          alias for $2;\r
-       p_sub_receiver          alias for $3;\r
-       v_n                                     int4;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- The real work is done in the replication engine. All\r
-       -- we have to do here is remembering that it happened.\r
-       -- ----\r
-       update @NAMESPACE@.sl_subscribe\r
-                       set sub_active = ''t''\r
-                       where sub_set = p_sub_set\r
-                       and sub_receiver = p_sub_receiver;\r
-       get diagnostics v_n = row_count;\r
-       if v_n = 0 then\r
-               insert into @NAMESPACE@.sl_subscribe\r
-                               (sub_set, sub_provider, sub_receiver,\r
-                               sub_forward, sub_active)\r
-                               values\r
-                               (p_sub_set, p_sub_provider, p_sub_receiver,\r
-                               false, true);\r
-       end if;\r
-\r
-       return p_sub_set;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION forwardConfirm ()\r
---\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.forwardConfirm (int4, int4, int8, timestamp)\r
-returns bigint\r
-as '\r
-declare\r
-       p_con_origin    alias for $1;\r
-       p_con_received  alias for $2;\r
-       p_con_seqno             alias for $3;\r
-       p_con_timestamp alias for $4;\r
-       v_max_seqno             bigint;\r
-begin\r
-       select into v_max_seqno coalesce(max(con_seqno), 0)\r
-                       from @NAMESPACE@.sl_confirm\r
-                       where con_origin = p_con_origin\r
-                       and con_received = p_con_received;\r
-       if v_max_seqno < p_con_seqno then\r
-               insert into @NAMESPACE@.sl_confirm \r
-                               (con_origin, con_received, con_seqno, con_timestamp)\r
-                               values (p_con_origin, p_con_received, p_con_seqno,\r
-                                       p_con_timestamp);\r
-               notify "_@CLUSTERNAME@_Confirm";\r
-               v_max_seqno = p_con_seqno;\r
-       end if;\r
-\r
-       return v_max_seqno;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION cleanupEvent ()\r
---\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.cleanupEvent ()\r
-returns int4\r
-as '\r
-declare\r
-       v_max_row       record;\r
-       v_min_row       record;\r
-       v_max_sync      int8;\r
-begin\r
-       -- ----\r
-       -- First remove all but the oldest confirm row per origin,receiver pair\r
-       -- ----\r
-       delete from @NAMESPACE@.sl_confirm\r
-                               where con_origin not in (select no_id from @NAMESPACE@.sl_node);\r
-       delete from @NAMESPACE@.sl_confirm\r
-                               where con_received not in (select no_id from @NAMESPACE@.sl_node);\r
-       -- ----\r
-       -- Next remove all but the oldest confirm row per origin,receiver pair.\r
-       -- Ignore confirmations that are younger than 10 minutes. We currently\r
-       -- have an not confirmed suspicion that a possibly lost transaction due\r
-       -- to a server crash might have been visible to another session, and\r
-       -- that this led to log data that is needed again got removed.\r
-       -- ----\r
-       for v_max_row in select con_origin, con_received, max(con_seqno) as con_seqno\r
-                               from @NAMESPACE@.sl_confirm\r
-                               where con_timestamp < (CURRENT_TIMESTAMP - ''10 min''::interval)\r
-                               group by con_origin, con_received\r
-       loop\r
-               delete from @NAMESPACE@.sl_confirm\r
-                               where con_origin = v_max_row.con_origin\r
-                               and con_received = v_max_row.con_received\r
-                               and con_seqno < v_max_row.con_seqno;\r
-       end loop;\r
-\r
-       -- ----\r
-       -- Then remove all events that are confirmed by all nodes in the\r
-       -- whole cluster up to the last SYNC\r
-       -- ----\r
-       for v_min_row in select con_origin, min(con_seqno) as con_seqno\r
-                               from @NAMESPACE@.sl_confirm\r
-                               group by con_origin\r
-       loop\r
-               select coalesce(max(ev_seqno), 0) into v_max_sync\r
-                               from @NAMESPACE@.sl_event\r
-                               where ev_origin = v_min_row.con_origin\r
-                               and ev_seqno <= v_min_row.con_seqno\r
-                               and ev_type = ''SYNC'';\r
-               if v_max_sync > 0 then\r
-                       delete from @NAMESPACE@.sl_event\r
-                                       where ev_origin = v_min_row.con_origin\r
-                                       and ev_seqno < v_max_sync;\r
-               end if;\r
-       end loop;\r
-\r
-       return 0;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION tableAddKey (tab_fqname)\r
---\r
---     If the specified table does not have a column \r
---     "_Slony-I_<clustername>_rowID", then add it as a bigint\r
---     with default nextval('"_<clustername>".sl_rowid_seq').\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.tableAddKey(text) returns text\r
-as '\r
-declare\r
-       p_tab_fqname    alias for $1;\r
-       v_attkind               text default '''';\r
-       v_attrow                record;\r
-       v_have_serial   bool default ''f'';\r
-begin\r
-       --\r
-       -- Loop over the attributes of this relation\r
-       -- and add a "v" for every user column, and a "k"\r
-       -- if we find the Slony-I special serial column.\r
-       --\r
-       for v_attrow in select PGA.attnum, PGA.attname\r
-                       from "pg_catalog".pg_class PGC,\r
-                           "pg_catalog".pg_namespace PGN,\r
-                               "pg_catalog".pg_attribute PGA\r
-                       where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                           "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                               and PGN.oid = PGC.relnamespace\r
-                               and PGA.attrelid = PGC.oid\r
-                               and not PGA.attisdropped\r
-                               and PGA.attnum > 0\r
-                       order by attnum\r
-       loop\r
-               if v_attrow.attname = ''_Slony-I_@CLUSTERNAME@_rowID'' then\r
-                   v_attkind := v_attkind || ''k'';\r
-                       v_have_serial := ''t'';\r
-               else\r
-                       v_attkind := v_attkind || ''v'';\r
-               end if;\r
-       end loop;\r
-       \r
-       --\r
-       -- A table must have at least one attribute, so not finding\r
-       -- anything means the table does not exist.\r
-       --\r
-       if not found then\r
-               raise exception ''Slony-I: table % not found'', p_tab_fqname;\r
-       end if;\r
-\r
-       --\r
-       -- If it does not have the special serial column, we\r
-       -- have to add it. This will be only half way done.\r
-       -- The function to add the table to the set must finish\r
-       -- these definitions with NOT NULL and UNIQUE after\r
-       -- updating all existing rows.\r
-       --\r
-       if not v_have_serial then\r
-               execute ''lock table '' || p_tab_fqname ||\r
-                       '' in access exclusive mode'';\r
-               execute ''alter table only '' || p_tab_fqname ||\r
-                       '' add column "_Slony-I_@CLUSTERNAME@_rowID" bigint;'';\r
-               execute ''alter table only '' || p_tab_fqname ||\r
-                       '' alter column "_Slony-I_@CLUSTERNAME@_rowID" '' ||\r
-                       '' set default "pg_catalog".nextval(''''@NAMESPACE@.sl_rowid_seq'''');'';\r
-\r
-               v_attkind := v_attkind || ''k'';\r
-       end if;\r
-\r
-       --\r
-       -- Return the resulting Slony-I attkind\r
-       --\r
-       return v_attkind;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION tableDropKey (tab_id)\r
---\r
---     If the specified table does not have a column \r
---     "_Slony-I_<clustername>_rowID", then add it as a bigint\r
---     with default nextval('"_<clustername>".sl_rowid_seq').\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.tableDropKey(int4) returns int4\r
-as '\r
-declare\r
-       p_tab_id                alias for $1;\r
-       v_tab_fqname    text;\r
-       v_tab_oid               oid;\r
-begin\r
-       -- ----\r
-       -- Grab the central configuration lock\r
-       -- ----\r
-       lock table @NAMESPACE@.sl_config_lock;\r
-\r
-       -- ----\r
-       -- Construct the tables fully qualified name and get its oid\r
-       -- ----\r
-       select "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                               "pg_catalog".quote_ident(PGC.relname),\r
-                               PGC.oid into v_tab_fqname, v_tab_oid\r
-                       from @NAMESPACE@.sl_table T,\r
-                               "pg_catalog".pg_class PGC,\r
-                               "pg_catalog".pg_namespace PGN\r
-                       where T.tab_id = p_tab_id\r
-                               and T.tab_reloid = PGC.oid\r
-                               and PGC.relnamespace = PGN.oid;\r
-       if not found then\r
-               raise exception ''Slony-I: table with ID % not found'', p_tab_id;\r
-       end if;\r
-\r
-       -- ----\r
-       -- Drop the special serial ID column if the table has it\r
-       -- ----\r
-       if exists (select true from "pg_catalog".pg_attribute\r
-                       where attrelid = v_tab_oid\r
-                               and attname = ''_Slony-I_@CLUSTERNAME@_rowID'')\r
-       then\r
-               execute ''lock table '' || v_tab_fqname ||\r
-                               '' in access exclusive mode'';\r
-               execute ''alter table '' || v_tab_fqname ||\r
-                               '' drop column "_Slony-I_@CLUSTERNAME@_rowID"'';\r
-       end if;\r
-\r
-       return p_tab_id;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION determineIdxnameUnique (tab_fqname, indexname)\r
---\r
---     Given a tablename, check that a unique index exists or return\r
---     the tables primary key index name.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.determineIdxnameUnique(text, name) returns name\r
-as '\r
-declare\r
-       p_tab_fqname    alias for $1;\r
-       p_idx_name              alias for $2;\r
-       v_idxrow                record;\r
-begin\r
-       --\r
-       -- Lookup the tables primary key or the specified unique index\r
-       --\r
-       if p_idx_name isnull then\r
-               select PGXC.relname\r
-                               into v_idxrow\r
-                               from "pg_catalog".pg_class PGC,\r
-                                       "pg_catalog".pg_namespace PGN,\r
-                                       "pg_catalog".pg_index PGX,\r
-                                       "pg_catalog".pg_class PGXC\r
-                               where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                                       "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                                       and PGN.oid = PGC.relnamespace\r
-                                       and PGX.indrelid = PGC.oid\r
-                                       and PGX.indexrelid = PGXC.oid\r
-                                       and PGX.indisprimary;\r
-               if not found then\r
-                       raise exception ''Slony-I: table % has no primary key'',\r
-                                       p_tab_fqname;\r
-               end if;\r
-       else\r
-               select PGXC.relname\r
-                               into v_idxrow\r
-                               from "pg_catalog".pg_class PGC,\r
-                                       "pg_catalog".pg_namespace PGN,\r
-                                       "pg_catalog".pg_index PGX,\r
-                                       "pg_catalog".pg_class PGXC\r
-                               where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                                       "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                                       and PGN.oid = PGC.relnamespace\r
-                                       and PGX.indrelid = PGC.oid\r
-                                       and PGX.indexrelid = PGXC.oid\r
-                                       and PGX.indisunique\r
-                                       and PGXC.relname = p_idx_name;\r
-               if not found then\r
-                       raise exception ''Slony-I: table % has no unique index %'',\r
-                                       p_tab_fqname, p_idx_name;\r
-               end if;\r
-       end if;\r
-\r
-       --\r
-       -- Return the found index name\r
-       --\r
-       return v_idxrow.relname;\r
-end;\r
-' language plpgsql called on null input;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION determineIdxnameSerial (tab_fqname)\r
---\r
---     Given a tablename, construct the serial columns index name\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.determineIdxnameSerial(text) returns name\r
-as '\r
-declare\r
-       p_tab_fqname    alias for $1;\r
-       v_row                   record;\r
-begin\r
-       --\r
-       -- Lookup the table name alone\r
-       --\r
-       select PGC.relname\r
-                       into v_row\r
-                       from "pg_catalog".pg_class PGC,\r
-                               "pg_catalog".pg_namespace PGN\r
-                       where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                               "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                               and PGN.oid = PGC.relnamespace;\r
-       if not found then\r
-               raise exception ''Slony-I: table % not found'',\r
-                               p_tab_fqname;\r
-       end if;\r
-\r
-       --\r
-       -- Return the found index name\r
-       --\r
-       return v_row.relname || ''__Slony-I_@CLUSTERNAME@_rowID_key'';\r
-end;\r
-' language plpgsql called on null input;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION determineAttKindUnique (tab_fqname, indexname)\r
---\r
---     Given a tablename, return the Slony-I specific attkind (used for\r
---     the log trigger) of the table. Use the specified unique index or\r
---     the primary key (if indexname is NULL).\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.determineAttkindUnique(text, name) returns text\r
-as '\r
-declare\r
-       p_tab_fqname    alias for $1;\r
-       p_idx_name              alias for $2;\r
-       v_idxrow                record;\r
-       v_attrow                record;\r
-       v_i                             integer;\r
-       v_attno                 int2;\r
-       v_attkind               text default '''';\r
-       v_attfound              bool;\r
-begin\r
-       --\r
-       -- Lookup the tables primary key or the specified unique index\r
-       --\r
-       if p_idx_name isnull then\r
-               raise exception ''Slony-I: index name must be specified'';\r
-       else\r
-               select PGXC.relname, PGX.indexrelid, PGX.indkey\r
-                               into v_idxrow\r
-                               from "pg_catalog".pg_class PGC,\r
-                                       "pg_catalog".pg_namespace PGN,\r
-                                       "pg_catalog".pg_index PGX,\r
-                                       "pg_catalog".pg_class PGXC\r
-                               where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                                       "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                                       and PGN.oid = PGC.relnamespace\r
-                                       and PGX.indrelid = PGC.oid\r
-                                       and PGX.indexrelid = PGXC.oid\r
-                                       and PGX.indisunique\r
-                                       and PGXC.relname = p_idx_name;\r
-               if not found then\r
-                       raise exception ''Slony-I: table % has no unique index %'',\r
-                                       p_tab_fqname, p_idx_name;\r
-               end if;\r
-       end if;\r
-\r
-       --\r
-       -- Loop over the tables attributes and check if they are\r
-       -- index attributes. If so, add a "k" to the return value,\r
-       -- otherwise add a "v".\r
-       --\r
-       for v_attrow in select PGA.attnum, PGA.attname\r
-                       from "pg_catalog".pg_class PGC,\r
-                           "pg_catalog".pg_namespace PGN,\r
-                               "pg_catalog".pg_attribute PGA\r
-                       where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                           "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                               and PGN.oid = PGC.relnamespace\r
-                               and PGA.attrelid = PGC.oid\r
-                               and not PGA.attisdropped\r
-                               and PGA.attnum > 0\r
-                       order by attnum\r
-       loop\r
-               v_attfound = ''f'';\r
-\r
-               v_i := 0;\r
-               loop\r
-                       select indkey[v_i] into v_attno from "pg_catalog".pg_index\r
-                                       where indexrelid = v_idxrow.indexrelid;\r
-                       if v_attno = 0 then\r
-                               exit;\r
-                       end if;\r
-                       if v_attrow.attnum = v_attno then\r
-                               v_attfound = ''t'';\r
-                               exit;\r
-                       end if;\r
-                       v_i := v_i + 1;\r
-               end loop;\r
-\r
-               if v_attfound then\r
-                       v_attkind := v_attkind || ''k'';\r
-               else\r
-                       v_attkind := v_attkind || ''v'';\r
-               end if;\r
-       end loop;\r
-\r
-       --\r
-       -- Return the resulting attkind\r
-       --\r
-       return v_attkind;\r
-end;\r
-' language plpgsql called on null input;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION determineAttKindSerial (tab_fqname)\r
---\r
---     A table was that was specified without a primary key is added\r
---     to the replication. Assume that tableAddKey() was called before\r
---     and finish the creation of the serial column. The return an\r
---     attkind according to that.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.determineAttkindSerial(text)\r
-returns text\r
-as '\r
-declare\r
-       p_tab_fqname    alias for $1;\r
-       v_attkind               text default '''';\r
-       v_attrow                record;\r
-       v_have_serial   bool default ''f'';\r
-begin\r
-       --\r
-       -- Loop over the attributes of this relation\r
-       -- and add a "v" for every user column, and a "k"\r
-       -- if we find the Slony-I special serial column.\r
-       --\r
-       for v_attrow in select PGA.attnum, PGA.attname\r
-                       from "pg_catalog".pg_class PGC,\r
-                           "pg_catalog".pg_namespace PGN,\r
-                               "pg_catalog".pg_attribute PGA\r
-                       where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                           "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                               and PGN.oid = PGC.relnamespace\r
-                               and PGA.attrelid = PGC.oid\r
-                               and not PGA.attisdropped\r
-                               and PGA.attnum > 0\r
-                       order by attnum\r
-       loop\r
-               if v_attrow.attname = ''_Slony-I_@CLUSTERNAME@_rowID'' then\r
-                   v_attkind := v_attkind || ''k'';\r
-                       v_have_serial := ''t'';\r
-               else\r
-                       v_attkind := v_attkind || ''v'';\r
-               end if;\r
-       end loop;\r
-       \r
-       --\r
-       -- A table must have at least one attribute, so not finding\r
-       -- anything means the table does not exist.\r
-       --\r
-       if not found then\r
-               raise exception ''Slony-I: table % not found'', p_tab_fqname;\r
-       end if;\r
-\r
-       --\r
-       -- If it does not have the special serial column, we\r
-       -- should not have been called in the first place.\r
-       --\r
-       if not v_have_serial then\r
-               raise exception ''Slony-I: table % does not have the serial key'',\r
-                               p_tab_fqname;\r
-       end if;\r
-\r
-       execute ''update '' || p_tab_fqname ||\r
-               '' set "_Slony-I_@CLUSTERNAME@_rowID" ='' ||\r
-               '' "pg_catalog".nextval(''''@NAMESPACE@.sl_rowid_seq'''');'';\r
-       execute ''alter table only '' || p_tab_fqname ||\r
-               '' add unique ("_Slony-I_@CLUSTERNAME@_rowID");'';\r
-       execute ''alter table only '' || p_tab_fqname ||\r
-               '' alter column "_Slony-I_@CLUSTERNAME@_rowID" '' ||\r
-               '' set not null;'';\r
-\r
-       --\r
-       -- Return the resulting Slony-I attkind\r
-       --\r
-       return v_attkind;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION tableHasSerialKey (tab_fqname)\r
---\r
---     Checks if a table has our special serial key column that is\r
---     used if the table has no natural unique constraint.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.tableHasSerialKey(text) \r
-returns bool\r
-as '\r
-declare\r
-       p_tab_fqname    alias for $1;\r
-       v_attnum                int2;\r
-begin\r
-       select PGA.attnum into v_attnum\r
-                       from "pg_catalog".pg_class PGC,\r
-                               "pg_catalog".pg_namespace PGN,\r
-                               "pg_catalog".pg_attribute PGA\r
-                       where "pg_catalog".quote_ident(PGN.nspname) || ''.'' ||\r
-                               "pg_catalog".quote_ident(PGC.relname) = p_tab_fqname\r
-                               and PGC.relnamespace = PGN.oid\r
-                               and PGA.attrelid = PGC.oid\r
-                               and PGA.attname = ''_Slony-I_@CLUSTERNAME@_rowID''\r
-                               and not PGA.attisdropped;\r
-       return found;\r
-end;\r
-' language plpgsql;\r
-\r
-\r
--- **********************************************************************\r
--- * Views\r
--- **********************************************************************\r
-\r
-\r
--- ----------------------------------------------------------------------\r
--- VIEW sl_status\r
---\r
---     This view shows the local nodes last event sequence number\r
---     and how far all remote nodes have processed events.\r
--- ----------------------------------------------------------------------\r
-create or replace view @NAMESPACE@.sl_status as select\r
-       E.ev_origin as st_origin,\r
-       C.con_received as st_received,\r
-       E.ev_seqno as st_last_event,\r
-       E.ev_timestamp as st_last_event_ts,\r
-       C.con_seqno as st_last_received,\r
-       C.con_timestamp as st_last_received_ts,\r
-       CE.ev_timestamp as st_last_received_event_ts,\r
-       E.ev_seqno - C.con_seqno as st_lag_num_events,\r
-       current_timestamp - CE.ev_timestamp as st_lag_time\r
-       from @NAMESPACE@.sl_event E, @NAMESPACE@.sl_confirm C,\r
-               @NAMESPACE@.sl_event CE\r
-       where E.ev_origin = C.con_origin\r
-       and CE.ev_origin = E.ev_origin\r
-       and CE.ev_seqno = C.con_seqno\r
-       and (E.ev_origin, E.ev_seqno) in \r
-               (select ev_origin, max(ev_seqno)\r
-                       from @NAMESPACE@.sl_event\r
-                       where ev_origin = @NAMESPACE@.getLocalNodeId('_@CLUSTERNAME@')\r
-                       group by 1\r
-               )\r
-       and (C.con_origin, C.con_received, C.con_seqno) in\r
-               (select con_origin, con_received, max(con_seqno)\r
-                       from @NAMESPACE@.sl_confirm\r
-                       where con_origin = @NAMESPACE@.getLocalNodeId('_@CLUSTERNAME@')\r
-                       group by 1, 2\r
-               );\r
-\r
-\r
diff --git a/sql/plugins/slony1_funcs.v73.sql b/sql/plugins/slony1_funcs.v73.sql
deleted file mode 100755 (executable)
index 97580e7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
--- ----------------------------------------------------------------------\r
--- slony1_funcs.v73.sql\r
---\r
---    Version 7.3 specific part of the replication support functions.\r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: slony1_funcs.v73.sql,v 1.2 2005/06/16 14:40:15 chriskl Exp $\r
--- ----------------------------------------------------------------------\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION truncateTable(tab_fqname)\r
---\r
---     Remove all content from a table before the subscription\r
---     content is loaded via COPY.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.truncateTable(text)\r
-returns int4\r
-as '\r
-declare\r
-       p_tab_fqname            alias for $1;\r
-begin\r
-       execute ''delete from only '' || p_tab_fqname;\r
-       return 1;\r
-end;\r
-' language plpgsql;\r
-\r
diff --git a/sql/plugins/slony1_funcs.v74.sql b/sql/plugins/slony1_funcs.v74.sql
deleted file mode 100755 (executable)
index 489d9a6..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
--- ----------------------------------------------------------------------\r
--- slony1_funcs.v74.sql\r
---\r
---    Version 7.4 specific part of the replication support functions.\r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: slony1_funcs.v74.sql,v 1.2 2005/06/16 14:40:15 chriskl Exp $\r
--- ----------------------------------------------------------------------\r
-\r
--- ----------------------------------------------------------------------\r
--- FUNCTION truncateTable(tab_fqname)\r
---\r
---     Remove all content from a table before the subscription\r
---     content is loaded via COPY.\r
--- ----------------------------------------------------------------------\r
-create or replace function @NAMESPACE@.truncateTable(text)\r
-returns int4\r
-as '\r
-declare\r
-       p_tab_fqname            alias for $1;\r
-begin\r
-       execute ''delete from only '' || p_tab_fqname;\r
-       return 1;\r
-end;\r
-' language plpgsql;\r
-\r
diff --git a/sql/plugins/xxid.v73.sql b/sql/plugins/xxid.v73.sql
deleted file mode 100755 (executable)
index 20cd6d7..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
--- ----------\r
--- xxid.v73.sql.in\r
---\r
---     SQL script for loading the transaction ID compatible datatype \r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: xxid.v73.sql,v 1.2 2005/06/16 14:40:15 chriskl Exp $\r
--- ----------\r
-\r
---\r
--- Type specific input and output functions\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxidin"(cstring) RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_xxidin'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidout"(@NAMESPACE@."xxid") RETURNS cstring\r
-       AS '$libdir/xxid', '_Slony_I_xxidout'\r
-       LANGUAGE C;\r
-\r
-\r
---\r
--- The data type itself\r
---\r
-CREATE TYPE @NAMESPACE@."xxid" (\r
-       INPUT = @NAMESPACE@."xxidin",\r
-       OUTPUT = @NAMESPACE@."xxidout",\r
-       EXTERNALLENGTH = 12,\r
-       INTERNALLENGTH = 4,\r
-       PASSEDBYVALUE,\r
-       ALIGNMENT = int4\r
-);\r
-\r
-\r
---\r
--- Since our xxid type has special cases for values 0-3, it\r
--- in fact IS xid, so allow implicit type casting to and from.\r
---\r
-CREATE CAST (xid AS @NAMESPACE@.xxid)\r
-       WITHOUT FUNCTION AS IMPLICIT;\r
-CREATE CAST (@NAMESPACE@.xxid AS xid)\r
-       WITHOUT FUNCTION AS IMPLICIT;\r
-\r
-\r
---\r
--- Comparision functions for the new datatype\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxideq"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxideq'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidne"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidne'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidlt"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidlt'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidle"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidle'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidgt"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidgt'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidge"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidge'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."btxxidcmp"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS int4\r
-       AS '$libdir/xxid', '_Slony_I_btxxidcmp'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@.getCurrentXid() RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_getCurrentXid'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@.getMinXid() RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_getMinXid'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@.getMaxXid() RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_getMaxXid'\r
-       LANGUAGE C;\r
-\r
-\r
---\r
--- Operators on these comparision functions\r
---\r
-CREATE OPERATOR < (\r
-       PROCEDURE = @NAMESPACE@."xxidlt",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = >, NEGATOR = >=,\r
-       RESTRICT = scalarltsel, JOIN = scalarltjoinsel\r
-);\r
-CREATE OPERATOR = (\r
-       PROCEDURE = @NAMESPACE@."xxideq",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = =, NEGATOR = <>,\r
-       RESTRICT = eqsel, JOIN = eqjoinsel,\r
-       SORT1 = <, SORT2 = <,\r
-       HASHES\r
-);\r
-CREATE OPERATOR <> (\r
-       PROCEDURE = @NAMESPACE@."xxidne",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = <>, NEGATOR = =,\r
-       RESTRICT = neqsel, JOIN = neqjoinsel\r
-);\r
-CREATE OPERATOR > (\r
-       PROCEDURE = @NAMESPACE@."xxidgt",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = <, NEGATOR = <=,\r
-       RESTRICT = scalargtsel, JOIN = scalargtjoinsel\r
-);\r
-CREATE OPERATOR <= (\r
-       PROCEDURE = @NAMESPACE@."xxidle",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = >=, NEGATOR = >,\r
-       RESTRICT = scalarltsel, JOIN = scalarltjoinsel\r
-);\r
-CREATE OPERATOR >= (\r
-       PROCEDURE = @NAMESPACE@."xxidge",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = <=, NEGATOR = <,\r
-       RESTRICT = scalargtsel, JOIN = scalargtjoinsel\r
-);\r
-\r
-\r
---\r
--- Finally the default operator class so that we can use our\r
--- new data type in btree indexes.\r
---\r
-CREATE OPERATOR CLASS @NAMESPACE@."xxid_ops"\r
-       DEFAULT FOR TYPE @NAMESPACE@."xxid" USING btree AS\r
-       OPERATOR 1 <  (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 2 <= (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 3 =  (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 4 >= (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 5 >  (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       FUNCTION 1 @NAMESPACE@."btxxidcmp" (@NAMESPACE@."xxid", @NAMESPACE@."xxid");\r
-\r
-\r
---\r
--- A special transaction snapshot data type for faster visibility checks\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxid_snapshot_in"(cstring)\r
-RETURNS @NAMESPACE@."xxid_snapshot"\r
-       AS '$libdir/xxid', '_Slony_I_xxid_snapshot_in'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxid_snapshot_out"(@NAMESPACE@."xxid_snapshot")\r
-RETURNS cstring\r
-       AS '$libdir/xxid', '_Slony_I_xxid_snapshot_out'\r
-       LANGUAGE C;\r
-\r
-\r
---\r
--- The data type itself\r
---\r
-CREATE TYPE @NAMESPACE@."xxid_snapshot" (\r
-       INPUT = @NAMESPACE@."xxid_snapshot_in",\r
-       OUTPUT = @NAMESPACE@."xxid_snapshot_out",\r
-       INTERNALLENGTH = variable,\r
-       ALIGNMENT = int4\r
-);\r
-\r
-\r
---\r
--- Special comparision functions used by the remote worker\r
--- for sync chunk selection\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxid_lt_snapshot"(\r
-               @NAMESPACE@."xxid",\r
-               @NAMESPACE@."xxid_snapshot")\r
-RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxid_lt_snapshot'\r
-       LANGUAGE C;\r
-\r
-CREATE FUNCTION @NAMESPACE@."xxid_ge_snapshot"(\r
-               @NAMESPACE@."xxid",\r
-               @NAMESPACE@."xxid_snapshot")\r
-RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxid_ge_snapshot'\r
-       LANGUAGE C;\r
-\r
-\r
diff --git a/sql/plugins/xxid.v74.sql b/sql/plugins/xxid.v74.sql
deleted file mode 100755 (executable)
index 1563256..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
--- ----------\r
--- xxid.v73.sql.in\r
---\r
---     SQL script for loading the transaction ID compatible datatype \r
---\r
---     Copyright (c) 2003-2004, PostgreSQL Global Development Group\r
---     Author: Jan Wieck, Afilias USA INC.\r
---\r
--- $Id: xxid.v74.sql,v 1.2 2005/06/16 14:40:15 chriskl Exp $\r
--- ----------\r
-\r
---\r
--- Type specific input and output functions\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxidin"(cstring) RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_xxidin'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidout"(@NAMESPACE@."xxid") RETURNS cstring\r
-       AS '$libdir/xxid', '_Slony_I_xxidout'\r
-       LANGUAGE C;\r
-\r
-\r
---\r
--- The data type itself\r
---\r
-CREATE TYPE @NAMESPACE@."xxid" (\r
-       INPUT = @NAMESPACE@."xxidin",\r
-       OUTPUT = @NAMESPACE@."xxidout",\r
-       EXTERNALLENGTH = 12,\r
-       INTERNALLENGTH = 4,\r
-       PASSEDBYVALUE,\r
-       ALIGNMENT = int4\r
-);\r
-\r
-\r
---\r
--- Since our xxid type has special cases for values 0-3, it\r
--- in fact IS xid, so allow implicit type casting to and from.\r
---\r
-CREATE CAST (xid AS @NAMESPACE@.xxid)\r
-       WITHOUT FUNCTION AS IMPLICIT;\r
-CREATE CAST (@NAMESPACE@.xxid AS xid)\r
-       WITHOUT FUNCTION AS IMPLICIT;\r
-\r
-\r
---\r
--- Comparision functions for the new datatype\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxideq"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxideq'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidne"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidne'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidlt"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidlt'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidle"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidle'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidgt"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidgt'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxidge"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxidge'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."btxxidcmp"(@NAMESPACE@."xxid", @NAMESPACE@."xxid") RETURNS int4\r
-       AS '$libdir/xxid', '_Slony_I_btxxidcmp'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@.getCurrentXid() RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_getCurrentXid'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@.getMinXid() RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_getMinXid'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@.getMaxXid() RETURNS @NAMESPACE@."xxid"\r
-       AS '$libdir/xxid', '_Slony_I_getMaxXid'\r
-       LANGUAGE C;\r
-\r
-\r
---\r
--- Operators on these comparision functions\r
---\r
-CREATE OPERATOR < (\r
-       PROCEDURE = @NAMESPACE@."xxidlt",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = >, NEGATOR = >=,\r
-       RESTRICT = scalarltsel, JOIN = scalarltjoinsel\r
-);\r
-CREATE OPERATOR = (\r
-       PROCEDURE = @NAMESPACE@."xxideq",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = =, NEGATOR = <>,\r
-       RESTRICT = eqsel, JOIN = eqjoinsel,\r
-       SORT1 = <, SORT2 = <,\r
-       HASHES\r
-);\r
-CREATE OPERATOR <> (\r
-       PROCEDURE = @NAMESPACE@."xxidne",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = <>, NEGATOR = =,\r
-       RESTRICT = neqsel, JOIN = neqjoinsel\r
-);\r
-CREATE OPERATOR > (\r
-       PROCEDURE = @NAMESPACE@."xxidgt",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = <, NEGATOR = <=,\r
-       RESTRICT = scalargtsel, JOIN = scalargtjoinsel\r
-);\r
-CREATE OPERATOR <= (\r
-       PROCEDURE = @NAMESPACE@."xxidle",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = >=, NEGATOR = >,\r
-       RESTRICT = scalarltsel, JOIN = scalarltjoinsel\r
-);\r
-CREATE OPERATOR >= (\r
-       PROCEDURE = @NAMESPACE@."xxidge",\r
-       LEFTARG = @NAMESPACE@."xxid",\r
-       RIGHTARG = @NAMESPACE@."xxid",\r
-       COMMUTATOR = <=, NEGATOR = <,\r
-       RESTRICT = scalargtsel, JOIN = scalargtjoinsel\r
-);\r
-\r
-\r
---\r
--- Finally the default operator class so that we can use our\r
--- new data type in btree indexes.\r
---\r
-CREATE OPERATOR CLASS @NAMESPACE@."xxid_ops"\r
-       DEFAULT FOR TYPE @NAMESPACE@."xxid" USING btree AS\r
-       OPERATOR 1 <  (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 2 <= (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 3 =  (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 4 >= (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       OPERATOR 5 >  (@NAMESPACE@."xxid", @NAMESPACE@."xxid"),\r
-       FUNCTION 1 @NAMESPACE@."btxxidcmp" (@NAMESPACE@."xxid", @NAMESPACE@."xxid");\r
-\r
-\r
---\r
--- A special transaction snapshot data type for faster visibility checks\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxid_snapshot_in"(cstring)\r
-RETURNS @NAMESPACE@."xxid_snapshot"\r
-       AS '$libdir/xxid', '_Slony_I_xxid_snapshot_in'\r
-       LANGUAGE C;\r
-CREATE FUNCTION @NAMESPACE@."xxid_snapshot_out"(@NAMESPACE@."xxid_snapshot")\r
-RETURNS cstring\r
-       AS '$libdir/xxid', '_Slony_I_xxid_snapshot_out'\r
-       LANGUAGE C;\r
-\r
-\r
---\r
--- The data type itself\r
---\r
-CREATE TYPE @NAMESPACE@."xxid_snapshot" (\r
-       INPUT = @NAMESPACE@."xxid_snapshot_in",\r
-       OUTPUT = @NAMESPACE@."xxid_snapshot_out",\r
-       INTERNALLENGTH = variable,\r
-       ALIGNMENT = int4\r
-);\r
-\r
-\r
---\r
--- Special comparision functions used by the remote worker\r
--- for sync chunk selection\r
---\r
-CREATE FUNCTION @NAMESPACE@."xxid_lt_snapshot"(\r
-               @NAMESPACE@."xxid",\r
-               @NAMESPACE@."xxid_snapshot")\r
-RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxid_lt_snapshot'\r
-       LANGUAGE C;\r
-\r
-CREATE FUNCTION @NAMESPACE@."xxid_ge_snapshot"(\r
-               @NAMESPACE@."xxid",\r
-               @NAMESPACE@."xxid_snapshot")\r
-RETURNS boolean\r
-       AS '$libdir/xxid', '_Slony_I_xxid_ge_snapshot'\r
-       LANGUAGE C;\r
-\r
-\r