proof_of_sql/sql/proof_plans/
dyn_proof_plan.rs

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