Relix

Manual

Language reference

One page per keyword, operator and built-in function, with worked examples.

This is the complete reference for the Relix relational-algebra language — one page per keyword, operator and built-in function. The pages are arranged below in a learning order: start with getting started, which runs a first script end to end, then work down through the statements of a .relix file and the core operators toward joins, set algebra, aggregation, nested data and the advanced operators. The glossary defines the vocabulary the rest of the manual assumes. Every operator has both a Unicode form (e.g. σ, ⋈, ∪) and an ASCII keyword form (e.g. SELECT, JOIN, UNION); the two are interchangeable and produce identical results. Each page gives the syntax, a plain-English description, real-world examples, and "See Also" links to related pages. The harder operators include a fully worked example with sample data and the expected result.

New to relational algebra? Read the sections in order. Already fluent? Jump straight to the operator you need from the tables below.

Download this manual as a PDF

1. Getting started

New here? This is the whole language in one page: bring data in, filter and combine it, name the interesting steps, ask for a result. Everything below is detail on one of those four moves.

PageWhat it does
Getting startedYour first script — declare data, name a result, run it
GlossaryThe vocabulary: relation, tuple, bag vs set, materialisation, pushdown
Operators by taskThe operator for each task SQL has no operator for, named in a question's words

2. Language & scripts

The shape of a .relix file — declaring data, naming results, and reusing code.

PageWhat it does
sourceDeclare an external data source (CSV, database, …)
http sourceRead JSON from an HTTP/REST API (headers, auth, body)
connectionShare one database connection across many sources
mongodb sourceRead a MongoDB collection as a relation
json sourceRead a JSON file as a relation, with no declared columns
generator sourceA generated series of rows: Range, Naturals, Primes
envName the environment file and profile a script's placeholders come from
gedcom sourceRead a GEDCOM genealogy file as individuals and families
log sourceRead a web server access log as a typed relation
relateDeclare named, bounded relationships between relations (schema graph)
inline-tableEmbed small reference data directly in a script
assignment & queryName a view with := and mark a result query
delimited identifierBacktick a name that collides with a reserved word (`order`)
bound parameter$name — a value supplied when the query runs, never written into it
comments-- to end of line, /* … */ for a block
operator spellingsEvery operator's Unicode glyph and its ASCII equivalent
grammar (EBNF)The whole language as one EBNF grammar — every statement, operator and token
namespaceDeclare the script's namespace
importReuse symbols defined in another file
defDefine a scalar (per-value) function
def … : RELATIONDefine a table-valued (relation-returning) function
relation catalogrelix.relations — every relation the script can name, with its kind, size and whether it ends
column catalogrelix.columns — every column of every relation, with its type and distinct and NULL counts
logical plan catalogrelix.plan / relix.dependencies — every view's expression tree, and which view reads which relation, as rows
connection catalogrelix.connections — the declared connections, by name and dialect
introspection stdlibrelix.unused / relix.deps / relix.impact / relix.find / relix.schema / relix.cycles / relix.funcs — the engine's own introspection, shipped as Relix
observability feedrelix.events / relix.rules — the previous run's engine decisions, as queryable rows
component inventoryrelix.version — the engine, the facade and every discovered provider, as queryable rows
candidate keysrelix.keys — the collected candidate keys of every relation, one row per key column
reserved namespacerelix.catalog — the relix.* surface describing itself

3. Core operators

The everyday relational-algebra operators — the ones you reach for first.

OperatorUnicode / ASCIIWhat it does
Selectionσ / SELECTKeep rows that match a condition
Projectionπ / PROJECTPick, reorder, rename or compute columns
Renameρ / RENAMERename a relation or its columns
Distinctδ / DISTINCTRemove duplicate rows
Sortτ / SORT / ORDER [BY]Order rows by one or more keys
ShuffleSHUFFLEReturn every row once, in a uniformly random order
RollROLLEndless uniform draws with replacement from a finite face set (a die roll)
Limitλ / LIMITTake the first N rows (with optional offset)

4. Predicates

The conditions that go inside a σ (selection) or join.

PageUnicode / ASCIIWhat it does
Comparison= ≠ < ≤ > ≥Compare two values
Range testBETWEEN, NOT BETWEENValue within a range, both ends included
Null-safe comparisonIS [NOT] DISTINCT FROMCompare two values, NULL equal to NULL
Truth testIS [NOT] TRUE / FALSE / UNKNOWNWhich of its three values a boolean has, never UNKNOWN
Row value comparison(a, b) = (c, d), (a, b) IN {…}Compare several columns as one, ordering lexicographically
Quantified comparisonANY / SOME / ALLCompare a value with each value of a list or a one-column relation
EXISTSEXISTS (…), NOT EXISTS (…)Whether a relation, often about the row tested, has a row
And∧ / ANDBoth conditions hold
Or∨ / OREither condition holds
Not¬ / NOTNegate a condition
Null test⊥ / NULL / IS [NOT] NULLTest for a missing value
Set membership∈ / IN, ∉ / NOT INTest membership in a set or a one-column relation
Pattern matchLIKE, NOT LIKE, ESCAPEWildcard string match (% = any run, _ = any one char)
Regex match~ / MATCHESDoes a regular expression match (~* ignores case)

5. Joins

Combining two relations. The outer joins keep unmatched rows (with NULLs); the semi/anti joins filter the left relation by the existence of a match.

JoinUnicode / ASCIIWhat it does
Natural join⋈ / JOINMatch on shared column names
USING join⋈ USING / JOIN … USINGMatch on the named shared columns only — inner, left, right or full
Theta join⨝ / ><Match on an explicit condition
Left outer join⟕ / |>< / LJOINKeep all left rows
Right outer join⟖ / ><| / RJOINKeep all right rows
Full outer join⟗ / |><| / FJOINKeep all rows from both sides
Semi join⋉ / SEMILeft rows that have a match
Anti join▷ / ANTILeft rows that have no match
Universal semi joinUSEMILeft rows that match every right row
AS-OF joinASOFMatch each row to the nearest-in-time row
Interval joinIJOINMatch intervals by an Allen relation (OVERLAPS, DURING, …)
Lateral joinLATERAL, OUTER LATERALEvaluate a TVF call or a relation per left row, reading that row's columns

6. Set operations

Treating relations as sets of rows.

OperationUnicode / ASCIIWhat it does
Union∪ / UNIONRows in either (deduplicated)
Union all⊎ / UALLRows in either (keeps duplicates)
Outer-union⊔ / OUNIONMerge different-schema relations (align common columns, NULL-pad the rest)
Intersection∩ / INTER / INTERSECTRows in both
Difference− / DIFF / MINUS / EXCEPTRows in the first but not the second
Symmetric difference∆ / SYMDIFFRows in exactly one
Cartesian product× / CROSSEvery combination of rows
Division÷ / DIVWhich X relate to all of the Y
Composition∘ / COMPOSEChain on a shared column and drop it

7. Grouping & aggregation

Collapse many rows into summary rows with γ (GROUP) and aggregate functions.

PageWhat it does
Group / Aggregationγ / GROUP [BY] — group rows and aggregate
SUMTotal of a numeric expression
AVGMean of a numeric expression
COUNTRows (COUNT(*)) or non-NULL values (COUNT(expr))
MINSmallest value
MAXLargest value
COLLECTGather a group's values into an array (NEST)
ARGMAXA value from the row with the maximum
ARGMINA value from the row with the minimum
STDDEVStandard deviation, of a sample
STDDEV_SAMPSample standard deviation
STDDEV_POPPopulation standard deviation
VARIANCEVariance, of a sample
VAR_SAMPSample variance
VAR_POPPopulation variance
MEDIANThe middle value
PERCENTILE_CONTThe value a fraction of the group lies below, interpolated
PERCENTILE_DISCThe first value a fraction of the group reaches
STRING_AGGJoin a group's values into one string (GROUP_CONCAT, LISTAGG)
BOOL_ANDWhether every value in a group is true (EVERY)
BOOL_ORWhether any value in a group is true
MODEThe most frequent value, a tie going to the smallest (STATS_MODE)
FILTERAGG(x) FILTER (WHERE c) — aggregate only the rows where a condition holds
GROUPINGWhich keys a ROLLUP, CUBE or GROUPING SETS row rolled up (GROUPING_ID)
Window / RollingROLLING … OVER … ROWS, ROWS/RANGE BETWEEN, PARTITION — sliding, cumulative, framed or whole-partition aggregate added as a column (no row collapse)
Window / RankingWINDOW ROW_NUMBER/RANK/DENSE_RANK/PERCENT_RANK/CUME_DIST/NTILE — per-partition rank column added to every row
Window / OffsetWINDOW LAG/LEAD/FIRST_VALUE/LAST_VALUE/NTH_VALUE — adjacent / boundary row value added as a column (no row collapse)

8. Nested data (NF²)

Relix relations can hold structs and arrays. These operators build and flatten nested values.

PageWhat it does
Struct constructionBuild a nested object { … } in a projection
Array constructionBuild an array [ … ] in a projection
COLLECTAggregate a group's values into an array (NEST)
Unnestμ / UNNEST — expand an array into rows (the inverse of COLLECT)
WITH ORDINALITYAdd a 1-based position column to an unnest
UnpivotUNPIVOT — fold named columns into rows (wide → long)
PivotPIVOT … BY … PER — turn distinct key values into columns (long → wide)
TreeTREE key BY parentKey [ORDER …] AS children — fold an adjacency relation into nested documents (recursive COLLECT)

9. Literals & temporal types

Writing constant values, including the first-class temporal types.

PageWhat it does
String, number and boolean literals"text" or 'text', 42, 3.25, 1e6, TRUE / FALSE
CASECASE WHEN c THEN a … ELSE d END, CASE x WHEN v THEN a … END — a value chosen by conditions
Subquery(γ COUNT(*) → n (σ k = R.k (S))) — a relation's one value, per row when it reads the row
COLLATEs COLLATE NOCASE, s COLLATE 'en-US' — compare, sort and group strings ignoring case or by a language's order
CASTCAST(x AS type) — convert a value to NUMBER, STRING, BOOLEAN, DATE, TIME or TIMESTAMP
AT TIME ZONEts AT TIME ZONE 'Europe/London' — the wall-clock time in a zone
EXTRACTEXTRACT(field FROM d) — a field of a date or time, day of week and ISO week among them
Arithmetic and concatenation+ - * /, SQL's % and ||
DATE literalDATE '2026-01-31'
TIME literalTIME '09:30:00'
TIMESTAMP literalTIMESTAMP '2026-01-31T09:30:00Z'
TIMESTAMPTZ literalTIMESTAMPTZ '2026-01-31T09:30:00+02:00', which keeps its offset
DURATION literalDURATION 'PT90M', DURATION 'P1M', INTERVAL '1 month'
Truth relationsUNIT / EMPTY (aliases DEE / DUM) — the two zero-column relations

10. Built-in functions

Scalar functions usable in any expression (projection, selection, aggregate argument). An argument that must be a whole number (a length, a position, a character code, a count of units) has its fraction cut off toward zero, so Left(s, 1.9) is Left(s, 1); Round and CInt are the functions that round.

11. Advanced operators

Beyond standard SQL — recursion, per-group ranking, sampling, the declarative solver, combinatorial covering, and universal quantification. Each of these pages includes a fully worked example.

PageWhat it does
Universal quantification∀ / FORALL — groups where every row satisfies a condition
Top-K per groupTOP … PER — the N highest rows in each group
Transitive closureCLOSURE / RCLOSURE — reachability over a binary relation
Connected componentsCLUSTER … AS — label each node with its undirected component id
Record linkagesimilarity join → TOP 1 … PER → CLUSTER — find the rows that probably describe the same thing
Bounded path reachabilityPATH … HOPS m TO n AS — pairs reachable within a hop window, with shortest distance
Optimal-path extractionTRACE … VIA … MINIMIZE|MAXIMIZE AS — cheapest/longest path with route array
General recursionFIX — least-fixpoint recursion (WITH RECURSIVE)
IterationITERATE — repeat a step until it settles: PageRank, state machines, convergence
Goal-seekSOLVE — fill the one blank in an equation, per row
Declarative optimisationOPTIMIZE — knapsack / allocation under constraints
Combinatorial coveringCOVER — minimal all-pairs (pairwise) subset
Bernoulli samplingSAMPLE p — keep each row with probability p
Reservoir samplingSAMPLE n ROWS — an exact-count uniform sample
DOWNSAMPLEDOWNSAMPLE ts BY '5m' USING AVG — time-series bucket aggregation
SessionizationSESSIONIZE ts GAP DURATION 'PT30M' PER … AS — split an ordered stream into sessions by an idle gap
Why (lineage provenance)ω / WHY — reify a tuple's lineage (which source rows produced it) as a queryable nested column
Query optimizerThe logical rewrite rules (SEL-…, LIM-…) and how to see which fired
PushdownWhat the backend computes and what the engine does — the boundary relix explain draws