Documentation
¶
Overview ¶
Package expr provides expression parsing and evaluation capabilities for StreamSQL.
This package implements a comprehensive expression engine that supports mathematical operations, logical comparisons, function calls, field references, and complex CASE expressions. It serves as the foundation for WHERE clauses, HAVING clauses, and computed fields in SQL queries.
Core Features ¶
• Mathematical Operations - Supports arithmetic operators (+, -, *, /, %, ^) with proper precedence • Logical Operations - Boolean logic with AND, OR operators and comparison operators (=, !=, <, >, <=, >=, LIKE) • Function Integration - Seamless integration with the functions package for built-in and custom functions • Field References - Dynamic field access with dot notation support for nested data structures • CASE Expressions - Full support for both simple and searched CASE expressions • Type Safety - Automatic type conversion and validation during expression evaluation • Fallback Support - Integration with expr-lang/expr library for complex expressions
Expression Types ¶
The package supports various expression node types:
// Basic types TypeNumber - Numeric constants (integers and floats) TypeString - String literals with proper escaping TypeField - Field references (e.g., "temperature", "device.id") TypeOperator - Binary and unary operators TypeFunction - Function calls with argument validation TypeParenthesis - Grouped expressions for precedence control TypeCase - CASE expressions for conditional logic
Usage Examples ¶
Basic mathematical expression:
expr, err := NewExpression("temperature * 1.8 + 32")
if err != nil {
log.Fatal(err)
}
result, err := expr.Evaluate(data)
Logical expression with field references:
expr, err := NewExpression("temperature > 25 AND humidity < 60")
result, err := expr.Evaluate(data)
Function call expression:
expr, err := NewExpression("UPPER(device_name) LIKE 'SENSOR%'")
result, err := expr.Evaluate(data)
CASE expression for conditional logic:
expr, err := NewExpression(` CASE WHEN temperature > 30 THEN 'hot' WHEN temperature > 20 THEN 'warm' ELSE 'cold' END `) result, err := expr.Evaluate(data)
Operator Precedence ¶
The expression parser follows standard mathematical precedence rules:
- Parentheses (highest)
- Power (^)
- Multiplication, Division, Modulo (*, /, %)
- Addition, Subtraction (+, -)
- Comparison (>, <, >=, <=, LIKE, IS)
- Equality (=, ==, !=, <>)
- Logical AND
- Logical OR (lowest)
Error Handling ¶
The package provides comprehensive error handling with detailed error messages:
• Syntax validation during expression creation • Type checking during evaluation • Function argument validation • Graceful fallback to expr-lang for unsupported expressions
Performance Considerations ¶
• Expressions are parsed once and can be evaluated multiple times • Built-in operator optimization for common mathematical operations • Lazy evaluation for logical operators (short-circuiting) • Efficient field access caching for repeated evaluations • Automatic fallback to optimized expr-lang library when needed
Integration ¶
This package integrates seamlessly with other StreamSQL components:
• Functions package - For built-in and custom function execution • Types package - For data type definitions and conversions • Stream package - For real-time expression evaluation in data streams • RSQL package - For SQL parsing and expression extraction
Index ¶
- Constants
- func ValidateExpression(expr string) error
- type CaseExpression
- type ExprNode
- type Expression
- func (e *Expression) Evaluate(data map[string]interface{}) (float64, error)
- func (e *Expression) EvaluateBool(data map[string]interface{}) (bool, error)
- func (e *Expression) EvaluateValueWithNull(data map[string]interface{}) (interface{}, bool, error)
- func (e *Expression) EvaluateWithNull(data map[string]interface{}) (float64, bool, error)
- func (e *Expression) GetFields() []string
- type Token
- type TokenType
- type WhenClause
Constants ¶
const ( TypeNumber = "number" // Number constant TypeField = "field" // Field reference TypeOperator = "operator" // Operator TypeFunction = "function" // Function call TypeParenthesis = "parenthesis" // Parenthesis TypeCase = "case" // CASE expression TypeString = "string" // String constant )
Expression types - expression type constants
Variables ¶
This section is empty.
Functions ¶
func ValidateExpression ¶ added in v0.10.2
ValidateExpression public interface: validates expression string
Types ¶
type CaseExpression ¶ added in v0.10.2
type CaseExpression struct {
Value *ExprNode // Expression after CASE (simple CASE)
WhenClauses []WhenClause // List of WHEN clauses
ElseResult *ExprNode // ELSE expression
}
CaseExpression represents the structure of a CASE expression
type ExprNode ¶
type ExprNode struct {
Type string // Node type
Value string // Node value
Left *ExprNode // Left child node
Right *ExprNode // Right child node
Args []*ExprNode // Function argument list
// Fields specific to CASE expressions
CaseExpr *CaseExpression // CASE expression structure
}
ExprNode represents an expression node
func ParseExpression ¶ added in v0.10.2
ParseExpression parses expression token list to AST
type Expression ¶
type Expression struct {
Root *ExprNode // Expression root node
// contains filtered or unexported fields
}
Expression represents a computable expression
func NewExpression ¶
func NewExpression(exprStr string) (*Expression, error)
NewExpression creates a new expression
func (*Expression) Evaluate ¶
func (e *Expression) Evaluate(data map[string]interface{}) (float64, error)
Evaluate calculates the value of the expression
func (*Expression) EvaluateBool ¶ added in v0.10.2
func (e *Expression) EvaluateBool(data map[string]interface{}) (bool, error)
EvaluateBool calculates the boolean value of the expression
func (*Expression) EvaluateValueWithNull ¶ added in v0.10.2
func (e *Expression) EvaluateValueWithNull(data map[string]interface{}) (interface{}, bool, error)
EvaluateValueWithNull evaluates expression and returns value of any type, supports NULL
func (*Expression) EvaluateWithNull ¶
func (e *Expression) EvaluateWithNull(data map[string]interface{}) (float64, bool, error)
EvaluateWithNull provides public interface for aggregate function calls, supports NULL value handling
func (*Expression) GetFields ¶
func (e *Expression) GetFields() []string
GetFields gets all fields referenced in the expression Returns fields in sorted order to ensure consistent results
type TokenType ¶ added in v0.10.2
type TokenType int
TokenType represents token type
const ( // TokenKeyword keyword token TokenKeyword TokenType = iota // TokenField field token TokenField // TokenOperator operator token TokenOperator // TokenNumber number token TokenNumber // TokenString string token TokenString // TokenLeftParen left parenthesis token TokenLeftParen // TokenRightParen right parenthesis token TokenRightParen // TokenComma comma token TokenComma )
type WhenClause ¶
WhenClause represents a WHEN clause in a CASE expression