1use std::collections::HashSet;
22
23use crate::cell::Cell;
24use crate::error::{Result, SqliteError};
25use crate::page::{BtreePage, PageKind};
26use crate::record::{self, SqliteValue};
27use crate::source::Source;
28use crate::Reader;
29
30#[derive(Debug, Clone, PartialEq)]
35pub struct Row {
36 pub rowid: Option<i64>,
37 pub values: Vec<SqliteValue>,
38}
39
40#[derive(Debug, Clone, PartialEq)]
46pub struct TableRow {
47 pub rowid: i64,
48 pub values: Vec<SqliteValue>,
49}
50
51struct Frame {
53 page: u32,
54 next: usize,
57}
58
59pub struct TableScan<'a, S: Source> {
66 reader: &'a Reader<S>,
67 stack: Vec<Frame>,
68 visited: HashSet<u32>,
69 current: Option<BtreePage>,
73 last_rowid: Option<i64>,
77 finished: bool,
78}
79
80impl<'a, S: Source> TableScan<'a, S> {
81 pub(crate) fn new(reader: &'a Reader<S>, root: u32) -> Result<TableScan<'a, S>> {
82 let page = reader.btree_page(root)?;
83 if !page.kind.is_table() {
84 return Err(SqliteError::malformed(
85 root,
86 format!(
87 "page {root} is a {:?}, not a table b-tree; a without rowid table is \
88 read with index_scan, or with rows, which picks for itself",
89 page.kind
90 ),
91 ));
92 }
93 let mut visited = HashSet::new();
94 visited.insert(root);
95 Ok(TableScan {
96 reader,
97 stack: vec![Frame {
98 page: root,
99 next: 0,
100 }],
101 visited,
102 current: Some(page),
103 last_rowid: None,
104 finished: false,
105 })
106 }
107
108 fn ensure_page(&mut self, number: u32) -> Result<()> {
114 if !matches!(&self.current, Some(page) if page.number == number) {
115 self.current = Some(self.reader.btree_page(number)?);
116 }
117 Ok(())
118 }
119
120 fn page_in_hand(&self) -> &BtreePage {
121 self.current
122 .as_ref()
123 .expect("ensure_page runs before every read")
124 }
125
126 fn descend(&mut self, child: u32) -> Result<()> {
127 if !self.visited.insert(child) {
128 return Err(SqliteError::malformed(
129 child,
130 "the b-tree visits this page twice, so its pointers form a cycle",
131 ));
132 }
133 let page = self.reader.btree_page(child)?;
134 if !page.kind.is_table() {
135 return Err(SqliteError::malformed(
136 child,
137 format!("a table b-tree points at a {:?}", page.kind),
138 ));
139 }
140 self.current = Some(page);
141 self.stack.push(Frame {
142 page: child,
143 next: 0,
144 });
145 Ok(())
146 }
147
148 fn step(&mut self) -> Result<Option<TableRow>> {
150 let Some(frame) = self.stack.last() else {
151 self.finished = true;
152 return Ok(None);
153 };
154 let (number, next) = (frame.page, frame.next);
155 self.ensure_page(number)?;
156 let page = self.page_in_hand();
157 let (kind, cell_count, right_most) = (page.kind, page.cell_count(), page.right_most);
158
159 if kind == PageKind::LeafTable {
160 if next >= cell_count {
161 self.stack.pop();
162 return Ok(None);
163 }
164 let cell = self.reader.cell(self.page_in_hand(), next)?;
165 self.bump();
166 return match cell {
167 Cell::TableLeaf { rowid, payload } => {
168 if let Some(previous) = self.last_rowid {
173 if rowid <= previous {
174 return Err(SqliteError::malformed(
175 number,
176 format!(
177 "rowid {rowid} follows {previous}, so the table b-tree \
178 is not in key order"
179 ),
180 ));
181 }
182 }
183 self.last_rowid = Some(rowid);
184 Ok(Some(TableRow {
185 rowid,
186 values: record::decode(&payload, self.reader.header().text_encoding)?,
187 }))
188 }
189 other => Err(SqliteError::malformed(
190 number,
191 format!("a table leaf page holds {other:?}"),
192 )),
193 };
194 }
195
196 if next < cell_count {
198 let cell = self.reader.cell(self.page_in_hand(), next)?;
199 self.bump();
200 match cell {
201 Cell::TableInterior { child, .. } => self.descend(child)?,
202 other => {
203 return Err(SqliteError::malformed(
204 number,
205 format!("a table interior page holds {other:?}"),
206 ))
207 }
208 }
209 } else if next == cell_count {
210 self.bump();
211 let child = right_most.ok_or_else(|| {
212 SqliteError::malformed(number, "an interior page without a right most child")
213 })?;
214 self.descend(child)?;
215 } else {
216 self.stack.pop();
217 }
218 Ok(None)
219 }
220
221 fn bump(&mut self) {
222 if let Some(frame) = self.stack.last_mut() {
223 frame.next += 1;
224 }
225 }
226}
227
228impl<S: Source> Iterator for TableScan<'_, S> {
229 type Item = Result<TableRow>;
230
231 fn next(&mut self) -> Option<Result<TableRow>> {
232 while !self.finished {
233 if self.stack.is_empty() {
234 self.finished = true;
235 return None;
236 }
237 match self.step() {
238 Ok(Some(row)) => return Some(Ok(row)),
239 Ok(None) => continue,
240 Err(e) => {
241 self.finished = true;
242 return Some(Err(e));
243 }
244 }
245 }
246 None
247 }
248}
249
250struct IndexFrame {
257 page: u32,
258 next: usize,
259 descended: bool,
260}
261
262pub struct IndexScan<'a, S: Source> {
272 reader: &'a Reader<S>,
273 stack: Vec<IndexFrame>,
274 visited: HashSet<u32>,
275 current: Option<BtreePage>,
276 finished: bool,
277}
278
279impl<'a, S: Source> IndexScan<'a, S> {
280 pub(crate) fn new(reader: &'a Reader<S>, root: u32) -> Result<IndexScan<'a, S>> {
281 let page = reader.btree_page(root)?;
282 if page.kind.is_table() {
283 return Err(SqliteError::malformed(
284 root,
285 format!("page {root} is a {:?}, not an index b-tree", page.kind),
286 ));
287 }
288 let mut visited = HashSet::new();
289 visited.insert(root);
290 Ok(IndexScan {
291 reader,
292 stack: vec![IndexFrame {
293 page: root,
294 next: 0,
295 descended: false,
296 }],
297 visited,
298 current: Some(page),
299 finished: false,
300 })
301 }
302
303 fn ensure_page(&mut self, number: u32) -> Result<()> {
307 if !matches!(&self.current, Some(page) if page.number == number) {
308 self.current = Some(self.reader.btree_page(number)?);
309 }
310 Ok(())
311 }
312
313 fn page_in_hand(&self) -> &BtreePage {
314 self.current
315 .as_ref()
316 .expect("ensure_page runs before every read")
317 }
318
319 fn descend(&mut self, child: u32) -> Result<()> {
320 if !self.visited.insert(child) {
321 return Err(SqliteError::malformed(
322 child,
323 "the index b-tree visits this page twice, so its pointers form a cycle",
324 ));
325 }
326 let page = self.reader.btree_page(child)?;
327 if page.kind.is_table() {
328 return Err(SqliteError::malformed(
329 child,
330 format!("an index b-tree points at a {:?}", page.kind),
331 ));
332 }
333 self.current = Some(page);
334 self.stack.push(IndexFrame {
335 page: child,
336 next: 0,
337 descended: false,
338 });
339 Ok(())
340 }
341
342 fn payload_of(&mut self, number: u32, index: usize) -> Result<Vec<u8>> {
343 self.ensure_page(number)?;
344 match self.reader.cell(self.page_in_hand(), index)? {
345 Cell::IndexLeaf { payload } | Cell::IndexInterior { payload, .. } => Ok(payload),
346 other => Err(SqliteError::malformed(
347 number,
348 format!("an index page holds {other:?}"),
349 )),
350 }
351 }
352
353 fn step(&mut self) -> Result<Option<Vec<SqliteValue>>> {
354 let Some(frame) = self.stack.last() else {
355 self.finished = true;
356 return Ok(None);
357 };
358 let (number, next, descended) = (frame.page, frame.next, frame.descended);
359 self.ensure_page(number)?;
360 let page = self.page_in_hand();
361 let (kind, cell_count, right_most) = (page.kind, page.cell_count(), page.right_most);
362
363 if kind == PageKind::LeafIndex {
364 if next >= cell_count {
365 self.stack.pop();
366 return Ok(None);
367 }
368 let payload = self.payload_of(number, next)?;
369 if let Some(frame) = self.stack.last_mut() {
370 frame.next += 1;
371 }
372 return Ok(Some(record::decode(
373 &payload,
374 self.reader.header().text_encoding,
375 )?));
376 }
377
378 if !descended {
380 if let Some(frame) = self.stack.last_mut() {
381 frame.descended = true;
382 }
383 let child = if next < cell_count {
384 self.ensure_page(number)?;
385 match self.reader.cell(self.page_in_hand(), next)? {
386 Cell::IndexInterior { child, .. } => child,
387 other => {
388 return Err(SqliteError::malformed(
389 number,
390 format!("an index interior page holds {other:?}"),
391 ))
392 }
393 }
394 } else {
395 right_most.ok_or_else(|| {
396 SqliteError::malformed(number, "an interior page without a right most child")
397 })?
398 };
399 self.descend(child)?;
400 return Ok(None);
401 }
402
403 if next < cell_count {
404 let payload = self.payload_of(number, next)?;
405 if let Some(frame) = self.stack.last_mut() {
406 frame.next += 1;
407 frame.descended = false;
408 }
409 return Ok(Some(record::decode(
410 &payload,
411 self.reader.header().text_encoding,
412 )?));
413 }
414
415 self.stack.pop();
416 Ok(None)
417 }
418}
419
420impl<S: Source> Iterator for IndexScan<'_, S> {
421 type Item = Result<Vec<SqliteValue>>;
422
423 fn next(&mut self) -> Option<Result<Vec<SqliteValue>>> {
424 while !self.finished {
425 if self.stack.is_empty() {
426 self.finished = true;
427 return None;
428 }
429 match self.step() {
430 Ok(Some(values)) => return Some(Ok(values)),
431 Ok(None) => continue,
432 Err(e) => {
433 self.finished = true;
434 return Some(Err(e));
435 }
436 }
437 }
438 None
439 }
440}
441
442pub enum Rows<'a, S: Source> {
444 Rowid(TableScan<'a, S>),
445 Keyed(IndexScan<'a, S>),
446}
447
448impl<S: Source> Iterator for Rows<'_, S> {
449 type Item = Result<Row>;
450
451 fn next(&mut self) -> Option<Result<Row>> {
452 match self {
453 Rows::Rowid(scan) => scan.next().map(|row| {
454 row.map(|row| Row {
455 rowid: Some(row.rowid),
456 values: row.values,
457 })
458 }),
459 Rows::Keyed(scan) => scan.next().map(|values| {
460 values.map(|values| Row {
461 rowid: None,
462 values,
463 })
464 }),
465 }
466 }
467}