proof_of_sql/base/database/
table_test_accessor.rs

1use super::{
2    Column, ColumnType, CommitmentAccessor, DataAccessor, MetadataAccessor, SchemaAccessor, Table,
3    TableRef, TestAccessor,
4};
5use crate::base::{
6    commitment::{CommitmentEvaluationProof, VecCommitmentExt},
7    map::IndexMap,
8};
9use alloc::vec::Vec;
10use sqlparser::ast::Ident;
11
12/// A test accessor that uses [`Table`] as the underlying table type.
13/// 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.
14pub struct TableTestAccessor<'a, CP: CommitmentEvaluationProof> {
15    tables: IndexMap<TableRef, (Table<'a, CP::Scalar>, usize)>,
16    setup: Option<CP::ProverPublicSetup<'a>>,
17}
18
19impl<CP: CommitmentEvaluationProof> Default for TableTestAccessor<'_, CP> {
20    fn default() -> Self {
21        Self {
22            tables: IndexMap::default(),
23            setup: None,
24        }
25    }
26}
27
28impl<CP: CommitmentEvaluationProof> Clone for TableTestAccessor<'_, CP> {
29    fn clone(&self) -> Self {
30        Self {
31            tables: self.tables.clone(),
32            setup: self.setup,
33        }
34    }
35}
36
37impl<'a, CP: CommitmentEvaluationProof> TestAccessor<CP::Commitment> for TableTestAccessor<'a, CP> {
38    type Table = Table<'a, CP::Scalar>;
39
40    fn new_empty() -> Self {
41        TableTestAccessor::default()
42    }
43
44    fn add_table(&mut self, table_ref: TableRef, data: Self::Table, table_offset: usize) {
45        self.tables.insert(table_ref, (data, table_offset));
46    }
47    ///
48    /// # Panics
49    ///
50    /// Will panic if the `table_ref` is not found in `self.tables`, indicating
51    /// that an invalid reference was provided.
52    fn get_column_names(&self, table_ref: &TableRef) -> Vec<&str> {
53        self.tables
54            .get(&table_ref)
55            .unwrap()
56            .0
57            .column_names()
58            .map(|ident| ident.value.as_str())
59            .collect()
60    }
61
62    ///
63    /// # Panics
64    ///
65    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
66    fn update_offset(&mut self, table_ref: &TableRef, new_offset: usize) {
67        self.tables.get_mut(&table_ref).unwrap().1 = new_offset;
68    }
69}
70
71///
72/// # Panics
73///
74/// Will panic if the `table_ref` is not found in `self.tables`, or if
75/// the `column_id` is not found in the inner table for that reference,
76/// indicating that an invalid column reference was provided.
77impl<'a, CP: CommitmentEvaluationProof> DataAccessor<CP::Scalar> for TableTestAccessor<'a, CP> {
78    fn get_column(&self, table_ref: &TableRef, column_id: &Ident) -> Column<'a, CP::Scalar> {
79        *self
80            .tables
81            .get(table_ref)
82            .unwrap()
83            .0
84            .inner_table()
85            .get(column_id)
86            .unwrap()
87    }
88}
89
90///
91/// # Panics
92///
93/// 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.
94impl<CP: CommitmentEvaluationProof> CommitmentAccessor<CP::Commitment>
95    for TableTestAccessor<'_, CP>
96{
97    fn get_commitment(&self, table_ref: &TableRef, column_id: &Ident) -> CP::Commitment {
98        let (table, offset) = self.tables.get(table_ref).unwrap();
99        let borrowed_column = table.inner_table().get(column_id).unwrap();
100        Vec::<CP::Commitment>::from_columns_with_offset(
101            [borrowed_column],
102            *offset,
103            self.setup.as_ref().unwrap(),
104        )[0]
105        .clone()
106    }
107}
108impl<CP: CommitmentEvaluationProof> MetadataAccessor for TableTestAccessor<'_, CP> {
109    ///
110    /// # Panics
111    ///
112    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
113    fn get_length(&self, table_ref: &TableRef) -> usize {
114        self.tables.get(&table_ref).unwrap().0.num_rows()
115    }
116    ///
117    /// # Panics
118    ///
119    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
120    fn get_offset(&self, table_ref: &TableRef) -> usize {
121        self.tables.get(&table_ref).unwrap().1
122    }
123}
124impl<CP: CommitmentEvaluationProof> SchemaAccessor for TableTestAccessor<'_, CP> {
125    fn lookup_column(&self, table_ref: &TableRef, column_id: &Ident) -> Option<ColumnType> {
126        Some(
127            self.tables
128                .get(table_ref)?
129                .0
130                .inner_table()
131                .get(column_id)?
132                .column_type(),
133        )
134    }
135    ///
136    /// # Panics
137    ///
138    /// Will panic if the `table_ref` is not found in `self.tables`, indicating that an invalid reference was provided.
139    fn lookup_schema(&self, table_ref: &TableRef) -> Vec<(Ident, ColumnType)> {
140        self.tables
141            .get(table_ref)
142            .unwrap()
143            .0
144            .inner_table()
145            .iter()
146            .map(|(id, col)| (id.clone(), col.column_type()))
147            .collect()
148    }
149}
150
151impl<'a, CP: CommitmentEvaluationProof> TableTestAccessor<'a, CP> {
152    /// Create a new empty test accessor with the given setup.
153    pub fn new_empty_with_setup(setup: CP::ProverPublicSetup<'a>) -> Self {
154        let mut res = Self::new_empty();
155        res.setup = Some(setup);
156        res
157    }
158
159    /// Create a new test accessor containing the provided table.
160    pub fn new_from_table(
161        table_ref: TableRef,
162        table: Table<'a, CP::Scalar>,
163        offset: usize,
164        setup: CP::ProverPublicSetup<'a>,
165    ) -> Self {
166        let mut res = Self::new_empty_with_setup(setup);
167        res.add_table(table_ref, table, offset);
168        res
169    }
170}