ff_backend_sqlite/queries/signal.rs
1//! SQL statements for signal delivery ops (RFC-023 Phase 2b.2.1).
2//!
3//! Mirrors `ff-backend-postgres/src/signal_event.rs` +
4//! the signal-delivery bodies in `suspend_ops.rs`.
5
6/// Append one signal-delivery event to the outbox.
7///
8/// Binds:
9/// * 1 = execution_uuid stringified — `ff_signal_event.execution_id`
10/// is TEXT (mirrors PG at `ff-backend-postgres/migrations/0007`).
11/// * 2 = signal_id stringified — TEXT column.
12/// * 3 = waitpoint_id stringified (nullable) — TEXT column.
13/// * 4 = source_identity (nullable) — TEXT.
14/// * 5 = delivered_at_ms.
15/// * 6 = partition_key (reused in the `WHERE` clause).
16/// * 7 = execution_uuid as BLOB — `ff_exec_core.execution_id` is
17/// stored as a 16-byte BLOB; the co-transactional SELECT looks it
18/// up by BLOB equality while emitting the TEXT stringification
19/// onto `ff_signal_event`.
20///
21/// The SQLite ff_signal_event table populates `namespace` +
22/// `instance_tag` from `ff_exec_core.raw_fields` via a co-transactional
23/// SELECT — same pattern as the PG reference
24/// (`ff-backend-postgres/src/signal_event.rs:33-49`).
25/// `json_extract` is the SQLite JSON1 analogue of PG's `->>` operator.
26pub const INSERT_SIGNAL_EVENT_SQL: &str = "INSERT INTO ff_signal_event \
27 (execution_id, signal_id, waitpoint_id, source_identity, \
28 delivered_at_ms, partition_key, namespace, instance_tag) \
29 SELECT ?1, ?2, ?3, ?4, ?5, ?6, \
30 json_extract(raw_fields, '$.namespace'), \
31 json_extract(raw_fields, '$.tags.\"cairn.instance_id\"') \
32 FROM ff_exec_core \
33 WHERE partition_key = ?6 AND execution_id = ?7 \
34 UNION ALL \
35 SELECT ?1, ?2, ?3, ?4, ?5, ?6, NULL, NULL \
36 WHERE NOT EXISTS ( \
37 SELECT 1 FROM ff_exec_core \
38 WHERE partition_key = ?6 AND execution_id = ?7 \
39 )";
40
41/// Completion outbox insert for the `resumable` transition when a
42/// signal satisfies a waitpoint. Back-fills `namespace` +
43/// `instance_tag` from `ff_exec_core.raw_fields` via a
44/// co-transactional SELECT so tag-filtered subscribers receive the
45/// event (Phase 3.2 fix — pre-fix both columns landed NULL).
46/// `flow_id` stays NULL here (matches the PG minimal insert shape at
47/// `ff-backend-postgres/src/suspend_ops.rs:845-854`).
48///
49/// Binds: ?1 partition_key, ?2 execution_id (BLOB — reused for the
50/// exec_core lookup), ?3 occurred_at_ms.
51pub const INSERT_COMPLETION_RESUMABLE_SQL: &str = r#"
52 INSERT INTO ff_completion_event
53 (partition_key, execution_id, outcome, occurred_at_ms, namespace, instance_tag)
54 SELECT ?1, ?2, 'resumable', ?3,
55 json_extract(raw_fields, '$.namespace'),
56 json_extract(raw_fields, '$.tags."cairn.instance_id"')
57 FROM ff_exec_core
58 WHERE partition_key = ?1 AND execution_id = ?2
59 UNION ALL
60 SELECT ?1, ?2, 'resumable', ?3, NULL, NULL
61 WHERE NOT EXISTS (
62 SELECT 1 FROM ff_exec_core
63 WHERE partition_key = ?1 AND execution_id = ?2
64 )
65"#;