DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`zone_getLeaves`(
	vSelf INT,
	vParentFk INT,
	vSearch VARCHAR(255),
	vHasInsert BOOL
)
BEGIN 
/**
 * Devuelve las ubicaciones incluidas en la ruta y que sean hijos de parentFk.
 * @param vSelf Id de la zona
 * @param vParentFk Id del geo a calcular
 * @param vSearch Cadena a buscar
 * @param vHasInsert Indica si inserta en tmp.zoneNodes
 * Optional @table tmp.zoneNodes(geoFk, name, parentFk, sons, isChecked, zoneFk)
 */
	DECLARE vIsNumber BOOL;
	DECLARE vIsSearch BOOL DEFAULT vSearch IS NOT NULL AND vSearch <> '';

	CREATE OR REPLACE TEMPORARY TABLE tNodes
		(UNIQUE (id))
		ENGINE = MEMORY
		SELECT id 
			FROM zoneGeo 
			LIMIT 0;

	IF vIsSearch THEN
		SET vIsNumber = vSearch REGEXP '^[0-9]+$';
	
		INSERT INTO tNodes
			SELECT id 
				FROM zoneGeo
				WHERE (vIsNumber AND `name` = vSearch)
					OR (!vIsNumber AND `name` LIKE CONCAT('%', vSearch, '%'))
				LIMIT 1000;
			
	ELSEIF vParentFk IS NULL THEN
		INSERT INTO tNodes
			SELECT geoFk 
				FROM zoneIncluded
				WHERE zoneFk = vSelf;
	END IF;

	IF vParentFk IS NULL THEN
		CREATE OR REPLACE TEMPORARY TABLE tChilds
			(INDEX(id))
			ENGINE = MEMORY
			SELECT id FROM tNodes;

		CREATE OR REPLACE TEMPORARY TABLE tParents
			(INDEX(id))
			ENGINE = MEMORY
			SELECT id FROM zoneGeo LIMIT 0;

		myLoop: LOOP
			DELETE FROM tParents;
			INSERT INTO tParents
				SELECT parentFk id
					FROM zoneGeo g
						JOIN tChilds c ON c.id = g.id
					WHERE  g.parentFk IS NOT NULL;
			
			INSERT IGNORE INTO tNodes
				SELECT id FROM tParents;
			
			IF NOT ROW_COUNT() THEN
				LEAVE myLoop;
			END IF;
			
			DELETE FROM tChilds;
			INSERT INTO tChilds
				SELECT id FROM tParents;
		END LOOP;
		
		DROP TEMPORARY TABLE tChilds, tParents;
	END IF;

	IF NOT vIsSearch THEN
		INSERT IGNORE INTO tNodes
			SELECT id 
				FROM zoneGeo
				WHERE parentFk <=> vParentFk;
	END IF;

	CREATE OR REPLACE TEMPORARY TABLE tZones
		SELECT g.id,
				g.name,
				g.parentFk,
				g.sons,
				NOT g.sons OR `type` = 'country' isChecked,
				i.isIncluded selected,
				g.`depth`,
				vSelf
			FROM zoneGeo g
				JOIN tNodes n ON n.id = g.id
				LEFT JOIN zoneIncluded i ON i.geoFk = g.id
					AND i.zoneFk = vSelf
			ORDER BY g.`depth`, selected DESC, g.name;

	IF vHasInsert THEN
		INSERT IGNORE INTO tmp.zoneNodes(geoFk, name, parentFk, sons, isChecked, zoneFk)
			SELECT id,
					name,
					parentFk,
					sons,
					isChecked,
					vSelf
				FROM tZones
				WHERE selected
					OR (selected IS NULL AND vParentFk IS NOT NULL);
	ELSE
		SELECT id,
				name,
				parentFk,
				sons,
				selected
			FROM tZones
			ORDER BY `depth`, selected DESC, name;
	END IF;

	DROP TEMPORARY TABLE tNodes, tZones;
END$$
DELIMITER ;