aegis-query
SQL query engine with parsing, analysis, planning, and execution.
Overview
The aegis-query crate implements a complete SQL query processing pipeline. It parses SQL statements, performs semantic analysis, generates optimized query plans, and executes them using a Volcano-style iterator model.
Modules
parser.rs
SQL parser using sqlparser-rs:
Parser Struct:
pub struct Parser {
dialect: GenericDialect,
}
impl Parser {
pub fn new() -> Self;
pub fn parse(&self, sql: &str) -> Result<Vec<Statement>>;
pub fn parse_single(&self, sql: &str) -> Result<Statement>;
}
Supported Statements:
- SELECT (with JOIN, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT)
- INSERT (VALUES and SELECT subqueries)
- UPDATE
- DELETE
- CREATE TABLE
- DROP TABLE
- ALTER TABLE (ADD/DROP/RENAME COLUMN, ALTER COLUMN, RENAME TABLE)
- CREATE INDEX
- DROP INDEX
- BEGIN, COMMIT, ROLLBACK
ast.rs
Internal AST representation:
Statement Types:
SelectStatement- SELECT queriesInsertStatement- INSERT operations (VALUES and SELECT subqueries)UpdateStatement- UPDATE operationsDeleteStatement- DELETE operationsCreateTableStatement- DDL for creating tablesDropTableStatement- DDL for dropping tablesAlterTableStatement- DDL for modifying tablesCreateIndexStatement- DDL for creating indexesDropIndexStatement- DDL for dropping indexes
Expression Types:
- Literals (Null, Boolean, Integer, Float, String)
- Column references
- Binary operations (+, -, *, /, =, <>, <, >, AND, OR, etc.)
- Unary operations (NOT, -)
- Function calls
- CASE expressions
- CAST expressions
- Subqueries
- IN, BETWEEN, LIKE, IS NULL
analyzer.rs
Semantic analysis and type checking:
Analyzer Struct:
pub struct Analyzer {
catalog: Catalog,
}
impl Analyzer {
pub fn new(catalog: Catalog) -> Self;
pub fn analyze(&self, stmt: &Statement) -> Result<AnalyzedStatement>;
}
Features:
- Table and column resolution
- Type inference
- Semantic validation
- Schema compatibility checking
planner.rs
Cost-based query planner:
Plan Nodes:
ScanNode- Table scan (sequential or index)FilterNode- Predicate filteringProjectNode- Column projectionJoinNode- Join operationsAggregateNode- AggregationSortNode- OrderingLimitNode- Row limitingCreateTableNode- CREATE TABLEDropTableNode- DROP TABLEAlterTableNode- ALTER TABLECreateIndexNode- CREATE INDEXDropIndexNode- DROP INDEXInsertNode- INSERT (with InsertPlanSource for VALUES/SELECT)UpdateNode- UPDATEDeleteNode- DELETE
Join Strategies:
- NestedLoop
- HashJoin
- MergeJoin
Cost Estimation:
- Row count estimation
- Operation cost modeling
- Join strategy selection
executor.rs
Volcano-style query executor:
Operator Trait:
pub trait Operator: Send {
fn next_batch(&mut self) -> ExecutorResult<Option<ResultBatch>>;
fn columns(&self) -> &[String];
}
Operators:
ScanOperator- Table scanningFilterOperator- Row filteringProjectOperator- Column projectionJoinOperator- Join executionAggregateOperator- Aggregation with accumulatorsSortOperator- In-memory sortingLimitOperator- Row limiting with offset
Aggregate Functions:
- COUNT, SUM, AVG, MIN, MAX
Scalar Functions:
- UPPER, LOWER, LENGTH, ABS, COALESCE
Usage
use aegis_query::{Parser, Analyzer, Planner, Executor};
let parser = Parser::new();
let stmt = parser.parse_single("SELECT * FROM users WHERE age > 18")?;
let analyzer = Analyzer::new(catalog);
let analyzed = analyzer.analyze(&stmt)?;
let planner = Planner::new(schema);
let plan = planner.plan(&analyzed)?;
let executor = Executor::new(context);
let result = executor.execute(&plan)?;
Tests
27 tests covering parsing, analysis, planning, and execution.