# Phase 10 Advanced Database Features > Implementation plan for SQL, Graph, and Replication features in Synor Database L2 ## Overview These advanced features extend the Synor Database to support: 1. **Relational (SQL)** - SQLite-compatible query subset for structured data 2. **Graph Store** - Relationship queries for connected data 3. **Replication** - Raft consensus for high availability ## Feature 1: Relational (SQL) Store ### Purpose Provide a familiar SQL interface for developers who need structured relational queries, joins, and ACID transactions. ### Architecture ```text ┌─────────────────────────────────────────────────────────────┐ │ SQL QUERY LAYER │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ SQL Parser │ │ Planner │ │ Executor │ │ │ │ (sqlparser) │ │ (logical) │ │ (physical) │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Table Storage Engine │ │ │ │ - Row-oriented storage │ │ │ │ - B-tree indexes │ │ │ │ - Transaction log (WAL) │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### Supported SQL Subset | Category | Statements | |----------|------------| | DDL | CREATE TABLE, DROP TABLE, ALTER TABLE | | DML | SELECT, INSERT, UPDATE, DELETE | | Clauses | WHERE, ORDER BY, LIMIT, OFFSET, GROUP BY, HAVING | | Joins | INNER JOIN, LEFT JOIN, RIGHT JOIN | | Functions | COUNT, SUM, AVG, MIN, MAX, COALESCE | | Operators | =, !=, <, >, <=, >=, AND, OR, NOT, IN, LIKE | ### Data Types | SQL Type | Rust Type | Storage | |----------|-----------|---------| | INTEGER | i64 | 8 bytes | | REAL | f64 | 8 bytes | | TEXT | String | Variable | | BLOB | Vec | Variable | | BOOLEAN | bool | 1 byte | | TIMESTAMP | u64 | 8 bytes (Unix ms) | ### Implementation Components ``` crates/synor-database/src/sql/ ├── mod.rs # Module exports ├── parser.rs # SQL parsing (sqlparser-rs) ├── planner.rs # Query planning & optimization ├── executor.rs # Query execution engine ├── table.rs # Table definition & storage ├── row.rs # Row representation ├── types.rs # SQL type system ├── transaction.rs # ACID transactions └── index.rs # SQL-specific indexing ``` ### API Design ```rust // Table definition pub struct TableDef { pub name: String, pub columns: Vec, pub primary_key: Option, pub indexes: Vec, } pub struct ColumnDef { pub name: String, pub data_type: SqlType, pub nullable: bool, pub default: Option, } // SQL execution pub struct SqlEngine { tables: HashMap, transaction_log: TransactionLog, } impl SqlEngine { pub fn execute(&mut self, sql: &str) -> Result; pub fn begin_transaction(&mut self) -> TransactionId; pub fn commit(&mut self, txn: TransactionId) -> Result<(), SqlError>; pub fn rollback(&mut self, txn: TransactionId); } ``` ### Gateway Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/db/:db/sql` | POST | Execute SQL query | | `/db/:db/sql/tables` | GET | List tables | | `/db/:db/sql/tables/:table` | GET | Get table schema | | `/db/:db/sql/tables/:table` | DELETE | Drop table | --- ## Feature 2: Graph Store ### Purpose Enable relationship-based queries for social networks, knowledge graphs, recommendation engines, and any connected data. ### Architecture ```text ┌─────────────────────────────────────────────────────────────┐ │ GRAPH QUERY LAYER │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Graph Query │ │ Traversal │ │ Path Finding │ │ │ │ Parser │ │ Engine │ │ (Dijkstra) │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Graph Storage Engine │ │ │ │ - Adjacency list storage │ │ │ │ - Edge index (source, target, type) │ │ │ │ - Property storage │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### Data Model ```text Node (Vertex): - id: NodeId (32 bytes) - labels: Vec - properties: JsonValue Edge (Relationship): - id: EdgeId (32 bytes) - source: NodeId - target: NodeId - edge_type: String - properties: JsonValue - directed: bool ``` ### Query Language (Simplified Cypher-like) ``` // Find all friends of user Alice MATCH (a:User {name: "Alice"})-[:FRIEND]->(friend) RETURN friend // Find shortest path between two nodes MATCH path = shortestPath((a:User {id: "123"})-[*]-(b:User {id: "456"})) RETURN path // Find mutual friends MATCH (a:User {name: "Alice"})-[:FRIEND]->(mutual)<-[:FRIEND]-(b:User {name: "Bob"}) RETURN mutual ``` ### Implementation Components ``` crates/synor-database/src/graph/ ├── mod.rs # Module exports ├── node.rs # Node definition & storage ├── edge.rs # Edge definition & storage ├── store.rs # Graph storage engine ├── query.rs # Query language parser ├── traversal.rs # Graph traversal algorithms ├── path.rs # Path finding (BFS, DFS, Dijkstra) └── index.rs # Graph-specific indexes ``` ### API Design ```rust pub struct Node { pub id: NodeId, pub labels: Vec, pub properties: JsonValue, } pub struct Edge { pub id: EdgeId, pub source: NodeId, pub target: NodeId, pub edge_type: String, pub properties: JsonValue, } pub struct GraphStore { nodes: HashMap, edges: HashMap, adjacency: HashMap>, // outgoing reverse_adj: HashMap>, // incoming } impl GraphStore { // Node operations pub fn create_node(&mut self, labels: Vec, props: JsonValue) -> NodeId; pub fn get_node(&self, id: &NodeId) -> Option<&Node>; pub fn update_node(&mut self, id: &NodeId, props: JsonValue) -> Result<(), GraphError>; pub fn delete_node(&mut self, id: &NodeId) -> Result<(), GraphError>; // Edge operations pub fn create_edge(&mut self, source: NodeId, target: NodeId, edge_type: &str, props: JsonValue) -> EdgeId; pub fn get_edge(&self, id: &EdgeId) -> Option<&Edge>; pub fn delete_edge(&mut self, id: &EdgeId) -> Result<(), GraphError>; // Traversal pub fn neighbors(&self, id: &NodeId, direction: Direction) -> Vec<&Node>; pub fn edges_of(&self, id: &NodeId, direction: Direction) -> Vec<&Edge>; pub fn shortest_path(&self, from: &NodeId, to: &NodeId) -> Option>; pub fn traverse(&self, start: &NodeId, query: &TraversalQuery) -> Vec; } ``` ### Gateway Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/db/:db/graph/nodes` | POST | Create node | | `/db/:db/graph/nodes/:id` | GET | Get node | | `/db/:db/graph/nodes/:id` | PUT | Update node | | `/db/:db/graph/nodes/:id` | DELETE | Delete node | | `/db/:db/graph/edges` | POST | Create edge | | `/db/:db/graph/edges/:id` | GET | Get edge | | `/db/:db/graph/edges/:id` | DELETE | Delete edge | | `/db/:db/graph/query` | POST | Execute graph query | | `/db/:db/graph/path` | POST | Find shortest path | | `/db/:db/graph/traverse` | POST | Traverse from node | --- ## Feature 3: Replication (Raft Consensus) ### Purpose Provide high availability and fault tolerance through distributed consensus, ensuring data consistency across multiple nodes. ### Architecture ```text ┌─────────────────────────────────────────────────────────────┐ │ RAFT CONSENSUS LAYER │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Leader │ │ Follower │ │ Candidate │ │ │ │ Election │ │ Replication │ │ (Election) │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Log Replication │ │ │ │ - Append entries │ │ │ │ - Commit index │ │ │ │ - Log compaction (snapshots) │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ State Machine │ │ │ │ - Apply committed entries │ │ │ │ - Database operations │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### Raft Protocol Overview ```text Leader Election: 1. Followers timeout → become Candidate 2. Candidate requests votes from peers 3. Majority votes → become Leader 4. Leader sends heartbeats to maintain authority Log Replication: 1. Client sends write to Leader 2. Leader appends to local log 3. Leader replicates to Followers 4. Majority acknowledge → entry committed 5. Leader applies to state machine 6. Leader responds to client ``` ### Implementation Components ``` crates/synor-database/src/replication/ ├── mod.rs # Module exports ├── raft.rs # Core Raft implementation ├── state.rs # Node state (Leader/Follower/Candidate) ├── log.rs # Replicated log ├── rpc.rs # RPC messages (AppendEntries, RequestVote) ├── election.rs # Leader election logic ├── snapshot.rs # Log compaction & snapshots ├── cluster.rs # Cluster membership └── client.rs # Client for forwarding to leader ``` ### API Design ```rust #[derive(Clone, Copy, PartialEq)] pub enum NodeRole { Leader, Follower, Candidate, } pub struct RaftConfig { pub node_id: u64, pub peers: Vec, pub election_timeout_ms: (u64, u64), // min, max pub heartbeat_interval_ms: u64, pub snapshot_threshold: u64, } pub struct LogEntry { pub term: u64, pub index: u64, pub command: Command, } pub enum Command { // Database operations KvSet { key: String, value: Vec }, KvDelete { key: String }, DocInsert { collection: String, doc: JsonValue }, DocUpdate { collection: String, id: DocumentId, update: JsonValue }, DocDelete { collection: String, id: DocumentId }, // ... other operations } pub struct RaftNode { config: RaftConfig, state: RaftState, log: ReplicatedLog, state_machine: Arc, } impl RaftNode { pub async fn start(&mut self) -> Result<(), RaftError>; pub async fn propose(&self, command: Command) -> Result<(), RaftError>; pub fn is_leader(&self) -> bool; pub fn leader_id(&self) -> Option; pub fn status(&self) -> ClusterStatus; } // RPC Messages pub struct AppendEntries { pub term: u64, pub leader_id: u64, pub prev_log_index: u64, pub prev_log_term: u64, pub entries: Vec, pub leader_commit: u64, } pub struct RequestVote { pub term: u64, pub candidate_id: u64, pub last_log_index: u64, pub last_log_term: u64, } ``` ### Cluster Configuration ```yaml # docker-compose.raft.yml services: db-node-1: image: synor/database:latest environment: RAFT_NODE_ID: 1 RAFT_PEERS: "db-node-2:5000,db-node-3:5000" RAFT_ELECTION_TIMEOUT: "150-300" RAFT_HEARTBEAT_MS: 50 ports: - "8484:8484" # HTTP API - "5000:5000" # Raft RPC db-node-2: image: synor/database:latest environment: RAFT_NODE_ID: 2 RAFT_PEERS: "db-node-1:5000,db-node-3:5000" ports: - "8485:8484" - "5001:5000" db-node-3: image: synor/database:latest environment: RAFT_NODE_ID: 3 RAFT_PEERS: "db-node-1:5000,db-node-2:5000" ports: - "8486:8484" - "5002:5000" ``` ### Gateway Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/cluster/status` | GET | Get cluster status | | `/cluster/leader` | GET | Get current leader | | `/cluster/nodes` | GET | List all nodes | | `/cluster/nodes/:id` | DELETE | Remove node from cluster | | `/cluster/nodes` | POST | Add node to cluster | --- ## Implementation Order ### Step 1: SQL Store 1. Add `sqlparser` dependency 2. Implement type system (`types.rs`) 3. Implement row storage (`row.rs`, `table.rs`) 4. Implement SQL parser wrapper (`parser.rs`) 5. Implement query planner (`planner.rs`) 6. Implement query executor (`executor.rs`) 7. Add transaction support (`transaction.rs`) 8. Add gateway endpoints 9. Write tests ### Step 2: Graph Store 1. Implement node/edge types (`node.rs`, `edge.rs`) 2. Implement graph storage (`store.rs`) 3. Implement query parser (`query.rs`) 4. Implement traversal algorithms (`traversal.rs`, `path.rs`) 5. Add graph indexes (`index.rs`) 6. Add gateway endpoints 7. Write tests ### Step 3: Replication 1. Implement Raft state machine (`state.rs`, `raft.rs`) 2. Implement replicated log (`log.rs`) 3. Implement RPC layer (`rpc.rs`) 4. Implement leader election (`election.rs`) 5. Implement log compaction (`snapshot.rs`) 6. Implement cluster management (`cluster.rs`) 7. Integrate with database operations 8. Add gateway endpoints 9. Write tests 10. Create Docker Compose for cluster --- ## Pricing Impact | Feature | Operation | Cost (SYNOR) | |---------|-----------|--------------| | SQL | Query/million | 0.02 | | SQL | Write/million | 0.05 | | Graph | Traversal/million | 0.03 | | Graph | Path query/million | 0.05 | | Replication | Included | Base storage cost | --- ## Success Criteria ### SQL Store - [ ] Parse and execute basic SELECT, INSERT, UPDATE, DELETE - [ ] Support WHERE clauses with operators - [ ] Support ORDER BY, LIMIT, OFFSET - [ ] Support simple JOINs - [ ] Support aggregate functions - [ ] ACID transactions ### Graph Store - [ ] Create/read/update/delete nodes and edges - [ ] Traverse neighbors (in/out/both) - [ ] Find shortest path between nodes - [ ] Execute pattern matching queries - [ ] Support property filters ### Replication - [ ] Leader election works correctly - [ ] Log replication achieves consensus - [ ] Reads from any node (eventual consistency) - [ ] Writes only through leader - [ ] Node failure handled gracefully - [ ] Log compaction reduces storage