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