
DROP procedure IF EXISTS `vn`.`zone_getLeaves`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zone_getLeaves`(
	vSelf INT,
    vParentFk INT,
    vSearch VARCHAR(255)
)
BEGIN 
	DECLARE vIsNumber BOOL;
	DECLARE vIsSearch BOOL DEFAULT vSearch IS NOT NULL AND vSearch != '';

	DROP TEMPORARY TABLE IF EXISTS tNodes;
	CREATE 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
		DROP TEMPORARY TABLE IF EXISTS tChilds;
		CREATE TEMPORARY TABLE tChilds
			ENGINE = MEMORY
			SELECT id FROM tNodes;

		DROP TEMPORARY TABLE IF EXISTS tParents;
		CREATE TEMPORARY TABLE tParents
			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 ROW_COUNT() = 0 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 !vIsSearch THEN
		INSERT IGNORE INTO tNodes
			SELECT id FROM zoneGeo
				WHERE parentFk <=> vParentFk;
	END IF;

	SELECT g.id,
			g.`name`,
			g.parentFk,
			g.sons,
			isIncluded selected
		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 depth, selected DESC, `name`;

	DROP TEMPORARY TABLE tNodes;
END$$
DELIMITER ;
