Relix

Programming guide

relix

Runs Relix relational-algebra scripts as a stage of a Unix pipeline. Rows go to standard output; everything else goes to standard error.

Usage

relix [OPTIONS] [SCRIPT...] [COMMAND]

Arguments

ArgumentDescription
SCRIPT...Script files, each run in a session of its own; - is standard input. With neither -e nor SCRIPT, standard input is read when it is not a terminal.

Run options

With no command, relix is relix run, and takes its options:

OptionDescription
-e, --expr=TEXTRelix text to run. Repeatable: the texts are one script, in order. A bare relational expression runs as a query.
-i, --input=NAME=[FORMAT:]LOCATIONBind the relation NAME to a file, an http(s) URL (with --remote), or - for standard input. FORMAT is csv, tsv, json or ndjson; without it the extension decides, and standard input must name one. Repeatable.
--schema=NAME={...}The heading of the input NAME, such as NAME='{ id: NUMBER, name: STRING }', instead of inferring one.
--infer-rows=NInfer an input's heading from its first N records (default: 1000).
--unbounded=NAMEThe input NAME never ends, as tail -f's does: its rows stream as they arrive, and a query that would have to read all of it first is refused. Repeatable.
-o, --output=FORMATThe rows' format: table, tsv, csv, ndjson, json or markdown (default: $RELIX_OUTPUT, else relixrc's, else table on a terminal, tsv in a pipe).
--no-headerLeave out the header row of csv and tsv.
--null=STRINGHow NULL is written (default: empty in csv, tsv and markdown; NULL in a table).
--color=WHENColour a table: auto, always or never (default: auto). auto colours on a terminal unless $NO_COLOR is set.
--line-bufferedFlush each row as it is written, for a reader that wants it at once.
--query=NAMEPrint only the query NAME. A machine format (tsv, csv, ndjson, json) prints one query: the script's last, unless this names another.
--allWith ndjson, print every query, each row tagged "_query": NAME.
--fail-emptyExit 1 when the queries printed return no rows.
--fail-rowsExit 1 when the queries printed return any row.
--trace=FILEWrite the event feed (what was rewritten, planned and run) to standard error, or to FILE with --trace=FILE, while the rows go to standard output.

Global options

Every command takes these, before or after its name.

OptionDescription
-C DIRAct as if started in DIR: relative paths and .relix/ discovery start there.
-P, --profile=NAMEThe profile ${VAR} placeholders resolve from (default: $RELIX_PROFILE).
-D NAME=VALUESet one ${VAR} for this run; it beats the profile and the environment. Not for secrets: it lands in shell history and ps.
-a, --arg=NAME=VALUEBind the query parameter $NAME to VALUE. Repeatable. The value is bound, never pasted into the script, so it cannot change the query.
-N, --no-catalogIgnore the .relix/ directories' catalogs and relixrc; --catalog files still load.
--catalog=FILEAdd a catalog file, nearer than the .relix/ directories'. Repeatable. $RELIX_CATALOG_PATH adds files too, separated as in PATH.
-q, --quietPrint errors only, not warnings.
-v, --verboseAlso print notices (drivers loaded); -vv adds timings.
--now=INSTANTPin NOW() to an ISO-8601 instant, such as 2026-07-22T12:00:00Z (default: $RELIX_NOW).
--max-fixpoint-rounds=NFail a recursive query that needs more than N rounds.
--max-materialized-rows=NFail a query in which one blocking operator buffers more than N rows.
--max-processed-rows=NFail a query that processes more than N rows in all.
--timeout=DURATIONFail a query that runs longer than DURATION: 500ms, 30s, 5m, 1h, or ISO-8601 (PT30S).
--sandbox=FILERun under the sandbox FILE describes.
--remotePermit http(s) file locations.
--allow-downloadPermit fetching a missing JDBC driver or connector during the run.
-h, --helpShow this help message and exit.
-V, --versionPrint version information and exit.

Commands

CommandWhat it does
relix runRuns scripts and writes their queries' rows to standard output.
relix checkAnalyses scripts without running them, and reports what is wrong with them on standard error as FILE:LINE:COL: severity: message.
relix explainPrints the physical plan of each query: how the engine would run it.
relix optimizePrints the script with each query rewritten by the optimiser, so that it works as a filter: relix optimize slow.relix > fast.relix.
relix traceRuns each query and prints its event feed, what the engine rewrote, planned and ran, discarding the rows.
relix bundlePrints each script's JSON bundle: diagnostics and, per query, the logical plan, the rewrites, the physical plan and the planner's events.
relix irPrints the IR report: the symbols, views and queries the analyser made of each script.
relix provenanceRuns each query and prints its rows, each annotated with where it came from in a provenance semiring.
relix fmtPrints scripts canonically, keeping their comments.
relix catalogInspects the catalog: the declarations a run takes from the .relix/ directories from ~/.relix down to the working directory, and from --catalog files.
relix driversLists and installs JDBC drivers.
relix connectorsLists and installs connector plugins, such as mongodb.
relix docShows the reference page for TOPIC, found by glyph, keyword or name (σ, select, selection), through $PAGER on a terminal.
relix helpWhen no COMMAND is given, the usage help for the main command is displayed.
relix versionPrints the versions of relix and of the Relix engine it runs.
relix completionPrints a completion script for SHELL: bash, zsh, fish or powershell.

Exit status

StatusMeaning
0success
1an assertion failed (--fail-empty, --fail-rows)
2usage error (bad option, nothing to run)
3the script did not parse or analyse
4execution failed (a data error, a limit hit)
5environment (a missing driver, an untrusted catalog, a connection refused)
70internal error in relix
130interrupted (SIGINT)
141standard output closed (SIGPIPE)

Examples

With no command, relix runs scripts, as relix run does:

shell
relix -e 'PROJECT name, city (Customers)' -o tsv
Result
name	city
Alice	London
Bob	Leeds
Carol	London
Dan	York

Global options go before or after the command's name:

shell
relix -C reports catalog ls -o tsv --no-header
Result
BigSpenders	QR	2	~/shop/.relix/catalog/10-views.relix
Completed	QR	5	~/shop/.relix/catalog/10-views.relix
Customers	SRC	3	~/shop/.relix/catalog/00-sources.relix
Orders	SRC	5	~/shop/reports/.relix/catalog/10-sample.relix
Regions	INL	2	~/.relix/catalog/00-regions.relix
Spend	QR	2	~/shop/.relix/catalog/10-views.relix
Stock	SRC	2	~/shop/.relix/catalog/20-warehouse.relix

Environment

VariableEffect
RELIX_OUTPUTthe output format when -o is not given
RELIX_PROFILEthe profile when -P is not given
RELIX_NOWthe instant NOW() returns when --now is not given
RELIX_CATALOG_PATHcatalog files to load, separated as in PATH, before the --catalog files
RELIX_TRUST_ALL1 or true trusts every project's .relix/ directory
RELIX_DRIVERSthe directory JDBC drivers are installed in and loaded from, instead of ~/.relix/drivers
NO_COLORwhen set, a table on a terminal is not coloured unless --color=always
PAGERthe program relix doc shows a page through on a terminal; cat or empty shows it directly

A ${NAME} placeholder in a declaration may also be resolved from the environment; see Secrets and profiles.

Files

PathWhat it holds
~/.relix/catalog/*.relixyour own catalog, which every directory under your home sees
~/.relix/profiles.jsonyour own profiles
~/.relix/trustedthe projects you have trusted, with a hash of each one's files
~/.relix/drivers/installed JDBC drivers
~/.relix/connectors/installed connector plugins
~/.relix/cache/files/files fetched over https by a file connection
.relix/catalog/*.relix, .relix/relixrc, .relix/profiles.json, .relix/roota project's catalog, defaults, profiles, and the marker that ends the walk up; see The catalog