Skip to content

Commit f7dc4de

Browse files
authored
refactor: move examples to the planner crate (#1014)
# Rationale for this change We need to use `proof-of-sql-planner` to process queries now. Hence the examples need to be moved. Unsupported features such as ORDER BY are removed. # What changes are included in this PR? <!-- There is no need to duplicate the description in the ticket here but it is sometimes worth providing a summary of the individual changes in this PR. Example: - Add `NestedLoopJoinExec`. - Speed up `HashJoinExec`. - Route joins to `NestedLoopJoinExec` if the outer input is sufficiently small. --> # Are these changes tested? <!-- We typically require tests for all PRs in order to: 1. Prevent the code from being accidentally broken by subsequent changes 2. Serve as another way to document the expected behavior of the code If tests are not included in your PR, please explain why (for example, are they covered by existing tests)? Example: Yes. -->
1 parent ac1216c commit f7dc4de

File tree

50 files changed

+748
-575
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+748
-575
lines changed

.github/workflows/lint-and-test.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,21 @@ jobs:
132132
- name: Install stable toolchain
133133
run: curl https://sh.rustup.rs -sSf | bash -s -- -y --profile minimal && source ~/.cargo/env && rustup toolchain install
134134
- name: Run hello_world example (With Blitzar)
135-
run: cargo run --example hello_world --features="test"
135+
run: cargo run --example hello_world --features="proof-of-sql/test"
136136
- name: Run hello_world example (Without Blitzar and With Rayon)
137-
run: cargo run --example hello_world --no-default-features --features="rayon test"
137+
run: cargo run --example hello_world --no-default-features --features="proof-of-sql/rayon proof-of-sql/test"
138138
- name: Run hello_world example (Without Blitzar and Without Rayon)
139-
run: cargo run --example hello_world --no-default-features --features="test"
139+
run: cargo run --example hello_world --no-default-features --features="proof-of-sql/test"
140140
- name: Run space example
141141
run: cargo run --example space
142142
- name: Run dog breeds example
143143
run: cargo run --example dog_breeds
144144
- name: Run wood types example
145145
run: cargo run --example wood_types
146146
- name: Run posql_db example (With Blitzar)
147-
run: bash crates/proof-of-sql/examples/posql_db/run_example.sh
147+
run: bash crates/proof-of-sql-planner/examples/posql_db/run_example.sh
148148
- name: Run posql_db example (Without Blitzar)
149-
run: bash crates/proof-of-sql/examples/posql_db/run_example.sh --no-default-features --features="rayon"
149+
run: bash crates/proof-of-sql-planner/examples/posql_db/run_example.sh --no-default-features --features="proof-of-sql/rayon"
150150

151151
clippy:
152152
name: Clippy

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ ark-serialize = { version = "0.5.0" }
2121
ark-std = { version = "0.5.0", default-features = false }
2222
arrayvec = { version = "0.7", default-features = false }
2323
arrow = { version = "51.0.0" }
24-
arrow-csv = { version = "51.0.0" }
2524
bincode = { version = "2.0.0-rc.3", default-features = false }
2625
bit-iter = { version = "1.1.1" }
2726
bigdecimal = { version = "0.4.5", default-features = false, features = ["serde"] }
@@ -62,7 +61,7 @@ proptest-derive = { version = "0.5.1" }
6261
rand = { version = "0.8", default-features = false }
6362
rand_chacha = { version = "0.3.1" }
6463
rand_core = { version = "0.6", default-features = false }
65-
rayon = { version = "1.5" }
64+
rayon = { version = "1.11.0" }
6665
serde = { version = "1", default-features = false }
6766
serde_json = { version = "1", default-features = false, features = ["alloc"] }
6867
sha2 = { version = "0.10.8", default-features = false }

crates/proof-of-sql-planner/Cargo.toml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ crate-type = ["cdylib", "rlib"]
1414
[dependencies]
1515
ahash = { workspace = true }
1616
arrow = { workspace = true }
17+
clap = { workspace = true, features = ["derive", "env"]}
1718
datafusion = { workspace = true }
1819
# getrandom and uuid must be compiled with js feature
1920
getrandom = { workspace = true, features = ["js"] }
2021
indexmap = { workspace = true }
22+
postcard = { workspace = true }
2123
proof-of-sql = { workspace = true, features = ["arrow"] }
24+
rand = { workspace = true, default-features = false }
2225
serde = { workspace = true }
2326
snafu = { workspace = true }
2427
sqlparser = { workspace = true }
@@ -34,5 +37,70 @@ hex = { workspace = true }
3437
itertools = { workspace = true }
3538
proof-of-sql = { workspace = true, features = ["arrow", "hyperkzg_proof"] }
3639

40+
[package.metadata.cargo-udeps.ignore]
41+
normal = ["clap", "postcard"]
42+
3743
[lints]
3844
workspace = true
45+
46+
[features]
47+
cpu-perf = ["proof-of-sql/cpu-perf"]
48+
49+
[[example]]
50+
name = "hello_world"
51+
required-features = ["proof-of-sql/test"]
52+
53+
[[example]]
54+
name = "posql_db"
55+
required-features = ["proof-of-sql/utils"]
56+
57+
[[example]]
58+
name = "space"
59+
60+
[[example]]
61+
name = "dog_breeds"
62+
63+
[[example]]
64+
name = "wood_types"
65+
66+
[[example]]
67+
name = "dinosaurs"
68+
69+
[[example]]
70+
name = "books"
71+
72+
[[example]]
73+
name = "programming_books"
74+
75+
[[example]]
76+
name = "brands"
77+
78+
[[example]]
79+
name = "census"
80+
81+
[[example]]
82+
name = "plastics"
83+
84+
[[example]]
85+
name = "avocado-prices"
86+
87+
[[example]]
88+
name = "sushi"
89+
90+
[[example]]
91+
name = "stocks"
92+
93+
[[example]]
94+
name = "tech_gadget_prices"
95+
96+
[[example]]
97+
name = "albums"
98+
99+
[[example]]
100+
name = "vehicles"
101+
102+
[[example]]
103+
name = "countries"
104+
105+
[[example]]
106+
name = "rockets"
File renamed without changes.

crates/proof-of-sql/examples/albums/main.rs renamed to crates/proof-of-sql-planner/examples/albums/main.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
//! To run this, use `cargo run --release --example albums`.
33
//!
44
//! NOTE: If this doesn't work because you do not have the appropriate GPU drivers installed,
5-
//! you can run `cargo run --release --example albums --no-default-features --features="arrow cpu-perf"` instead. It will be slower for proof generation.
5+
//! you can run `cargo run --release --example albums --no-default-features --features="cpu-perf"` instead. It will be slower for proof generation.
66
7-
use arrow::datatypes::SchemaRef;
8-
use arrow_csv::{infer_schema_from_files, ReaderBuilder};
7+
use datafusion::{
8+
arrow::{
9+
csv::{infer_schema_from_files, ReaderBuilder},
10+
datatypes::SchemaRef,
11+
record_batch::RecordBatch,
12+
util::pretty::pretty_format_batches,
13+
},
14+
config::ConfigOptions,
15+
};
916
use proof_of_sql::{
1017
base::database::{
1118
arrow_schema_utility::get_posql_compatible_schema, OwnedTable, OwnedTableTestAccessor,
@@ -14,11 +21,11 @@ use proof_of_sql::{
1421
proof_primitive::dory::{
1522
DynamicDoryEvaluationProof, ProverSetup, PublicParameters, VerifierSetup,
1623
},
17-
sql::{
18-
parse::QueryExpr, postprocessing::apply_postprocessing_steps, proof::VerifiableQueryResult,
19-
},
24+
sql::proof::VerifiableQueryResult,
2025
};
26+
use proof_of_sql_planner::sql_to_proof_plans;
2127
use rand::{rngs::StdRng, SeedableRng};
28+
use sqlparser::{dialect::GenericDialect, parser::Parser};
2229
use std::{fs::File, time::Instant};
2330

2431
// We generate the public parameters and the setups used by the prover and verifier for the Dory PCS.
@@ -38,14 +45,16 @@ fn prove_and_verify_query(
3845
// Parse the query:
3946
println!("Parsing the query: {sql}...");
4047
let now = Instant::now();
41-
let query_plan = QueryExpr::try_new(sql.parse().unwrap(), "albums".into(), accessor).unwrap();
48+
let config = ConfigOptions::default();
49+
let statements = Parser::parse_sql(&GenericDialect {}, sql).unwrap();
50+
let query_plan = &sql_to_proof_plans(&statements, accessor, &config).unwrap()[0];
4251
println!("Done in {} ms.", now.elapsed().as_secs_f64() * 1000.);
4352

4453
// Generate the proof and result:
4554
print!("Generating proof...");
4655
let now = Instant::now();
4756
let verifiable_result = VerifiableQueryResult::<DynamicDoryEvaluationProof>::new(
48-
query_plan.proof_expr(),
57+
query_plan,
4958
accessor,
5059
&prover_setup,
5160
&[],
@@ -56,15 +65,17 @@ fn prove_and_verify_query(
5665
// Verify the result with the proof:
5766
print!("Verifying proof...");
5867
let now = Instant::now();
59-
let result = verifiable_result
60-
.verify(query_plan.proof_expr(), accessor, &verifier_setup, &[])
68+
let result: RecordBatch = verifiable_result
69+
.verify(query_plan, accessor, &verifier_setup, &[])
70+
.unwrap()
71+
.table
72+
.try_into()
6173
.unwrap();
62-
let result = apply_postprocessing_steps(result.table, query_plan.postprocessing());
6374
println!("Verified in {} ms.", now.elapsed().as_secs_f64() * 1000.);
6475

6576
// Display the result
6677
println!("Query Result:");
67-
println!("{result:?}");
78+
println!("{}", pretty_format_batches(&[result]).unwrap());
6879
}
6980

7081
fn main() {
@@ -73,7 +84,7 @@ fn main() {
7384
let prover_setup = ProverSetup::from(&public_parameters);
7485
let verifier_setup = VerifierSetup::from(&public_parameters);
7586

76-
let filename = "crates/proof-of-sql/examples/albums/albums.csv";
87+
let filename = "crates/proof-of-sql-planner/examples/albums/albums.csv";
7788
let schema = get_posql_compatible_schema(&SchemaRef::new(
7889
infer_schema_from_files(&[filename.to_string()], b',', None, true).unwrap(),
7990
));
@@ -96,15 +107,15 @@ fn main() {
96107

97108
// Query 1: Count number of albums by genre
98109
prove_and_verify_query(
99-
"SELECT genre, COUNT(*) AS album_count FROM albums.collection GROUP BY genre ORDER BY genre",
110+
"SELECT genre, COUNT(*) AS album_count FROM albums.collection GROUP BY genre",
100111
&accessor,
101112
&prover_setup,
102113
&verifier_setup,
103114
);
104115

105116
// Query 2: Find all albums from the 1970s
106117
prove_and_verify_query(
107-
"SELECT artist, album, year FROM albums.collection WHERE year >= 1970 AND year < 1980 ORDER BY year",
118+
"SELECT artist, album, year FROM albums.collection WHERE year >= 1970 AND year < 1980",
108119
&accessor,
109120
&prover_setup,
110121
&verifier_setup,
@@ -120,7 +131,7 @@ fn main() {
120131

121132
// Query 4: List all rock albums after 1975 (using exact matches for Rock genres)
122133
prove_and_verify_query(
123-
"SELECT artist, album, year FROM albums.collection WHERE (genre = 'Rock' OR genre = 'Hard Rock' OR genre = 'Progressive Rock') AND year > 1975 ORDER BY year DESC",
134+
"SELECT artist, album, year FROM albums.collection WHERE (genre = 'Rock' OR genre = 'Hard Rock' OR genre = 'Progressive Rock') AND year > 1975",
124135
&accessor,
125136
&prover_setup,
126137
&verifier_setup,

crates/proof-of-sql/examples/avocado-prices/avocado-prices.csv renamed to crates/proof-of-sql-planner/examples/avocado-prices/avocado-prices.csv

File renamed without changes.

crates/proof-of-sql/examples/avocado-prices/main.rs renamed to crates/proof-of-sql-planner/examples/avocado-prices/main.rs

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,29 @@
22
//! To run, use `cargo run --example avocado-prices`.
33
//!
44
//! NOTE: If this doesn't work because you do not have the appropriate GPU drivers installed,
5-
//! you can run `cargo run --release --example avocado-prices --no-default-features --features="arrow cpu-perf"` instead. It will be slower for proof generation.
6-
use arrow::datatypes::SchemaRef;
7-
use arrow_csv::{infer_schema_from_files, ReaderBuilder};
5+
//! you can run `cargo run --release --example avocado-prices --no-default-features --features="cpu-perf"` instead. It will be slower for proof generation.
6+
use datafusion::{
7+
arrow::{
8+
csv::{infer_schema_from_files, ReaderBuilder},
9+
datatypes::SchemaRef,
10+
record_batch::RecordBatch,
11+
util::pretty::pretty_format_batches,
12+
},
13+
config::ConfigOptions,
14+
};
815
use proof_of_sql::{
9-
base::database::{OwnedTable, OwnedTableTestAccessor, TableRef},
16+
base::database::{
17+
arrow_schema_utility::get_posql_compatible_schema, OwnedTable, OwnedTableTestAccessor,
18+
TableRef,
19+
},
1020
proof_primitive::dory::{
1121
DynamicDoryEvaluationProof, ProverSetup, PublicParameters, VerifierSetup,
1222
},
13-
sql::{
14-
parse::QueryExpr, postprocessing::apply_postprocessing_steps, proof::VerifiableQueryResult,
15-
},
23+
sql::proof::VerifiableQueryResult,
1624
};
25+
use proof_of_sql_planner::sql_to_proof_plans;
1726
use rand::{rngs::StdRng, SeedableRng};
27+
use sqlparser::{dialect::GenericDialect, parser::Parser};
1828
use std::{fs::File, time::Instant};
1929

2030
// We generate the public parameters and the setups used by the prover and verifier for the Dory PCS.
@@ -42,14 +52,16 @@ fn prove_and_verify_query(
4252
// Parse the query:
4353
println!("Parsing the query: {sql}...");
4454
let now = Instant::now();
45-
let query_plan = QueryExpr::try_new(sql.parse().unwrap(), "avocado".into(), accessor).unwrap();
55+
let config = ConfigOptions::default();
56+
let statements = Parser::parse_sql(&GenericDialect {}, sql).unwrap();
57+
let query_plan = &sql_to_proof_plans(&statements, accessor, &config).unwrap()[0];
4658
println!("Done in {} ms.", now.elapsed().as_secs_f64() * 1000.);
4759

4860
// Generate the proof and result:
4961
print!("Generating proof...");
5062
let now = Instant::now();
5163
let verifiable_result = VerifiableQueryResult::<DynamicDoryEvaluationProof>::new(
52-
query_plan.proof_expr(),
64+
query_plan,
5365
accessor,
5466
&prover_setup,
5567
&[],
@@ -60,15 +72,17 @@ fn prove_and_verify_query(
6072
// Verify the result with the proof:
6173
print!("Verifying proof...");
6274
let now = Instant::now();
63-
let result = verifiable_result
64-
.verify(query_plan.proof_expr(), accessor, &verifier_setup, &[])
75+
let result: RecordBatch = verifiable_result
76+
.verify(query_plan, accessor, &verifier_setup, &[])
77+
.unwrap()
78+
.table
79+
.try_into()
6580
.unwrap();
66-
let result = apply_postprocessing_steps(result.table, query_plan.postprocessing());
6781
println!("Verified in {} ms.", now.elapsed().as_secs_f64() * 1000.);
6882

6983
// Display the result
7084
println!("Query Result:");
71-
println!("{result:?}");
85+
println!("{}", pretty_format_batches(&[result]).unwrap());
7286
}
7387

7488
fn main() {
@@ -77,16 +91,18 @@ fn main() {
7791
let prover_setup = ProverSetup::from(&public_parameters);
7892
let verifier_setup = VerifierSetup::from(&public_parameters);
7993

80-
let filename = "./crates/proof-of-sql/examples/avocado-prices/avocado-prices.csv";
81-
let data_batch = ReaderBuilder::new(SchemaRef::new(
94+
let filename = "crates/proof-of-sql-planner/examples/avocado-prices/avocado-prices.csv";
95+
let schema = get_posql_compatible_schema(&SchemaRef::new(
8296
infer_schema_from_files(&[filename.to_string()], b',', None, true).unwrap(),
83-
))
84-
.with_header(true)
85-
.build(File::open(filename).unwrap())
86-
.unwrap()
87-
.next()
88-
.unwrap()
89-
.unwrap();
97+
));
98+
99+
let data_batch = ReaderBuilder::new(schema.clone())
100+
.with_header(true)
101+
.build(File::open(filename).unwrap())
102+
.unwrap()
103+
.next()
104+
.unwrap()
105+
.unwrap();
90106

91107
// Load the table into an "Accessor" so that the prover and verifier can access the data/commitments.
92108
let accessor = OwnedTableTestAccessor::<DynamicDoryEvaluationProof>::new_from_table(
@@ -97,19 +113,19 @@ fn main() {
97113
);
98114

99115
prove_and_verify_query(
100-
"SELECT COUNT(*) AS total FROM prices",
116+
"SELECT COUNT(*) AS total FROM avocado.prices",
101117
&accessor,
102118
&prover_setup,
103119
&verifier_setup,
104120
);
105121
prove_and_verify_query(
106-
"SELECT Price, COUNT(*) AS total FROM prices GROUP BY Price ORDER BY total",
122+
"SELECT Price, COUNT(*) AS total FROM avocado.prices GROUP BY Price",
107123
&accessor,
108124
&prover_setup,
109125
&verifier_setup,
110126
);
111127
prove_and_verify_query(
112-
"SELECT Year, COUNT(*) AS total FROM prices WHERE Price > 100 GROUP BY Year ORDER BY total DESC LIMIT 5",
128+
"SELECT Year, COUNT(*) AS total FROM avocado.prices WHERE Price > 100 GROUP BY Year",
113129
&accessor,
114130
&prover_setup,
115131
&verifier_setup,
File renamed without changes.

0 commit comments

Comments
 (0)