## 1.69. moveset_int( integer, integer, integer )

Function Properties
Language: PLPGSQL
Return Type: integer

moveSet(set_id, old_origin, new_origin) Process MOVE_SET event to request that the origin for set set_id be moved from old_origin to node new_origin

    declare
    	p_set_id			alias for $1;
    	p_old_origin		alias for $2;
    	p_new_origin		alias for $3;
    	v_local_node_id		int4;
    	v_tab_row			record;
    	v_sub_row			record;
    	v_sub_node			int4;
    	v_sub_last			int4;
    	v_sub_next			int4;
    	v_last_sync			int8;
    begin
    	-- ----
    	-- Grab the central configuration lock
    	-- ----
    	lock table sl_config_lock;

    	-- ----
    	-- Get our local node ID
    	-- ----
    	v_local_node_id := getLocalNodeId('_schemadoc');

    	-- ----
    	-- If we are the old or new origin of the set, we need to
    	-- remove the log trigger from all tables first.
    	-- ----
    	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
    		for v_tab_row in select tab_id from sl_table
    				where tab_set = p_set_id
    				order by tab_id
    		loop
    			perform alterTableRestore(v_tab_row.tab_id);
    		end loop;
    	end if;

    	-- On the new origin, raise an event - ACCEPT_SET
    	if v_local_node_id = p_new_origin then
    		-- Find the event number from the origin
    		select max(ev_seqno) as seqno into v_sub_row
    			from sl_event
    			where ev_type = 'MOVE_SET' and
    			  ev_data1 = p_set_id and
    			  ev_data2 = p_old_origin and
    			  ev_data3 = p_new_origin and
    			  ev_origin = p_old_origin;

    		perform createEvent('_schemadoc', 'ACCEPT_SET',
    			p_set_id, p_old_origin, p_new_origin, v_sub_row.seqno);
    	end if;

    	-- ----
    	-- Next we have to reverse the subscription path
    	-- ----
    	v_sub_last = p_new_origin;
    	select sub_provider into v_sub_node
    			from sl_subscribe
    			where sub_set = p_set_id
    			and sub_receiver = p_new_origin;
    	if not found then
    		raise exception 'Slony-I: subscription path broken in moveSet_int';
    	end if;
    	while v_sub_node <> p_old_origin loop
    		-- ----
    		-- Tracing node by node, the old receiver is now in
    		-- v_sub_last and the old provider is in v_sub_node.
    		-- ----

    		-- ----
    		-- Get the current provider of this node as next
    		-- and change the provider to the previous one in
    		-- the reverse chain.
    		-- ----
    		select sub_provider into v_sub_next
    				from sl_subscribe
    				where sub_set = p_set_id
    					and sub_receiver = v_sub_node
    				for update;
    		if not found then
    			raise exception 'Slony-I: subscription path broken in moveSet_int';
    		end if;
    		update sl_subscribe
    				set sub_provider = v_sub_last
    				where sub_set = p_set_id
    					and sub_receiver = v_sub_node;

    		v_sub_last = v_sub_node;
    		v_sub_node = v_sub_next;
    	end loop;

    	-- ----
    	-- This includes creating a subscription for the old origin
    	-- ----
    	insert into sl_subscribe
    			(sub_set, sub_provider, sub_receiver,
    			sub_forward, sub_active)
    			values (p_set_id, v_sub_last, p_old_origin, true, true);
    	if v_local_node_id = p_old_origin then
    		select coalesce(max(ev_seqno), 0) into v_last_sync
    				from sl_event
    				where ev_origin = p_new_origin
    					and ev_type = 'SYNC';
    		if v_last_sync > 0 then
    			insert into sl_setsync
    					(ssy_setid, ssy_origin, ssy_seqno,
    					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
    					select p_set_id, p_new_origin, v_last_sync,
    					ev_minxid, ev_maxxid, ev_xip, NULL
    					from sl_event
    					where ev_origin = p_new_origin
    						and ev_seqno = v_last_sync;
    		else
    			insert into sl_setsync
    					(ssy_setid, ssy_origin, ssy_seqno,
    					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
    					values (p_set_id, p_new_origin, '0',
    					'0', '0', '', NULL);
    		end if;
    	end if;

    	-- ----
    	-- Now change the ownership of the set.
    	-- ----
    	update sl_set
    			set set_origin = p_new_origin
    			where set_id = p_set_id;

    	-- ----
    	-- On the new origin, delete the obsolete setsync information
    	-- and the subscription.
    	-- ----
    	if v_local_node_id = p_new_origin then
    		delete from sl_setsync
    				where ssy_setid = p_set_id;
    	else
    		if v_local_node_id <> p_old_origin then
    			--
    			-- On every other node, change the setsync so that it will
    			-- pick up from the new origins last known sync.
    			--
    			delete from sl_setsync
    					where ssy_setid = p_set_id;
    			select coalesce(max(ev_seqno), 0) into v_last_sync
    					from sl_event
    					where ev_origin = p_new_origin
    						and ev_type = 'SYNC';
    			if v_last_sync > 0 then
    				insert into sl_setsync
    						(ssy_setid, ssy_origin, ssy_seqno,
    						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
    						select p_set_id, p_new_origin, v_last_sync,
    						ev_minxid, ev_maxxid, ev_xip, NULL
    						from sl_event
    						where ev_origin = p_new_origin
    							and ev_seqno = v_last_sync;
    			else
    				insert into sl_setsync
    						(ssy_setid, ssy_origin, ssy_seqno,
    						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
    						values (p_set_id, p_new_origin, '0',
    						'0', '0', '', NULL);
    			end if;
    		end if;
    	end if;
    	delete from sl_subscribe
    			where sub_set = p_set_id
    			and sub_receiver = p_new_origin;

    	-- Regenerate sl_listen since we revised the subscriptions
    	perform RebuildListenEntries();

    	-- ----
    	-- If we are the new or old origin, we have to
    	-- put all the tables into altered state again.
    	-- ----
    	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
    		for v_tab_row in select tab_id from sl_table
    				where tab_set = p_set_id
    				order by tab_id
    		loop
    			perform alterTableForReplication(v_tab_row.tab_id);
    		end loop;
    	end if;

    	return p_set_id;
    end;