use crate::{
base::{
database::{ColumnField, ColumnRef, ColumnType, LiteralValue, TableRef},
try_standard_binary_deserialization, try_standard_binary_serialization,
},
sql::{
evm_proof_plan::EVMProofPlan,
proof_exprs::{AliasedDynProofExpr, ColumnExpr, DynProofExpr, EqualsExpr, LiteralExpr},
proof_plans::{DynProofPlan, FilterExec, TableExec},
},
};
use alloc::boxed::Box;
use core::iter;
use sqlparser::ast::Ident;
use std::sync::LazyLock;
static SIMPLE_FILTER_SERIALIZED_BYTES: LazyLock<Vec<u8>> = LazyLock::new(|| {
iter::empty()
.chain(&1_usize.to_be_bytes()) .chain(&15_usize.to_be_bytes()) .chain("namespace.table".as_bytes())
.chain(&2_usize.to_be_bytes()) .chain(&0_usize.to_be_bytes()) .chain(&1_usize.to_be_bytes()) .chain("a".as_bytes()) .chain(&5_u32.to_be_bytes()) .chain(&0_usize.to_be_bytes()) .chain(&1_usize.to_be_bytes()) .chain("b".as_bytes()) .chain(&5_u32.to_be_bytes()) .chain(&1_usize.to_be_bytes()) .chain(&5_usize.to_be_bytes()) .chain("alias".as_bytes()) .chain(&8_u32.to_be_bytes()) .chain(&2_u32.to_be_bytes()) .chain(&0_usize.to_be_bytes()) .chain(&2_usize.to_be_bytes()) .chain(&0_usize.to_be_bytes()) .chain(&1_usize.to_be_bytes()) .chain(&2_u32.to_be_bytes()) .chain(&0_u32.to_be_bytes()) .chain(&0_usize.to_be_bytes()) .chain(&1_u32.to_be_bytes()) .chain(&5_u32.to_be_bytes()) .chain(&5_i64.to_be_bytes()) .chain(&1_usize.to_be_bytes()) .chain(&0_u32.to_be_bytes()) .chain(&1_usize.to_be_bytes()) .copied()
.collect()
});
#[test]
fn we_can_generate_serialized_proof_plan_for_simple_filter() {
let table_ref: TableRef = "namespace.table".parse().unwrap();
let identifier_a: Ident = "a".into();
let identifier_b: Ident = "b".into();
let identifier_alias: Ident = "alias".into();
let column_ref_a = ColumnRef::new(table_ref.clone(), identifier_a.clone(), ColumnType::BigInt);
let column_ref_b = ColumnRef::new(table_ref.clone(), identifier_b.clone(), ColumnType::BigInt);
let column_fields = vec![
ColumnField::new(identifier_a, ColumnType::BigInt),
ColumnField::new(identifier_b, ColumnType::BigInt),
];
let table_exec = TableExec::new(table_ref, column_fields);
let plan = DynProofPlan::Filter(FilterExec::new(
vec![AliasedDynProofExpr {
expr: DynProofExpr::Column(ColumnExpr::new(column_ref_b)),
alias: identifier_alias,
}],
Box::new(DynProofPlan::Table(table_exec)),
DynProofExpr::Equals(
EqualsExpr::try_new(
Box::new(DynProofExpr::Column(ColumnExpr::new(column_ref_a))),
Box::new(DynProofExpr::Literal(LiteralExpr::new(
LiteralValue::BigInt(5),
))),
)
.unwrap(),
),
));
let bytes = try_standard_binary_serialization(EVMProofPlan::new(plan)).unwrap();
assert_eq!(bytes, *SIMPLE_FILTER_SERIALIZED_BYTES);
}
#[test]
fn we_can_deserialize_proof_plan_for_simple_filter() {
let table_ref: TableRef = "namespace.table".parse().unwrap();
let identifier_a: Ident = "a".into();
let identifier_b: Ident = "b".into();
let empty_table_ref = TableRef::from_names(None, "");
let column_ref_a = ColumnRef::new(
empty_table_ref.clone(),
identifier_a.clone(),
ColumnType::BigInt,
);
let column_ref_b = ColumnRef::new(empty_table_ref, identifier_b.clone(), ColumnType::BigInt);
let column_fields = vec![
ColumnField::new(identifier_a, ColumnType::BigInt),
ColumnField::new(identifier_b, ColumnType::BigInt),
];
let table_exec = TableExec::new(table_ref, column_fields);
let expected_plan = DynProofPlan::Filter(FilterExec::new(
vec![AliasedDynProofExpr {
expr: DynProofExpr::Column(ColumnExpr::new(column_ref_b)),
alias: Ident::new("alias"),
}],
Box::new(DynProofPlan::Table(table_exec)),
DynProofExpr::Equals(
EqualsExpr::try_new(
Box::new(DynProofExpr::Column(ColumnExpr::new(column_ref_a))),
Box::new(DynProofExpr::Literal(LiteralExpr::new(
LiteralValue::BigInt(5),
))),
)
.unwrap(),
),
));
let deserialized =
try_standard_binary_deserialization::<EVMProofPlan>(&SIMPLE_FILTER_SERIALIZED_BYTES)
.unwrap();
let plan = deserialized.0.inner();
assert_eq!(plan, &expected_plan);
}