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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! The typed failure channel of the post-EncodingStats SerializationHeader
//! schema decoder.
//!
//! `parse_serialization_header_schema` can fail for two reasons that a caller
//! must NOT treat alike, and a `nom::Err` cannot tell them apart:
//!
//! * The bytes at the TOC-anchored offset do not hold a readable header at all —
//! truncated, mispositioned, an implausible declared length, a non-UTF-8 type
//! name. Retrying with the marker-search decoder is legitimate: it is a second
//! attempt to find WHERE the header is.
//! * The bytes decoded fine and DECLARE a type Cassandra cannot have written (a
//! `frozen<scalar>`; `CQL3Type.Raw::freeze()` throws for every
//! non-collection/tuple/UDT/vector — cassandra-5.0.8
//! `src/java/org/apache/cassandra/cql3/CQL3Type.java:647-651`). Nothing about
//! WHERE we are looking is in doubt, so a second decoder cannot improve the
//! answer — it can only replace a correct refusal with a marker-search guess,
//! which is both fail-open and a no-heuristics violation (#28).
//!
//! Issue #4104 (roborev job 116): the second case used to reach the caller as a
//! bare `nom::Err` and was retried through the heuristic fallback, so a header
//! the frozen-scalar gate had correctly refused was accepted anyway — while the
//! sibling KEY-type gate in the same function failed closed. This enum is what
//! makes the two gates agree.
//!
//! # Its reach, after the #4158 review round
//!
//! It is no longer only the anchored decoder's channel. Job 119 found the same
//! fail-open in the MARKER-SEARCH decoders — a refusal there became an ordinary
//! failed candidate, so the search continued to its empty-schema success — so
//! `serialization_header::{mod, sequential}` and `parse_regular_columns` and the
//! ASCII fallback all carry this type now, and `Refused` terminates the search
//! wherever it arises. Blocker A extended it in the other direction: the carried
//! `Error` is propagated out through `parse_nb_format_statistics_data_with_toc`
//! and the `_detailed` entry points to `StatisticsReader::open`, so the refusal
//! the user sees is the message the gate wrote.
use crateError;
/// Why [`super::serialization_header::parse_serialization_header_schema`] did not
/// return a schema.
///
/// Callers MUST match on the variant: only [`Self::Structural`] may be retried
/// with the marker-search fallback.
pub