Skip to content

Commit 7bbded0

Browse files
committed
pgf-3hs.14: Add Condition Fields to FlowShape for Auto-Compilation
1 parent cb18eaf commit 7bbded0

43 files changed

Lines changed: 631 additions & 180 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pkgs/core/schemas/0050_tables_definitions.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ create table pgflow.steps (
2424
opt_base_delay int,
2525
opt_timeout int,
2626
opt_start_delay int,
27-
condition_pattern jsonb, -- JSON pattern for @> containment check (if)
28-
condition_not_pattern jsonb, -- JSON pattern for NOT @> containment check (ifNot)
27+
required_input_pattern jsonb, -- JSON pattern for @> containment check (if)
28+
forbidden_input_pattern jsonb, -- JSON pattern for NOT @> containment check (ifNot)
2929
when_unmet text not null default 'skip', -- What to do when condition not met (skip is natural default)
3030
when_failed text not null default 'fail', -- What to do when handler fails after retries
3131
created_at timestamptz not null default now(),

pkgs/core/schemas/0100_function_add_step.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ create or replace function pgflow.add_step(
77
timeout int default null,
88
start_delay int default null,
99
step_type text default 'single',
10-
condition_pattern jsonb default null,
11-
condition_not_pattern jsonb default null,
10+
required_input_pattern jsonb default null,
11+
forbidden_input_pattern jsonb default null,
1212
when_unmet text default 'skip',
1313
when_failed text default 'fail'
1414
)
@@ -41,7 +41,7 @@ BEGIN
4141
INSERT INTO pgflow.steps (
4242
flow_slug, step_slug, step_type, step_index, deps_count,
4343
opt_max_attempts, opt_base_delay, opt_timeout, opt_start_delay,
44-
condition_pattern, condition_not_pattern, when_unmet, when_failed
44+
required_input_pattern, forbidden_input_pattern, when_unmet, when_failed
4545
)
4646
VALUES (
4747
add_step.flow_slug,
@@ -53,8 +53,8 @@ BEGIN
5353
add_step.base_delay,
5454
add_step.timeout,
5555
add_step.start_delay,
56-
add_step.condition_pattern,
57-
add_step.condition_not_pattern,
56+
add_step.required_input_pattern,
57+
add_step.forbidden_input_pattern,
5858
add_step.when_unmet,
5959
add_step.when_failed
6060
)

pkgs/core/schemas/0100_function_cascade_resolve_conditions.sql

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ BEGIN
4747
-- ==========================================
4848
-- Find first step (by topological order) with unmet condition and 'fail' mode.
4949
-- Condition is unmet when:
50-
-- (condition_pattern is set AND input does NOT contain it) OR
51-
-- (condition_not_pattern is set AND input DOES contain it)
50+
-- (required_input_pattern is set AND input does NOT contain it) OR
51+
-- (forbidden_input_pattern is set AND input DOES contain it)
5252
WITH steps_with_conditions AS (
5353
SELECT
5454
step_state.flow_slug,
5555
step_state.step_slug,
56-
step.condition_pattern,
57-
step.condition_not_pattern,
56+
step.required_input_pattern,
57+
step.forbidden_input_pattern,
5858
step.when_unmet,
5959
step.deps_count,
6060
step.step_index
@@ -65,7 +65,7 @@ BEGIN
6565
WHERE step_state.run_id = cascade_resolve_conditions.run_id
6666
AND step_state.status = 'created'
6767
AND step_state.remaining_deps = 0
68-
AND (step.condition_pattern IS NOT NULL OR step.condition_not_pattern IS NOT NULL)
68+
AND (step.required_input_pattern IS NOT NULL OR step.forbidden_input_pattern IS NOT NULL)
6969
),
7070
step_deps_output AS (
7171
SELECT
@@ -84,16 +84,16 @@ BEGIN
8484
SELECT
8585
swc.*,
8686
-- condition_met = (if IS NULL OR input @> if) AND (ifNot IS NULL OR NOT(input @> ifNot))
87-
(swc.condition_pattern IS NULL OR
88-
CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.condition_pattern)
87+
(swc.required_input_pattern IS NULL OR
88+
CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.required_input_pattern)
8989
AND
90-
(swc.condition_not_pattern IS NULL OR
91-
NOT (CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.condition_not_pattern))
90+
(swc.forbidden_input_pattern IS NULL OR
91+
NOT (CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.forbidden_input_pattern))
9292
AS condition_met
9393
FROM steps_with_conditions swc
9494
LEFT JOIN step_deps_output sdo ON sdo.step_slug = swc.step_slug
9595
)
96-
SELECT flow_slug, step_slug, condition_pattern, condition_not_pattern
96+
SELECT flow_slug, step_slug, required_input_pattern, forbidden_input_pattern
9797
INTO v_first_fail
9898
FROM condition_evaluations
9999
WHERE NOT condition_met AND when_unmet = 'fail'
@@ -128,8 +128,8 @@ BEGIN
128128
SELECT
129129
step_state.flow_slug,
130130
step_state.step_slug,
131-
step.condition_pattern,
132-
step.condition_not_pattern,
131+
step.required_input_pattern,
132+
step.forbidden_input_pattern,
133133
step.when_unmet,
134134
step.deps_count,
135135
step.step_index
@@ -140,7 +140,7 @@ BEGIN
140140
WHERE step_state.run_id = cascade_resolve_conditions.run_id
141141
AND step_state.status = 'created'
142142
AND step_state.remaining_deps = 0
143-
AND (step.condition_pattern IS NOT NULL OR step.condition_not_pattern IS NOT NULL)
143+
AND (step.required_input_pattern IS NOT NULL OR step.forbidden_input_pattern IS NOT NULL)
144144
),
145145
step_deps_output AS (
146146
SELECT
@@ -159,11 +159,11 @@ BEGIN
159159
SELECT
160160
swc.*,
161161
-- condition_met = (if IS NULL OR input @> if) AND (ifNot IS NULL OR NOT(input @> ifNot))
162-
(swc.condition_pattern IS NULL OR
163-
CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.condition_pattern)
162+
(swc.required_input_pattern IS NULL OR
163+
CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.required_input_pattern)
164164
AND
165-
(swc.condition_not_pattern IS NULL OR
166-
NOT (CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.condition_not_pattern))
165+
(swc.forbidden_input_pattern IS NULL OR
166+
NOT (CASE WHEN swc.deps_count = 0 THEN v_run_input ELSE COALESCE(sdo.deps_output, '{}'::jsonb) END @> swc.forbidden_input_pattern))
167167
AS condition_met
168168
FROM steps_with_conditions swc
169169
LEFT JOIN step_deps_output sdo ON sdo.step_slug = swc.step_slug
@@ -244,15 +244,15 @@ BEGIN
244244
WHERE ready_step.run_id = cascade_resolve_conditions.run_id
245245
AND ready_step.status = 'created'
246246
AND ready_step.remaining_deps = 0
247-
AND (step.condition_pattern IS NOT NULL OR step.condition_not_pattern IS NOT NULL)
247+
AND (step.required_input_pattern IS NOT NULL OR step.forbidden_input_pattern IS NOT NULL)
248248
AND step.when_unmet = 'skip-cascade'
249249
-- Condition is NOT met when: (if fails) OR (ifNot fails)
250250
AND NOT (
251-
(step.condition_pattern IS NULL OR
252-
CASE WHEN step.deps_count = 0 THEN v_run_input ELSE COALESCE(agg_deps.deps_output, '{}'::jsonb) END @> step.condition_pattern)
251+
(step.required_input_pattern IS NULL OR
252+
CASE WHEN step.deps_count = 0 THEN v_run_input ELSE COALESCE(agg_deps.deps_output, '{}'::jsonb) END @> step.required_input_pattern)
253253
AND
254-
(step.condition_not_pattern IS NULL OR
255-
NOT (CASE WHEN step.deps_count = 0 THEN v_run_input ELSE COALESCE(agg_deps.deps_output, '{}'::jsonb) END @> step.condition_not_pattern))
254+
(step.forbidden_input_pattern IS NULL OR
255+
NOT (CASE WHEN step.deps_count = 0 THEN v_run_input ELSE COALESCE(agg_deps.deps_output, '{}'::jsonb) END @> step.forbidden_input_pattern))
256256
)
257257
ORDER BY step.step_index;
258258

pkgs/core/schemas/0100_function_compare_flow_shapes.sql

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,34 @@ BEGIN
133133
)
134134
);
135135
END IF;
136+
137+
-- Compare requiredInputPattern (structural - affects DAG execution semantics)
138+
-- Uses -> (jsonb) not ->> (text) to properly compare wrapper objects
139+
IF v_local_step->'requiredInputPattern' IS DISTINCT FROM v_db_step->'requiredInputPattern' THEN
140+
v_differences := array_append(
141+
v_differences,
142+
format(
143+
$$Step at index %s: requiredInputPattern differs '%s' vs '%s'$$,
144+
v_idx,
145+
v_local_step->'requiredInputPattern',
146+
v_db_step->'requiredInputPattern'
147+
)
148+
);
149+
END IF;
150+
151+
-- Compare forbiddenInputPattern (structural - affects DAG execution semantics)
152+
-- Uses -> (jsonb) not ->> (text) to properly compare wrapper objects
153+
IF v_local_step->'forbiddenInputPattern' IS DISTINCT FROM v_db_step->'forbiddenInputPattern' THEN
154+
v_differences := array_append(
155+
v_differences,
156+
format(
157+
$$Step at index %s: forbiddenInputPattern differs '%s' vs '%s'$$,
158+
v_idx,
159+
v_local_step->'forbiddenInputPattern',
160+
v_db_step->'forbiddenInputPattern'
161+
)
162+
);
163+
END IF;
136164
END IF;
137165
END LOOP;
138166

pkgs/core/schemas/0100_function_create_flow_from_shape.sql

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,17 @@ BEGIN
4949
start_delay => (v_step_options->>'startDelay')::int,
5050
step_type => v_step->>'stepType',
5151
when_unmet => v_step->>'whenUnmet',
52-
when_failed => v_step->>'whenFailed'
52+
when_failed => v_step->>'whenFailed',
53+
required_input_pattern => CASE
54+
WHEN (v_step->'requiredInputPattern'->>'defined')::boolean
55+
THEN v_step->'requiredInputPattern'->'value'
56+
ELSE NULL
57+
END,
58+
forbidden_input_pattern => CASE
59+
WHEN (v_step->'forbiddenInputPattern'->>'defined')::boolean
60+
THEN v_step->'forbiddenInputPattern'->'value'
61+
ELSE NULL
62+
END
5363
);
5464
END LOOP;
5565
END;

pkgs/core/schemas/0100_function_get_flow_shape.sql

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,17 @@ as $$
2424
'[]'::jsonb
2525
),
2626
'whenUnmet', step.when_unmet,
27-
'whenFailed', step.when_failed
27+
'whenFailed', step.when_failed,
28+
'requiredInputPattern', CASE
29+
WHEN step.required_input_pattern IS NULL
30+
THEN '{"defined": false}'::jsonb
31+
ELSE jsonb_build_object('defined', true, 'value', step.required_input_pattern)
32+
END,
33+
'forbiddenInputPattern', CASE
34+
WHEN step.forbidden_input_pattern IS NULL
35+
THEN '{"defined": false}'::jsonb
36+
ELSE jsonb_build_object('defined', true, 'value', step.forbidden_input_pattern)
37+
END
2838
)
2939
ORDER BY step.step_index
3040
),

pkgs/core/src/database-types.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,47 +278,47 @@ export type Database = {
278278
}
279279
steps: {
280280
Row: {
281-
condition_not_pattern: Json | null
282-
condition_pattern: Json | null
283281
created_at: string
284282
deps_count: number
285283
flow_slug: string
284+
forbidden_input_pattern: Json | null
286285
opt_base_delay: number | null
287286
opt_max_attempts: number | null
288287
opt_start_delay: number | null
289288
opt_timeout: number | null
289+
required_input_pattern: Json | null
290290
step_index: number
291291
step_slug: string
292292
step_type: string
293293
when_failed: string
294294
when_unmet: string
295295
}
296296
Insert: {
297-
condition_not_pattern?: Json | null
298-
condition_pattern?: Json | null
299297
created_at?: string
300298
deps_count?: number
301299
flow_slug: string
300+
forbidden_input_pattern?: Json | null
302301
opt_base_delay?: number | null
303302
opt_max_attempts?: number | null
304303
opt_start_delay?: number | null
305304
opt_timeout?: number | null
305+
required_input_pattern?: Json | null
306306
step_index?: number
307307
step_slug: string
308308
step_type?: string
309309
when_failed?: string
310310
when_unmet?: string
311311
}
312312
Update: {
313-
condition_not_pattern?: Json | null
314-
condition_pattern?: Json | null
315313
created_at?: string
316314
deps_count?: number
317315
flow_slug?: string
316+
forbidden_input_pattern?: Json | null
318317
opt_base_delay?: number | null
319318
opt_max_attempts?: number | null
320319
opt_start_delay?: number | null
321320
opt_timeout?: number | null
321+
required_input_pattern?: Json | null
322322
step_index?: number
323323
step_slug?: string
324324
step_type?: string
@@ -413,11 +413,11 @@ export type Database = {
413413
add_step: {
414414
Args: {
415415
base_delay?: number
416-
condition_not_pattern?: Json
417-
condition_pattern?: Json
418416
deps_slugs?: string[]
419417
flow_slug: string
418+
forbidden_input_pattern?: Json
420419
max_attempts?: number
420+
required_input_pattern?: Json
421421
start_delay?: number
422422
step_slug: string
423423
step_type?: string
@@ -426,15 +426,15 @@ export type Database = {
426426
when_unmet?: string
427427
}
428428
Returns: {
429-
condition_not_pattern: Json | null
430-
condition_pattern: Json | null
431429
created_at: string
432430
deps_count: number
433431
flow_slug: string
432+
forbidden_input_pattern: Json | null
434433
opt_base_delay: number | null
435434
opt_max_attempts: number | null
436435
opt_start_delay: number | null
437436
opt_timeout: number | null
437+
required_input_pattern: Json | null
438438
step_index: number
439439
step_slug: string
440440
step_type: string

0 commit comments

Comments
 (0)