CVS User Account cvsuser
Wed Sep 29 23:16:01 PDT 2004
Log Message:
-----------
Implement SET DROP TABLE and SET DROP SEQUENCE.

1.  This adds to the slonik grammar
2.  This adds setdropsequence/setdroptable functions to
    the stored function repository
3.  This adds the SET_DROP_SEQUENCE and SET_DROP_TABLE events
    to those that need to be supported by slon.
4.  Documentation has been updated to reference the new
    functions and syntax.

Modified Files:
--------------
    slony1-engine/doc/howto:
        helpitsbroken.txt (r1.11 -> r1.12)
        schemadoc.html (r1.5 -> r1.6)
        slonik_commands.html (r1.7 -> r1.8)
    slony1-engine/src/backend:
        slony1_funcs.sql (r1.29 -> r1.30)
    slony1-engine/src/slon:
        local_listen.c (r1.24 -> r1.25)
        remote_worker.c (r1.63 -> r1.64)
        runtime_config.c (r1.20 -> r1.21)
        slon.h (r1.38 -> r1.39)
    slony1-engine/src/slonik:
        parser.y (r1.18 -> r1.19)
        slonik.c (r1.30 -> r1.31)
        slonik.h (r1.18 -> r1.19)

-------------- next part --------------
Index: remote_worker.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_worker.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -Lsrc/slon/remote_worker.c -Lsrc/slon/remote_worker.c -u -w -r1.63 -r1.64
--- src/slon/remote_worker.c
+++ src/slon/remote_worker.c
@@ -685,6 +685,18 @@
 				 * and sequences information is not
 				 * maintained in the runtime configuration.
 				 */
+			} else if (strcmp(event->ev_type, "SET_DROP_TABLE") == 0) 
+			{
+			  int tab_id = (int) strtol(event->ev_data1, NULL, 10);
+			  slon_appendquery(&query1, "select %s.setDropTable_int(%d);", 
+					   rtcfg_namespace,
+					   tab_id);
+			} else if (strcmp(event->ev_type, "SET_DROP_SEQUENCE") == 0)
+			{
+			  int seq_id = (int) strtol(event->ev_data1, NULL, 10);
+			  slon_appendquery(&query1, "select %s.setDropSequence_int(%d);", 
+					   rtcfg_namespace,
+					   seq_id);
 			} else if (strcmp(event->ev_type, "STORE_TRIGGER") == 0)
 			{
 				int             trig_tabid = (int)strtol(event->ev_data1, NULL, 10);
@@ -3866,3 +3878,11 @@
 		pthread_mutex_unlock(&(provider->helper_lock));
 	}
 }
+
+/*
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
Index: slon.h
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -Lsrc/slon/slon.h -Lsrc/slon/slon.h -u -w -r1.38 -r1.39
--- src/slon/slon.h
+++ src/slon/slon.h
@@ -498,3 +498,11 @@
 
 #endif /*  SLON_H_INCLUDED */
 
+
+/*
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
Index: runtime_config.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/runtime_config.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -Lsrc/slon/runtime_config.c -Lsrc/slon/runtime_config.c -u -w -r1.20 -r1.21
--- src/slon/runtime_config.c
+++ src/slon/runtime_config.c
@@ -610,7 +610,6 @@
 	rtcfg_unlock();
 }
 
-
 void
 rtcfg_moveSet(int set_id, int old_origin, int new_origin, int sub_provider)
 {
@@ -1035,3 +1034,11 @@
 
 	return retval;
 }
+
+/*
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
Index: local_listen.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/local_listen.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -Lsrc/slon/local_listen.c -Lsrc/slon/local_listen.c -u -w -r1.24 -r1.25
--- src/slon/local_listen.c
+++ src/slon/local_listen.c
@@ -402,6 +402,28 @@
 				 * the runtime configuration.
 				 */
 			}
+			else if (strcmp(ev_type, "SET_DROP_TABLE") == 0)
+			{
+				/*
+				 * SET_DROP_TABLE
+				 */
+				/*
+				 * Nothing to do ATM ... 
+				 * table information is not maintained in
+				 * the runtime configuration.
+				 */
+			}
+			else if (strcmp(ev_type, "SET_DROP_SEQUENCE") == 0)
+			{
+				/*
+				 * SET_DROP_SEQUENCE
+				 */
+				/*
+				 * Nothing to do ATM ... 
+				 * table information is not maintained in
+				 * the runtime configuration.
+				 */
+			}
 			else if (strcmp(ev_type, "ADJUST_SEQ") == 0)
 			{
 				/*
@@ -620,3 +642,11 @@
 }
 
 
+
+/*
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
Index: helpitsbroken.txt
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/doc/howto/helpitsbroken.txt,v
retrieving revision 1.11
retrieving revision 1.12
diff -Ldoc/howto/helpitsbroken.txt -Ldoc/howto/helpitsbroken.txt -u -w -r1.11 -r1.12
--- doc/howto/helpitsbroken.txt
+++ doc/howto/helpitsbroken.txt
@@ -52,7 +52,8 @@
 identifier name.
 
 You may be able to defeat this by putting "quotes" around identifier
-names, but it's liable to bite you somewhere...
+names, but it's liable to bite you some, so this is something that is
+probably not worth working around.
 
 4.  After an immediate stop of postgresql (simulation of system crash)
 in pg_catalog.pg_listener a tuple with
@@ -187,31 +188,14 @@
 data, and kills the usability of the cluster on the rest of the set
 while that's happening.
 
-b) Some day, someone will get around to implementing the Slonik
-command SET DROP TABLE, which will involve (roughly speaking) the
-following set of changes:
+b) If you are running 1.0.3 or later, there is the command SET DROP
+TABLE, which will "do the trick."
 
- 1.  Need to augment the grammar to know about "set drop table"
-
- 2.  Need to have a C function for set_drop_table
-
- 3.  Need a stored procedure, droptable(), which initiates the event
-
- 4.  Need another stored procedure, droptable_int() which does the
-      alterTableRestore(), tableDropKey()
-
- 5.  I presume (haven't looked) that slon needs to have a case
-      statement added to allow it to propagate the "DROP_TABLE" 
-      event.
-
-That will happen when someone gets around to implementing it.  The
-likely "first volunteer" is Chris Browne <cbbrowne at acm.org>, but if
-somone gets to it first, he won't mind too much.
-
-c) The _essential_ functionality of SET DROP TABLE is the bits in step
-4, droptable_int().  You can fiddle this by hand by finding the table
-ID for the table you want to get rid of, which you can find in
-sl_table, and then run three queries, on each host:
+c) If you are still using 1.0.1 or 1.0.2, the _essential_
+functionality of SET DROP TABLE involves the functionality in
+droptable_int().  You can fiddle this by hand by finding the table ID
+for the table you want to get rid of, which you can find in sl_table,
+and then run the following three queries, on each host:
 
   select _slonyschema.alterTableRestore(40);
   select _slonyschema.tableDropKey(40);
@@ -228,21 +212,13 @@
 SCRIPT could do that.  Also possible would be to connect to each
 database and submit the queries by hand.
 
-11.  I tried to add a table to a set, and got the following message:
+11.  I want to stop replicating a sequence
 
-   Slony-I: cannot add table to currently subscribed set 1
+If you are running 1.0.3 or later, there is a SET DROP SEQUENCE
+command in Slonik to allow you to do this, parallelling SET DROP
+TABLE.
 
-You cannot add tables to sets that already have subscribers.
-
-The workaround to this is to create ANOTHER set, add the new tables to
-that new set, subscribe the same nodes subscribing to "set 1" to the
-new set, and then merge the sets together.
-
-12.  I want to stop replicating a sequence
-
-There is not at this point a SET DROP SEQUENCE command in Slonik to
-allow you to do this.  That should come in at the same time as SET
-DROP TABLE does (see #10).
+If you are running 1.0.2 or earlier, the process is a bit more manual.
 
 Supposing I want to get rid of the two sequences listed below,
 whois_cachemgmt_seq and epp_whoi_cach_seq_, we start by needing the
@@ -266,6 +242,19 @@
 ddlscript() / EXECUTE SCRIPT, thus eliminating the sequence everywhere
 "at once."  Or they may be applied by hand to each of the nodes.
 
+Similarly to SET DROP TABLE, this should be in place for Slony-I version
+1.0.3 as SET DROP SEQUENCE.
+
+12.  I tried to add a table to a set, and got the following message:
+
+   Slony-I: cannot add table to currently subscribed set 1
+
+You cannot add tables to sets that already have subscribers.
+
+The workaround to this is to create ANOTHER set, add the new tables to
+that new set, subscribe the same nodes subscribing to "set 1" to the
+new set, and then merge the sets together.
+
 13.  Some nodes start consistently falling behind
 
 I have been running Slony-I on a node for a while, and am seeing
@@ -282,12 +271,12 @@
 
 You quite likely need to do a VACUUM FULL on pg_listener, to
 vigorously clean it out, and need to vacuum pg_listener really
-frequently.  (Once every five minutes would likely be AOK.)
+frequently.  Once every five minutes would likely be AOK.
 
 Slon daemons already vacuum a bunch of tables, and cleanup_thread.c
 contains a list of tables that are frequently vacuumed automatically.
-In Slony-I 1.0.2, pg_listener is not included.  In later versions, it
-will be, so this may be an obsolete problem.
+In Slony-I 1.0.2, pg_listener is not included.  In 1.0.3 and later, it
+is regularly vacuumed, so this should cease to be an issue.
 
 14.  I started doing a backup using pg_dump, and suddenly Slony stops
 replicating anything.
@@ -329,6 +318,9 @@
  b) It would be nice to add an "--exclude-schema" option to pg_dump to
     exclude the Slony cluster schema.  Maybe in 8.0 or 8.1...
 
+Note that 1.0.3 uses a more precise lock that is less exclusive that
+should relieve this problem.
+
 15.  The slons spent the weekend out of commission [for some reason],
 and it's taking a long time to get a sync through.
 
@@ -344,6 +336,10 @@
 Conclusion: Even if there is not going to be a subscriber around, you
 _really_ want to have a slon running to service the "master" node.
 
+Some future version (probably 1.1) may provide a way for SYNC counts
+to be updated on the master by the stored function that is invoked by
+the table triggers.
+
 16.  I pointed a subscribing node to a different parent and it stopped
 replicating
 
@@ -382,3 +378,12 @@
 
 Immediately after this script was run, SYNC events started propagating
 again to node 3.
+
+This points out two principles:
+
+ 1.  If you have multiple nodes, and cascaded subscribers, you need to
+     be quite careful in populating the STORE LISTEN entries, and in
+     modifying them if the structure of the replication "tree" changes.
+
+ 2.  Version 1.1 probably ought to provide better tools to help manage
+     this.
Index: schemadoc.html
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/doc/howto/schemadoc.html,v
retrieving revision 1.5
retrieving revision 1.6
diff -Ldoc/howto/schemadoc.html -Ldoc/howto/schemadoc.html -u -w -r1.5 -r1.6
--- doc/howto/schemadoc.html
+++ doc/howto/schemadoc.html
@@ -111,13 +111,13 @@
   <body>
 
     <!-- Primary Index -->
-	<p><br><br>Dumped on 2004-09-23</p>
+	<p><br><br>Dumped on 2004-09-29</p>
 <h1><a name="index">Index of database - schemadoc</a></h1>
 <ul>
     
     <li><a name="schemadoc.schema">schemadoc</a></li><ul>
     	<li><a href="#schemadoc.table.sl-config-lock">sl_config_lock</a></li><li><a href="#schemadoc.table.sl-confirm">sl_confirm</a></li><li><a href="#schemadoc.table.sl-event">sl_event</a></li><li><a href="#schemadoc.table.sl-listen">sl_listen</a></li><li><a href="#schemadoc.table.sl-log-1">sl_log_1</a></li><li><a href="#schemadoc.table.sl-log-2">sl_log_2</a></li><li><a href="#schemadoc.table.sl-node">sl_node</a></li><li><a href="#schemadoc.table.sl-path">sl_path</a></li><li><a href="#schemadoc.view.sl-seqlastvalue">sl_seqlastvalue</a></li><li><a href="#schemadoc.table.sl-seqlog">sl_seqlog</a></li><li><a href="#schemadoc.table.sl-sequence">sl_sequence</a></li><li><a href="#schemadoc.table.sl-set">sl_set</a></li><li><a href="#schemadoc.table.sl-setsync">sl_setsync</a></li><li><a href="#schemadoc.table.sl-subscribe">sl_subscribe</a></li><li><a href="#schemadoc.table.sl-table">sl_table</a></li><li><a href="#schemadoc.table.sl-trigger">sl_trigger</a></li>
-  	<li><a href="#schemadoc.function.altertableforreplication-integer">altertableforreplication( integer )</a></li><li><a href="#schemadoc.function.altertablerestore-integer">altertablerestore( integer )</a></li><li><a href="#schemadoc.function.cleanupevent">cleanupevent(  )</a></li><li><a href="#schemadoc.function.ddlscript-integer-text-integer">ddlscript( integer, text, integer )</a></li><li><a href="#schemadoc.function.ddlscript-int-integer-text-integer">ddlscript_int( integer, text, integer )</a></li><li><a href="#schemadoc.function.determineattkindserial-text">determineattkindserial( text )</a></li><li><a href="#schemadoc.function.determineattkindunique-text-name">determineattkindunique( text, name )</a></li><li><a href="#schemadoc.function.determineidxnameserial-text">determineidxnameserial( text )</a></li><li><a href="#schemadoc.function.determineidxnameunique-text-name">determineidxnameunique( text, name )</a></li><li><a href="#schemadoc.function.disablenode-integer">disablenode( integer )</a></li><li><a href="#schemadoc.function.disablenode-int-integer">disablenode_int( integer )</a></li><li><a href="#schemadoc.function.droplisten-integer-integer-integer">droplisten( integer, integer, integer )</a></li><li><a href="#schemadoc.function.droplisten-int-integer-integer-integer">droplisten_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.dropnode-integer">dropnode( integer )</a></li><li><a href="#schemadoc.function.dropnode-int-integer">dropnode_int( integer )</a></li><li><a href="#schemadoc.function.droppath-integer-integer">droppath( integer, integer )</a></li><li><a href="#schemadoc.function.droppath-int-integer-integer">droppath_int( integer, integer )</a></li><li><a href="#schemadoc.function.dropset-integer">dropset( integer )</a></li><li><a href="#schemadoc.function.dropset-int-integer">dropset_int( integer )</a></li><li><a href="#schemadoc.function.droptrigger-integer-name">droptrigger( integer, name )</a></li><li><a href="#schemadoc.function.droptrigger-int-integer-name">droptrigger_int( integer, name )</a></li><li><a href="#schemadoc.function.enablenode-integer">enablenode( integer )</a></li><li><a href="#schemadoc.function.enablenode-int-integer">enablenode_int( integer )</a></li><li><a href="#schemadoc.function.enablesubscription-integer-integer-integer">enablesubscription( integer, integer, integer )</a></li><li><a href="#schemadoc.function.enablesubscription-int-integer-integer-integer">enablesubscription_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.failednode-integer-integer">failednode( integer, integer )</a></li><li><a href="#schemadoc.function.failednode2-integer-integer-integer-bigint-bigint">failednode2( integer, integer, integer, bigint, bigint )</a></li><li><a href="#schemadoc.function.failoverset-int-integer-integer-integer">failoverset_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.forwardconfirm-integer-integer-bigint-timestamp-without-time-zone">forwardconfirm( integer, integer, bigint, timestamp without time zone )</a></li><li><a href="#schemadoc.function.initializelocalnode-integer-text">initializelocalnode( integer, text )</a></li><li><a href="#schemadoc.function.lockset-integer">lockset( integer )</a></li><li><a href="#schemadoc.function.mergeset-integer-integer">mergeset( integer, integer )</a></li><li><a href="#schemadoc.function.mergeset-int-integer-integer">mergeset_int( integer, integer )</a></li><li><a href="#schemadoc.function.moveset-integer-integer">moveset( integer, integer )</a></li><li><a href="#schemadoc.function.moveset-int-integer-integer-integer">moveset_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.sequencelastvalue-text">sequencelastvalue( text )</a></li><li><a href="#schemadoc.function.sequencesetvalue-integer-integer-bigint-bigint">sequencesetvalue( integer, integer, bigint, bigint )</a></li><li><a href="#schemadoc.function.setaddsequence-integer-integer-text-text">setaddsequence( integer, integer, text, text )</a></li><li><a href="#schemadoc.function.setaddsequence-int-integer-integer-text-text">setaddsequence_int( integer, integer, text, text )</a></li><li><a href="#schemadoc.function.setaddtable-integer-integer-text-name-text">setaddtable( integer, integer, text, name, text )</a></li><li><a href="#schemadoc.function.setaddtable-int-integer-integer-text-name-text">setaddtable_int( integer, integer, text, name, text )</a></li><li><a href="#schemadoc.function.slonyversion">slonyversion(  )</a></li><li><a href="#schemadoc.function.slonyversionmajor">slonyversionmajor(  )</a></li><li><a href="#schemadoc.function.slonyversionminor">slonyversionminor(  )</a></li><li><a href="#schemadoc.function.slonyversionpatchlevel">slonyversionpatchlevel(  )</a></li><li><a href="#schemadoc.function.storelisten-integer-integer-integer">storelisten( integer, integer, integer )</a></li><li><a href="#schemadoc.function.storelisten-int-integer-integer-integer">storelisten_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.storenode-integer-text">storenode( integer, text )</a></li><li><a href="#schemadoc.function.storenode-int-integer-text">storenode_int( integer, text )</a></li><li><a href="#schemadoc.function.storepath-integer-integer-text-integer">storepath( integer, integer, text, integer )</a></li><li><a href="#schemadoc.function.storepath-int-integer-integer-text-integer">storepath_int( integer, integer, text, integer )</a></li><li><a href="#schemadoc.function.storeset-integer-text">storeset( integer, text )</a></li><li><a href="#schemadoc.function.storeset-int-integer-integer-text">storeset_int( integer, integer, text )</a></li><li><a href="#schemadoc.function.storetrigger-integer-name">storetrigger( integer, name )</a></li><li><a href="#schemadoc.function.storetrigger-int-integer-name">storetrigger_int( integer, name )</a></li><li><a href="#schemadoc.function.subscribeset-integer-integer-integer-boolean">subscribeset( integer, integer, integer, boolean )</a></li><li><a href="#schemadoc.function.subscribeset-int-integer-integer-integer-boolean">subscribeset_int( integer, integer, integer, boolean )</a></li><li><a href="#schemadoc.function.tableaddkey-text">tableaddkey( text )</a></li><li><a href="#schemadoc.function.tabledropkey-integer">tabledropkey( integer )</a></li><li><a href="#schemadoc.function.tablehasserialkey-text">tablehasserialkey( text )</a></li><li><a href="#schemadoc.function.uninstallnode">uninstallnode(  )</a></li><li><a href="#schemadoc.function.unlockset-integer">unlockset( integer )</a></li><li><a href="#schemadoc.function.unsubscribeset-integer-integer">unsubscribeset( integer, integer )</a></li><li><a href="#schemadoc.function.unsubscribeset-int-integer-integer">unsubscribeset_int( integer, integer )</a></li>
+  	<li><a href="#schemadoc.function.altertableforreplication-integer">altertableforreplication( integer )</a></li><li><a href="#schemadoc.function.altertablerestore-integer">altertablerestore( integer )</a></li><li><a href="#schemadoc.function.cleanupevent">cleanupevent(  )</a></li><li><a href="#schemadoc.function.ddlscript-integer-text-integer">ddlscript( integer, text, integer )</a></li><li><a href="#schemadoc.function.ddlscript-int-integer-text-integer">ddlscript_int( integer, text, integer )</a></li><li><a href="#schemadoc.function.determineattkindserial-text">determineattkindserial( text )</a></li><li><a href="#schemadoc.function.determineattkindunique-text-name">determineattkindunique( text, name )</a></li><li><a href="#schemadoc.function.determineidxnameserial-text">determineidxnameserial( text )</a></li><li><a href="#schemadoc.function.determineidxnameunique-text-name">determineidxnameunique( text, name )</a></li><li><a href="#schemadoc.function.disablenode-integer">disablenode( integer )</a></li><li><a href="#schemadoc.function.disablenode-int-integer">disablenode_int( integer )</a></li><li><a href="#schemadoc.function.droplisten-integer-integer-integer">droplisten( integer, integer, integer )</a></li><li><a href="#schemadoc.function.droplisten-int-integer-integer-integer">droplisten_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.dropnode-integer">dropnode( integer )</a></li><li><a href="#schemadoc.function.dropnode-int-integer">dropnode_int( integer )</a></li><li><a href="#schemadoc.function.droppath-integer-integer">droppath( integer, integer )</a></li><li><a href="#schemadoc.function.droppath-int-integer-integer">droppath_int( integer, integer )</a></li><li><a href="#schemadoc.function.dropset-integer">dropset( integer )</a></li><li><a href="#schemadoc.function.dropset-int-integer">dropset_int( integer )</a></li><li><a href="#schemadoc.function.droptrigger-integer-name">droptrigger( integer, name )</a></li><li><a href="#schemadoc.function.droptrigger-int-integer-name">droptrigger_int( integer, name )</a></li><li><a href="#schemadoc.function.enablenode-integer">enablenode( integer )</a></li><li><a href="#schemadoc.function.enablenode-int-integer">enablenode_int( integer )</a></li><li><a href="#schemadoc.function.enablesubscription-integer-integer-integer">enablesubscription( integer, integer, integer )</a></li><li><a href="#schemadoc.function.enablesubscription-int-integer-integer-integer">enablesubscription_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.failednode-integer-integer">failednode( integer, integer )</a></li><li><a href="#schemadoc.function.failednode2-integer-integer-integer-bigint-bigint">failednode2( integer, integer, integer, bigint, bigint )</a></li><li><a href="#schemadoc.function.failoverset-int-integer-integer-integer">failoverset_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.forwardconfirm-integer-integer-bigint-timestamp-without-time-zone">forwardconfirm( integer, integer, bigint, timestamp without time zone )</a></li><li><a href="#schemadoc.function.initializelocalnode-integer-text">initializelocalnode( integer, text )</a></li><li><a href="#schemadoc.function.lockset-integer">lockset( integer )</a></li><li><a href="#schemadoc.function.mergeset-integer-integer">mergeset( integer, integer )</a></li><li><a href="#schemadoc.function.mergeset-int-integer-integer">mergeset_int( integer, integer )</a></li><li><a href="#schemadoc.function.moveset-integer-integer">moveset( integer, integer )</a></li><li><a href="#schemadoc.function.moveset-int-integer-integer-integer">moveset_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.sequencelastvalue-text">sequencelastvalue( text )</a></li><li><a href="#schemadoc.function.sequencesetvalue-integer-integer-bigint-bigint">sequencesetvalue( integer, integer, bigint, bigint )</a></li><li><a href="#schemadoc.function.setaddsequence-integer-integer-text-text">setaddsequence( integer, integer, text, text )</a></li><li><a href="#schemadoc.function.setaddsequence-int-integer-integer-text-text">setaddsequence_int( integer, integer, text, text )</a></li><li><a href="#schemadoc.function.setaddtable-integer-integer-text-name-text">setaddtable( integer, integer, text, name, text )</a></li><li><a href="#schemadoc.function.setaddtable-int-integer-integer-text-name-text">setaddtable_int( integer, integer, text, name, text )</a></li><li><a href="#schemadoc.function.setdropsequence-integer">setdropsequence( integer )</a></li><li><a href="#schemadoc.function.setdropsequence-int-integer">setdropsequence_int( integer )</a></li><li><a href="#schemadoc.function.setdroptable-integer">setdroptable( integer )</a></li><li><a href="#schemadoc.function.setdroptable-int-integer">setdroptable_int( integer )</a></li><li><a href="#schemadoc.function.slonyversion">slonyversion(  )</a></li><li><a href="#schemadoc.function.slonyversionmajor">slonyversionmajor(  )</a></li><li><a href="#schemadoc.function.slonyversionminor">slonyversionminor(  )</a></li><li><a href="#schemadoc.function.slonyversionpatchlevel">slonyversionpatchlevel(  )</a></li><li><a href="#schemadoc.function.storelisten-integer-integer-integer">storelisten( integer, integer, integer )</a></li><li><a href="#schemadoc.function.storelisten-int-integer-integer-integer">storelisten_int( integer, integer, integer )</a></li><li><a href="#schemadoc.function.storenode-integer-text">storenode( integer, text )</a></li><li><a href="#schemadoc.function.storenode-int-integer-text">storenode_int( integer, text )</a></li><li><a href="#schemadoc.function.storepath-integer-integer-text-integer">storepath( integer, integer, text, integer )</a></li><li><a href="#schemadoc.function.storepath-int-integer-integer-text-integer">storepath_int( integer, integer, text, integer )</a></li><li><a href="#schemadoc.function.storeset-integer-text">storeset( integer, text )</a></li><li><a href="#schemadoc.function.storeset-int-integer-integer-text">storeset_int( integer, integer, text )</a></li><li><a href="#schemadoc.function.storetrigger-integer-name">storetrigger( integer, name )</a></li><li><a href="#schemadoc.function.storetrigger-int-integer-name">storetrigger_int( integer, name )</a></li><li><a href="#schemadoc.function.subscribeset-integer-integer-integer-boolean">subscribeset( integer, integer, integer, boolean )</a></li><li><a href="#schemadoc.function.subscribeset-int-integer-integer-integer-boolean">subscribeset_int( integer, integer, integer, boolean )</a></li><li><a href="#schemadoc.function.tableaddkey-text">tableaddkey( text )</a></li><li><a href="#schemadoc.function.tabledropkey-integer">tabledropkey( integer )</a></li><li><a href="#schemadoc.function.tablehasserialkey-text">tablehasserialkey( text )</a></li><li><a href="#schemadoc.function.uninstallnode">uninstallnode(  )</a></li><li><a href="#schemadoc.function.unlockset-integer">unlockset( integer )</a></li><li><a href="#schemadoc.function.unsubscribeset-integer-integer">unsubscribeset( integer, integer )</a></li><li><a href="#schemadoc.function.unsubscribeset-int-integer-integer">unsubscribeset_int( integer, integer )</a></li>
     </ul>
     
 </ul>
@@ -2671,8 +2671,20 @@
 	-- ----
 	-- First remove all but the oldest confirm row per origin,receiver pair
 	-- ----
+	delete from schemadoc.sl_confirm
+				where con_origin not in (select no_id from schemadoc.sl_node);
+	delete from schemadoc.sl_confirm
+				where con_received not in (select no_id from schemadoc.sl_node);
+	-- ----
+	-- Next remove all but the oldest confirm row per origin,receiver pair.
+	-- Ignore confirmations that are younger than 10 minutes. We currently
+	-- have an not confirmed suspicion that a possibly lost transaction due
+	-- to a server crash might have been visible to another session, and
+	-- that this led to log data that is needed again got removed.
+	-- ----
 	for v_max_row in select con_origin, con_received, max(con_seqno) as con_seqno
 				from schemadoc.sl_confirm
+				where con_timestamp &lt; (CURRENT_TIMESTAMP - &#39;10 min&#39;::interval)
 				group by con_origin, con_received
 	loop
 		delete from schemadoc.sl_confirm
@@ -5026,6 +5038,259 @@
 	
 		<hr>
 		<h2>Function: 
+			<a href="#schemadoc.schema"><a name="schemadoc.function.setdropsequence-integer">setdropsequence( integer )</a>
+		</h2>
+<h3>Returns: bigint</h3>
+<h3>Language: PLPGSQL</h3>
+        <p>setDropSequence (seq_id)
+
+On the origin node for the set, drop sequence seq_id from replication
+set, and raise SET_DROP_SEQUENCE to cause this to replicate to
+subscriber nodes.</p>
+        <pre>
+declare
+	p_seq_id		alias for $1;
+	v_set_id		int4;
+	v_set_origin		int4;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table schemadoc.sl_config_lock;
+
+	-- ----
+	-- Determine set id for this sequence
+	-- ----
+	select seq_set into v_set_id from schemadoc.sl_sequence where seq_id = p_seq_id;
+
+	-- ----
+	-- Ensure sequence exists
+	-- ----
+	if not found then
+		raise exception &#39;Slony-I: setDropSequence_int(): sequence % not found&#39;,
+			p_seq_id;
+	end if;
+
+	-- ----
+	-- Check that we are the origin of the set
+	-- ----
+	select set_origin into v_set_origin
+			from schemadoc.sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception &#39;Slony-I: setDropSequence(): set % not found&#39;, v_set_id;
+	end if;
+	if v_set_origin != schemadoc.getLocalNodeId(&#39;_schemadoc&#39;) then
+		raise exception &#39;Slony-I: setDropSequence(): set % has remote origin&#39;, v_set_id;
+	end if;
+
+	-- ----
+	-- Add the sequence to the set and generate the SET_ADD_SEQUENCE event
+	-- ----
+	perform schemadoc.setDropSequence_int(p_seq_id);
+	return  schemadoc.createEvent(&#39;_schemadoc&#39;, &#39;SET_DROP_SEQUENCE&#39;,
+			p_seq_id);
+end;
+</pre>
+	
+		<hr>
+		<h2>Function: 
+			<a href="#schemadoc.schema"><a name="schemadoc.function.setdropsequence-int-integer">setdropsequence_int( integer )</a>
+		</h2>
+<h3>Returns: integer</h3>
+<h3>Language: PLPGSQL</h3>
+        <p>setDropSequence_int (seq_id)
+
+This processes the SET_DROP_SEQUENCE event.  On remote nodes that
+subscribe to the set containing sequence seq_id, drop the sequence
+from the replication set.</p>
+        <pre>
+declare
+	p_seq_id		alias for $1;
+	v_set_id		int4;
+	v_local_node_id		int4;
+	v_set_origin		int4;
+	v_sub_provider		int4;
+	v_relkind			char;
+	v_sync_row			record;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table schemadoc.sl_config_lock;
+
+	-- ----
+	-- Determine set id for this sequence
+	-- ----
+	select seq_set into v_set_id from schemadoc.sl_sequence where seq_id = p_seq_id;
+
+	-- ----
+	-- Ensure sequence exists
+	-- ----
+	if not found then
+		return 0;
+	end if;
+
+	-- ----
+	-- For sets with a remote origin, check that we are subscribed 
+	-- to that set. Otherwise we ignore the sequence because it might 
+	-- not even exist in our database.
+	-- ----
+	v_local_node_id := schemadoc.getLocalNodeId(&#39;_schemadoc&#39;);
+	select set_origin into v_set_origin
+			from schemadoc.sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception &#39;Slony-I: setDropSequence_int(): set % not found&#39;,
+				v_set_id;
+	end if;
+	if v_set_origin != v_local_node_id then
+		select sub_provider into v_sub_provider
+				from schemadoc.sl_subscribe
+				where sub_set = v_set_id
+				and sub_receiver = schemadoc.getLocalNodeId(&#39;_schemadoc&#39;);
+		if not found then
+			return 0;
+		end if;
+	end if;
+
+	-- ----
+	-- drop the sequence from sl_sequence, sl_seqlog
+	-- ----
+	delete from schemadoc.sl_seqlog where seql_seqid = p_seq_id;
+	delete from schemadoc.sl_sequence where seq_id = p_seq_id;
+
+	return p_seq_id;
+end;
+</pre>
+	
+		<hr>
+		<h2>Function: 
+			<a href="#schemadoc.schema"><a name="schemadoc.function.setdroptable-integer">setdroptable( integer )</a>
+		</h2>
+<h3>Returns: bigint</h3>
+<h3>Language: PLPGSQL</h3>
+        <p>setDropTable (tab_id)
+
+Drop table tab_id from set on origin node, and generate SET_DROP_TABLE
+event to allow this to propagate to other nodes.</p>
+        <pre>
+declare
+	p_tab_id		alias for $1;
+	v_set_id		int4;
+	v_set_origin		int4;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table schemadoc.sl_config_lock;
+
+        -- ----
+	-- Determine the set_id
+        -- ----
+	select tab_set into v_set_id from schemadoc.sl_table where tab_id = p_tab_id;
+
+	-- ----
+	-- Ensure table exists
+	-- ----
+	if not found then
+		raise exception &#39;Slony-I: setDropTable_int(): table % not found&#39;,
+			p_tab_id;
+	end if;
+
+	-- ----
+	-- Check that we are the origin of the set
+	-- ----
+	select set_origin into v_set_origin
+			from schemadoc.sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception &#39;Slony-I: setDropTable(): set % not found&#39;, v_set_id;
+	end if;
+	if v_set_origin != schemadoc.getLocalNodeId(&#39;_schemadoc&#39;) then
+		raise exception &#39;Slony-I: setDropTable(): set % has remote origin&#39;, v_set_id;
+	end if;
+
+	-- ----
+	-- Drop the table from the set and generate the SET_ADD_TABLE event
+	-- ----
+	perform schemadoc.setDropTable_int(p_tab_id);
+	return  schemadoc.createEvent(&#39;_schemadoc&#39;, &#39;SET_DROP_TABLE&#39;, p_tab_id);
+end;
+</pre>
+	
+		<hr>
+		<h2>Function: 
+			<a href="#schemadoc.schema"><a name="schemadoc.function.setdroptable-int-integer">setdroptable_int( integer )</a>
+		</h2>
+<h3>Returns: integer</h3>
+<h3>Language: PLPGSQL</h3>
+        <p>setDropTable_int (tab_id)
+
+This function processes the SET_DROP_TABLE event on remote nodes,
+dropping a table from replication if the remote node is subscribing to
+its replication set.</p>
+        <pre>
+declare
+	p_tab_id		alias for $1;
+	v_set_id		int4;
+	v_local_node_id		int4;
+	v_set_origin		int4;
+	v_sub_provider		int4;
+	v_tab_reloid		oid;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table schemadoc.sl_config_lock;
+
+        -- ----
+	-- Determine the set_id
+        -- ----
+	select tab_set into v_set_id from schemadoc.sl_table where tab_id = p_tab_id;
+
+	-- ----
+	-- Ensure table exists
+	-- ----
+	if not found then
+		return 0;
+	end if;
+
+	-- ----
+	-- For sets with a remote origin, check that we are subscribed 
+	-- to that set. Otherwise we ignore the table because it might 
+	-- not even exist in our database.
+	-- ----
+	v_local_node_id := schemadoc.getLocalNodeId(&#39;_schemadoc&#39;);
+	select set_origin into v_set_origin
+			from schemadoc.sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception &#39;Slony-I: setDropTable_int(): set % not found&#39;,
+				v_set_id;
+	end if;
+	if v_set_origin != v_local_node_id then
+		select sub_provider into v_sub_provider
+				from schemadoc.sl_subscribe
+				where sub_set = v_set_id
+				and sub_receiver = schemadoc.getLocalNodeId(&#39;_schemadoc&#39;);
+		if not found then
+			return 0;
+		end if;
+	end if;
+	
+	-- ----
+	-- Drop the table from sl_table and drop trigger from it.
+	-- ----
+	perform schemadoc.alterTableRestore(p_tab_id);
+	perform schemadoc.tableDropKey(p_tab_id);
+	delete from schemadoc.sl_table where tab_id = p_tab_id;
+	return p_tab_id;
+end;
+</pre>
+	
+		<hr>
+		<h2>Function: 
 			<a href="#schemadoc.schema"><a name="schemadoc.function.slonyversion">slonyversion(  )</a>
 		</h2>
 <h3>Returns: text</h3>
@@ -5946,12 +6211,14 @@
 			where ssy_setid = p_sub_set;
 
 	-- ----
-	-- Remove all sl_table entries for this set.
+	-- Remove all sl_table and sl_sequence entries for this set.
 	-- Should we ever subscribe again, the initial data
 	-- copy process will create new ones.
 	-- ----
 	delete from schemadoc.sl_table
 			where tab_set = p_sub_set;
+	delete from schemadoc.sl_sequence
+			where seq_set = p_sub_set;
 
 	-- ----
 	-- Call the internal procedure to drop the subscription
Index: slonik_commands.html
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/doc/howto/slonik_commands.html,v
retrieving revision 1.7
retrieving revision 1.8
diff -Ldoc/howto/slonik_commands.html -Ldoc/howto/slonik_commands.html -u -w -r1.7 -r1.8
--- doc/howto/slonik_commands.html
+++ doc/howto/slonik_commands.html
@@ -37,6 +37,8 @@
 		<li><a href="#stmt_merge_set">MERGE SET</a>
 		<li><a href="#stmt_set_add_table">SET ADD TABLE</a>
 		<li><a href="#stmt_set_add_sequence">SET ADD SEQUENCE</a>
+		<li><a href="#stmt_set_drop_table">SET DROP TABLE</a>
+		<li><a href="#stmt_set_drop_sequence">SET DROP SEQUENCE</a>
 		<li><a href="#stmt_store_trigger">STORE TRIGGER</a>
 		<li><a href="#stmt_drop_trigger">DROP TRIGGER</a>
 		<li><a href="#stmt_subscribe_set">SUBSCRIBE SET</a>
@@ -1024,6 +1026,77 @@
 <p align="right">Back to <a href="#index">Index</a></p>
 
 <!-- **************************************** -->
+<a name="stmt_set_drop_table">
+<h3>SET DROP TABLE</h3>
+</a>
+<div style="margin-left:40px; margin-right:0px;">
+<h3>Synopsis:</h3>
+	SET DROP TABLE ( &lt;options&gt; );
+<h3>Description:</h3>
+<p>
+	Drop an existing user table to a replication set.
+</p>
+<table border="0" cellpadding="10">
+<tr>
+	<td align="left" valign="top" nowrap><b>ORIGIN = &lt;ival&gt;</b></td>
+	<td align="left" valign="top"><p>
+		The current origin of the set. A future version of slonik
+		might figure out this information by itself.
+	</p></td>
+</tr>
+<tr>
+	<td align="left" valign="top" nowrap><b>ID = &lt;ival&gt;</b></td>
+	<td align="left" valign="top"><p>
+		Unique ID of the table. 
+	</p></td>
+</tr>
+</table>
+<h3>Example:</h3>
+<p>
+	SET DROP TABLE (
+	<br>&nbsp;&nbsp;&nbsp;&nbsp;ORIGIN = 1,
+	<br>&nbsp;&nbsp;&nbsp;&nbsp;ID = 20,
+	<br>);
+</p>
+</div>
+<p align="right">Back to <a href="#index">Index</a></p>
+
+<!-- **************************************** -->
+<a name="stmt_set_drop_sequence">
+<h3>SET DROP SEQUENCE</h3>
+</a>
+<div style="margin-left:40px; margin-right:0px;">
+<h3>Synopsis:</h3>
+	SET DROP SEQUENCE ( &lt;options&gt; );
+<h3>Description:</h3>
+<p>
+	Drops an existing user sequence from a replication set.
+</p>
+<table border="0" cellpadding="10">
+<tr>
+	<td align="left" valign="top" nowrap><b>ORIGIN = &lt;ival&gt;</b></td>
+	<td align="left" valign="top"><p>
+		The current origin of the set.
+	</p></td>
+</tr>
+<tr>
+	<td align="left" valign="top" nowrap><b>ID = &lt;ival&gt;</b></td>
+	<td align="left" valign="top"><p>
+		Unique ID of the sequence.
+	</p></td>
+</tr>
+</table>
+<h3>Example:</h3>
+<p>
+	SET DROP SEQUENCE (
+	<br>&nbsp;&nbsp;&nbsp;&nbsp;ORIGIN = 1,
+	<br>&nbsp;&nbsp;&nbsp;&nbsp;ID = 21,
+	<br>);
+</p>
+</div>
+<p align="right">Back to <a href="#index">Index</a></p>
+
+<!-- **************************************** -->
 <a name="stmt_store_trigger">
 <h3>STORE TRIGGER</h3>
 </a>
Index: slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.29
retrieving revision 1.30
diff -Lsrc/backend/slony1_funcs.sql -Lsrc/backend/slony1_funcs.sql -u -w -r1.29 -r1.30
--- src/backend/slony1_funcs.sql
+++ src/backend/slony1_funcs.sql
@@ -2311,6 +2311,131 @@
 replication set.';
 
 -- ----------------------------------------------------------------------
+-- FUNCTION setDropTable (tab_id)
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .setDropTable(int4)
+returns bigint
+as '
+declare
+	p_tab_id		alias for $1;
+	v_set_id		int4;
+	v_set_origin		int4;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table @NAMESPACE at .sl_config_lock;
+
+        -- ----
+	-- Determine the set_id
+        -- ----
+	select tab_set into v_set_id from @NAMESPACE at .sl_table where tab_id = p_tab_id;
+
+	-- ----
+	-- Ensure table exists
+	-- ----
+	if not found then
+		raise exception ''Slony-I: setDropTable_int(): table % not found'',
+			p_tab_id;
+	end if;
+
+	-- ----
+	-- Check that we are the origin of the set
+	-- ----
+	select set_origin into v_set_origin
+			from @NAMESPACE at .sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception ''Slony-I: setDropTable(): set % not found'', v_set_id;
+	end if;
+	if v_set_origin != @NAMESPACE at .getLocalNodeId(''_ at CLUSTERNAME@'') then
+		raise exception ''Slony-I: setDropTable(): set % has remote origin'', v_set_id;
+	end if;
+
+	-- ----
+	-- Drop the table from the set and generate the SET_ADD_TABLE event
+	-- ----
+	perform @NAMESPACE at .setDropTable_int(p_tab_id);
+	return  @NAMESPACE at .createEvent(''_ at CLUSTERNAME@'', ''SET_DROP_TABLE'', p_tab_id);
+end;
+' language plpgsql;
+comment on function @NAMESPACE at .setDropTable(int4) is
+'setDropTable (tab_id)
+
+Drop table tab_id from set on origin node, and generate SET_DROP_TABLE
+event to allow this to propagate to other nodes.';
+
+-- ----------------------------------------------------------------------
+-- FUNCTION setDropTable_int (tab_id)
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .setDropTable_int(int4)
+returns int4
+as '
+declare
+	p_tab_id		alias for $1;
+	v_set_id		int4;
+	v_local_node_id		int4;
+	v_set_origin		int4;
+	v_sub_provider		int4;
+	v_tab_reloid		oid;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table @NAMESPACE at .sl_config_lock;
+
+        -- ----
+	-- Determine the set_id
+        -- ----
+	select tab_set into v_set_id from @NAMESPACE at .sl_table where tab_id = p_tab_id;
+
+	-- ----
+	-- Ensure table exists
+	-- ----
+	if not found then
+		return 0;
+	end if;
+
+	-- ----
+	-- For sets with a remote origin, check that we are subscribed 
+	-- to that set. Otherwise we ignore the table because it might 
+	-- not even exist in our database.
+	-- ----
+	v_local_node_id := @NAMESPACE at .getLocalNodeId(''_ at CLUSTERNAME@'');
+	select set_origin into v_set_origin
+			from @NAMESPACE at .sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception ''Slony-I: setDropTable_int(): set % not found'',
+				v_set_id;
+	end if;
+	if v_set_origin != v_local_node_id then
+		select sub_provider into v_sub_provider
+				from @NAMESPACE at .sl_subscribe
+				where sub_set = v_set_id
+				and sub_receiver = @NAMESPACE at .getLocalNodeId(''_ at CLUSTERNAME@'');
+		if not found then
+			return 0;
+		end if;
+	end if;
+	
+	-- ----
+	-- Drop the table from sl_table and drop trigger from it.
+	-- ----
+	perform @NAMESPACE at .alterTableRestore(p_tab_id);
+	perform @NAMESPACE at .tableDropKey(p_tab_id);
+	delete from @NAMESPACE at .sl_table where tab_id = p_tab_id;
+	return p_tab_id;
+end;
+' language plpgsql;
+comment on function @NAMESPACE at .setDropTable_int(int4) is
+'setDropTable_int (tab_id)
+
+This function processes the SET_DROP_TABLE event on remote nodes,
+dropping a table from replication if the remote node is subscribing to
+its replication set.';
+
+-- ----------------------------------------------------------------------
 -- FUNCTION setAddSequence (set_id, seq_id, seq_fqname, seq_comment)
 -- ----------------------------------------------------------------------
 create or replace function @NAMESPACE at .setAddSequence (int4, int4, text, text)
@@ -2461,6 +2586,134 @@
 subscribe to set_id, add the sequence to the replication set.';
 
 -- ----------------------------------------------------------------------
+-- FUNCTION setDropSequence (seq_id)
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .setDropSequence (int4)
+returns bigint
+as '
+declare
+	p_seq_id		alias for $1;
+	v_set_id		int4;
+	v_set_origin		int4;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table @NAMESPACE at .sl_config_lock;
+
+	-- ----
+	-- Determine set id for this sequence
+	-- ----
+	select seq_set into v_set_id from @NAMESPACE at .sl_sequence where seq_id = p_seq_id;
+
+	-- ----
+	-- Ensure sequence exists
+	-- ----
+	if not found then
+		raise exception ''Slony-I: setDropSequence_int(): sequence % not found'',
+			p_seq_id;
+	end if;
+
+	-- ----
+	-- Check that we are the origin of the set
+	-- ----
+	select set_origin into v_set_origin
+			from @NAMESPACE at .sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception ''Slony-I: setDropSequence(): set % not found'', v_set_id;
+	end if;
+	if v_set_origin != @NAMESPACE at .getLocalNodeId(''_ at CLUSTERNAME@'') then
+		raise exception ''Slony-I: setDropSequence(): set % has remote origin'', v_set_id;
+	end if;
+
+	-- ----
+	-- Add the sequence to the set and generate the SET_ADD_SEQUENCE event
+	-- ----
+	perform @NAMESPACE at .setDropSequence_int(p_seq_id);
+	return  @NAMESPACE at .createEvent(''_ at CLUSTERNAME@'', ''SET_DROP_SEQUENCE'',
+			p_seq_id);
+end;
+' language plpgsql;
+comment on function @NAMESPACE at .setDropSequence (int4) is
+'setDropSequence (seq_id)
+
+On the origin node for the set, drop sequence seq_id from replication
+set, and raise SET_DROP_SEQUENCE to cause this to replicate to
+subscriber nodes.';
+
+-- ----------------------------------------------------------------------
+-- FUNCTION setDropSequence_int (seq_id)
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .setDropSequence_int(int4)
+returns int4
+as '
+declare
+	p_seq_id		alias for $1;
+	v_set_id		int4;
+	v_local_node_id		int4;
+	v_set_origin		int4;
+	v_sub_provider		int4;
+	v_relkind			char;
+	v_sync_row			record;
+begin
+	-- ----
+	-- Grab the central configuration lock
+	-- ----
+	lock table @NAMESPACE at .sl_config_lock;
+
+	-- ----
+	-- Determine set id for this sequence
+	-- ----
+	select seq_set into v_set_id from @NAMESPACE at .sl_sequence where seq_id = p_seq_id;
+
+	-- ----
+	-- Ensure sequence exists
+	-- ----
+	if not found then
+		return 0;
+	end if;
+
+	-- ----
+	-- For sets with a remote origin, check that we are subscribed 
+	-- to that set. Otherwise we ignore the sequence because it might 
+	-- not even exist in our database.
+	-- ----
+	v_local_node_id := @NAMESPACE at .getLocalNodeId(''_ at CLUSTERNAME@'');
+	select set_origin into v_set_origin
+			from @NAMESPACE at .sl_set
+			where set_id = v_set_id;
+	if not found then
+		raise exception ''Slony-I: setDropSequence_int(): set % not found'',
+				v_set_id;
+	end if;
+	if v_set_origin != v_local_node_id then
+		select sub_provider into v_sub_provider
+				from @NAMESPACE at .sl_subscribe
+				where sub_set = v_set_id
+				and sub_receiver = @NAMESPACE at .getLocalNodeId(''_ at CLUSTERNAME@'');
+		if not found then
+			return 0;
+		end if;
+	end if;
+
+	-- ----
+	-- drop the sequence from sl_sequence, sl_seqlog
+	-- ----
+	delete from @NAMESPACE at .sl_seqlog where seql_seqid = p_seq_id;
+	delete from @NAMESPACE at .sl_sequence where seq_id = p_seq_id;
+
+	return p_seq_id;
+end;
+' language plpgsql;
+comment on function @NAMESPACE at .setDropSequence_int(int4) is
+'setDropSequence_int (seq_id)
+
+This processes the SET_DROP_SEQUENCE event.  On remote nodes that
+subscribe to the set containing sequence seq_id, drop the sequence
+from the replication set.';
+
+-- ----------------------------------------------------------------------
 -- FUNCTION sequenceSetValue (seq_id, seq_origin, ev_seqno, last_value)
 -- ----------------------------------------------------------------------
 create or replace function @NAMESPACE at .sequenceSetValue(int4, int4, int8, int8) returns int4
Index: slonik.h
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -Lsrc/slonik/slonik.h -Lsrc/slonik/slonik.h -u -w -r1.18 -r1.19
--- src/slonik/slonik.h
+++ src/slonik/slonik.h
@@ -32,6 +32,8 @@
 typedef struct SlonikStmt_merge_set_s			SlonikStmt_merge_set;
 typedef struct SlonikStmt_set_add_table_s		SlonikStmt_set_add_table;
 typedef struct SlonikStmt_set_add_sequence_s	SlonikStmt_set_add_sequence;
+typedef struct SlonikStmt_set_drop_table_s		SlonikStmt_set_drop_table;
+typedef struct SlonikStmt_set_drop_sequence_s	SlonikStmt_set_drop_sequence;
 typedef struct SlonikStmt_table_add_key_s		SlonikStmt_table_add_key;
 typedef struct SlonikStmt_store_trigger_s		SlonikStmt_store_trigger;
 typedef struct SlonikStmt_drop_trigger_s		SlonikStmt_drop_trigger;
@@ -63,6 +65,8 @@
 	STMT_RESTART_NODE,
 	STMT_SET_ADD_SEQUENCE,
 	STMT_SET_ADD_TABLE,
+	STMT_SET_DROP_SEQUENCE,
+	STMT_SET_DROP_TABLE,
 	STMT_STORE_LISTEN,
 	STMT_STORE_NODE,
 	STMT_STORE_PATH,
@@ -250,6 +254,19 @@
 	char			   *seq_comment;
 };
 
+struct SlonikStmt_set_drop_table_s {
+	SlonikStmt			hdr;
+	int					set_origin;
+	int					tab_id;
+};
+
+
+struct SlonikStmt_set_drop_sequence_s {
+	SlonikStmt			hdr;
+	int					set_origin;
+	int					seq_id;
+};
+
 
 struct SlonikStmt_table_add_key_s {
 	SlonikStmt			hdr;
@@ -443,6 +460,8 @@
 extern int		slonik_merge_set(SlonikStmt_merge_set *stmt);
 extern int		slonik_set_add_table(SlonikStmt_set_add_table *stmt);
 extern int		slonik_set_add_sequence(SlonikStmt_set_add_sequence *stmt);
+extern int		slonik_set_drop_table(SlonikStmt_set_drop_table *stmt);
+extern int		slonik_set_drop_sequence(SlonikStmt_set_drop_sequence *stmt);
 extern int		slonik_table_add_key(SlonikStmt_table_add_key *stmt);
 extern int		slonik_store_trigger(SlonikStmt_store_trigger *stmt);
 extern int		slonik_drop_trigger(SlonikStmt_drop_trigger *stmt);
@@ -506,3 +525,11 @@
 extern int		yyparse(void);
 extern int		yylex(void);
 
+
+/*
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
Index: parser.y
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/parser.y,v
retrieving revision 1.18
retrieving revision 1.19
diff -Lsrc/slonik/parser.y -Lsrc/slonik/parser.y -u -w -r1.18 -r1.19
--- src/slonik/parser.y
+++ src/slonik/parser.y
@@ -141,6 +141,8 @@
 %type <statement>	stmt_merge_set
 %type <statement>	stmt_set_add_table
 %type <statement>	stmt_set_add_sequence
+%type <statement>	stmt_set_drop_table
+%type <statement>	stmt_set_drop_sequence
 %type <statement>	stmt_table_add_key
 %type <statement>	stmt_store_trigger
 %type <statement>	stmt_drop_trigger
@@ -435,6 +437,10 @@
 						{ $$ = $1; }
 					| stmt_set_add_sequence
 						{ $$ = $1; }
+					| stmt_set_drop_table
+						{ $$ = $1; }
+					| stmt_set_drop_sequence
+						{ $$ = $1; }
 					| stmt_store_trigger
 						{ $$ = $1; }
 					| stmt_drop_trigger
@@ -982,6 +988,60 @@
 					}
 					;
 
+stmt_set_drop_table	: lno K_SET K_DROP K_TABLE option_list
+					{
+						SlonikStmt_set_drop_table *new;
+						statement_option opt[] = {
+							STMT_OPTION_INT( O_ORIGIN, -1 ),
+							STMT_OPTION_INT( O_ID, -1 ),
+							STMT_OPTION_END
+						};
+						new = (SlonikStmt_set_drop_table *)
+							malloc(sizeof(SlonikStmt_set_drop_table));
+						memset(new, 0, sizeof(SlonikStmt_set_drop_table));
+						new->hdr.stmt_type		= STMT_SET_DROP_TABLE;
+						new->hdr.stmt_filename	= current_file;
+						new->hdr.stmt_lno		= $1;
+
+						if (assign_options(opt, $5) == 0) {
+							new->set_origin		= opt[0].ival;
+							new->tab_id			= opt[1].ival;
+						}
+						else
+							parser_errors++;
+
+						$$ = (SlonikStmt *)new;
+					}
+					;
+
+stmt_set_drop_sequence : lno K_SET K_DROP K_SEQUENCE option_list
+					{
+						SlonikStmt_set_drop_sequence *new;
+						statement_option opt[] = {
+							STMT_OPTION_INT( O_ORIGIN, -1 ),
+							STMT_OPTION_INT( O_ID, -1 ),
+							STMT_OPTION_END
+						};
+
+						new = (SlonikStmt_set_drop_sequence *)
+								malloc(sizeof(SlonikStmt_set_drop_sequence));
+						memset(new, 0, sizeof(SlonikStmt_set_drop_sequence));
+						new->hdr.stmt_type		= STMT_SET_DROP_SEQUENCE;
+						new->hdr.stmt_filename	= current_file;
+						new->hdr.stmt_lno		= $1;
+
+						if (assign_options(opt, $5) == 0)
+						{
+							new->set_origin		= opt[0].ival;
+							new->seq_id			= opt[1].ival;
+						}
+						else
+							parser_errors++;
+
+						$$ = (SlonikStmt *)new;
+					}
+					;
+
 stmt_store_trigger	: lno K_STORE K_TRIGGER option_list
 					{
 						SlonikStmt_store_trigger *new;
@@ -1670,3 +1730,11 @@
 #include "scan.c"
 
 
+
+/*
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
Index: slonik.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -Lsrc/slonik/slonik.c -Lsrc/slonik/slonik.c -u -w -r1.30 -r1.31
--- src/slonik/slonik.c
+++ src/slonik/slonik.c
@@ -561,6 +561,78 @@
 				}
 				break;
 
+			case STMT_SET_DROP_TABLE:
+				{
+					SlonikStmt_set_drop_table *stmt =
+							(SlonikStmt_set_drop_table *)hdr;
+
+					/*
+					 * Check that we have the set_id and set_origin
+					 * and that we can reach the origin.
+					 */
+					if (stmt->set_origin < 0)
+					{
+						printf("%s:%d: Error: "
+								"origin must be specified\n",
+								hdr->stmt_filename, hdr->stmt_lno);
+						errors++;
+					}
+					else
+					{
+						if (script_check_adminfo(hdr, stmt->set_origin) < 0)
+							errors++;
+					}
+
+					/*
+					 * Check that we have the table id, name
+					 * and what to use for the key.
+					 */
+					if (stmt->tab_id < 0)
+					{
+						printf("%s:%d: Error: "
+								"table id must be specified\n",
+								hdr->stmt_filename, hdr->stmt_lno);
+						errors++;
+					}
+				}
+				break;
+
+			case STMT_SET_DROP_SEQUENCE:
+				{
+					SlonikStmt_set_drop_sequence *stmt =
+							(SlonikStmt_set_drop_sequence *)hdr;
+
+					/*
+					 * Check that we have the set_id and set_origin
+					 * and that we can reach the origin.
+					 */
+					if (stmt->set_origin < 0)
+					{
+						printf("%s:%d: Error: "
+								"origin must be specified\n",
+								hdr->stmt_filename, hdr->stmt_lno);
+						errors++;
+					}
+					else
+					{
+						if (script_check_adminfo(hdr, stmt->set_origin) < 0)
+							errors++;
+					}
+
+					/*
+					 * Check that we have the table id, name
+					 * and what to use for the key.
+					 */
+					if (stmt->seq_id < 0)
+					{
+						printf("%s:%d: Error: "
+								"sequence id must be specified\n",
+								hdr->stmt_filename, hdr->stmt_lno);
+						errors++;
+					}
+				}
+				break;
+
 			case STMT_TABLE_ADD_KEY:
 				{
 					SlonikStmt_table_add_key *stmt =
@@ -1127,6 +1199,25 @@
 						errors++;
 				}
 				break;
+			case STMT_SET_DROP_TABLE:
+				{
+					SlonikStmt_set_drop_table *stmt =
+							(SlonikStmt_set_drop_table *)hdr;
+
+					if (slonik_set_drop_table(stmt) < 0)
+						errors++;
+				}
+				break;
+
+			case STMT_SET_DROP_SEQUENCE:
+				{
+					SlonikStmt_set_drop_sequence *stmt =
+							(SlonikStmt_set_drop_sequence *)hdr;
+
+					if (slonik_set_drop_sequence(stmt) < 0)
+						errors++;
+				}
+				break;
 
 			case STMT_TABLE_ADD_KEY:
 				{
@@ -2968,7 +3059,72 @@
 		return -1;
 	}
 	db_notice_silent = false;
+	dstring_free(&query);
+	return 0;
+}
+
+
+int
+slonik_set_drop_table(SlonikStmt_set_drop_table *stmt)
+{
+	SlonikAdmInfo  *adminfo1;
+	SlonDString		query;
+	char		   *idxname;
+	PGresult	   *res;
+	
+	adminfo1 = get_active_adminfo((SlonikStmt *)stmt, stmt->set_origin);
+	if (adminfo1 == NULL)
+		return -1;
+	
+	if (db_begin_xact((SlonikStmt *)stmt, adminfo1) < 0)
+		return -1;
+	
+	dstring_init(&query);
+	
+	slon_mkquery(&query,
+				 "select \"_%s\".setDropTable(%d); ",
+				 stmt->hdr.script->clustername,		     
+				 stmt->tab_id);
+	if (db_exec_evcommand((SlonikStmt *)stmt, adminfo1, &query) < 0) {
+		PQclear(res);
+		dstring_free(&query);
+		return -1;
+	}
+	dstring_free(&query);
+	return 0;
+}
+
+
+int
+slonik_set_drop_sequence(SlonikStmt_set_drop_sequence *stmt)
+{
+	SlonikAdmInfo  *adminfo1;
+	SlonDString		query;
 
+	adminfo1 = get_active_adminfo((SlonikStmt *)stmt, stmt->set_origin);
+	if (adminfo1 == NULL)
+		return -1;
+
+	if (db_begin_xact((SlonikStmt *)stmt, adminfo1) < 0)
+		return -1;
+
+	dstring_init(&query);
+
+	/*
+	 * call setDropSequence()
+	 */
+	db_notice_silent = true;
+	slon_mkquery(&query,
+		     "select \"_%s\".setDropSequence(%d); ",
+		     stmt->hdr.script->clustername,		     
+		     stmt->seq_id);
+	if (db_exec_evcommand((SlonikStmt *)stmt, adminfo1, &query) < 0)
+	{
+		db_notice_silent = false;
+		dstring_free(&query);
+		return -1;
+	}
+	db_notice_silent = false;
 	dstring_free(&query);
 	return 0;
 }
@@ -3582,3 +3738,10 @@
 	return true;
 }
 
+/*
+ * Local Variables:
+ *  tab-width: 4
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */


More information about the Slony1-commit mailing list