CVS User Account cvsuser
Wed Dec 1 20:26:15 PST 2004
Log Message:
-----------
Added new function upgradeSchema(old_version). Slonik now determines
the currently loaded slony1_funcs.sql version by calling slonyVersion()
before updating the functions. It then calls upgradeSchema(old_version)
so that this function can perform all the required modifications to the
slony1_base schema depending on the old version.

Jan

Modified Files:
--------------
    slony1-engine/src/backend:
        slony1_base.sql (r1.23 -> r1.24)
        slony1_funcs.sql (r1.46 -> r1.47)
    slony1-engine/src/ducttape:
        test_1_update_functions (r1.1 -> r1.2)
    slony1-engine/src/slonik:
        slonik.c (r1.33 -> r1.34)

-------------- next part --------------
Index: slony1_base.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_base.sql,v
retrieving revision 1.23
retrieving revision 1.24
diff -Lsrc/backend/slony1_base.sql -Lsrc/backend/slony1_base.sql -u -w -r1.23 -r1.24
--- src/backend/slony1_base.sql
+++ src/backend/slony1_base.sql
@@ -22,6 +22,7 @@
 	no_id				int4,
 	no_active			bool,
 	no_comment			text,
+	no_spool			boolean,
 
 	CONSTRAINT "sl_node-pkey"
 		PRIMARY KEY (no_id)
Index: slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.46
retrieving revision 1.47
diff -Lsrc/backend/slony1_funcs.sql -Lsrc/backend/slony1_funcs.sql -u -w -r1.46 -r1.47
--- src/backend/slony1_funcs.sql
+++ src/backend/slony1_funcs.sql
@@ -4708,64 +4708,32 @@
 Checks if a table has our special serial key column that is used if
 the table has no natural unique constraint.';
 
--- ----------------------------------------------------------------------
--- FUNCTION add_missing_table_field(text, text, text, text)
---
---  support function of only adding the fields to a table if they do not yet exist.
---
--- ----------------------------------------------------------------------
-create or replace function @NAMESPACE at .add_missing_table_field (text, text, text, text) 
-returns bool as '
-DECLARE
-  p_namespace alias for $1;
-  p_table     alias for $2;
-  p_field     alias for $3;
-  p_type      alias for $4;
-  v_row       record;
-  v_query     text;
-BEGIN
-  select 1 into v_row from pg_namespace n, pg_class c, pg_attribute a
-     where quote_ident(n.nspname) = p_namespace and 
-         c.relnamespace = n.oid and
-         quote_ident(c.relname) = p_table and
-         a.attrelid = c.oid and
-         quote_ident(a.attname) = p_field;
-  if not found then
-    raise notice ''Upgrade table %.% - add field %'', p_namespace, p_table, p_field;
-    v_query := ''alter table '' || p_namespace || ''.'' || p_table || '' add column '';
-    v_query := v_query || p_field || '' '' || p_type || '';'';
-    execute v_query;
-    return ''t'';
-  else
-    return ''f'';
-  end if;
-END;' language plpgsql;
-
-comment on function @NAMESPACE at .add_missing_table_field(text,text,text,text) is
-  'add_missing_table_field(namespace, table, field, type)';
-
 
 -- ----------------------------------------------------------------------
--- FUNCTION upgrade_sl_node ()
---
---  adds the no_spool  bool to sl_node
+-- FUNCTION upgradeSchema(old_version)
 --
+--	Called by slonik during the function upgrade process. 
 -- ----------------------------------------------------------------------
-create or replace function @NAMESPACE at .upgrade_sl_node () returns bool
-as '
-DECLARE
-	v_row  record;
-	ret boolean;
-BEGIN
-	select @NAMESPACE at .add_missing_table_field(''@NAMESPACE@'', ''sl_node'', ''no_spool'', ''boolean'') into ret;
-	return ret;
-
-END;' 
-language plpgsql;
+create or replace function @NAMESPACE at .upgradeSchema(text)
+returns text as '
+declare
+	p_old	alias for $1;
+begin
+	-- ----
+	-- Changes from 1.0.x to 1.1.0
+	-- ----
+	if p_old = ''1.0.2'' or p_old = ''1.0.5'' then
+		-- Add new column sl_node.no_spool for virtual spool nodes
+		execute ''alter table @NAMESPACE at .sl_node add column no_spool boolean'';
+		update @NAMESPACE at .sl_node set no_spool = false;
+	end if;
 
-comment on function @NAMESPACE at .upgrade_sl_node() is
-  'Schema changes required to upgrade to version 1.1';
+	return p_old;
+end;
+' language plpgsql;
 
+comment on function @NAMESPACE at .upgradeSchema(text) is
+    'Called during "update functions" by slonik to perform schema changes';
 
 -- ----------------------------------------------------------------------
 -- VIEW sl_status
Index: test_1_update_functions
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/ducttape/test_1_update_functions,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lsrc/ducttape/test_1_update_functions -Lsrc/ducttape/test_1_update_functions -u -w -r1.1 -r1.2
--- src/ducttape/test_1_update_functions
+++ src/ducttape/test_1_update_functions
@@ -14,12 +14,13 @@
 # Move set 1 to node 2
 ######################################################################
 
-echo "**** Reloading the functions in node 2"
+echo "**** Reloading the functions in nodes 1 and 2"
 slonik <<_EOF_
 	cluster name = T1;
 	node 1 admin conninfo = 'dbname=$DB1';
 	node 2 admin conninfo = 'dbname=$DB2';
 
+	update functions (id = 1);
 	update functions (id = 2);
 _EOF_
 
Index: slonik.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -Lsrc/slonik/slonik.c -Lsrc/slonik/slonik.c -u -w -r1.33 -r1.34
--- src/slonik/slonik.c
+++ src/slonik/slonik.c
@@ -3680,8 +3680,6 @@
 
 	dstring_free(&query);
 	return 0;
-
-	return 0;
 }
 
 
@@ -3689,8 +3687,8 @@
 slonik_update_functions(SlonikStmt_update_functions *stmt)
 {
 	SlonikAdmInfo  *adminfo;
+	PGresult	   *res;
 	SlonDString		query;
-	int				rc;
 
 	adminfo = get_checked_adminfo((SlonikStmt *)stmt, stmt->no_id);
 	if (adminfo == NULL)
@@ -3699,21 +3697,97 @@
 	if (db_begin_xact((SlonikStmt *)stmt, adminfo) < 0)
 		return -1;
 
-	rc = load_slony_functions((SlonikStmt *)stmt, stmt->no_id);
-	if (rc < 0)
+	/*
+	 * Check if the currently loaded schema has the function
+	 * slonyVersion() defined.
+	 */
+	dstring_init(&query);
+	slon_mkquery(&query,
+			"select true from pg_proc P, pg_namespace N "
+			"    where P.proname = 'slonyversion' "
+			"    and P.pronamespace = N.oid "
+			"    and N.nspname = '_%s';",
+			stmt->hdr.script->clustername);
+	res = db_exec_select((SlonikStmt *)stmt, adminfo, &query);
+	if (res == NULL)
+	{
+		dstring_free(&query);
 		return -1;
+	}
+	if (PQntuples(res) == 0)
+	{
+		/*
+		 * No - this must be a 1.0.2 or earlier. Generate a query to
+		 * call upgradeSchema() from 1.0.2.
+		 */
+		PQclear(res);
+		slon_mkquery(&query,
+				"select \"_%s\".upgradeSchema('1.0.2'); ",
+				stmt->hdr.script->clustername);
+	}
+	else
+	{
+		/*
+		 * Yes - call the function and generate a query to call
+		 * upgradeSchema() from that version later.
+		 */
+		PQclear(res);
+		slon_mkquery(&query,
+				"select \"_%s\".slonyVersion(); ",
+				stmt->hdr.script->clustername);
+		res = db_exec_select((SlonikStmt *)stmt, adminfo, &query);
+		if (res == NULL)
+		{
+			dstring_free(&query);
+			return -1;
+		}
+		if (PQntuples(res) != 1)
+		{
+			 printf("%s:%d: failed to determine current schema version\n",
+						 stmt->hdr.stmt_filename, stmt->hdr.stmt_lno);
+			PQclear(res);
+			dstring_free(&query);
+			return -1;
+		}
+		slon_mkquery(&query,
+				"select \"_%s\".upgradeSchema('%s'); ",
+				 stmt->hdr.script->clustername,
+				 PQgetvalue(res, 0, 0));
+		PQclear(res);
+	}
 
-	dstring_init(&query);
+	/*
+	 * Load the new slony1_functions.sql
+	 */
+	if (load_slony_functions((SlonikStmt *)stmt, stmt->no_id) < 0)
+	{
+		dstring_free(&query);
+		return -1;
+	}
+
+	/*
+	 * Call the upgradeSchema() function
+	 */
+	if (db_exec_command((SlonikStmt *)stmt, adminfo, &query) < 0)
+	{
+		dstring_free(&query);
+		return -1;
+	}
+
+	/*
+	 * Finally restart the node.
+	 */
 	slon_mkquery(&query,
 			"notify \"_%s_Restart\"; ",
 			stmt->hdr.script->clustername);
 	if (db_exec_command((SlonikStmt *)stmt, adminfo, &query) < 0)
-		rc = -1;
-	else
-		rc = 0;
+	{
 	dstring_free(&query);
+		return -1;
+	}
 
-	return rc;
+	dstring_free(&query);
+	return 0;
 }
 
 


More information about the Slony1-commit mailing list