cqlite_core/parser/mod.rs
1//! # SSTable Binary Format Parser Module
2//!
3//! This module provides parsing functionality for Apache Cassandra SSTable binary formats.
4//! It handles deserialization of binary data structures from SSTable files (Data.db,
5//! Index.db, Statistics.db, etc.) produced by Cassandra 5.0+.
6//!
7//! ## Architecture Overview
8//!
9//! This is one of four parsing subsystems in cqlite-core:
10//!
11//! | Module | Purpose |
12//! |--------|---------|
13//! | `cql/` | Full CQL text → AST parsing |
14//! | **`parser/`** | SSTable binary format parsing (this module) |
15//! | `schema/cql_parser.rs` | CREATE TABLE → TableSchema |
16//! | `query/parser.rs` | Lightweight DML → ParsedQuery |
17//!
18//! See `docs/architecture/parser-overview.md` for the complete architecture overview.
19//!
20//! ## Module Architecture
21//!
22//! ```text
23//! parser/ (SSTable Binary Format Parsing)
24//! │
25//! ├── Core Binary Parsing
26//! │ ├── vint.rs - Variable-length integer (VInt) encoding
27//! │ └── header.rs - SSTable header parsing (magic numbers, version detection)
28//! │
29//! ├── Statistics Parsing
30//! │ ├── statistics.rs - Statistics.db basic format
31//! │ └── enhanced_statistics_parser.rs - Statistics.db enhanced format (nb/oa)
32//! │
33//! ├── CQL Type Deserialization
34//! │ ├── types.rs - All CQL primitive types (int, text, uuid, etc.)
35//! │ └── complex_types.rs - Collections, UDTs, tuples, frozen types
36//! │
37//! └── High-Level Interface
38//! └── binary.rs - SSTableParser facade
39//! ```
40//!
41//! Note: Test modules (`*_test.rs`, `*_tests.rs`) and benchmarks (`*_benchmarks.rs`)
42//! are omitted from the diagram. See feature flag `benchmarks` for performance testing.
43//!
44//! ## Key Distinction: parser/ vs cql/
45//!
46//! | Module | Purpose | Input | Output |
47//! |--------|---------|-------|--------|
48//! | **parser/** | SSTable binary parsing | Raw bytes from .db files | Structured Rust values |
49//! | **cql/** | CQL text parsing | Query strings ("SELECT...") | Abstract Syntax Trees |
50//!
51//! This module (`parser/`) handles **binary deserialization**:
52//! - Reading bytes from SSTable files (Data.db, Statistics.db, etc.)
53//! - Decoding VInt-encoded integers per Cassandra's wire format
54//! - Deserializing CQL values (int → i32, text → String, uuid → Uuid)
55//!
56//! For **CQL text parsing** (CREATE TABLE, SELECT, etc.), see the [`crate::cql`] module.
57//!
58//! ## Sub-module Reference
59//!
60//! ### Variable-Length Integer Encoding
61//! - [`vint`] - VInt encoding/decoding per Cassandra specification
62//!
63//! ### SSTable Headers
64//! - [`header`] - SSTable header parsing with version detection (oa/nb/legacy formats)
65//!
66//! ### Statistics Files
67//! - [`statistics`] - Statistics.db parsing for row counts, timestamps, min/max metadata
68//! - [`enhanced_statistics_parser`] - Enhanced Statistics.db format for Cassandra 5.0's
69//! nb (nested btree) and oa (open addressing) formats
70//!
71//! ### CQL Type Deserialization
72//! - [`types`] - All 20+ CQL primitive types: int, bigint, text, blob, uuid, timestamp,
73//! date, time, inet, varint, decimal, duration, boolean, float, double, ascii, timeuuid
74//! - [`complex_types`] - Collections (list, set, map), UDTs, tuples, with depth tracking
75//! for nested types
76//!
77//! ### High-Level Interface
78//! - [`binary`] - `SSTableParser` facade providing unified access to parsing functionality
79//!
80//! ## Usage Examples
81//!
82//! ```rust,ignore
83//! use cqlite_core::parser::{parse_vint, SSTableHeader, CqlType};
84//!
85//! // Parse variable-length integer from raw bytes
86//! let bytes = [0x8A, 0x01]; // VInt-encoded value
87//! let (remaining, value) = parse_vint(&bytes)?;
88//!
89//! // Parse SSTable header to detect format version
90//! let header = SSTableHeader::parse(&file_bytes)?;
91//! println!("SSTable format: {:?}", header.format_type);
92//! ```
93//!
94//! ## Backward Compatibility
95//!
96//! The [`parse_cql_schema`] function is maintained for backward compatibility with
97//! existing code. **New code should use [`crate::cql::parse_cql_schema_enhanced`]**
98//! which provides better error handling and configuration options.
99//!
100//! ## Related Documentation
101//!
102//! - SSTable format specification: `docs/sstables-definitive-guide/`
103//! - Known limitations: `docs/sstables-definitive-guide/chapters/appendix-f-known-limitations.md`
104
105// Binary format parsing (SSTable components)
106pub mod binary;
107
108// Re-export existing modules for backward compatibility
109#[cfg(feature = "benchmarks")]
110pub mod benchmarks;
111#[cfg(feature = "benchmarks")]
112pub mod collection_benchmarks;
113#[cfg(test)]
114pub mod collection_correctness_tests; // Property tests for Issue #61
115#[cfg(test)]
116pub mod collection_tests;
117#[cfg(test)]
118pub mod collection_validation_tests;
119pub mod complex_types;
120pub mod enhanced_statistics_parser;
121#[cfg(test)]
122pub mod enhanced_statistics_test;
123pub mod header;
124pub(crate) mod repair_clustering;
125pub mod repair_metadata;
126pub mod statistics;
127#[cfg(test)]
128pub mod statistics_test;
129pub mod toc_walk_metrics;
130pub mod types;
131#[cfg(test)]
132pub mod udt_tests;
133pub mod vint;
134// #3848: truncation-free narrowing of a VInt/VUInt length for the `nom`
135// parsers (`take(len as usize)` silently accepts a truncated length on a 32-bit
136// target). Its own module because `vint.rs` is over the size threshold.
137#[cfg(test)]
138mod vint_j4_tests;
139#[cfg(test)]
140mod vint_length_corpus_audit_tests;
141pub mod vint_narrow;
142
143// Re-export binary format parser
144pub use binary::{CQLiteParseError, ParseResult, SSTableParser};
145
146// Re-export binary format parsers for backward compatibility
147#[cfg(feature = "benchmarks")]
148pub use benchmarks::*;
149pub use complex_types::*;
150pub use enhanced_statistics_parser::*;
151pub use header::*;
152pub use statistics::*;
153pub use types::*;
154pub use vint::*;
155
156/// Re-export common result types
157pub use crate::error::Result as CqlResult;
158
159/// Parse CQL CREATE TABLE statement (backward compatibility function)
160///
161/// **DEPRECATED**: This function maintains backward compatibility with existing code.
162/// For new code, use `cqlite_core::schema::parse_cql_schema()` which is synchronous
163/// and returns `Result<TableSchema>` instead of `nom::IResult`.
164///
165/// # Arguments
166/// * `input` - The CQL CREATE TABLE statement to parse
167///
168/// # Returns
169/// * `nom::IResult<&str, crate::schema::TableSchema>` - Parsed schema or error
170#[deprecated(
171 since = "0.2.0",
172 note = "Use cqlite_core::cql::parse_cql_schema_enhanced() instead for better error handling"
173)]
174pub fn parse_cql_schema(input: &str) -> nom::IResult<&str, crate::schema::TableSchema> {
175 // Delegate to the cql module (which now uses synchronous parsing)
176 #[allow(deprecated)]
177 crate::cql::schema_integration::parse_cql_schema_compat(input)
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183
184 #[test]
185 #[allow(deprecated)] // Testing deprecated API for backward compatibility
186 fn test_parse_cql_schema_backward_compat() {
187 // Test that the backward compatibility function still works
188 let schema = "CREATE TABLE test_keyspace.test_table (id int PRIMARY KEY)";
189 let result = parse_cql_schema(schema);
190
191 // The result should delegate to cql module and parse successfully
192 assert!(
193 result.is_ok(),
194 "Valid schema should parse successfully via backward-compat function"
195 );
196 }
197}