1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! Per-statement side-channel counters tracked by the document path and read
//! by the executor when emitting [`crate::observe::StatementEvent`]s.
//!
//! The post-RETURN [`crate::val::Value`] is not a reliable source for the
//! number of records affected by a DML statement: `RETURN NONE` causes the
//! iterator to drop every touched document (see `IgnoreError::Ignore` in
//! `crate::dbs::iterator`) so the executor sees an empty array, while
//! `RETURN BEFORE` on a fresh `CREATE` collapses to `Value::None`. To honour
//! the documented contract on
//! [`crate::observe::StatementEventSafe::result_rows`] -- "rows returned
//! (SELECT) or affected (CREATE / UPDATE / UPSERT / DELETE / RELATE / INSERT)"
//! -- the document path increments this counter only after a real KV write
//! has succeeded (`store_record_data` / `purge` set
//! [`crate::doc::Document::mutated`], which is then consumed once per row by
//! [`crate::doc::Document::process`]). The executor reads the snapshot at
//! statement completion.
//!
//! Pre-mutation `IgnoreError::Ignore` paths -- `check_record_exists`,
//! `check_where_condition`, permission gates, `ctx.is_done` short-circuits --
//! and `set_record` no-ops suppressed by `!self.changed()` therefore never
//! inflate the count, even when the visited row would otherwise have been
//! counted by the iterator.
use Arc;
use ;
/// Atomic per-statement counter set, shared between the iterator and the
/// executor for the lifetime of a single top-level statement.
///
/// `Relaxed` ordering is sufficient because the counter is never used to
/// gate other state: the executor only reads it after the statement has
/// returned, by which point all writes to the counter have happened-before
/// the read through the executor's await.
pub