User-Defined Expressions#
The expressions section lets you define named functions from expr-lang expression strings. Each expression becomes a callable function available in any query arg. Expressions can reference globals, built-in functions, and other expressions. Arguments passed to the function are available via the args slice.
globals:
total_rows: 10000
num_buckets: 10
expressions:
# No-arg expressions (computed from globals).
rows_per_bucket: "total_rows / num_buckets"
ten_percent: "int(ceil(total_rows * 0.1))"
# Parameterized expressions (use args[0], args[1], etc.).
clamp: "max(min(args[0], args[1]), 0)"
pct_of: "int(ceil(args[0] * args[1] / 100))"
like_prefix: "string(args[0]) + '%'"
pick_label: "args[0] > 1000 ? 'large' : 'small'"
wrapped_offset: "abs(args[0] - args[1]) % args[2]"
power_scale: "int(floor(float(args[0]) ** 2))"
is_active: "not (args[0] == 0) and (args[0] != args[1] or args[0] < args[2])"
safe_val: "args[0] ?? args[1]"
round_ratio: "round(float(args[0]) / float(args[1]))"
normalize: "lower(trim(replace(args[0], ' ', '_')))"
shout: "upper(split(args[0], ',')[0])"
add_piped: "(args[0] + args[1]) | int"
run:
- name: example_query
query: >-
SELECT * FROM t
WHERE bucket = $1
AND label = $2
AND name LIKE $3
AND score >= $4
AND active = $5
AND tag = $6
AND rank >= $7
AND tier = $8
AND fallback = $9
AND weight = $10
AND grp = $11
AND max_id <= $12
LIMIT $13
OFFSET $14
args:
- gen('number:1,' + num_buckets) # $1 random int 1-num_buckets
- pick_label(total_rows) # $2 "large"
- like_prefix('foo') # $3 "foo%"
- pct_of(total_rows, 5) # $4 500
- is_active(1, 2, 100) # $5 true
- normalize(' Foo Bar ') # $6 "foo_bar"
- power_scale(3) # $7 9
- shout('hello,world') # $8 "HELLO"
- safe_val('premium', 'basic') # $9 "premium"
- round_ratio(total_rows, num_buckets) # $10 1000
- wrapped_offset(7, 20, num_buckets) # $11 3
- add_piped(rows_per_bucket, ten_percent) # $12 2000
- clamp(rows_per_bucket, 500) # $13 500
- ten_percent # $14 1000