SQL & Expressions
Choose between condition trees, SQL predicates, and arithmetic expressions for each rule.
BlazeRules supports three complementary forms of rule logic:
- structured YAML leaves and
and/or/notbranches; - a
sql:boolean predicate leaf; - an
expr:arithmetic value followed by a comparison.
All three compile into the same rule plan. SQL is a rule-authoring syntax, not a database query or a separate execution service.
Supported SQL grammar
| Form | Example |
|---|---|
| Comparison | amount >= 1000, country != 'US' |
| Boolean logic | A AND B, A OR B, NOT A |
| Grouping | (A OR B) AND C |
| Null test | field IS NULL, field IS NOT NULL |
| Membership | country IN ('US', 'GB'), status NOT IN (...) |
| Inclusive range | amount BETWEEN 100 AND 500 |
| Pattern | user_agent LIKE '%bot%' |
| Array objects | any_match(items, x -> x.price > 100) |
Field names may be dotted. String literals may use single or double quotes. Numeric and boolean literals are typed during compilation.
SQL and YAML equivalents
conditions:
sql: >-
order.amount >= 750
AND customer.account_age_days < 14
AND network.country NOT IN ('US', 'GB')conditions:
and:
- {field: order.amount, op: gte, value: 750}
- {field: customer.account_age_days, op: lt, value: 14}
- {field: network.country, op: not_in, values: [US, GB]}Use a condition tree when the rule depends on operators that SQL does not expose, such as lookups, windows, CIDR sets, geo distance, model scores, or vector similarity. A SQL leaf can still be one child of a larger YAML branch.
Precedence and grouping
NOT binds tighter than AND; AND binds tighter than OR. Parentheses make intent explicit:
conditions:
sql: >-
order.amount > 500
AND (device.type = 'emulator' OR network.connection_type = 'proxy')Deeply nested expressions are rejected after the parser's safety limit rather than consuming unbounded stack or memory.
LIKE and ILIKE
LIKE and ILIKEBlazeRules maps wildcard placement to string operators:
| Pattern | Compiled behavior |
|---|---|
'bot%' | starts with bot |
'%bot' | ends with bot |
'%bot%' | contains bot |
'bot' | contains bot |
ILIKE currently follows the same case-sensitive mapping as LIKE. Use YAML ci_eq for case-insensitive equality. Use the RE2-backed regex operator for richer patterns.
Array objects with any_match
any_matchany_match is the SQL equivalent of array_any:
conditions:
sql: >-
any_match(cart.items, item ->
item.price > 500
AND item.category = 'electronics'
AND item.seller.risk_score >= 60)The lambda alias is local to the array element. Every conjunct must match the same item. any_match(...) must be the complete SQL leaf; it is not an arbitrary scalar function embedded inside a larger SQL expression. Nested arrays inside arrays are not supported.
Arithmetic expressions
An expr: leaf computes a numeric value and compares it with the outer op and value:
conditions:
op: gt
expr:
op: div
left: order.discount_amount
right: order.subtotal
value: 0.5Supported arithmetic operations are add, sub, mul, and div (or +, -, *, /). Operands may be field names, numeric literals, or nested expression objects.
conditions:
op: gte
expr:
op: sub
left:
op: add
left: order.subtotal
right: order.shipping_amount
right: order.discount_amount
value: 1000Use explicit operands when a field name could be mistaken for a literal:
expr:
op: div
left: {field: order.refund_amount}
right: {literal: 100}Arithmetic fields must be numeric. Division by zero does not produce a matching comparison.
Mixing SQL with derived signals
SQL predicates can sit beside lookups, windows, or models in an ordinary condition tree:
conditions:
and:
- sql: "order.amount > 750 AND customer.account_age_days < 14"
- {field: merchant.id, op: in_lookup, lookup: risky_merchants}
- model_score:
model: checkout_risk
features: [order.amount, customer.account_age_days, device.risk_score]
op: gte
value: 0.8Choosing a form
| Requirement | Recommended form |
|---|---|
| Simple field predicates | Compact YAML leaf |
| Deep boolean logic familiar to SQL users | sql: |
| Lookup, CIDR, geo, window, model, vector | Structured YAML leaf |
| Computed numeric ratio or delta | expr: |
| Array of objects | array_any or top-level SQL any_match |
The forms may be mixed within one rule. Prefer the form that keeps the business condition easiest to review and validate.
Updated about 2 hours ago