radixdb_executor/pipeline/
shape.rs1use radixdb_core::{CompactArc, Error, Result};
4use radixdb_storage::traits::QueryResult;
5
6use crate::result::ProjectedResult;
7
8#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct RowShape {
14 physical_columns: CompactArc<Vec<String>>,
15 public_width: usize,
16}
17
18impl RowShape {
19 pub fn new(physical_columns: CompactArc<Vec<String>>, public_width: usize) -> Result<Self> {
20 if public_width > physical_columns.len() {
21 return Err(Error::internal(format!(
22 "public row width {public_width} exceeds physical width {}",
23 physical_columns.len()
24 )));
25 }
26 Ok(Self {
27 physical_columns,
28 public_width,
29 })
30 }
31
32 pub fn physical_columns(&self) -> &CompactArc<Vec<String>> {
33 &self.physical_columns
34 }
35
36 pub fn physical_width(&self) -> usize {
37 self.physical_columns.len()
38 }
39
40 pub fn public_width(&self) -> usize {
41 self.public_width
42 }
43
44 pub fn has_private_tail(&self) -> bool {
45 self.public_width > 0 && self.physical_width() > self.public_width
46 }
47
48 pub fn project_public(&self, result: Box<dyn QueryResult>) -> Box<dyn QueryResult> {
49 if self.has_private_tail() {
50 Box::new(ProjectedResult::new(result, self.public_width))
51 } else {
52 result
53 }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn private_tail_is_explicit_and_bounded_by_physical_width() {
63 let shape = RowShape::new(
64 CompactArc::new(vec!["public".into(), "order-key".into()]),
65 1,
66 )
67 .unwrap();
68 assert_eq!(shape.public_width(), 1);
69 assert_eq!(shape.physical_width(), 2);
70 assert!(shape.has_private_tail());
71
72 assert!(RowShape::new(CompactArc::new(vec!["only".into()]), 2).is_err());
73 }
74}