Определение шаблонов ветвления с помощью выражений CTE в Postgresql - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь пройти несколько ветвей рабочего процесса, чтобы определить следующий набор выполнений.Возьмем рабочий процесс ниже:

Изображение: пример рабочего процесса

Каждый блок представляет задачу с условием (ями), объединяющими задачи.У меня есть следующие таблицы / материализованные представления (упрощенно для этого поста):

Задачи :

  • Описание: Содержит информацию о различных задачах.
  • Схема: идентификатор, имя, идентификатор рабочего потока

Условия :

  • Описание: Содержит блок кода для принятия решения.
  • Схема: id, name, workflow_id

Ссылки :

  • Описание: Соединение между двумя объектами для формирования рабочего процесса.
  • Схема: предыдущий_идентификатор, предыдущий_тип, следующий_идентификатор, следующий_тип
  • Примечания. Типом может быть Задача или Условие

Выполнения :

  • Описание: выполнение задачи или условия.
  • Схема: id, reference_id, reference_type, parent_id, status
  • Примечания: ссылка может быть либо задачей, либо условием.Parent_id будет нулевым для первого выполнения в дереве.

Ограничения:

  1. Все соединительные ссылки на Задачу должны быть выполнены до выполнения текущих Задач.выполнение, если не произошел дальнейший сбой в рабочем процессе.
  2. Задача может быть выполнена, если одна ссылка была успешной, однако перед выполнением должны быть предприняты все ссылки.
  3. Нет возможностей в памяти во время выполнения рабочих процессов, поэтому операции должны определяться с учетом одной позиции Задача / Выполнение.

Так что теперь у меня есть две похожие проблемы:

A) Перед выполнением задачи она должна пройти назад по ссылкам, чтобы определить, нужно ли: а) дождаться завершения другой ссылки / задачи или;б) определить, все ли ссылки / задачи выполнены, и хотя бы одна ссылка была успешной. Ожидаемое значение: логическое значение, если разрешено выполнение.

Пример T1, T2, T3, T4 все успешно выполнены.T4 пытается выполнить T6, но выполнение T6 должно ждать выполнения T5.Кроме того, T2 попытается выполнить T5, но должен дождаться выполнения T3.

B) После того, как задача не выполнена, она должна перейти по ссылкам, чтобы определить, ожидали ли какие-либо задачи, с которыми она связана, ожиданиеего исполнение.Если эта задача находилась на рассмотрении и имеет хотя бы одну успешную ссылку, она может быть выполнена. Ожидаемые значения: идентификатор задачи, требующий выполнения.

Пример T1, T2, T3, T4 все успешно выполнены.T6 ожидает выполнения T5, но не удается.Учитывая, что T4 успешно выполнен, теперь он должен планировать выполнение T6, потому что присутствует одна успешная ссылка.


Я попытался решить проблему с CTE.Моя главная проблема в том, что я не могу группировать по соответствующим ссылкам, которые делают ветку для определения статуса.Пока я работаю со следующим:

WITH RECURSIVE
items(id, name) AS 
(
	SELECT t.id, t.name FROM tasks t
	UNION ALL
	SELECT c.id, c.name FROM conditions c
),
execution_tree(id, reference_id, reference_type, status) AS (
	SELECT e.id, e.reference_id, e.reference_type, e.status FROM executions e WHERE id = '1bb17c35-643a-4351-a163-c2c6b23b2343' --id or top most execution
	UNION ALL
	SELECT e.id, e.reference_id, e.reference_type, e.status FROM execution_tree t, executions e where e.parent_id = t.id
),
branches(id, type, name, status, branch) AS
(
	SELECT c.previous_id, c.previous_type, i.name, e.status, i.name AS branch FROM links c
	LEFT OUTER JOIN execution_tree e ON c.previous_id = e.reference_id AND c.previous_type = e.reference_type
	JOIN items i ON c.previous_id = i.id
	WHERE c.next_id = '32dd1211-3cc0-4bde-9481-35a804b5bbff' --reference_id of item to work backwards from
	UNION ALL
	SELECT c.previous_id, c.previous_type, i.name, e.status, b.branch || '  ->  ' || i.name AS branch FROM branches b, links c 
	LEFT OUTER JOIN execution_tree e ON c.previous_id = e.reference_id AND c.previous_type = e.reference_type
	JOIN items i ON c.previous_id = i.id
	WHERE c.next_id = b.id
)
SELECT *
FROM branches b

Это приводит к следующему:

|                  id                  |   type    |     name      | status  |                                    branch                                    
+--------------------------------------+--------------------------+---------------+---------+------------------------------------------------------------------------------
| 38ba778b-b18f-4991-98d3-bb8fd8736eeb | Condition | C_T5>T6       |         | C_T5>T6
| ad89a47c-bd80-4ba5-aa63-c7b36daf6efd | Condition | C_T4>T6       |         | C_T4>T6
| ccfbbaae-1835-482f-9b20-4e20e46c9207 | Task      | T4            | passed  | C_T4>T6  ->  T4
| 338ee869-89f2-4485-82f7-220898914225 | Task      | T5            | passed  | C_T5>T6  ->  T5
| 338ee869-89f2-4485-82f7-220898914225 | Task      | T5            | passed  | C_T5>T6  ->  T5
| 3868c2d6-2bc4-4817-a11b-8aa16f310584 | Condition | C_T1>T4       | passed  | C_T4>T6  ->  T4  ->  C_T1>T4
| 6e5ba531-8c6a-47b4-bde5-fbd86da74b72 | Condition | C_T2>T5       | passed  | C_T5>T6  ->  T5  ->  C_T2>T5
| 6e5ba531-8c6a-47b4-bde5-fbd86da74b72 | Condition | C_T2>T5       | passed  | C_T5>T6  ->  T5  ->  C_T2>T5
| 89dde639-99de-4770-ae10-160e208f3f71 | Condition | C_T3>T5       | passed  | C_T5>T6  ->  T5  ->  C_T3>T5
| 89dde639-99de-4770-ae10-160e208f3f71 | Condition | C_T3>T5       | passed  | C_T5>T6  ->  T5  ->  C_T3>T5
| 58bdcd73-d1fe-4dab-86c8-8039ab9305e9 | Task      | T1            | passed  | C_T4>T6  ->  T4  ->  C_T1>T4  ->  T1
| e83d595f-46a0-4f54-90bf-ba32e6b79d75 | Task      | T2            | passed  | C_T5>T6  ->  T5  ->  C_T2>T5  ->  T2
| e83d595f-46a0-4f54-90bf-ba32e6b79d75 | Task      | T2            | passed  | C_T5>T6  ->  T5  ->  C_T2>T5  ->  T2
| f918e0ea-d7e3-4f7e-8a93-ceb5403b454c | Task      | T3            | passed  | C_T5>T6  ->  T5  ->  C_T3>T5  ->  T3
| f918e0ea-d7e3-4f7e-8a93-ceb5403b454c | Task      | T3            | passed  | C_T5>T6  ->  T5  ->  C_T3>T5  ->  T3
| db49c261-7e0a-44a1-808d-bdb31f217439 | Condition | C_T1>T2       | passed  | C_T5>T6  ->  T5  ->  C_T2>T5  ->  T2  ->  C_T1>T2
| db49c261-7e0a-44a1-808d-bdb31f217439 | Condition | C_T1>T2       | passed  | C_T5>T6  ->  T5  ->  C_T2>T5  ->  T2  ->  C_T1>T2
| 7709eb61-4349-47ee-b206-a71b8f290e0f | Condition | C_T1>T3       | passed  | C_T5>T6  ->  T5  ->  C_T3>T5  ->  T3  ->  C_T1>T3
| 7709eb61-4349-47ee-b206-a71b8f290e0f | Condition | C_T1>T3       | passed  | C_T5>T6  ->  T5  ->  C_T3>T5  ->  T3  ->  C_T1>T3
| 58bdcd73-d1fe-4dab-86c8-8039ab9305e9 | Task      | T1            | passed  | C_T5>T6  ->  T5  ->  C_T3>T5  ->  T3  ->  C_T1>T3  ->  T1
| 58bdcd73-d1fe-4dab-86c8-8039ab9305e9 | Task      | T1            | passed  | C_T5>T6  ->  T5  ->  C_T3>T5  ->  T3  ->  C_T1>T3  ->  T1
| 58bdcd73-d1fe-4dab-86c8-8039ab9305e9 | Task      | T1            | passed  | C_T5>T6  ->  T5  ->  C_T2>T5  ->  T2  ->  C_T1>T2  ->  T1
| 58bdcd73-d1fe-4dab-86c8-8039ab9305e9 | Task      | T1            | passed  | C_T5>T6  ->  T5  ->  C_T2>T5  ->  T2  ->  C_T1>T2  ->  T1

В приведенном выше наборе результатов вы заметите, что T5 выполнялся дважды.Это неверно, так как код еще не учитывает проблему А.

Разве CTE здесь не подходит?Нужно ли мне создать функцию?Цени любую помощь.

...