proof_of_sql/base/database/
owned_table_test_accessor.rs

1use super::{
2    Column, ColumnType, CommitmentAccessor, DataAccessor, MetadataAccessor, OwnedColumn,
3    OwnedTable, SchemaAccessor, TableRef, TestAccessor,
4};
5use crate::base::{
6    commitment::{CommitmentEvaluationProof, VecCommitmentExt},
7    map::IndexMap,
8    scalar::ScalarExt,
9};
10use alloc::{string::String, vec::Vec};
11use bumpalo::Bump;
12use sqlparser::ast::Ident;
13/// A test accessor that uses [`OwnedTable`] as the underlying table type.
14/// Note: this is intended for testing and examples. It is not optimized for performance, so should not be used for benchmarks or production use-cases.
15pub struct OwnedTableTestAccessor<'a, CP: CommitmentEvaluationProof> {
16    tables: IndexMap<TableRef, (OwnedTable<CP::Scalar>, usize)>,
17    alloc: Bump,
18    setup: Option<CP::ProverPublicSetup<'a>>,
19}
20
21impl<CP: CommitmentEvaluationProof> Default for OwnedTableTestAccessor<'_, CP> {
22    fn default() -> Self {
23        Self {
24            tables: IndexMap::default(),
25            alloc: Bump::new(),
26            setup: None,
27        }
28    }
29}
30
31impl<CP: CommitmentEvaluationProof> Clone for OwnedTableTestAccessor<'_, CP> {
32    fn clone(&self) -> Self {
33        Self {
34            tables: self.tables.clone(),
35            setup: self.setup,
36            ..Default::default()
37        }
38    }
39}
40
41impl<CP: CommitmentEvaluationProof> TestAccessor<CP::Commitment>
42    for OwnedTableTestAccessor<'_, CP>
43{
44    type Table = OwnedTable<CP::Scalar>;
45
46    fn new_empty() -> Self {
47        OwnedTableTestAccessor::default()
48    }
49
50    fn add_table(&mut self, table_ref: TableRef, data: Self::Table, table_offset: usize) {
51        self.tables.insert(table_ref, (data, table_offset));
52    }
53    ///
54    /// # Panics
55    ///
56    /// Will panic if the `table_ref` is not found in `self.tables`, indicating
57    /// that an invalid reference was provided.
58    fn get_column_names(&self, table_ref: &TableRef) -> Vec<&str> {
59        self.tables
60            .get(&table_ref)
61            .unwrap()
62            .0
63            .column_names()
64            .map(|ident| ident.value.as_str())
65            .collect()
66    }
67
68    ///
69    /// # Panics
70    ///
71    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
72    fn update_offset(&mut self, table_ref: &TableRef, new_offset: usize) {
73        self.tables.get_mut(&table_ref).unwrap().1 = new_offset;
74    }
75}
76
77///
78/// # Panics
79///
80/// Will panic if the `table_ref` is not found in `self.tables`, or if
81/// the `column_id` is not found in the inner table for that reference,
82/// indicating that an invalid column reference was provided.
83impl<CP: CommitmentEvaluationProof> DataAccessor<CP::Scalar> for OwnedTableTestAccessor<'_, CP> {
84    fn get_column(&self, table_ref: &TableRef, column_id: &Ident) -> Column<CP::Scalar> {
85        match self
86            .tables
87            .get(table_ref)
88            .unwrap()
89            .0
90            .inner_table()
91            .get(column_id)
92            .unwrap()
93        {
94            OwnedColumn::Boolean(col) => Column::Boolean(col),
95            OwnedColumn::TinyInt(col) => Column::TinyInt(col),
96            OwnedColumn::Uint8(col) => Column::Uint8(col),
97            OwnedColumn::SmallInt(col) => Column::SmallInt(col),
98            OwnedColumn::Int(col) => Column::Int(col),
99            OwnedColumn::BigInt(col) => Column::BigInt(col),
100            OwnedColumn::Int128(col) => Column::Int128(col),
101            OwnedColumn::Decimal75(precision, scale, col) => {
102                Column::Decimal75(*precision, *scale, col)
103            }
104            OwnedColumn::Scalar(col) => Column::Scalar(col),
105            OwnedColumn::VarChar(col) => {
106                let col: &mut [&str] = self
107                    .alloc
108                    .alloc_slice_fill_iter(col.iter().map(String::as_str));
109                let scals: &mut [_] = self
110                    .alloc
111                    .alloc_slice_fill_iter(col.iter().map(|s| (*s).into()));
112                Column::VarChar((col, scals))
113            }
114            OwnedColumn::VarBinary(col) => {
115                // Convert each `Vec<u8>` to `&[u8]` for the `Column::VarBinary` "string-like" part.
116                let col_as_slices: &mut [&[u8]] = self
117                    .alloc
118                    .alloc_slice_fill_iter(col.iter().map(Vec::as_slice));
119
120                // Convert each `Vec<u8>` to a scalar by calling `from_le_bytes_mod_order`.
121                // That is the crucial step, because there's no direct `From<&[u8]>`.
122                let scals: &mut [CP::Scalar] = self.alloc.alloc_slice_fill_iter(
123                    col.iter()
124                        .map(|b| CP::Scalar::from_byte_slice_via_hash(b.as_slice())),
125                );
126
127                Column::VarBinary((col_as_slices, scals))
128            }
129            OwnedColumn::TimestampTZ(tu, tz, col) => Column::TimestampTZ(*tu, *tz, col),
130        }
131    }
132}
133
134///
135/// # Panics
136///
137/// Will panic if the `table_ref` is not found in `self.tables`, or if the `column_id` is not found in the inner table for that reference,indicating that an invalid column reference was provided.
138impl<CP: CommitmentEvaluationProof> CommitmentAccessor<CP::Commitment>
139    for OwnedTableTestAccessor<'_, CP>
140{
141    fn get_commitment(&self, table_ref: &TableRef, column_id: &Ident) -> CP::Commitment {
142        let (table, offset) = self.tables.get(table_ref).unwrap();
143        let owned_column = table.inner_table().get(column_id).unwrap();
144        Vec::<CP::Commitment>::from_columns_with_offset(
145            [owned_column],
146            *offset,
147            self.setup.as_ref().unwrap(),
148        )[0]
149        .clone()
150    }
151}
152impl<CP: CommitmentEvaluationProof> MetadataAccessor for OwnedTableTestAccessor<'_, CP> {
153    ///
154    /// # Panics
155    ///
156    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
157    fn get_length(&self, table_ref: &TableRef) -> usize {
158        self.tables.get(&table_ref).unwrap().0.num_rows()
159    }
160    ///
161    /// # Panics
162    ///
163    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
164    fn get_offset(&self, table_ref: &TableRef) -> usize {
165        self.tables.get(&table_ref).unwrap().1
166    }
167}
168impl<CP: CommitmentEvaluationProof> SchemaAccessor for OwnedTableTestAccessor<'_, CP> {
169    fn lookup_column(&self, table_ref: &TableRef, column_id: &Ident) -> Option<ColumnType> {
170        Some(
171            self.tables
172                .get(table_ref)?
173                .0
174                .inner_table()
175                .get(column_id)?
176                .column_type(),
177        )
178    }
179    ///
180    /// # Panics
181    ///
182    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
183    fn lookup_schema(&self, table_ref: &TableRef) -> Vec<(Ident, ColumnType)> {
184        self.tables
185            .get(table_ref)
186            .unwrap()
187            .0
188            .inner_table()
189            .iter()
190            .map(|(id, col)| (id.clone(), col.column_type()))
191            .collect()
192    }
193}
194
195impl<'a, CP: CommitmentEvaluationProof> OwnedTableTestAccessor<'a, CP> {
196    /// Create a new empty test accessor with the given setup.
197    pub fn new_empty_with_setup(setup: CP::ProverPublicSetup<'a>) -> Self {
198        let mut res = Self::new_empty();
199        res.setup = Some(setup);
200        res
201    }
202
203    /// Create a new test accessor containing the provided table.
204    pub fn new_from_table(
205        table_ref: TableRef,
206        owned_table: OwnedTable<CP::Scalar>,
207        offset: usize,
208        setup: CP::ProverPublicSetup<'a>,
209    ) -> Self {
210        let mut res = Self::new_empty_with_setup(setup);
211        res.add_table(table_ref, owned_table, offset);
212        res
213    }
214}