WebAssembly Stored Procedures for HeliosDB
WebAssembly Stored Procedures for HeliosDB
Executive Summary
HeliosDB’s WebAssembly (WASM) Stored Procedures enable polyglot, sandboxed server-side logic written in any language that compiles to WASM (Rust, Python, JavaScript, Go, C++, etc.). This provides:
- Language Freedom: Write procedures in your preferred language
- Security: Sandboxed execution with capability-based security
- Performance: Near-native execution speed with WASM
- Portability: Compile once, run anywhere HeliosDB is deployed
- Future-Proof: Standards-based approach (W3C WebAssembly)
Architecture
High-Level Design
┌─────────────────────────────────────────────────────────────┐│ HeliosDB Core │├─────────────────────────────────────────────────────────────┤│ ││ ┌──────────────────────────────────────────────────────┐ ││ │ WASM Procedure Manager │ ││ │ - Procedure registry │ ││ │ - Version management │ ││ │ - Permission control │ ││ └──────────────────────────────────────────────────────┘ ││ ▲ ││ │ ││ ┌───────────────────────┴──────────────────────────────┐ ││ │ WASM Runtime (wasmer/wasmtime) │ ││ │ - Module loading and caching │ ││ │ - Memory management │ ││ │ - Host function imports │ ││ └──────────────────────────────────────────────────────┘ ││ ▲ ││ │ ││ ┌───────────────────────┴──────────────────────────────┐ ││ │ Host Interface (WASI + HeliosDB API) │ ││ │ - Table access (read/write) │ ││ │ - Transaction control │ ││ │ - Logging and metrics │ ││ │ - External API calls (optional) │ ││ └──────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐│ WASM Procedure Modules │├─────────────────────────────────────────────────────────────┤│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │ Rust │ │ Python │ │ Go │ ││ │ procedure │ │ procedure │ │ procedure │ ││ │ (.wasm) │ │ (.wasm) │ │ (.wasm) │ ││ └─────────────┘ └─────────────┘ └─────────────┘ │└─────────────────────────────────────────────────────────────┘Key Components
- WASM Runtime: wasmer or wasmtime for executing WASM modules
- Procedure Manager: Registry, versioning, and permission control
- Host Interface: Safe API for WASM modules to interact with HeliosDB
- Language SDKs: Helper libraries for each supported language
Supported Languages
Tier 1 (Fully Supported)
- Rust: Native WASM support, zero-overhead
- JavaScript/TypeScript: Via AssemblyScript or QuickJS
- Python: Via RustPython or Pyodide
- Go: Via TinyGo
Tier 2 (Community Support)
- C/C++: Via Emscripten or clang
- C#/.NET: Via Blazor WebAssembly
- Ruby: Via ruby.wasm
- Java: Via TeaVM or JWebAssembly
HeliosDB WASM API
Core Functions
// Host functions available to WASM modules
/// Execute a SQL queryextern "C" fn heliosdb_query( query_ptr: *const u8, query_len: u32, result_ptr: *mut u8, result_len: *mut u32,) -> i32;
/// Get parameter value by indexextern "C" fn heliosdb_get_param( index: u32, value_ptr: *mut u8, value_len: *mut u32,) -> i32;
/// Return a value to the callerextern "C" fn heliosdb_return( value_ptr: *const u8, value_len: u32, value_type: u32, // DataType enum) -> i32;
/// Log a messageextern "C" fn heliosdb_log( level: u32, // debug=0, info=1, warn=2, error=3 message_ptr: *const u8, message_len: u32,) -> i32;
/// Begin a transactionextern "C" fn heliosdb_begin_tx() -> i32;
/// Commit the current transactionextern "C" fn heliosdb_commit_tx() -> i32;
/// Rollback the current transactionextern "C" fn heliosdb_rollback_tx() -> i32;
/// Get current timestampextern "C" fn heliosdb_now() -> i64;
/// Raise an errorextern "C" fn heliosdb_error( code: i32, message_ptr: *const u8, message_len: u32,) -> !;Memory Management
WASM modules have their own linear memory space:
- Export memory: WASM module exports its memory to the host
- Allocation: Host allocates memory in WASM space for large data transfers
- Serialization: JSON or MessagePack for complex data structures
Example Implementations
1. Rust Procedure
use heliosdb_wasm_sdk::*;
#[heliosdb_procedure]fn calculate_discount(customer_id: i64, order_total: f64) -> Result<f64, Error> { // Query customer loyalty tier let query = format!( "SELECT loyalty_tier FROM customers WHERE id = {}", customer_id );
let result = heliosdb_query(&query)?; let tier: String = result.get_string(0)?;
// Calculate discount based on tier let discount_rate = match tier.as_str() { "platinum" => 0.20, "gold" => 0.15, "silver" => 0.10, _ => 0.05, };
let discount = order_total * discount_rate;
// Log for auditing heliosdb_log( LogLevel::Info, &format!("Applied {} discount: ${:.2}", tier, discount), )?;
Ok(discount)}
// Compile: cargo build --target wasm32-wasi --release2. Python Procedure
from heliosdb_wasm import heliosdb_query, heliosdb_log, heliosdb_error
def validate_order(order_id: int) -> bool: """Validate an order has all required items in stock"""
# Get order items query = f""" SELECT product_id, quantity FROM order_items WHERE order_id = {order_id} """
items = heliosdb_query(query)
# Check inventory for each item for item in items: product_id = item['product_id'] quantity = item['quantity']
inventory_query = f""" SELECT available_quantity FROM inventory WHERE product_id = {product_id} """
inventory = heliosdb_query(inventory_query) available = inventory[0]['available_quantity']
if available < quantity: heliosdb_log('warn', f'Insufficient stock for product {product_id}') return False
heliosdb_log('info', f'Order {order_id} validated successfully') return True
# Compile: python -m wasm_compiler validate_order.py -o validate_order.wasm3. JavaScript Procedure
import { heliosdbQuery, heliosdbLog } from 'heliosdb-wasm-sdk';
export function detectFraud(transactionId) { // Get transaction details const query = ` SELECT amount, merchant_id, customer_id, timestamp FROM transactions WHERE id = ${transactionId} `;
const tx = heliosdbQuery(query)[0];
// Check recent transaction velocity const velocityQuery = ` SELECT COUNT(*) as count FROM transactions WHERE customer_id = ${tx.customer_id} AND timestamp > NOW() - INTERVAL '1 hour' `;
const velocity = heliosdbQuery(velocityQuery)[0].count;
// Check amount anomaly const avgQuery = ` SELECT AVG(amount) as avg_amount FROM transactions WHERE customer_id = ${tx.customer_id} AND timestamp > NOW() - INTERVAL '30 days' `;
const avgAmount = heliosdbQuery(avgQuery)[0].avg_amount;
// Fraud detection logic let riskScore = 0;
if (velocity > 10) riskScore += 30; if (tx.amount > avgAmount * 3) riskScore += 40; if (tx.amount > 10000) riskScore += 20;
const isFraud = riskScore >= 50;
heliosdbLog('info', `Transaction ${transactionId} risk score: ${riskScore}`);
return { is_fraud: isFraud, risk_score: riskScore, reason: riskScore >= 50 ? 'High risk detected' : 'Normal' };}
// Compile: asc fraud_detection.js -o fraud_detection.wasm4. Go Procedure
package main
import ( "github.com/heliosdb/wasm-sdk-go")
//export aggregate_salesfunc aggregateSales(startDate string, endDate string) map[string]interface{} { // Query sales data query := fmt.Sprintf(` SELECT DATE(order_date) as date, SUM(total) as daily_total, COUNT(*) as order_count, AVG(total) as avg_order_value FROM orders WHERE order_date BETWEEN '%s' AND '%s' GROUP BY DATE(order_date) ORDER BY date `, startDate, endDate)
results := heliosdb.Query(query)
// Calculate summary statistics var totalRevenue float64 var totalOrders int
for _, row := range results { totalRevenue += row["daily_total"].(float64) totalOrders += row["order_count"].(int) }
heliosdb.Log("info", fmt.Sprintf( "Aggregated %d orders totaling $%.2f", totalOrders, totalRevenue, ))
return map[string]interface{}{ "total_revenue": totalRevenue, "total_orders": totalOrders, "avg_order_value": totalRevenue / float64(totalOrders), "daily_breakdown": results, }}
func main() {}
// Compile: tinygo build -o data_aggregation.wasm -target=wasi data_aggregation.goProcedure Management
Creating a Procedure
-- Register a WASM procedureCREATE PROCEDURE calculate_discount ( customer_id BIGINT, order_total DECIMAL)RETURNS DECIMALLANGUAGE wasmAS $wasm$-- Base64 encoded WASM module or file pathfile://procedures/calculate_discount.wasm$wasm$;Calling a Procedure
-- Simple callSELECT calculate_discount(12345, 599.99);
-- In a querySELECT order_id, total, calculate_discount(customer_id, total) as discount, total - calculate_discount(customer_id, total) as final_totalFROM ordersWHERE status = 'pending';Updating a Procedure
-- Update procedure (creates new version)ALTER PROCEDURE calculate_discountVERSION 2AS $wasm$file://procedures/calculate_discount_v2.wasm$wasm$;
-- Rollback to previous versionALTER PROCEDURE calculate_discountUSE VERSION 1;Dropping a Procedure
DROP PROCEDURE calculate_discount;Security Model
Capability-Based Security
Each procedure has an explicit capability list:
CREATE PROCEDURE fraud_detection (transaction_id BIGINT)RETURNS JSONLANGUAGE wasmCAPABILITIES ( 'read:transactions', 'read:customers', 'write:fraud_alerts', 'network:fraud_api.example.com')AS $wasm$file://procedures/fraud_detection.wasm$wasm$;Sandbox Restrictions
- No filesystem access (unless explicitly granted)
- No network access (unless explicitly granted with domain whitelist)
- Limited memory (configurable, default 16MB)
- CPU time limits (default 10 seconds)
- No direct system calls
Permission Levels
read:<table>: SELECT access to specific tablewrite:<table>: INSERT/UPDATE/DELETE accessddl:<table>: ALTER TABLE accessnetwork:<domain>: HTTPS requests to specific domainfilesystem:<path>: Read/write to specific pathcrypto: Access to cryptographic functions
Performance Characteristics
Execution Speed
- Rust procedures: ~5-10% overhead vs native
- Python procedures: ~20-30% overhead (RustPython)
- JavaScript procedures: ~15-25% overhead (QuickJS)
- Go procedures: ~10-15% overhead (TinyGo)
Memory Usage
- Base runtime: ~2MB per procedure instance
- Module cache: Shared across calls, ~100KB per unique module
- Instance pool: 10 instances per procedure (configurable)
Startup Time
- First call (cold start): 5-50ms depending on module size
- Subsequent calls (warm): <1ms (instance pool)
- Module compilation: Cached on first load
Integration with NL2SQL
Agentic Procedure Calls
The agentic NL2SQL engine can automatically decompose queries that require stored procedure calls:
Natural Language: "Calculate discounts for all platinum customers and show their savings"
Decomposed Plan:1. [task1] Identify platinum customers2. [task2] For each customer, call calculate_discount procedure (parallel)3. [task3] Aggregate and rank by savingsCode Advisor Integration
The Code Advisor can analyze procedure performance:
let advisor = CodeAdvisor::new(llm_client, schema_info);
// Analyze procedure usagelet advice = advisor.analyze_procedure("calculate_discount").await?;
// Recommendations might include:// - "Cache loyalty tier lookups to reduce queries"// - "Consider materializing discount rates in a table"// - "Add index on customers.loyalty_tier"Development Workflow
1. Write Procedure
# Rust examplecargo new calculate_discount --libcd calculate_discount
# Add heliosdb-wasm-sdk dependencycargo add heliosdb-wasm-sdk
# Write procedure in src/lib.rs2. Compile to WASM
# Rustcargo build --target wasm32-wasi --release
# Pythonpython -m wasm_compiler procedure.py -o procedure.wasm
# JavaScriptasc procedure.js -o procedure.wasm
# Gotinygo build -target=wasi -o procedure.wasm procedure.go3. Test Locally
# Run WASM module with test harnessheliosdb-wasm-test procedure.wasm \ --param customer_id=12345 \ --param order_total=599.99 \ --expect 119.9984. Deploy to HeliosDB
# Upload procedureheliosdb-cli procedure create \ --name calculate_discount \ --file procedure.wasm \ --params "customer_id:BIGINT,order_total:DECIMAL" \ --returns DECIMAL \ --capabilities "read:customers"
# Verify deploymentheliosdb-cli procedure listheliosdb-cli procedure info calculate_discount5. Monitor in Production
# View procedure metricsheliosdb-cli procedure metrics calculate_discount
# View logsheliosdb-cli logs --procedure calculate_discount --last 1h
# Profile executionheliosdb-cli procedure profile calculate_discountSDK Structure
Rust SDK
pub use heliosdb_wasm_macros::heliosdb_procedure;
pub enum LogLevel { Debug, Info, Warn, Error,}
pub struct QueryResult { rows: Vec<serde_json::Value>,}
impl QueryResult { pub fn get_string(&self, index: usize) -> Result<String, Error>; pub fn get_i64(&self, index: usize) -> Result<i64, Error>; pub fn get_f64(&self, index: usize) -> Result<f64, Error>; // ... more type getters}
pub fn heliosdb_query(sql: &str) -> Result<QueryResult, Error>;pub fn heliosdb_log(level: LogLevel, message: &str) -> Result<(), Error>;pub fn heliosdb_begin_tx() -> Result<(), Error>;pub fn heliosdb_commit_tx() -> Result<(), Error>;pub fn heliosdb_rollback_tx() -> Result<(), Error>;Migration Path
Phase 1: Foundation (v5.2)
- WASM runtime integration (wasmer)
- Basic host interface (query, log, return)
- Rust SDK and examples
- Procedure registry and versioning
Phase 2: Language Support (v5.3)
- Python SDK (RustPython)
- JavaScript SDK (QuickJS)
- Go SDK (TinyGo)
- Extended host interface (transactions, crypto)
Phase 3: Production Features (v5.4)
- Capability-based security
- Instance pooling and caching
- Performance monitoring
- Procedure migration tools
Phase 4: Advanced Features (v6.0)
- Multi-version procedures
- A/B testing support
- Distributed procedure execution
- Procedure marketplace
Benefits
- Developer Freedom: Use your preferred language and tools
- Performance: Near-native speed with WASM JIT compilation
- Security: Sandboxed execution with fine-grained capabilities
- Portability: Write once, deploy anywhere HeliosDB runs
- Maintainability: Version control, testing, and CI/CD like regular code
- Innovation: Rapid development of custom business logic
- Ecosystem: Leverage existing libraries and frameworks
Competitive Advantage
HeliosDB would be the first production database to offer:
- Multi-language stored procedures via WASM
- Capability-based security model for procedures
- Hot-swappable procedure versions
- Agentic integration with NL2SQL
Next Steps
- Design document (this document)
- ⏳ Implement basic WASM runtime integration
- ⏳ Create Rust SDK
- ⏳ Build procedure registry and versioning
- ⏳ Add Python and JavaScript SDKs
- ⏳ Implement capability-based security
- ⏳ Create comprehensive examples and tutorials
Status: Design Complete Target Release: v6.0 Owner: Engineering Team Last Updated: 2025-10-27