resubscribenode(p_receiver integer, p_provider integer, p_origin integer)

8.95. resubscribenode(p_receiver integer, p_provider integer, p_origin integer)

Function Properties

Language: PLPGSQL

Return Type: bigint

declare
	v_record record;
	v_missing_sets text;
	v_ev_seqno bigint;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table sl_config_lock;

	--
	-- Check that the receiver exists
	--
	if not exists (select no_id from sl_node where no_id=
	       	      p_receiver) then
		      raise exception 'Slony-I: subscribeSet() receiver % does not exist' , p_receiver;
	end if;

	--
	-- Check that the provider exists
	--
	if not exists (select no_id from sl_node where no_id=
	       	      p_provider) then
		      raise exception 'Slony-I: subscribeSet() provider % does not exist' , p_provider;
	end if;

	
	-- ----
	-- Check that this is called on the origin node
	-- ----
	if p_origin != getLocalNodeId('_schemadoc') then
		raise exception 'Slony-I: subscribeSet() must be called on origin';
	end if;

	-- ---
	-- Verify that the provider is either the origin or an active subscriber
	-- Bug report #1362
	-- ---
	if p_origin <> p_provider then
	   for v_record in select sub1.sub_set from 
		    sl_subscribe sub1			
		    left outer join  (sl_subscribe sub2 
				 inner join
				 sl_set  on (
								sl_set.set_id=sub2.sub_set
								and sub2.sub_set=p_origin)
								)
			ON (  sub1.sub_set = sub2.sub_set and 
                  sub1.sub_receiver = p_provider and
			      sub1.sub_forward and sub1.sub_active
				  and sub2.sub_receiver=p_receiver)
		
			where sub2.sub_set is null 
		loop
				v_missing_sets=v_missing_sets || ' ' || v_record.sub_set;
		end loop;
		if v_missing_sets is not null then
			raise exception 'Slony-I: subscribeSet(): provider % is not an active forwarding node for replication set %', p_sub_provider, v_missing_sets;
		end if;
	end if;

	for v_record in select *  from 
		sl_subscribe, sl_set where 
		sub_set=set_id and
		sub_receiver=p_receiver
		and set_origin=p_origin
	loop
	-- ----
	-- Create the SUBSCRIBE_SET event
	-- ----
	   v_ev_seqno :=  createEvent('_schemadoc', 'SUBSCRIBE_SET', 
				  v_record.sub_set::text, p_provider::text, p_receiver::text, 
				  case v_record.sub_forward when true then 't' else 'f' end,
				  	   'f' );

		-- ----
		-- Call the internal procedure to store the subscription
		-- ----
		perform subscribeSet_int(v_record.sub_set, 
				p_provider,
				p_receiver, v_record.sub_forward, false);
	end loop;

	return v_ev_seqno;	
end;