MT#58709 address update_sound_set_handle_parents() sp deadlocks

* update_sound_set_handle_parents() procedure is redesigned
  to avoid "insert into select from" statements as they cause
  gap locks when run concurrently and access the same index
  rows.

*** WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6594 page no 6 n bits 56 index parent_id_idx
of table `provisioning`.`voip_sound_sets` trx id 400852
lock mode S locks rec but not gap waiting

  the "insert into select from" statements are reworked:
   the "select from/with recursive" parts are now declared cursors
   and the data is inserted inside the opened cursor loop (if any).
   this way the selects are not causing exclusive gap locks.

(cherry picked from commit 4017d3519c)
(cherry picked from commit 9c0fd6e4a1889ddbcbb3a90521dd3e2d3bfe73a5)

Change-Id: I35ec28a33ecca42de898e67a2709eda4364e5f95
mr11.4
Kirill Solomko 3 years ago committed by Sipwise Jenkins Builder
parent 204d575941
commit 907d4d4424

@ -0,0 +1,190 @@
USE provisioning;
DELIMITER ;;
CREATE OR REPLACE PROCEDURE update_sound_set_handle_parents(IN u_sound_set_id INT, IN u_handle_id INT)
BEGIN
IF u_sound_set_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id = u_sound_set_id
AND NOT EXISTS (SELECT id
FROM voip_sound_sets
WHERE id = u_sound_set_id);
IF u_handle_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id IN (
WITH RECURSIVE cte as (
SELECT s.id
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id
FROM voip_sound_sets s
JOIN cte ON cte.id = s.parent_id
)
SELECT id
FROM cte
)
AND handle_id = u_handle_id;
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
AND v.handle_id = u_handle_id
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
ELSE
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id IN (
WITH RECURSIVE cte as (
SELECT s.id
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id
FROM voip_sound_sets s
JOIN cte ON cte.id = s.parent_id
)
SELECT id
FROM cte
);
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
END IF;
ELSE
IF u_handle_id IS NOT NULL THEN
DELETE FROM voip_sound_set_handle_parents WHERE handle_id = u_handle_id;
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.parent_id IS NULL
AND v.handle_id = u_handle_id
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte;
ELSE
DELETE FROM voip_sound_set_handle_parents;
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.parent_id IS NULL
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte;
END IF;
END IF;
END ;;
DELIMITER ;

@ -0,0 +1,265 @@
USE provisioning;
DELIMITER ;;
CREATE OR REPLACE PROCEDURE update_sound_set_handle_parents(IN u_sound_set_id INT, IN u_handle_id INT)
BEGIN
/* declare */
DECLARE done INT DEFAULT FALSE;
DECLARE x_set_id INT DEFAULT 0;
DECLARE x_handle_id INT DEFAULT 0;
DECLARE x_parent_set_id INT DEFAULT NULL;
DECLARE x_parent_chain VARCHAR(255) DEFAULT '';
/* u_sound_set_id and u_handle_id */
DECLARE x_sound_set_handle CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
AND v.handle_id = u_handle_id
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
/* u_sound_set_id */
DECLARE x_sound_set CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
/* u_handle_id */
DECLARE x_handle CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.parent_id IS NULL
AND v.handle_id = u_handle_id
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte;
/* none */
DECLARE x CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.parent_id IS NULL
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
/* code */
IF u_sound_set_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id = u_sound_set_id
AND NOT EXISTS (SELECT id
FROM voip_sound_sets
WHERE id = u_sound_set_id);
IF u_handle_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id IN (
WITH RECURSIVE cte as (
SELECT s.id
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id
FROM voip_sound_sets s
JOIN cte ON cte.id = s.parent_id
)
SELECT id
FROM cte
)
AND handle_id = u_handle_id;
OPEN x_sound_set_handle;
iter: LOOP
FETCH x_sound_set_handle INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x_sound_set_handle;
ELSE
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id IN (
WITH RECURSIVE cte as (
SELECT s.id
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id
FROM voip_sound_sets s
JOIN cte ON cte.id = s.parent_id
)
SELECT id
FROM cte
);
OPEN x_sound_set;
iter: LOOP
FETCH x_sound_set INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x_sound_set;
END IF;
ELSE
IF u_handle_id IS NOT NULL THEN
DELETE FROM voip_sound_set_handle_parents WHERE handle_id = u_handle_id;
OPEN x_handle;
iter: LOOP
FETCH x_handle INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x_handle;
ELSE
DELETE FROM voip_sound_set_handle_parents;
OPEN x;
iter: LOOP
FETCH x INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x;
END IF;
END IF;
END ;;
DELIMITER ;

@ -1069,7 +1069,7 @@ INSERT INTO `dom_preferences` VALUES (27,'','0','voip.sipwise.local','play_annou
INSERT INTO `dom_preferences` VALUES (28,'','0','voip.sipwise.local','mobile_push_enable',0,'never',NOW());
INSERT INTO `dom_preferences` VALUES (29,'','0','voip.sipwise.local','busy_hg_member_mode',0,'ring',NOW());
INSERT INTO `domain` VALUES (1,'voip.sipwise.local',NOW(),NULL);
INSERT INTO `subscriber` VALUES (1,'no_such_number','voip.sipwise.local','26d1f10fb754a3bb642439f12f839bc2','2661665476becee59a5c1d1a87a69709','467730a435b456bc53c1e18f84b9e8cf','9bcb88b6-541a-43da-8fdc-816f5557ff93','',NOW());
INSERT INTO `subscriber` VALUES (1,'no_such_number','voip.sipwise.local','300fe0133470abbd7fbe99ba24f85aa9','6e177569e4b9ee1d16c595f92185561f','e39aa0e7c1a9dbda4e6322fb84f6f0a4','9bcb88b6-541a-43da-8fdc-816f5557ff93','',NOW());
INSERT INTO `usr_preferences` VALUES (1,'9bcb88b6-541a-43da-8fdc-816f5557ff93','no_such_number','voip.sipwise.local','cloud_pbx_hunt_policy',0,'none',NOW());
INSERT INTO `usr_preferences` VALUES (5,'9bcb88b6-541a-43da-8fdc-816f5557ff93','no_such_number','voip.sipwise.local','emergency_location_format',0,'cirpack',NOW());
INSERT INTO `usr_preferences` VALUES (6,'9bcb88b6-541a-43da-8fdc-816f5557ff93','no_such_number','voip.sipwise.local','play_announce_before_recording',0,'never',NOW());

@ -20,7 +20,7 @@ CREATE TABLE `db_schema` (
`applied_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `rev_idx` (`revision`,`node`)
) ENGINE=InnoDB AUTO_INCREMENT=844 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
) ENGINE=InnoDB AUTO_INCREMENT=845 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
@ -30886,6 +30886,7 @@ INSERT INTO `db_schema` VALUES (840,15772,'spce',NOW());
INSERT INTO `db_schema` VALUES (841,15773,'spce',NOW());
INSERT INTO `db_schema` VALUES (842,15775,'spce',NOW());
INSERT INTO `db_schema` VALUES (843,15790,'spce',NOW());
INSERT INTO `db_schema` VALUES (844,15795,'spce',NOW());
INSERT INTO `timezone` VALUES ('1','localtime',NOW(),NOW(),NULL);
INSERT INTO `tzinfo_version` VALUES ('1','0',NOW(),NOW());
COMMIT;

File diff suppressed because one or more lines are too long

@ -1985,71 +1985,199 @@ DELIMITER ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `update_sound_set_handle_parents`(IN u_sound_set_id INT, IN u_handle_id INT)
BEGIN
IF u_sound_set_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id = u_sound_set_id
AND NOT EXISTS (SELECT id
FROM voip_sound_sets
WHERE id = u_sound_set_id);
DECLARE done INT DEFAULT FALSE;
IF u_handle_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id IN (
DECLARE x_set_id INT DEFAULT 0;
DECLARE x_handle_id INT DEFAULT 0;
DECLARE x_parent_set_id INT DEFAULT NULL;
DECLARE x_parent_chain VARCHAR(255) DEFAULT '';
DECLARE x_sound_set_handle CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.id = s.parent_id
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
AND handle_id = u_handle_id;
AND v.handle_id = u_handle_id
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
DECLARE x_sound_set CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
DECLARE x_handle CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
WHERE v.parent_id IS NULL
AND v.handle_id = u_handle_id
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte;
DECLARE x CURSOR FOR
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.parent_id IS NULL
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as parent_set_id,
parent_chain
FROM cte;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
IF u_sound_set_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id = u_sound_set_id
AND NOT EXISTS (SELECT id
FROM voip_sound_sets
WHERE id = u_sound_set_id);
IF u_handle_id IS NOT NULL THEN
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id IN (
WITH RECURSIVE cte as (
SELECT s.id
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id
FROM voip_sound_sets s
JOIN cte ON cte.id = s.parent_id
)
SELECT id
FROM cte
)
AND handle_id = u_handle_id;
OPEN x_sound_set_handle;
iter: LOOP
FETCH x_sound_set_handle INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x_sound_set_handle;
ELSE
DELETE p FROM voip_sound_set_handle_parents p
WHERE set_id IN (
@ -2066,103 +2194,50 @@ BEGIN
FROM cte
);
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain,
CAST(0 as unsigned) AS affected
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.id = (
WITH RECURSIVE cte as (
SELECT s.id, s.parent_id, CAST(0 as unsigned) as iter
FROM voip_sound_sets s
WHERE id = u_sound_set_id
UNION
SELECT s.id, s.parent_id, iter+1 as iter
FROM voip_sound_sets s
JOIN cte ON cte.parent_id = s.id
)
SELECT id
FROM cte
WHERE iter = (SELECT max(iter) from cte)
)
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain,
IF(v.id = u_sound_set_id OR v.parent_id = u_sound_set_id OR affected = 1, 1, 0)
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte
WHERE set_id = u_sound_set_id OR affected = 1;
OPEN x_sound_set;
iter: LOOP
FETCH x_sound_set INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x_sound_set;
END IF;
ELSE
IF u_handle_id IS NOT NULL THEN
DELETE FROM voip_sound_set_handle_parents WHERE handle_id = u_handle_id;
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.parent_id IS NULL
AND v.handle_id = u_handle_id
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte;
OPEN x_handle;
iter: LOOP
FETCH x_handle INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x_handle;
ELSE
DELETE FROM voip_sound_set_handle_parents;
INSERT INTO voip_sound_set_handle_parents(set_id, handle_id, parent_set_id, parent_chain)
WITH RECURSIVE cte as (
SELECT v.id AS set_id, v.handle_id,
v.id AS data_set_id,
CAST('' AS CHAR(4096)) AS parent_chain
FROM (SELECT s.*, h.id as handle_id
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
WHERE v.parent_id IS NULL
UNION
SELECT v.id AS set_id, v.handle_id,
IF(f.use_parent = 0, v.id, cte.data_set_id) AS data_set_id,
CONCAT(v.parent_id, IF(LENGTH(cte.parent_chain) > 1, ':', ''), cte.parent_chain) as parent_chain
FROM (SELECT s.*, h.id as handle_id, h.name as handle_name
FROM (voip_sound_sets s, voip_sound_handles h)
) AS v
LEFT JOIN voip_sound_files f ON f.handle_id = v.handle_id AND f.set_id = v.id
JOIN cte ON cte.set_id = v.parent_id AND cte.handle_id = v.handle_id
)
SELECT set_id, handle_id,
IF(data_set_id = set_id, NULL, data_set_id) as data_set_id,
parent_chain
FROM cte;
OPEN x;
iter: LOOP
FETCH x INTO x_set_id, x_handle_id, x_parent_set_id, x_parent_chain;
IF done THEN
LEAVE iter;
END IF;
INSERT INTO voip_sound_set_handle_parents
(set_id, handle_id, parent_set_id, parent_chain)
VALUES
(x_set_id, x_handle_id, x_parent_set_id, x_parent_chain);
END LOOP;
CLOSE x;
END IF;
END IF;
@ -4401,7 +4476,7 @@ INSERT INTO `voip_sound_handles` VALUES (149,'recent_call_deleted',12,1);
INSERT INTO `voip_sound_handles` VALUES (150,'ringback_tone',13,1);
INSERT INTO `voip_sound_handles` VALUES (151,'aa_timeout',2,1);
INSERT INTO `voip_sound_handles` VALUES (152,'aa_default',2,1);
INSERT INTO `voip_subscribers` VALUES (3,'no_such_number',2,'9bcb88b6-541a-43da-8fdc-816f5557ff93','26d1f10fb754a3bb642439f12f839bc2',0,NULL,NULL,NULL,0,0,'none',NULL,NULL,NULL,NULL,NOW(),NOW());
INSERT INTO `voip_subscribers` VALUES (3,'no_such_number',2,'9bcb88b6-541a-43da-8fdc-816f5557ff93','300fe0133470abbd7fbe99ba24f85aa9',0,NULL,NULL,NULL,0,0,'none',NULL,NULL,NULL,NULL,NOW(),NOW());
INSERT INTO `voip_usr_preferences` VALUES (1,3,97,'none',NOW());
INSERT INTO `voip_usr_preferences` VALUES (7,3,372,'cirpack',NOW());
INSERT INTO `voip_usr_preferences` VALUES (8,3,305,'never',NOW());

Loading…
Cancel
Save