Values & Types
FlyQL supports 10 value types: Integer, BigInt, Float, String, Boolean, Null, Array, Column, Function, and Parameter. Each value in the AST carries an explicit value_type field.
Value Types
Section titled “Value Types”Integer
Section titled “Integer”Whole numbers within the int64 range:
count = 42
status != 200
age >= 18
AST: value_type: "int"
BigInt
Section titled “BigInt”Integers exceeding the int64 range (Go/Python) or MAX_SAFE_INTEGER (JavaScript):
id = 18446744073709551615
AST: value_type: "bigint"
Numbers with a decimal point:
price > 9.99
ratio = 3.14
temperature<=-0.5
AST: value_type: "float"
String
Section titled “String”Text values must be quoted using single or double quotes. Unquoted values are interpreted as column references, not strings.
level = 'error'
user = "John Doe"
message = 'hello world'
count = '42'
AST: value_type: "string"
Escape quotes with backslash:
user = 'John\'s'
message = "said \"hello\""
Boolean
Section titled “Boolean”The keywords true and false (lowercase, case-sensitive):
active = true
debug = false
active != true
AST: value_type: "bool", value is native boolean.
Capitalized variants (True, FALSE) are treated as column references, not booleans.
SQL generation:
| Dialect | FlyQL | Generated SQL |
|---|---|---|
| ClickHouse | field = true | field = true |
| ClickHouse | field = false | field = false |
| PostgreSQL | field = true | field = TRUE |
| PostgreSQL | field = false | field = FALSE |
| StarRocks | field = true | field = true |
| StarRocks | field = false | field = false |
The keyword null (lowercase, case-sensitive):
field = null
field != null
AST: value_type: "null", value is native null.
Capitalized variants (Null, NULL) are treated as column references, not null.
Restrictions: Only = and != operators are valid with null. Using >, <, >=, <=, ~, or !~ with null produces a parse error.
SQL generation: field = null emits field IS NULL, field != null emits field IS NOT NULL (all dialects).
Column Reference
Section titled “Column Reference”Any unquoted value that is not a number, boolean, null, or temporal function is treated as a column reference — a pointer to another column for column-to-column comparisons:
price > min_price
updated_at > created_at
field = otherfield
AST: value_type: "column"
If you intend to match a string value, you must use quotes:
level = 'error'
Without quotes, level = error treats error as a reference to a column named error.
Arrays are used with in and not in operators. Elements can be mixed types (heterogeneous):
status in [200, 201, 202]
name in ['alice', 'bob']
field in [1, "hello", true, null]
Each element carries its own type in the values_types array.
Truthy/Falsy Expressions
Section titled “Truthy/Falsy Expressions”A standalone key without an operator checks if the field has a truthy value:
active
message and status
A value is considered falsy if it is:
null/None/ missing- Empty string
"" - Zero
0 - Boolean
false
Everything else is truthy.
Use not to check for falsy values:
not archived
active and not debug
Truthy/falsy checks are distinct from null comparisons: not field matches when the field is null, empty, or zero. field = null matches only when the field is specifically null.
Whitespace
Section titled “Whitespace”FlyQL is whitespace-tolerant. Spaces around operators are optional:
status = 200
status =200
All of the above are equivalent.
Literal Kind Constants
Section titled “Literal Kind Constants”Parsed expression values carry a LiteralKind tag. The constants are exported from the root package in every implementation.
Python:
from flyql import LiteralKind# LiteralKind.INTEGER, LiteralKind.BIGINT, LiteralKind.FLOAT,# LiteralKind.STRING, LiteralKind.BOOLEAN, LiteralKind.NULL, LiteralKind.ARRAYGo:
import "github.com/iamtelescope/flyql/golang/literal"// literal.Integer, literal.BigInt, literal.Float,// literal.String, literal.Boolean, literal.Null, literal.ArrayJavaScript:
import { LiteralKind } from 'flyql'// LiteralKind.INTEGER, LiteralKind.BIGINT, LiteralKind.FLOAT,// LiteralKind.STRING, LiteralKind.BOOLEAN, LiteralKind.NULL, LiteralKind.ARRAYTemporal Functions
Section titled “Temporal Functions”FlyQL supports temporal function calls as values on the right-hand side of comparison expressions. These enable time-relative filters without hardcoding timestamps.
AST: value_type: "function", value is a FunctionCall object.
ago(duration)
Section titled “ago(duration)”Returns a timestamp relative to the current time. Supports compound durations.
timestamp > ago(1h)
created_at >= ago(7d)
updated_at > ago(1h30m)
Units (lowercase): s (seconds), m (minutes), h (hours), d (days), w (weeks).
Grammar. A duration is one or more <integer><unit> pairs. Units must appear in strictly descending order and at most once each: w > d > h > m > s. This matches the Prometheus / Grafana / Loki convention.
Valid:
ago(30s)
ago(2h15m)
ago(1w2d3h4m5s)
ago(1w30s)
Rejected at parse time:
ago(30m1h)— units out of orderago(1h1h)— repeated unitago(3h1w)— larger unit after smallerago(1H)— unit letters must be lowercase
Returns the current timestamp.
expires_at < now()
today()
Section titled “today()”Returns today’s date. Accepts an optional IANA timezone argument.
date = today()
date = today('Europe/Berlin')
startOf(unit)
Section titled “startOf(unit)”Returns the start of the current day, week (Monday), or month. Accepts an optional timezone.
created_at > startOf('day')
created_at > startOf('week')
created_at > startOf('month', 'Asia/Tokyo')
Valid units: 'day', 'week', 'month'
Operator Restrictions
Section titled “Operator Restrictions”Temporal functions can only be used with comparison operators: =, !=, >, >=, <, <=.
Using ~ or !~ with a temporal function produces a parse error. Operators like in, has, like, and ilike use separate parsing paths and are not compatible with function values.
Column Reference Without Parens
Section titled “Column Reference Without Parens”Bare function names without parentheses are treated as column references, not function calls:
field = ago
This produces value_type: "column", not a function call.
Parameter
Section titled “Parameter”Parameter placeholders ($name for named, $1 for positional) stand in for values to be resolved at runtime by bindParams(). They can appear anywhere a literal value is valid — including IN-lists, temporal function arguments, and transformer arguments.
status = $code
level in [$primary, 'warn']
created > ago($duration)
AST: value_type: "parameter", value is a Parameter object with name and positional fields.
See Parameters for the full reference.