proof_of_sql/sql/proof_plans/
dyn_proof_plan.rs

1use super::{
2    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, where the result is sent in a dense form
49    /// ```ignore
50    ///     SELECT <result_expr1>, ..., <result_exprN> FROM <table> WHERE <where_clause>
51    /// ```
52    LegacyFilter(LegacyFilterExec),
53    /// Provable expressions for queries of the form, where the result is sent in a dense form
54    /// ```ignore
55    ///     SELECT <result_expr1>, ..., <result_exprN> FROM <input> WHERE <where_clause>
56    /// ```
57    /// Accepts a DynProofPlan as input
58    Filter(FilterExec),
59    /// `ProofPlan` for queries of the form
60    /// ```ignore
61    ///     <ProofPlan> LIMIT <fetch> [OFFSET <skip>]
62    /// ```
63    Slice(SliceExec),
64    /// `ProofPlan` for queries of the form
65    /// ```ignore
66    ///     <ProofPlan>
67    ///     UNION ALL
68    ///     <ProofPlan>
69    ///     ...
70    ///     UNION ALL
71    ///     <ProofPlan>
72    /// ```
73    Union(UnionExec),
74    /// `ProofPlan` for queries of the form
75    /// ```ignore
76    ///     <ProofPlan> INNER JOIN <ProofPlan>
77    ///     ON col1 = col2
78    /// ```
79    SortMergeJoin(SortMergeJoinExec),
80}
81
82impl DynProofPlan {
83    /// Creates a new empty plan.
84    #[must_use]
85    pub fn new_empty() -> Self {
86        Self::Empty(EmptyExec::new())
87    }
88
89    /// Creates a new table plan.
90    #[must_use]
91    pub fn new_table(table_ref: TableRef, schema: Vec<ColumnField>) -> Self {
92        Self::Table(TableExec::new(table_ref, schema))
93    }
94
95    /// Creates a new projection plan.
96    #[must_use]
97    pub fn new_projection(aliased_results: Vec<AliasedDynProofExpr>, input: DynProofPlan) -> Self {
98        Self::Projection(ProjectionExec::new(aliased_results, Box::new(input)))
99    }
100
101    /// Creates a new legacy filter plan.
102    #[must_use]
103    pub fn new_legacy_filter(
104        aliased_results: Vec<AliasedDynProofExpr>,
105        input: TableExpr,
106        filter_expr: DynProofExpr,
107    ) -> Self {
108        Self::LegacyFilter(LegacyFilterExec::new(aliased_results, input, filter_expr))
109    }
110
111    /// Creates a new group by plan.
112    #[must_use]
113    pub fn try_new_group_by(
114        group_by_exprs: Vec<ColumnExpr>,
115        sum_expr: Vec<AliasedDynProofExpr>,
116        count_alias: Ident,
117        table: TableExpr,
118        where_clause: DynProofExpr,
119    ) -> Option<Self> {
120        GroupByExec::try_new(group_by_exprs, sum_expr, count_alias, table, where_clause)
121            .map(Self::GroupBy)
122    }
123
124    /// Creates a new slice plan.
125    #[must_use]
126    pub fn new_slice(input: DynProofPlan, skip: usize, fetch: Option<usize>) -> Self {
127        Self::Slice(SliceExec::new(Box::new(input), skip, fetch))
128    }
129
130    /// Creates a new union plan.
131    pub fn try_new_union(inputs: Vec<DynProofPlan>) -> AnalyzeResult<Self> {
132        UnionExec::try_new(inputs).map(Self::Union)
133    }
134
135    /// Creates a new filter plan.
136    #[must_use]
137    pub fn new_filter(
138        aliased_results: Vec<AliasedDynProofExpr>,
139        input: DynProofPlan,
140        filter_expr: DynProofExpr,
141    ) -> Self {
142        Self::Filter(FilterExec::new(
143            aliased_results,
144            Box::new(input),
145            filter_expr,
146        ))
147    }
148}