Skip to main content

proof_of_sql/sql/proof_plans/
dyn_proof_plan.rs

1use super::{
2    AggregateExec, EmptyExec, FilterExec, GroupByExec, LegacyFilterExec, ProjectionExec, SliceExec,
3    SortMergeJoinExec, TableExec, UnionExec,
4};
5use crate::{
6    base::{
7        database::{ColumnField, ColumnRef, LiteralValue, Table, TableEvaluation, TableRef},
8        map::{IndexMap, IndexSet},
9        proof::{PlaceholderResult, ProofError},
10        scalar::Scalar,
11    },
12    sql::{
13        proof::{
14            FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder,
15        },
16        proof_exprs::{AliasedDynProofExpr, ColumnExpr, DynProofExpr, TableExpr},
17        AnalyzeResult,
18    },
19};
20use alloc::{boxed::Box, vec::Vec};
21use bumpalo::Bump;
22use serde::{Deserialize, Serialize};
23use sqlparser::ast::Ident;
24
25/// The query plan for proving a query
26#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
27#[enum_dispatch::enum_dispatch]
28pub enum DynProofPlan {
29    /// Source [`ProofPlan`] for (sub)queries without table source such as `SELECT "No table here" as msg;`
30    Empty(EmptyExec),
31    /// Source [`ProofPlan`] for (sub)queries with table source such as `SELECT col from tab;`
32    Table(TableExec),
33    /// Provable expressions for queries of the form
34    /// ```ignore
35    ///     SELECT <result_expr1>, ..., <result_exprN> FROM <table>
36    /// ```
37    Projection(ProjectionExec),
38    /// Provable expressions for queries of the form
39    /// ```ignore
40    ///     SELECT <group_by_expr1>, ..., <group_by_exprM>,
41    ///         SUM(<sum_expr1>.0) as <sum_expr1>.1, ..., SUM(<sum_exprN>.0) as <sum_exprN>.1,
42    ///         COUNT(*) as count_alias
43    ///     FROM <table>
44    ///     WHERE <where_clause>
45    ///     GROUP BY <group_by_expr1>, ..., <group_by_exprM>
46    /// ```
47    GroupBy(GroupByExec),
48    /// Provable expressions for queries of the form
49    /// ```ignore
50    ///     SELECT <group_by_expr1>.expr as <group_by_expr1>.alias, ..., <group_by_exprM>.expr as <group_by_exprM>.alias,
51    ///         SUM(<sum_expr1>.expr) as <sum_expr1>.alias, ..., SUM(<sum_exprN>.expr) as <sum_exprN>.alias,
52    ///         COUNT(*) as <count_alias>
53    ///     FROM <input>
54    ///     WHERE <where_clause>
55    ///     GROUP BY <group_by_expr1>.expr, ..., <group_by_exprM>.expr
56    /// ```
57    /// Similar to `GroupBy` but accepts a [`DynProofPlan`] as input
58    Aggregate(AggregateExec),
59    /// Provable expressions for queries of the form, where the result is sent in a dense form
60    /// ```ignore
61    ///     SELECT <result_expr1>, ..., <result_exprN> FROM <table> WHERE <where_clause>
62    /// ```
63    LegacyFilter(LegacyFilterExec),
64    /// Provable expressions for queries of the form, where the result is sent in a dense form
65    /// ```ignore
66    ///     SELECT <result_expr1>, ..., <result_exprN> FROM <input> WHERE <where_clause>
67    /// ```
68    /// Accepts a [`DynProofPlan`] as input
69    Filter(FilterExec),
70    /// `ProofPlan` for queries of the form
71    /// ```ignore
72    ///     <ProofPlan> LIMIT <fetch> [OFFSET <skip>]
73    /// ```
74    Slice(SliceExec),
75    /// `ProofPlan` for queries of the form
76    /// ```ignore
77    ///     <ProofPlan>
78    ///     UNION ALL
79    ///     <ProofPlan>
80    ///     ...
81    ///     UNION ALL
82    ///     <ProofPlan>
83    /// ```
84    Union(UnionExec),
85    /// `ProofPlan` for queries of the form
86    /// ```ignore
87    ///     <ProofPlan> INNER JOIN <ProofPlan>
88    ///     ON col1 = col2
89    /// ```
90    SortMergeJoin(SortMergeJoinExec),
91}
92
93impl DynProofPlan {
94    /// Creates a new empty plan.
95    #[must_use]
96    pub fn new_empty() -> Self {
97        Self::Empty(EmptyExec::new())
98    }
99
100    /// Creates a new table plan.
101    #[must_use]
102    pub fn new_table(table_ref: TableRef, schema: Vec<ColumnField>) -> Self {
103        Self::Table(TableExec::new(table_ref, schema))
104    }
105
106    /// Creates a new projection plan.
107    #[must_use]
108    pub fn new_projection(aliased_results: Vec<AliasedDynProofExpr>, input: DynProofPlan) -> Self {
109        Self::Projection(ProjectionExec::new(aliased_results, Box::new(input)))
110    }
111
112    /// Creates a new legacy filter plan.
113    #[must_use]
114    pub fn new_legacy_filter(
115        aliased_results: Vec<AliasedDynProofExpr>,
116        input: TableExpr,
117        filter_expr: DynProofExpr,
118    ) -> Self {
119        Self::LegacyFilter(LegacyFilterExec::new(aliased_results, input, filter_expr))
120    }
121
122    /// Creates a new group by plan.
123    #[must_use]
124    pub fn try_new_group_by(
125        group_by_exprs: Vec<ColumnExpr>,
126        sum_expr: Vec<AliasedDynProofExpr>,
127        count_alias: Ident,
128        table: TableExpr,
129        where_clause: DynProofExpr,
130    ) -> Option<Self> {
131        GroupByExec::try_new(group_by_exprs, sum_expr, count_alias, table, where_clause)
132            .map(Self::GroupBy)
133    }
134
135    /// Creates a new aggregate plan.
136    pub fn try_new_aggregate(
137        group_by_exprs: Vec<AliasedDynProofExpr>,
138        sum_expr: Vec<AliasedDynProofExpr>,
139        count_alias: Ident,
140        input: DynProofPlan,
141        where_clause: DynProofExpr,
142    ) -> Result<Self, super::AggregateExecError> {
143        AggregateExec::try_new(
144            group_by_exprs,
145            sum_expr,
146            count_alias,
147            Box::new(input),
148            where_clause,
149        )
150        .map(Self::Aggregate)
151    }
152
153    /// Creates a new slice plan.
154    #[must_use]
155    pub fn new_slice(input: DynProofPlan, skip: usize, fetch: Option<usize>) -> Self {
156        Self::Slice(SliceExec::new(Box::new(input), skip, fetch))
157    }
158
159    /// Creates a new union plan.
160    pub fn try_new_union(inputs: Vec<DynProofPlan>) -> AnalyzeResult<Self> {
161        UnionExec::try_new(inputs).map(Self::Union)
162    }
163
164    /// Creates a new filter plan.
165    #[must_use]
166    pub fn new_filter(
167        aliased_results: Vec<AliasedDynProofExpr>,
168        input: DynProofPlan,
169        filter_expr: DynProofExpr,
170    ) -> Self {
171        Self::Filter(FilterExec::new(
172            aliased_results,
173            Box::new(input),
174            filter_expr,
175        ))
176    }
177
178    /// Returns the resulting column fields of the plan as column references
179    pub(crate) fn get_column_result_fields_as_references(&self) -> IndexSet<ColumnRef> {
180        self.get_column_result_fields()
181            .into_iter()
182            .map(|f| ColumnRef::new(TableRef::from_names(None, ""), f.name(), f.data_type()))
183            .collect()
184    }
185}