Tellaro Query Language (TQL) - Rust
A blazing-fast, human-friendly query language for searching and filtering structured data in Rust.
TQL provides an intuitive SQL-like syntax for querying JSON, JSONL, CSV files, and OpenSearch indices with:
- 300x faster than Python for large file processing
- First-class file support with CLI and programmatic API
- OpenSearch integration with automatic DSL translation
- 25+ field mutators for data transformation (string, encoding, DNS, GeoIP, network)
- Statistical aggregations for data analysis
use Tql;
use json;
let tql = new;
let records = vec!;
// Simple query
let results = tql.query.unwrap;
assert_eq!;
// With field mutators
let results = tql.query.unwrap;
🚀 Quick Start
Installation
Add this to your Cargo.toml:
[]
= "0.1"
= "1.0"
# Optional: Enable OpenSearch backend
# tellaro-query-language = { version = "0.1", features = ["opensearch"] }
CLI Installation
Install the high-performance command-line tool:
# Query files directly
# Statistical aggregations
📁 Query Files (First-Class Support)
CLI Usage
TQL treats files as first-class data sources:
# Query JSON/JSONL files
# Query CSV files (auto-detects headers)
# Statistical aggregations
# Process folders recursively
# Stream data from stdin
|
# Output formats
Performance: Process 50MB files in ~200ms with streaming (no memory overhead).
Programmatic File Queries
use Tql;
use File;
use BufReader;
use Value;
let tql = new;
// Read and query JSON file
let file = open?;
let reader = new;
let records: = from_reader?;
let results = tql.query?;
// Stream JSONL for large files
let file = open?;
let reader = new;
for line in reader.lines
🗄️ OpenSearch Integration
TQL seamlessly integrates with OpenSearch/Elasticsearch:
Automatic DSL Translation
use ;
// Configure OpenSearch (reads from environment)
set_var;
set_var;
set_var;
// Create client
let config = from_env?;
let client = new?;
// Parse TQL query
let tql = new;
let ast = tql.parse?;
// Build OpenSearch DSL
let builder = new;
let opensearch_query = builder.build_query?;
// Execute search
let response = client.client
.search
.body
.send
.await?;
TQL → OpenSearch Query DSL
TQL automatically translates to optimized OpenSearch queries:
| TQL Operator | OpenSearch Query | Example |
|---|---|---|
eq, = |
term or match |
status = "active" |
ne, != |
bool + must_not |
status != "deleted" |
gt, gte, lt, lte |
range |
age > 25 |
contains |
wildcard or match_phrase |
email contains "@example.com" |
startswith |
prefix |
name startswith "John" |
endswith |
wildcard |
filename endswith ".pdf" |
matches (regexp) |
regexp |
email matches "^\\w+@\\w+" |
in |
terms |
status in ["active", "pending"] |
between |
range with gte + lte |
age between [18, 65] |
cidr |
IP range matching | ip cidr "192.168.0.0/16" |
AND |
bool + must |
age > 25 AND city = "NYC" |
OR |
bool + should |
city = "NYC" OR city = "LA" |
NOT |
bool + must_not |
NOT status = "deleted" |
Field Mapping Intelligence
use FieldMappings;
// Get mappings from OpenSearch
let mappings_response = client.client
.indices
.get_mapping
.index
.send
.await?;
let mappings = from_opensearch_response?;
// Use mappings for intelligent query generation
let builder = new;
let query = builder.build_query?;
// Automatically selects .keyword for exact matches on text fields
📖 Syntax Guide
Comparison Operators
// Equality
"status = 'active'" // Exact match (alias: eq)
"status != 'inactive'" // Not equal (alias: ne)
// Numeric comparisons
"age > 25" // Greater than
"age >= 18" // Greater or equal
"age < 65" // Less than
"age <= 100" // Less or equal
// String operations
"email contains '@example.com'" // Substring match
"name startswith 'John'" // Prefix match
"filename endswith '.pdf'" // Suffix match
// Pattern matching
"email matches '^\\w+@\\w+\\.\\w+$'" // Regex match
// Range and membership
"age between [18, 65]" // Inclusive range
"status in ['active', 'pending']" // Value in list
"status not in ['deleted', 'archived']" // Value not in list
// IP operations
"ip cidr '192.168.0.0/16'" // IP in CIDR range
// Null checks
"field is null" // Field is null or missing
"field is not null" // Field exists and is not null
Logical Operators
// AND (all conditions must be true)
"age > 25 AND city = 'NYC'"
"status = 'active' AND role in ['admin', 'moderator']"
// OR (either condition must be true)
"city = 'NYC' OR city = 'LA'"
"status = 'admin' OR role = 'superuser'"
// NOT (negates condition)
"NOT (age < 18)"
"NOT status = 'deleted'"
// Complex expressions with parentheses
"(age > 25 AND city = 'NYC') OR (status = 'vip' AND score > 90)"
Collection Operators
// ANY - at least one array element matches
"ANY tags = 'premium'"
"ANY user.roles = 'admin'"
// ALL - every array element matches
"ALL scores >= 80"
"ALL status = 'active'"
// NONE - no array elements match
"NONE flags = 'spam'"
"NONE violations.severity = 'critical'"
Nested Field Access
// Dot notation for nested objects
"user.profile.email contains '@example.com'"
"metadata.tags.priority = 'high'"
// Array indexing
"tags[0] = 'urgent'"
"history[5].status = 'completed'"
🔄 Field Mutators (25+)
Transform field values inline before comparison:
String Mutators
// Case conversion
"email | lowercase contains '@example.com'"
"name | uppercase = 'JOHN DOE'"
// Whitespace handling
"message | trim = 'hello'"
// String manipulation
"text | length > 100"
"path | split('/') | length = 3"
"text | replace('old', 'new') contains 'new'"
Encoding Mutators
// Base64
"data | b64encode = 'aGVsbG8='"
"encoded | b64decode contains 'secret'"
// URL encoding
"param | urldecode = 'hello world'"
// Hexadecimal encoding
"data | hexencode = '68656c6c6f'"
"encoded | hexdecode = 'hello'"
// Cryptographic hashing
"password | md5 = '5f4dcc3b5aa765d61d8327deb882cf99'"
"data | sha256 = '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'"
Network/Security Mutators
// Defang/Refang URLs (security analysis)
"url | defang contains 'hxxp://example[.]com'"
"indicator | refang = 'http://malicious.com'"
// IP address classification
"source_ip | is_private = true" // Check if IP is RFC 1918 private
"dest_ip | is_global = true" // Check if IP is globally routable
// Use cases
"source_ip | is_private = true and port = 22" // Internal SSH connections
"dest_ip | is_global = false" // Non-routable destinations
DNS Mutators
// DNS lookups with caching
"hostname | nslookup contains '8.8.8.8'"
"domain | nslookup = '1.1.1.1'"
Performance: DNS results are cached in memory to avoid repeated lookups.
GeoIP Mutators
// GeoIP enrichment (MaxMind and DB-IP support)
"ip | geoip.country_name = 'United States'"
"ip | geoip.city_name = 'New York'"
"ip | geoip.continent_code = 'NA'"
// Configure with environment variables
// TQL_GEOIP_DB_PATH=/path/to/GeoLite2-City.mmdb
// TQL_GEOIP_MMDB_PATH=/usr/share/GeoIP/
Supported fields:
geo.country_name,geo.country_iso_codegeo.city_namegeo.location(lat/lon)geo.continent_code,geo.continent_namegeo.region_name,geo.region_iso_codegeo.postal_code,geo.timezone
Performance: Uses memory-mapped I/O for efficient database access (200,000+ lookups/sec).
List Mutators
// Boolean aggregations
"tags | any = true" // Check if any element is truthy
"flags | all = true" // Check if all elements are truthy
// Numeric aggregations
"scores | avg > 80" // Calculate average
"values | sum > 1000" // Calculate sum
"prices | min >= 10" // Find minimum value
"ratings | max <= 5" // Find maximum value
// Example with nested arrays
"users.scores | avg > 75" // Average of nested array
"metrics.values | sum between [100, 500]" // Sum within range
Chaining Mutators
// Multiple transformations in sequence
"email | trim | lowercase contains '@example.com'"
"data | b64decode | lowercase = 'secret'"
"ip | geoip.country_name | lowercase = 'united states'"
📊 Statistical Aggregations
TQL includes powerful stats functions for data analysis:
Available Functions
use ;
use HashMap;
let evaluator = new;
let records = vec!;
// Count records
let query = StatsQuery ;
let result = evaluator.evaluate_stats?;
// result["value"] = 3
// Sum with grouping
let query = StatsQuery ;
let result = evaluator.evaluate_stats?;
// Groups by city: {"NYC": {"total_sales": 300}, "LA": {"total_sales": 150}}
CLI Stats Queries
# Simple aggregations
# Grouped analysis
# Top N analysis
# Combined filtering and stats
Aggregation Functions
- count: Count records (
count(*)orcount(field)) - unique_count: Count distinct values
- sum: Sum numeric values
- avg/average/mean: Calculate mean
- min/max: Find minimum/maximum values
- median/med: Calculate median
- std/stdev/standard_deviation: Calculate standard deviation
- percentile/p/pct: Calculate percentiles
- values/unique: Return unique values
🎯 API Reference
Basic Usage
use Tql;
use json;
// Create TQL instance
let tql = new;
// Or with custom depth limits
let tql = with_max_depth;
// Query records
let records = vec!;
// Execute query
let results = tql.query.unwrap;
println!;
// Count matches
let count = tql.count.unwrap;
println!;
// Check single record
let user = json!;
if tql.matches.unwrap
Query Pre-compilation
For queries executed multiple times, parse once and reuse the AST:
use ;
let tql = new;
// Parse query once
let ast = tql.parse.unwrap;
// Reuse AST for multiple datasets
let evaluator = new;
let results1 = evaluator.filter.unwrap;
let results2 = evaluator.filter.unwrap;
Error Handling
use ;
let tql = new;
match tql.query
⚡ Performance
Benchmarks
Rust Implementation:
- In-memory queries: ~3,000,000 records/sec
- File parsing (JSON): ~150MB/sec
- GeoIP lookups: ~200,000 lookups/sec (memory-mapped)
- DNS lookups: ~10,000 lookups/sec (with caching)
- Large file streaming: Process 50MB in ~200ms
vs Python Implementation:
- 300x faster for file processing
- 500x faster for GeoIP lookups (memory-mapped vs Python)
- 100x faster for DNS lookups (async + caching)
Performance Features
- Zero-copy deserialization where possible
- Memory-mapped I/O for GeoIP databases
- In-memory caching for DNS and GeoIP results
- Streaming file processing with no memory overhead
- Parallel query evaluation (planned)
Optimization Tips
// Pre-compile queries for reuse
let ast = tql.parse.unwrap;
let results1 = evaluator.filter.unwrap;
let results2 = evaluator.filter.unwrap;
// Use streaming for large files
let file = open?;
let reader = new;
for line in reader.lines
// Configure cache sizes for mutators
set_var;
set_var;
🗺️ Roadmap
✅ Implemented Features
- ✅ Core query engine with all operators
- ✅ 25+ field mutators (string, encoding, network, DNS, GeoIP, list)
- ✅ Statistical aggregations with grouping
- ✅ File support (JSON, JSONL, CSV) with CLI
- ✅ OpenSearch backend with automatic DSL translation
- ✅ Memory-mapped GeoIP lookups
- ✅ DNS resolution with caching
- ✅ High-performance streaming
🚧 In Progress
- 🚧 OpenSearch stats aggregation translation
- 🚧 Post-processing for complex mutator chains
- 🚧 Additional hash functions (SHA1, SHA512)
📋 Planned Features
- 📋 Parallel record evaluation
- 📋 Query optimization engine
- 📋 JSON parsing mutator
- 📋 Timestamp conversion mutators
- 📋 PostgreSQL/MySQL backends
- 📋 Custom mutator plugins via traits
🔮 Future Considerations
- 🔮 Distributed query execution
- 🔮 Query result caching
- 🔮 Real-time data streaming
- 🔮 WASM compilation for browser usage
🔧 Development
Setup
# Clone repository
# Build
# Run tests
# Build release
# Build with OpenSearch feature
Testing
# Run all tests
# Run with output
# Run integration tests (requires OpenSearch)
# Run benchmarks
Code Quality
# Format code
# Linting
# Check compilation
🤝 Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
📄 License
Tellaro Query Language (TQL) is source-available software with specific usage terms:
✅ Permitted Uses:
- Personal use (individual, non-commercial)
- Organizational use (within your company/organization)
- Integration into your applications and services
- Internal tools and automation
❌ Restricted Uses:
- Creating derivative query language products
- Commercial redistribution or resale
- Offering TQL-based commercial services to third parties
- Using source code to build competing products
For commercial licensing inquiries, contact: support@tellaro.io
See LICENSE for complete terms and conditions.
🔗 Related Projects
- TQL Python - Python implementation with rich ecosystem
- Tellaro Platform - Security operations platform using TQL
💬 Support
- Issues: GitHub Issues
- Documentation: docs.rs/tellaro-query-language
- Email: support@tellaro.io
🌟 Advanced Examples
Security Log Analysis
use Tql;
use json;
let tql = new;
let logs = vec!;
// Find high-severity events with malicious indicators
let query = r#"
severity in ['high', 'critical'] AND
source_ip | is_private = true AND
(ANY tags = 'malware' OR url | refang contains 'malicious')
"#;
let results = tql.query.unwrap;
assert_eq!;
E-commerce Product Search
let products = vec!;
// Find in-stock electronics with good ratings under $1500
let query = r#"
in_stock = true AND
price < 1500 AND
rating.average >= 4.0 AND
ANY tags = 'electronics'
"#;
let results = tql.query.unwrap;
assert_eq!;
GeoIP Enrichment Pipeline
// Set GeoIP database path
set_var;
let tql = new;
let events = vec!;
// Query with GeoIP enrichment
let query = "ip | geoip.country_name = 'United States'";
let results = tql.query.unwrap;
// Results include enriched geo data
println!;
// {
// "ip": "8.8.8.8",
// "event": "login",
// "geo": {
// "country_name": "United States",
// "country_iso_code": "US",
// "city_name": "Mountain View",
// "location": {"lat": 37.386, "lon": -122.0838}
// }
// }
Made with ❤️ by the Tellaro Team