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 #[must_use]
137 pub fn try_new_aggregate(
138 group_by_exprs: Vec<AliasedDynProofExpr>,
139 sum_expr: Vec<AliasedDynProofExpr>,
140 count_alias: Ident,
141 input: DynProofPlan,
142 where_clause: DynProofExpr,
143 ) -> Option<Self> {
144 AggregateExec::try_new(
145 group_by_exprs,
146 sum_expr,
147 count_alias,
148 Box::new(input),
149 where_clause,
150 )
151 .map(Self::Aggregate)
152 }
153
154 /// Creates a new slice plan.
155 #[must_use]
156 pub fn new_slice(input: DynProofPlan, skip: usize, fetch: Option<usize>) -> Self {
157 Self::Slice(SliceExec::new(Box::new(input), skip, fetch))
158 }
159
160 /// Creates a new union plan.
161 pub fn try_new_union(inputs: Vec<DynProofPlan>) -> AnalyzeResult<Self> {
162 UnionExec::try_new(inputs).map(Self::Union)
163 }
164
165 /// Creates a new filter plan.
166 #[must_use]
167 pub fn new_filter(
168 aliased_results: Vec<AliasedDynProofExpr>,
169 input: DynProofPlan,
170 filter_expr: DynProofExpr,
171 ) -> Self {
172 Self::Filter(FilterExec::new(
173 aliased_results,
174 Box::new(input),
175 filter_expr,
176 ))
177 }
178}