Attached is a patch to CVS HEAD that appears to successfully resolve bug
#1513

<http://gborg.postgresql.org/project/slony1/bugs/bugupdate.php?1513>

I'm not convinced I'm handling memory allocation for this in an entirely
"idiomatic-to-Slony-I" way; Jan can probably comment best on that.

I *know* that the build handling of "scanner.o", which is built in
src/parsestatements (which isn't in the patch; I already added it to CVS
HEAD :-)) is not quite ideal.  Darcy is probably best equipped to "throw
bricks" at that...
? conf11244.file
? config/config.sub.1
? doc/adminguide/HTML.index
? doc/adminguide/LEGALNOTICE.html
? doc/adminguide/addthings.html
? doc/adminguide/admconninfo.html
? doc/adminguide/altperl.html
? doc/adminguide/bestpractices.html
? doc/adminguide/bookindex.sgml
? doc/adminguide/cluster.html
? doc/adminguide/clustername.html
? doc/adminguide/cmds.html
? doc/adminguide/commandreference.html
? doc/adminguide/concepts.html
? doc/adminguide/ddlchanges.html
? doc/adminguide/definingsets.html
? doc/adminguide/dropthings.html
? doc/adminguide/failover.html
? doc/adminguide/faq.html
? doc/adminguide/function.add-missing-table-field-text-text-text-text.html
? doc/adminguide/function.altertableforreplication-integer.html
? doc/adminguide/function.altertablerestore-integer.html
? doc/adminguide/function.cleanupevent.html
? doc/adminguide/function.cleanuplistener.html
? doc/adminguide/function.createevent-name-text-text-text-text-text-text-text-text-text.html
? doc/adminguide/function.createevent-name-text-text-text-text-text-text-text-text.html
? doc/adminguide/function.createevent-name-text-text-text-text-text-text-text.html
? doc/adminguide/function.createevent-name-text-text-text-text-text-text.html
? doc/adminguide/function.createevent-name-text-text-text-text-text.html
? doc/adminguide/function.createevent-name-text-text-text-text.html
? doc/adminguide/function.createevent-name-text-text-text.html
? doc/adminguide/function.createevent-name-text-text.html
? doc/adminguide/function.createevent-name-text.html
? doc/adminguide/function.ddlscript-int-integer-text-integer.html
? doc/adminguide/function.ddlscript-integer-text-integer.html
? doc/adminguide/function.denyaccess.html
? doc/adminguide/function.determineattkindserial-text.html
? doc/adminguide/function.determineattkindunique-text-name.html
? doc/adminguide/function.determineidxnameserial-text.html
? doc/adminguide/function.determineidxnameunique-text-name.html
? doc/adminguide/function.disablenode-int-integer.html
? doc/adminguide/function.disablenode-integer.html
? doc/adminguide/function.droplisten-int-integer-integer-integer.html
? doc/adminguide/function.droplisten-integer-integer-integer.html
? doc/adminguide/function.dropnode-int-integer.html
? doc/adminguide/function.dropnode-integer.html
? doc/adminguide/function.droppath-int-integer-integer.html
? doc/adminguide/function.droppath-integer-integer.html
? doc/adminguide/function.dropset-int-integer.html
? doc/adminguide/function.dropset-integer.html
? doc/adminguide/function.droptrigger-int-integer-name.html
? doc/adminguide/function.droptrigger-integer-name.html
? doc/adminguide/function.enablenode-int-integer.html
? doc/adminguide/function.enablenode-integer.html
? doc/adminguide/function.enablesubscription-int-integer-integer-integer.html
? doc/adminguide/function.enablesubscription-integer-integer-integer.html
? doc/adminguide/function.failednode-integer-integer.html
? doc/adminguide/function.failednode2-integer-integer-integer-bigint-bigint.html
? doc/adminguide/function.failoverset-int-integer-integer-integer.html
? doc/adminguide/function.forwardconfirm-integer-integer-bigint-timestamp-without-time-zone.html
? doc/adminguide/function.generate-sync-event-interval.html
? doc/adminguide/function.getlocalnodeid-name.html
? doc/adminguide/function.getmoduleversion.html
? doc/adminguide/function.getsessionrole-name.html
? doc/adminguide/function.initializelocalnode-integer-text.html
? doc/adminguide/function.lockedset.html
? doc/adminguide/function.lockset-integer.html
? doc/adminguide/function.logtrigger.html
? doc/adminguide/function.mergeset-int-integer-integer.html
? doc/adminguide/function.mergeset-integer-integer.html
? doc/adminguide/function.moveset-int-integer-integer-integer.html
? doc/adminguide/function.moveset-integer-integer.html
? doc/adminguide/function.rebuildlistenentries.html
? doc/adminguide/function.rebuildlistenentriesone-integer-integer.html
? doc/adminguide/function.sequencelastvalue-text.html
? doc/adminguide/function.sequencesetvalue-integer-integer-bigint-bigint.html
? doc/adminguide/function.setaddsequence-int-integer-integer-text-text.html
? doc/adminguide/function.setaddsequence-integer-integer-text-text.html
? doc/adminguide/function.setaddtable-int-integer-integer-text-name-text.html
? doc/adminguide/function.setaddtable-integer-integer-text-name-text.html
? doc/adminguide/function.setdropsequence-int-integer.html
? doc/adminguide/function.setdropsequence-integer.html
? doc/adminguide/function.setdroptable-int-integer.html
? doc/adminguide/function.setdroptable-integer.html
? doc/adminguide/function.setmovesequence-int-integer-integer.html
? doc/adminguide/function.setmovesequence-integer-integer.html
? doc/adminguide/function.setmovetable-int-integer-integer.html
? doc/adminguide/function.setmovetable-integer-integer.html
? doc/adminguide/function.setsessionrole-name-text.html
? doc/adminguide/function.slon-quote-brute-text.html
? doc/adminguide/function.slon-quote-input-text.html
? doc/adminguide/function.slonyversion.html
? doc/adminguide/function.slonyversionmajor.html
? doc/adminguide/function.slonyversionminor.html
? doc/adminguide/function.slonyversionpatchlevel.html
? doc/adminguide/function.storelisten-int-integer-integer-integer.html
? doc/adminguide/function.storelisten-integer-integer-integer.html
? doc/adminguide/function.storenode-int-integer-text-boolean.html
? doc/adminguide/function.storenode-integer-text-boolean.html
? doc/adminguide/function.storepath-int-integer-integer-text-integer.html
? doc/adminguide/function.storepath-integer-integer-text-integer.html
? doc/adminguide/function.storeset-int-integer-integer-text.html
? doc/adminguide/function.storeset-integer-text.html
? doc/adminguide/function.storetrigger-int-integer-name.html
? doc/adminguide/function.storetrigger-integer-name.html
? doc/adminguide/function.subscribeset-int-integer-integer-integer-boolean.html
? doc/adminguide/function.subscribeset-integer-integer-integer-boolean.html
? doc/adminguide/function.tableaddkey-text.html
? doc/adminguide/function.tabledropkey-integer.html
? doc/adminguide/function.tablehasserialkey-text.html
? doc/adminguide/function.terminatenodeconnections-name.html
? doc/adminguide/function.uninstallnode.html
? doc/adminguide/function.unlockset-integer.html
? doc/adminguide/function.unsubscribeset-int-integer-integer.html
? doc/adminguide/function.unsubscribeset-integer-integer.html
? doc/adminguide/function.updaterelname-integer-integer.html
? doc/adminguide/function.updatereloid-integer-integer.html
? doc/adminguide/function.upgradeschema-text.html
? doc/adminguide/hdrcmds.html
? doc/adminguide/help.html
? doc/adminguide/i8069.html
? doc/adminguide/index.html
? doc/adminguide/installation.html
? doc/adminguide/listenpaths.html
? doc/adminguide/locking.html
? doc/adminguide/logshipping.html
? doc/adminguide/maintenance.html
? doc/adminguide/metacmds.html
? doc/adminguide/monitoring.html
? doc/adminguide/noslonik.html
? doc/adminguide/plainpaths.html
? doc/adminguide/requirements.html
? doc/adminguide/reshape.html
? doc/adminguide/runtime-config.html
? doc/adminguide/schema.html
? doc/adminguide/slon-config-connection.html
? doc/adminguide/slon-config-interval.html
? doc/adminguide/slon.html
? doc/adminguide/slonik.html
? doc/adminguide/slonikref.html
? doc/adminguide/slonikshell.html
? doc/adminguide/slonstart.html
? doc/adminguide/slonyadmin.html
? doc/adminguide/slonyintro.html
? doc/adminguide/slonylistenercosts.html
? doc/adminguide/stmtcreateset.html
? doc/adminguide/stmtddlscript.html
? doc/adminguide/stmtdefine.html
? doc/adminguide/stmtdroplisten.html
? doc/adminguide/stmtdropnode.html
? doc/adminguide/stmtdroppath.html
? doc/adminguide/stmtdropset.html
? doc/adminguide/stmtdroptrigger.html
? doc/adminguide/stmtecho.html
? doc/adminguide/stmtexit.html
? doc/adminguide/stmtfailover.html
? doc/adminguide/stmtinclude.html
? doc/adminguide/stmtinitcluster.html
? doc/adminguide/stmtlockset.html
? doc/adminguide/stmtmergeset.html
? doc/adminguide/stmtmoveset.html
? doc/adminguide/stmtrestartnode.html
? doc/adminguide/stmtsetaddsequence.html
? doc/adminguide/stmtsetaddtable.html
? doc/adminguide/stmtsetdropsequence.html
? doc/adminguide/stmtsetdroptable.html
? doc/adminguide/stmtsetmovesequence.html
? doc/adminguide/stmtsetmovetable.html
? doc/adminguide/stmtstorelisten.html
? doc/adminguide/stmtstorenode.html
? doc/adminguide/stmtstorepath.html
? doc/adminguide/stmtstoretrigger.html
? doc/adminguide/stmtsubscribeset.html
? doc/adminguide/stmttableaddkey.html
? doc/adminguide/stmtuninstallnode.html
? doc/adminguide/stmtunlockset.html
? doc/adminguide/stmtunsubscribeset.html
? doc/adminguide/stmtupdatefunctions.html
? doc/adminguide/stmtwaitevent.html
? doc/adminguide/subscribenodes.html
? doc/adminguide/supportedplatforms.html
? doc/adminguide/table.sl-confirm.html
? doc/adminguide/table.sl-event.html
? doc/adminguide/table.sl-listen.html
? doc/adminguide/table.sl-log-1.html
? doc/adminguide/table.sl-log-2.html
? doc/adminguide/table.sl-node.html
? doc/adminguide/table.sl-path.html
? doc/adminguide/table.sl-seqlog.html
? doc/adminguide/table.sl-sequence.html
? doc/adminguide/table.sl-set.html
? doc/adminguide/table.sl-setsync.html
? doc/adminguide/table.sl-subscribe.html
? doc/adminguide/table.sl-table.html
? doc/adminguide/table.sl-trigger.html
? doc/adminguide/testbed.html
? doc/adminguide/usingslonik.html
? doc/adminguide/version.sgml
? doc/adminguide/versionupgrade.html
? doc/adminguide/view.sl-seqlastvalue.html
? src/parsestatements
? src/slon/cleanup_thread.c.patch
? tests/testlogship
? tests/test2/init_moveset.ik
? tools/altperl/out
? tools/altperl/show_configuration
? tools/altperl/slon-tools
? tools/altperl/slon_kill
? tools/altperl/slon_start
? tools/altperl/slon_watchdog
? tools/altperl/slon_watchdog2
? tools/altperl/slonik_build_env
? tools/altperl/slonik_create_set
? tools/altperl/slonik_drop_node
? tools/altperl/slonik_drop_set
? tools/altperl/slonik_execute_script
? tools/altperl/slonik_failover
? tools/altperl/slonik_init_cluster
? tools/altperl/slonik_merge_sets
? tools/altperl/slonik_move_set
? tools/altperl/slonik_restart_node
? tools/altperl/slonik_store_node
? tools/altperl/slonik_subscribe_set
? tools/altperl/slonik_uninstall_nodes
? tools/altperl/slonik_unsubscribe_set
? tools/altperl/slonik_update_nodes
? tools/altperl/slony_show_configuration
Index: doc/adminguide/ddlchanges.sgml
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/doc/adminguide/ddlchanges.sgml,v
retrieving revision 1.20
diff -c -u -r1.20 ddlchanges.sgml
--- doc/adminguide/ddlchanges.sgml	17 Jan 2006 16:16:09 -0000	1.20
+++ doc/adminguide/ddlchanges.sgml	24 Feb 2006 22:01:34 -0000
@@ -117,6 +117,51 @@
 
 </itemizedlist></para></listitem>
 
+<listitem><para> In &slony1; versions 1.0 thru 1.1.5, the script is
+processed as a single query request, which can cause problems if you
+are making complex changes.  In version 1.2, the script is parsed into
+individual SQL statements, and each statement is submitted separately,
+which is a preferable handling of this.  </para>
+
+<para> The trouble with one query processing a <quote>compound
+statement</quote> is that the SQL parser does its processing for that
+entire set of queries based on the state of the database at the
+<emphasis>beginning</emphasis> of the query.</para>   
+
+<para> This causes no particular trouble if those statements are
+independent of one another, such as if you add two columns to a
+table.</para>
+
+<command> alter table t1 add column c1 integer; alter table t1 add
+column c2 integer; </command>
+
+<para> Trouble arises if a subsequent query needs to reference an
+earlier one.  Consider the following DDL statements...  </para>
+
+<command> alter table t1 add column c1 integer; create sequence s1;
+update t1 set c1=nextval('s1'); alter table t1 alter column c1 set not
+null; alter table t1 add primary key(c1); </command>
+
+<para> Up until &slony1; version 1.2, this query would <emphasis> fail
+</emphasis>.  It would specifically fail upon reaching the
+<command>UPDATE</command> statement, complaining that column
+<envar>c1</envar> doesn't exist.  This happens because
+<emphasis>all</emphasis> of those queries are parsed based on the
+state of things immediately before the query.  So, the
+<command>UPDATE</command> is evaluated based on a table definition
+<emphasis>before</emphasis> the new column was added. Oops. </para>
+
+<para>If you are running one of the earlier versions, the workaround
+is that you invoke a separate <xref linkend="stmtddlscript"> request
+with a separate script, cutting off to a new script each time a
+statement refers to something created in previous statements. </para>
+
+<para> In &slony1; version 1.2, there is a state machine that pulls
+apart the DDL script into individual statements.  Each statement is
+submitted as a separate <function>PQexec()</function> request, with
+the result that this is no longer an issue. </para>
+</listitem>
+
 </itemizedlist>
 
 <para>Unfortunately, this nonetheless implies that the use of the DDL
Index: doc/adminguide/slonik_ref.sgml
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/doc/adminguide/slonik_ref.sgml,v
retrieving revision 1.41
diff -c -u -r1.41 slonik_ref.sgml
--- doc/adminguide/slonik_ref.sgml	24 Feb 2006 18:43:10 -0000	1.41
+++ doc/adminguide/slonik_ref.sgml	24 Feb 2006 22:01:36 -0000
@@ -2298,7 +2298,9 @@
 
     <variablelist>
      <varlistentry><term><literal> SET ID = ival </literal></term>
-      <listitem><para> The unique numeric ID number of the set affected by the script</para></listitem>
+
+      <listitem><para> The unique numeric ID number of the set
+      affected by the script</para></listitem>
       
      </varlistentry>
      <varlistentry><term><literal> FILENAME = '/path/to/file' </literal></term>
@@ -2352,10 +2354,6 @@
     the token <command>@NAMESPACE@</command>; both will be expanded
     into the appropriate replacement tokens. </para>
 
-    <para> It generally seems a bad idea to use quotes in DDL scripts.
-    It appears preferable to handle that sort of thing <quote>out of
-    band.</quote> </para>
-
     <para> This uses &funddlscript;. </para>
    </refsect1>
    <refsect1><title>Example</title>
@@ -2381,7 +2379,21 @@
 
    </refsect1>
    <refsect1> <title> Version Information </title>
-    <para> This command was introduced in &slony1; 1.0 </para>
+    <para> This command was introduced in &slony1; 1.0. </para>
+
+    <para> Before &slony1; version 1.2, the entire DDL script was
+    submitted as one <function>PQexec()</function> request, with the
+    implication that the <emphasis>entire</emphasis> script was parsed
+    based on the state of the database before invokation of the
+    script.  This means statements later in the script cannot depend
+    on DDL changes made by earlier statements in the same script.
+    Thus, you cannot add a column to a table and add constraints to
+    that column later in the same request. </para>
+
+    <para> In &slony1; version 1.2, the DDL script is split into
+    statements, and each is submitted separately.  As a result, it is
+    fine for later statements to refer to objects or attributes
+    created or modified in earlier statements. </para>
    </refsect1>
   </refentry>
 
Index: src/backend/slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.77
diff -c -u -r1.77 slony1_funcs.sql
--- src/backend/slony1_funcs.sql	24 Feb 2006 20:02:37 -0000	1.77
+++ src/backend/slony1_funcs.sql	24 Feb 2006 22:01:41 -0000
@@ -3417,17 +3417,16 @@
 replicated table trig_tabid IS disabled.';
 
 -- ----------------------------------------------------------------------
--- FUNCTION ddlScript (set_id, script, only_on_node)
+-- FUNCTION ddlScript_prepare (set_id, only_on_node)
 --
 --	Generate the DDL_SCRIPT event
 -- ----------------------------------------------------------------------
-create or replace function @[EMAIL PROTECTED] (int4, text, int4)
-returns bigint
+create or replace function @[EMAIL PROTECTED] (int4, int4)
+returns integer
 as '
 declare
 	p_set_id			alias for $1;
-	p_script			alias for $2;
-	p_only_on_node		alias for $3;
+	p_only_on_node		alias for $2;
 	v_set_origin		int4;
 begin
 	-- ----
@@ -3454,31 +3453,53 @@
 	-- Create a SYNC event, run the script and generate the DDL_SCRIPT event
 	-- ----
 	perform @[EMAIL PROTECTED](''[EMAIL PROTECTED]@'', ''SYNC'', NULL);
-	perform @[EMAIL PROTECTED](p_set_id, p_script, p_only_on_node);
+	return 1;
+end;
+' language plpgsql;
+
+comment on function @[EMAIL PROTECTED] (int4, int4) is 
+'Prepare for DDL script execution on origin';
+
+-- 	perform @[EMAIL PROTECTED](p_set_id, p_script, p_only_on_node);
+
+-- ----------------------------------------------------------------------
+-- FUNCTION ddlScript_complete (set_id, script, only_on_node)
+--
+--	Generate the DDL_SCRIPT event
+-- ----------------------------------------------------------------------
+create or replace function @[EMAIL PROTECTED] (int4, text, int4)
+returns integer
+as '
+declare
+	p_set_id			alias for $1;
+	p_script			alias for $2;
+	p_only_on_node		alias for $3;
+	v_set_origin		int4;
+begin
 	perform @[EMAIL PROTECTED](p_set_id, p_only_on_node);
 	return  @[EMAIL PROTECTED](''[EMAIL PROTECTED]@'', ''DDL_SCRIPT'', 
 			p_set_id, p_script, p_only_on_node);
 end;
 ' language plpgsql;
-comment on function @[EMAIL PROTECTED](int4, text, int4) is
-'ddlScript(set_id, script, only_on_node)
 
-Generates a SYNC event, runs the script on the origin, and then
-generates a DDL_SCRIPT event to request it to be run on replicated
-slaves.';
+comment on function @[EMAIL PROTECTED](int4, text, int4) is
+'ddlScript_complete(set_id, script, only_on_node)
+
+After script has run on origin, this fixes up relnames, restores
+triggers, and generates a DDL_SCRIPT event to request it to be run on
+replicated slaves.';
 
 -- ----------------------------------------------------------------------
--- FUNCTION ddlScript_int (set_id, script, only_on_node)
+-- FUNCTION ddlScript_prepare_int (set_id, only_on_node)
 --
---	Process the DDL_SCRIPT event
+--	Prepare for the DDL_SCRIPT event
 -- ----------------------------------------------------------------------
-create or replace function @[EMAIL PROTECTED] (int4, text, int4)
+create or replace function @[EMAIL PROTECTED] (int4, int4)
 returns int4
 as '
 declare
 	p_set_id			alias for $1;
-	p_script			alias for $2;
-	p_only_on_node		alias for $3;
+	p_only_on_node		alias for $2;
 	v_set_origin		int4;
 	v_no_id				int4;
 	v_row				record;
@@ -3523,11 +3544,26 @@
 	loop
 		perform @[EMAIL PROTECTED](v_row.tab_id);
 	end loop;
+	return p_set_id;
+end;
+' language plpgsql;
 
-	-- ----
-	-- Run the script
-	-- ----
-	execute p_script;
+
+----	execute p_script;
+
+
+-- ----------------------------------------------------------------------
+-- FUNCTION ddlScript_complete_int (set_id, only_on_node)
+--
+--	Complete the DDL_SCRIPT event
+-- ----------------------------------------------------------------------
+create or replace function @[EMAIL PROTECTED] (int4, int4)
+returns int4
+as '
+declare
+	p_set_id			alias for $1;
+	p_only_on_node		alias for $2;
+	v_row				record;
 
 	-- ----
 	-- Put all tables back into replicated mode
@@ -3540,12 +3576,11 @@
 	return p_set_id;
 end;
 ' language plpgsql;
-comment on function @[EMAIL PROTECTED](int4, text, int4) is
-'ddlScript_int(set_id, script, only_on_node)
+comment on function @[EMAIL PROTECTED](int4, int4) is
+'ddlScript_complete_int(set_id, script, only_on_node)
 
-Processes the DDL_SCRIPT event.  On slave nodes, this restores
-original triggers/rules, runs the script, and then puts tables back
-into replicated mode.';
+Complete processing the DDL_SCRIPT event.  This puts tables back into
+replicated mode.';
 
 -- ----------------------------------------------------------------------
 -- FUNCTION alterTableForReplication (tab_id)
Index: src/slon/Makefile
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/Makefile,v
retrieving revision 1.39
diff -c -u -r1.39 Makefile
--- src/slon/Makefile	14 Nov 2005 14:17:12 -0000	1.39
+++ src/slon/Makefile	24 Feb 2006 22:01:41 -0000
@@ -38,7 +38,8 @@
 	dbutils.o		\
 	conf-file.o		\
 	confoptions.o		\
-	misc.o
+	misc.o                  \
+	../parsestatements/scanner.o
 
 ifdef HAVE_NETSNMP
 OBJS+= snmp_thread.o
Index: src/slon/remote_worker.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_worker.c,v
retrieving revision 1.105
diff -c -u -r1.105 remote_worker.c
--- src/slon/remote_worker.c	24 Feb 2006 20:02:37 -0000	1.105
+++ src/slon/remote_worker.c	24 Feb 2006 22:01:42 -0000
@@ -27,7 +27,8 @@
 
 #include "slon.h"
 #include "confoptions.h"
-
+#include "../parsestatements/scanner.h"
+extern STMTS[MAXSTATEMENTS];
 
 /* ----------
  * Local definitions 
@@ -1453,11 +1454,53 @@
 
 
 				slon_appendquery(&query1,
-								 "select %s.ddlScript_int(%d, '%q', %d); ",
-								 rtcfg_namespace,
-								 ddl_setid, ddl_script, ddl_only_on_node);
+						 "select %s.ddlScript_prepare_int(%d, %d); ",
+						 rtcfg_namespace,
+						 ddl_setid, ddl_only_on_node);
+
+				if (query_execute(node, local_dbconn, &query1) < 0) {
+						slon_log(SLON_ERROR, "remoteWorkerThread_%d: DDL preparation failed - set %d - only on node %\n",
+							 node->no_id, ddl_setid, ddl_only_on_node);
+						slon_retry();
+				}
+
+				int num_statements = -1, stmtno, startpos;
+				num_statements = scan_for_statements (ddl_script);
+				if ((num_statements < 0) || (num_statements >= MAXSTATEMENTS)) {
+					slon_log(SLON_ERROR, "remoteWorkerThread_%d: DDL had invalid number of statements - %d\n", 
+						 node->no_id, num_statements);
+					slon_retry();
+				}
+				for (stmtno=0, startpos=0; stmtno > num_statements; startpos = STMTS[stmtno], stmtno++) {
+					char *dest = (char *) malloc (STMTS[stmtno] - startpos + 1);
+					if (dest == 0) {
+						slon_log(SLON_ERROR, "remoteWorkerThread_%d: malloc() failure in DDL_SCRIPT\n");
+						slon_retry();
+					}
+					strncpy(dest, ddl_script + startpos, STMTS[stmtno]-startpos);
+					dest[STMTS[stmtno]-startpos+1] = 0;
+					slon_mkquery(&query1, dest);
+					free(dest);
+
+					if (query_execute(node, local_dbconn, &query1) < 0) {
+						slon_log(SLON_ERROR, "remoteWorkerThread_%d: DDL statement failed - %s\n",
+							 node->no_id, dstring_data(&query1));
+						slon_retry();
+					}
+				}
+	
+				slon_mkquery(&query1, "select \"_%s\".ddlScript_complete_int(%d, %d); ", 
+					     rtcfg_namespace,
+					     ddl_setid,
+					     ddl_only_on_node);
 
 				/* DDL_SCRIPT needs to be turned into a log shipping script */
+				/* Note that the issue about parsing that mandates breaking 
+				   up compound statements into
+				   individually-processed statements does not apply to log
+				   shipping as psql parses and processes each statement
+				   individually */
+
 				if (archive_dir)
 				{
 					if ((ddl_only_on_node < 1) || (ddl_only_on_node == rtcfg_nodeid))
Index: src/slonik/Makefile
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/Makefile,v
retrieving revision 1.22
diff -c -u -r1.22 Makefile
--- src/slonik/Makefile	23 Dec 2005 09:20:52 -0000	1.22
+++ src/slonik/Makefile	24 Feb 2006 22:01:42 -0000
@@ -32,7 +32,8 @@
 OBJS		= 			\
 	slonik.o			\
 	dbutil.o			\
-	parser.o $(WIN32RES)
+	parser.o $(WIN32RES)            \
+	../parsestatements/scanner.o
 
 DISTFILES = Makefile $(wildcard *.c) $(wildcard *.h) $(wildcard *.l) $(wildcard *.y)
 
@@ -85,4 +86,3 @@
 	for file in $(DISTFILES) ; do \
       cp $$file $(distdir)/$(subdir)/$$file ; \
     done
-
Index: src/slonik/slonik.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.c,v
retrieving revision 1.56
diff -c -u -r1.56 slonik.c
--- src/slonik/slonik.c	24 Feb 2006 20:02:38 -0000	1.56
+++ src/slonik/slonik.c	24 Feb 2006 22:01:44 -0000
@@ -33,7 +33,8 @@
 
 #include "slonik.h"
 #include "config.h"
-
+#include "../parsestatements/scanner.h"
+extern STMTS[MAXSTATEMENTS];
 
 /*
  * Global data
@@ -3871,9 +3872,49 @@
 
 	dstring_init(&query);
 	slon_mkquery(&query,
-				 "select \"_%s\".ddlScript(%d, '%q', %d); ",
-				 stmt->hdr.script->clustername,
-				 stmt->ddl_setid, dstring_data(&script), stmt->only_on_node);
+		     "select \"_%s\".ddlScript_prepare(%d, %d); ",
+		     stmt->hdr.script->clustername,
+		     stmt->ddl_setid, /* dstring_data(&script),  */ 
+		     stmt->only_on_node);
+
+	if (db_exec_evcommand((SlonikStmt *) stmt, adminfo1, &query) < 0)
+	{
+		dstring_free(&query);
+		return -1;
+	}
+
+	/* Split the script into a series of SQL statements - each needs to
+	   be submitted separately */
+	int num_statements = -1, stmtno, startpos;
+	num_statements = scan_for_statements (&script);
+
+	/* OOPS!  Something went wrong !!! */
+	if ((num_statements < 0) || (num_statements >= MAXSTATEMENTS)) {
+		return -1;
+	}
+	for (stmtno=0, startpos=0; stmtno > num_statements; startpos = STMTS[stmtno], stmtno++) {
+		char *dest = (char *) malloc (STMTS[stmtno] - startpos + 1);
+		if (dest == 0) {
+			return -1;
+		}
+		strncpy(dest, dstring_data(&script + startpos), STMTS[stmtno]-startpos);
+		dest[STMTS[stmtno]-startpos+1] = 0;
+		slon_mkquery(&query, dest);
+		free(dest);
+
+		if (db_exec_evcommand((SlonikStmt *) stmt, adminfo1, &query) < 0)
+		{
+			dstring_free(&query);
+			return -1;
+		}
+	}
+	
+
+	slon_mkquery(&query, "select \"_%s\".ddlScript_complete(%d, '%s' %d); ", 
+		     stmt->hdr.script->clustername,
+		     stmt->ddl_setid,  dstring_data(&script),
+		     stmt->only_on_node);
+
 	dstring_free(&script);
 	if (db_exec_evcommand((SlonikStmt *) stmt, adminfo1, &query) < 0)
 	{
_______________________________________________
Slony1-general mailing list
[email protected]
http://gborg.postgresql.org/mailman/listinfo/slony1-general

Reply via email to