vibesql-executor 0.2.0

Query execution engine for vibesql SQL database
Documentation
# Operator System

This module implements a trait-based operator evaluation system that replaces the monolithic match statement that was previously in `core.rs`.

## Architecture

The operator system is organized into specialized modules by operator category:

```
operators/
├── mod.rs           # Central registry and trait definitions
├── arithmetic.rs    # +, -, *, /
├── comparison.rs    # =, <>, <, <=, >, >=
├── logical.rs       # AND, OR
└── string.rs        # || (concatenation)
```

## Benefits of This Design

### 1. Modularity
Each operator category has its own module with focused responsibility:
- **Arithmetic**: Numeric operations with type coercion
- **Comparison**: Equality and ordering with SQL semantics
- **Logical**: Boolean operations with three-valued logic
- **String**: Text operations

### 2. Testability
Each operator module has comprehensive unit tests:
- Individual operator behavior
- Type coercion rules
- NULL handling
- Edge cases (e.g., division by zero)

### 3. Maintainability
- **Before**: 523 lines with one massive `eval_binary_op_static` function
- **After**: 200 lines in `core.rs`, with operators in separate modules
- Adding new operators: Create new struct method, wire up in registry

### 4. Performance
- Uses `#[inline]` for hot path functions
- Static dispatch through direct method calls
- No performance regression vs. original implementation

## Usage

The operator registry provides a unified interface:

```rust
use super::operators::OperatorRegistry;

let result = OperatorRegistry::eval_binary_op(
    &SqlValue::Integer(5),
    &BinaryOperator::Plus,
    &SqlValue::Integer(3)
)?;
// result = SqlValue::Integer(8)
```

## Type Coercion Rules

### Exact Numeric Types
When operating on `SMALLINT`, `INTEGER`, or `BIGINT`:
- Promote both operands to `i64`
- Perform operation
- Return `Integer` result

### Approximate Numeric Types
When operating on `FLOAT`, `REAL`, or `DOUBLE`:
- Promote both operands to `f64`
- Perform operation
- Return `Float` result

### Mixed Integer/Float
When mixing exact and approximate numeric types:
- Promote integer to float
- Perform operation as float
- Return `Float` result

### NUMERIC Type
The `NUMERIC` type is treated as approximate:
- Coerced to `f64` for operations
- Compatible with all numeric types

## NULL Handling

SQL three-valued logic is enforced:
- `NULL <op> anything` → `NULL`
- `anything <op> NULL` → `NULL`

This is handled in the registry before dispatching to operators.

## Adding New Operators

To add a new operator:

1. **Create operator method** in appropriate module:
   ```rust
   impl ArithmeticOps {
       pub fn modulo(left: &SqlValue, right: &SqlValue) -> Result<SqlValue, ExecutorError> {
           // Implementation
       }
   }
   ```

2. **Add to registry** in `mod.rs`:
   ```rust
   match op {
       // ... existing operators
       Modulo => ArithmeticOps::modulo(left, right),
   }
   ```

3. **Add tests** in operator module:
   ```rust
   #[test]
   fn test_modulo() {
       assert_eq!(
           ArithmeticOps::modulo(&SqlValue::Integer(10), &SqlValue::Integer(3)).unwrap(),
           SqlValue::Integer(1)
       );
   }
   ```

## Testing

Run operator tests:
```bash
# All operator tests
cargo test --package executor operators

# Specific operator category
cargo test --package executor operators::arithmetic
cargo test --package executor operators::comparison
```

## Performance Considerations

The new design maintains performance through:
- **Static dispatch**: Direct method calls, no vtable lookup
- **Inlining**: `#[inline]` on hot paths
- **Zero-cost abstraction**: Compiles to same code as original match statement

Benchmark results show no measurable performance difference vs. the original implementation.

## Future Enhancements

This architecture enables:
- **Constant folding**: Optimize `2 + 3` at compile time
- **SIMD operations**: Vectorize numeric operations
- **Custom operators**: User-defined operators via trait
- **Operator profiling**: Track per-operator performance
- **Specialized implementations**: Optimize specific type combinations