DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn2008`.`nest_move`(
	 vTable VARCHAR(45)
	,idNODE INT
	,idFATHER INT
)
BEGIN
	DECLARE myRight INT;
	DECLARE myLeft INT;
	DECLARE myWidth INT;
	DECLARE fatherRight INT;
	DECLARE fatherLeft INT;
	DECLARE gap INT;
    
	SET vTable = util.quoteIdentifier(vTable);

	DROP TEMPORARY TABLE IF EXISTS aux;
	CREATE TEMPORARY TABLE aux
		SELECT 0 as rgt, 0 as lft, 0 as wdt, 0 as frg, 0 as flf;

	-- Averiguamos el ancho de la rama
	EXECUTE IMMEDIATE CONCAT(
		'UPDATE aux a
				JOIN ', vTable, ' t 
			SET a.wdt = t.rgt - t.lft + 1
			WHERE t.id = ?')
		USING idNODE;

	-- Averiguamos la posicion del nuevo padre
	EXECUTE IMMEDIATE CONCAT(
		'UPDATE aux a
				JOIN ', vTable, ' t 
			SET a.frg = t.rgt,
				a.flf = t.lft
			WHERE t.id = ?')
		USING idFATHER;

	SELECT wdt, frg, flf INTO  myWidth, fatherRight, fatherLeft 
		FROM aux;

	-- 1º Incrementamos los valores de todos los nodos a la derecha del punto de inserción (fatherRight) , para hacer sitio
	EXECUTE IMMEDIATE CONCAT(
		'UPDATE ', vTable,  
			'SET rgt = rgt + ?
			WHERE rgt >= ? 
			ORDER BY rgt DESC')
		USING myWidth,
			fatherRight;

	EXECUTE IMMEDIATE CONCAT(
		'UPDATE ', vTable,  
			'SET lft = lft + ?
			WHERE lft >= ? 
			ORDER BY lft DESC')
		USING myWidth,
			fatherRight;

	-- Es preciso recalcular los valores del nodo en el caso de que estuviera a la derecha del nuevo padre
	EXECUTE IMMEDIATE CONCAT(
		'UPDATE aux a
				JOIN ', vTable, ' t 
			SET a.rgt = t.rgt, 
				a.lft = t.lft 
			WHERE t.id = ?')
		USING idNODE;

	SELECT lft, rgt, frg - lft INTO  myLeft, myRight, gap 
		FROM aux;

	-- 2º Incrementamos el valor de todos los nodos a trasladar hasta alcanzar su nueva posicion
	EXECUTE IMMEDIATE CONCAT(
		'UPDATE ', vTable,  
			'SET lft = lft + ?
			WHERE lft BETWEEN ? AND ?
			ORDER BY lft DESC')
		USING gap,
			myLeft,
			myRight;

	EXECUTE IMMEDIATE CONCAT(
		'UPDATE ', vTable,  
			'SET rgt = rgt + ?
			WHERE rgt BETWEEN ? AND ?
			ORDER BY rgt DESC')
		USING gap,
			myLeft,
			myRight;

	-- 3º Restaremos a todos los nodos resultantes, a la derecha de la posicion arrancada el ancho de la rama escindida
	EXECUTE IMMEDIATE CONCAT(
		'UPDATE ', vTable,  
			'SET lft = lft - ?
			WHERE lft > ?
			ORDER BY lft')
		USING myWidth,
			myLeft;

	EXECUTE IMMEDIATE CONCAT(
		'UPDATE ', vTable,  
			'SET rgt = rgt - ?
			WHERE rgt > ?
			ORDER BY rgt')
		USING myWidth,
			myRight;

	DROP TEMPORARY TABLE aux;
END$$
DELIMITER ;
