在Postgresql中使用CTE表达式确定分支模式

时间:2018-11-30 05:26:14

标签: postgresql tree workflow common-table-expression

我正在尝试遍历工作流的多个分支以确定下一组执行。请采用以下工作流程:

Image: Workflow example

每个框代表一个任务,条件与任务连接在一起。我有以下表格/实例化视图(本文简化):

任务

  • 说明:包含有关各种任务的信息。
  • 架构:ID,名称,工作流程ID

条件

  • 说明:包含用于决策的代码块。
  • 架构:ID,名称,工作流程ID

链接

  • 描述:两个对象之间的连接以形成工作流程。
  • 架构:previous_id,previous_type,next_id,next_type
  • 注意:类型可以是任务或条件

执行

  • 说明:任务或条件的执行。
  • 架构:id,reference_id,reference_type,parent_id,状态
  • 注意:引用可以是“任务”或“条件”。对于树中的第一次执行,parent_id将为null。

约束:

  1. 除非当前工作流出现故障,否则必须在执行当前任务之前执行到任务的所有连接链接。
  2. 如果单个链接成功,则任务可以执行,但是必须先尝试所有链接,然后才能执行。
  3. 在工作流执行期间没有可用的内存功能,因此必须在单个任务/执行位置下确定操作。

所以现在我有两个类似的问题:

A)在执行任务之前,它必须在链接上向后移动以确定是否必须执行以下操作:a)等待另一个链接/任务完成,或者; b)确定所有其他链接/任务是否都已执行并且至少一个链接成功。 期望值:布尔值(如果有资格执行)。

示例 T1,T2,T3,T4均已成功执行。 T4尝试执行T6,但是T6执行必须等待T5的执行。另外,T2将尝试执行T5,但必须等待T3的执行。

B):任务失败后,它必须向前浏览链接以确定与它链接的任何任务是否正在等待执行。如果该任务尚未完成,并且至少具有一个成功的链接,则可以执行该任务。 期望值:任务ID需要执行。

示例 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执行了两次。这是不正确的,因为代码尚未解决问题A。

这里不能选择CTE吗?我需要创建一个函数吗?感谢提供的任何帮助。

0 个答案:

没有答案