use real_rs::algebra::{
AggregateFunc, AggregateType, ColumnRef, CompareOp, Expr, JoinCondition, Operand, Predicate,
SortOrder,
};
use real_rs::backends::postgres::PostgresBackend;
use real_rs::backends::Backend;
use real_rs::schema::{DataType, Schema, Value};
use real_rs::Result;
fn main() -> Result<()> {
println!("🚀 real-rs PostgreSQL SQL Compilation Demo\n");
println!("{}", "=".repeat(70));
let backend = PostgresBackend::new();
demo_selection(&backend)?;
demo_projection(&backend)?;
demo_join(&backend)?;
demo_aggregation(&backend)?;
demo_complex_query(&backend)?;
demo_advanced_predicates(&backend)?;
println!("\n🎉 All SQL compilation demos completed!");
println!("\nKey Achievement: Same relational algebra compiles to PostgreSQL SQL!");
Ok(())
}
fn demo_selection(backend: &PostgresBackend) -> Result<()> {
println!("\n📌 Demo 1: Selection (σ) - WHERE clause");
println!("{}", "-".repeat(70));
let schema = Schema::new("users")
.with_column("id", DataType::Integer)
.with_column("name", DataType::String)
.with_column("age", DataType::Integer);
let query = Expr::relation("users", schema).select(Predicate::Compare {
left: ColumnRef::new("age"),
op: CompareOp::Gt,
right: Operand::Literal(Value::Integer(28)),
});
let compiled = backend.compile(&query)?;
println!("🔧 Algebra: σ(age > 28) users");
println!("📝 SQL: {}", compiled.sql);
println!("📦 Params: {:?}", compiled.params);
Ok(())
}
fn demo_projection(backend: &PostgresBackend) -> Result<()> {
println!("\n📌 Demo 2: Projection (π) - SELECT specific columns");
println!("{}", "-".repeat(70));
let schema = Schema::new("users")
.with_column("name", DataType::String)
.with_column("email", DataType::String);
let query = Expr::relation("users", schema)
.project(vec!["name".to_string(), "email".to_string()]);
let compiled = backend.compile(&query)?;
println!("🔧 Algebra: π(name, email) users");
println!("📝 SQL: {}", compiled.sql);
Ok(())
}
fn demo_join(backend: &PostgresBackend) -> Result<()> {
println!("\n📌 Demo 3: Join (⨝) - JOIN tables");
println!("{}", "-".repeat(70));
let users = Schema::new("users")
.with_column("id", DataType::Integer)
.with_column("name", DataType::String);
let orders = Schema::new("orders")
.with_column("user_id", DataType::Integer)
.with_column("amount", DataType::Float);
let query = Expr::relation("users", users).join(
Expr::relation("orders", orders),
JoinCondition::On(Predicate::Compare {
left: ColumnRef::qualified("users", "id"),
op: CompareOp::Eq,
right: Operand::Column(ColumnRef::qualified("orders", "user_id")),
}),
);
let compiled = backend.compile(&query)?;
println!("🔧 Algebra: users ⨝ orders ON users.id = orders.user_id");
println!("📝 SQL: {}", compiled.sql);
Ok(())
}
fn demo_aggregation(backend: &PostgresBackend) -> Result<()> {
println!("\n📌 Demo 4: Aggregation (γ) - GROUP BY");
println!("{}", "-".repeat(70));
let schema = Schema::new("orders")
.with_column("user_id", DataType::Integer)
.with_column("amount", DataType::Float);
let query = Expr::Aggregate {
input: Box::new(Expr::relation("orders", schema)),
group_by: vec!["user_id".to_string()],
aggregates: vec![
AggregateFunc {
name: "order_count".to_string(),
func: AggregateType::Count,
input: "id".to_string(),
},
AggregateFunc {
name: "total_spent".to_string(),
func: AggregateType::Sum,
input: "amount".to_string(),
},
],
};
let compiled = backend.compile(&query)?;
println!("🔧 Algebra: γ(user_id; COUNT(id), SUM(amount)) orders");
println!("📝 SQL: {}", compiled.sql);
Ok(())
}
fn demo_complex_query(backend: &PostgresBackend) -> Result<()> {
println!("\n📌 Demo 5: Complex Query - Composition");
println!("{}", "-".repeat(70));
println!("Query: Top 5 NY users by spending, ordered descending\n");
let users = Schema::new("users")
.with_column("id", DataType::Integer)
.with_column("name", DataType::String)
.with_column("city", DataType::String);
let orders = Schema::new("orders")
.with_column("user_id", DataType::Integer)
.with_column("amount", DataType::Float);
let ny_users = Expr::relation("users", users).select(Predicate::Compare {
left: ColumnRef::new("city"),
op: CompareOp::Eq,
right: Operand::Literal(Value::String("New York".to_string())),
});
let joined = ny_users.join(
Expr::relation("orders", orders),
JoinCondition::On(Predicate::Compare {
left: ColumnRef::qualified("users", "id"),
op: CompareOp::Eq,
right: Operand::Column(ColumnRef::qualified("orders", "user_id")),
}),
);
let aggregated = Expr::Aggregate {
input: Box::new(joined),
group_by: vec!["name".to_string()],
aggregates: vec![AggregateFunc {
name: "total".to_string(),
func: AggregateType::Sum,
input: "amount".to_string(),
}],
};
let sorted = Expr::Sort {
input: Box::new(aggregated),
columns: vec![("total".to_string(), SortOrder::Desc)],
};
let limited = Expr::Limit {
input: Box::new(sorted),
count: 5,
};
let compiled = backend.compile(&limited)?;
println!("🔧 Steps:");
println!(" 1. σ(city = 'New York') users");
println!(" 2. ⨝ orders");
println!(" 3. γ(name; SUM(amount))");
println!(" 4. Sort DESC");
println!(" 5. LIMIT 5");
println!("\n📝 Generated SQL:");
println!(" {}", compiled.sql);
println!("\n📦 Params: {:?}", compiled.params);
Ok(())
}
fn demo_advanced_predicates(backend: &PostgresBackend) -> Result<()> {
println!("\n📌 Demo 6: Advanced Predicates - IN, LIKE, BETWEEN");
println!("{}", "-".repeat(70));
let schema = Schema::new("products")
.with_column("name", DataType::String)
.with_column("category", DataType::String)
.with_column("price", DataType::Float);
let query = Expr::relation("products", schema).select(Predicate::And(
Box::new(Predicate::In {
column: ColumnRef::new("category"),
values: vec![
Value::String("Electronics".to_string()),
Value::String("Books".to_string()),
],
}),
Box::new(Predicate::And(
Box::new(Predicate::Like {
column: ColumnRef::new("name"),
pattern: "Pro%".to_string(),
}),
Box::new(Predicate::Between {
column: ColumnRef::new("price"),
low: Value::Integer(50),
high: Value::Integer(500),
}),
)),
));
let compiled = backend.compile(&query)?;
println!("🔧 Predicates:");
println!(" • category IN ('Electronics', 'Books')");
println!(" • name LIKE 'Pro%'");
println!(" • price BETWEEN 50 AND 500");
println!("\n📝 SQL:");
println!(" {}", compiled.sql);
println!("\n📦 Params: {:?}", compiled.params);
Ok(())
}