relate query
The relate query command with its three session forms, every query-run flag, output modes in brief, parameters, read-only opens, timeouts and exit codes.
cli
relate query runs a statement session against one store: the statements given as an argument, a script read from stdin, or the interactive shell. It takes every query-run flag. The path-first form, relate [OPTIONS] [QUERY], runs the same session with the same flags; the one difference is that it never reads a script from stdin. Without --database, the store is :memory:, which is gone when the process exits. A query A statement that reads, where the contrast with writing matters; also relate query, the command that runs a statement session. Read more in the glossary, in these docs, is a statement that reads; the command runs writes too.
Synopsis
relate query [STATEMENT] [--database PATH]| Part | Meaning |
|---|---|
STATEMENT | One Cypher statement, or a list separated by ;. Optional. -c and --command are the flag spelling of the same argument |
--database PATH | The store: a directory, a path ending in .rl, or :memory: (the default). Never a URL; a remote store is a --load source. Short form -d |
OPTIONS | Any query-run flag, before or after STATEMENT (Options) |
The word query is the command when it is the first positional argument, before or after flags; a later positional query is an unexpected argument (exit code 2). A directory named query is --database ./query.
Options
relate query takes the query-run flags, the same set as the path-first form. A flag beats its environment variable, which beats the built-in default. Flags may come before or after the statement, a flag's value is the next argument (--mode envelope, not --mode=envelope), and --read-only is the one flag whose value is attached (--read-only=live). -- ends the options: every argument after it is positional, so a statement that starts with - can follow it. How flags are parsed has every parsing rule, and Environment variables lists the variables.
| Flag | Argument | Default | Scope | Since | Description |
|---|---|---|---|---|---|
--database, -d | PATH | :memory: | query run | — | The store target: a directory, a .rl file (legacy .cl files still open), or :memory:. Never a URL; a remote store is a --load source. |
--command, -c | CYPHER | unset | query run | — | One statement or a ;-separated list; the same as the positional QUERY, and the two cannot be combined. |
--load | SOURCE | unset | query run | — | Load a store's content from a source (a local .rl file, a directory, or an http(s) URL to a .rl file) into the target: into :memory: it is an ephemeral read-only open; into a new -d PATH it creates the store. |
--mode | MODE | table on a terminal; jsonl when stdout is piped or redirected; toon instead of jsonl when agent mode is on | query run | — | Output mode: table, csv, json, jsonl, envelope, markdown, cypher, toon, speedscope. An explicit mode always overrides the default. |
--format | MODE | as --mode | query run | — | Alias of --mode (the neo4j-cli spelling). --output and -o are unknown flags whose did-you-mean names --format. |
--jsonalso -json | — | off | query run | — | Shortcut for --mode json: one object per result set with the rows in data; indented on a terminal, one compact line when piped. |
--csvalso -csv | — | off | query run | — | Shortcut for --mode csv. |
--jsonlalso -jsonl | — | off | query run | — | Shortcut for --mode jsonl. |
--markdownalso -markdown | — | off | query run | — | Shortcut for --mode markdown. |
--toon | — | off | query run | — | Shortcut for --mode toon. |
--pretty | — | off | query run | — | Force indented json output when stdout is not a terminal; ignored by the other modes. |
--noheaderalso -noheader | — | off | query run | — | Suppress column headers. |
--paramalso -param | N=V | unset | query run | — | Bind a Cypher parameter (repeatable). A value that parses as JSON keeps its JSON type (true, null and numbers included); a value that starts with a digit, -, ", [ or { and does not parse exits 2; any other value binds as a string. |
--fetch-params | N=SRC | unset | query run | — | Fetch an http(s) URL or read a file, parse it as JSON, and bind it as parameter N (repeatable; 64 MiB cap, 60 s timeout). A CLI-process fetch with no URL allowlist. |
--snapshot-format | parquet|json|markdown|parquet-wide | parquet (json in builds without the parquet feature) | query run | — | Snapshot codec for an empty directory; an existing store keeps its recorded codec, and a different codec fails the open (exit 1). parquet-wide is the parquet codec with one typed column per common property key (format version 5): on an empty directory it creates a wide store, on an existing parquet store the next checkpoint re-encodes every part, and the manifest keeps the store wide after that.Environment: RELATE_SNAPSHOT_FORMAT. |
--markdown-body-properties | LIST | body | query run | — | Body properties of a markdown-codec store (LIST or Label=LIST; entries separated by ;; the first is written bare, the rest as ## sections). |
--wal-dir | PATH | <DATABASE>/wal | query run | — | Local WAL directory for a directory store; rejected for .rl files. |
--checkpoint-interval-secs | N | 300 | query run | — | Timed checkpoint period; 0 disables the timer. Persistent stores only.Environment: RELATE_CHECKPOINT_INTERVAL_SECS. |
--durability-mode | full|everysecond|snapshot | full | query run | — | Commit durability policy. everysecond can lose about the last second of acknowledged writes in a crash; snapshot can lose every write since the last completed checkpoint.Environment: RELATE_DURABILITY_MODE. |
--logical-graph-size-limit | SIZE | unlimited | query run | — | Live graph and index cap in logical bytes; 0 or unset is unlimited.Environment: RELATE_LOGICAL_GRAPH_SIZE_LIMIT. |
--expression-memory-limit | SIZE | 256 MiB | query run | — | Per-allocation expression cap; none or 0 disables it.Environment: RELATE_EXPRESSION_MEMORY_LIMIT. |
--concurrent-logical-workspace-limit | SIZE | admission off | query run | — | Shared logical-workspace pool; a positive value turns query admission on; 0 is rejected.Environment: RELATE_CONCURRENT_LOGICAL_WORKSPACE_LIMIT. |
--max-traversal-depth | N | 500 | query run | — | Largest explicit traversal hop bound (1 through 2000); a larger bound fails at admission with TraversalDepthExceeded.Environment: RELATE_MAX_TRAVERSAL_DEPTH. |
--safe, --no-safe | — | off | query run | — | Opt-in safe mode: refuses a new named node without a label, and a MATCH read whose final RETURN/WITH has no LIMIT and no reducing aggregate, as SafeModeViolation (exit 6).Environment: RELATE_SAFE_MODE. |
--timeout | DURATION | unset (no bound) | query run | — | Per-statement wall-clock bound: a bare number is seconds, ms/s/m suffixes, fractions allowed; 0 disables. A timed-out statement exits 7 with code: "timeout". |
--max-rows | N | 100 under a detected agent harness with stdout not a terminal; otherwise unlimited | query run | — | Rows printed per statement; 0 is unlimited. A cut result warns on stderr, names the cut in-band in the machine modes, and exits 0.Environment: RELATE_MAX_ROWS. |
--width | N | the terminal width, else COLUMNS, else the natural width | query run | — | Wrap the human table output to N columns; a value under 20 exits 2. |
--read-only | [=snapshot|live] | off | query run | — | Open an existing store without writing, checkpointing or migrating. snapshot (default) freezes the state at open; live tails a directory store's WAL (refused for .rl and :memory:). Attached form only; once only. A write fails with exit 6. |
--load-csv-dir | PATH | denied | query run | — | Allow local LOAD CSV only for regular files under this directory; per-file limit 8 MiB.Environment: RELATE_LOAD_CSV_DIR. |
--namespace | NAME | neo4j | query run | — | Session namespace for the run: neo4j, system or system_ontologies (case-insensitive). Not accepted by pull. |
--agent-mode, --no-agent-mode | — | detected (stdout not a terminal and an agent harness variable set) | query run | — | Turn agent ergonomics (the row-cap default and the piped toon default) on or off unconditionally; overrides RELATE_AGENT_MODE and detection.Environment: RELATE_AGENT_MODE. |
--help, -h | — | — | query run | — | Print usage to stdout and exit 0; after a command word, that command's help. |
--versionalso -version, -v | — | — | query run | — | Print Relate v<version> and License: Apache 2.0 (binary); with --json, one JSON object with arch, license, name, os, version. |
-- | — | — | query run | — | Treat all following arguments as positional. |
A — under Since: the data does not record the release that added the flag.
Session forms
The form depends on whether a statement is given and on what stdin is:
| Form | Chosen when | Runs |
|---|---|---|
| Oneshot | STATEMENT or -c is given | The statement, or each statement of the ;-separated list in order, then exits |
| Stdin script | No statement, and stdin is a pipe, a file or /dev/null | Every statement on stdin until end of input, then exits. Statements end with ; (the last one may omit it), may span lines, and // starts a comment. Dot commands such as .begin and .commit work one per line |
| Interactive shell | No statement, and stdin is a terminal | A prompt with readline-style editing and the dot commands, until .quit or end of input |
In the oneshot and stdin forms, each statement prints its own result set and commits on its own, unless a .begin in a script opened a transaction A unit of work that commits as a whole or not at all; each statement is its own transaction unless an explicit begin … commit groups several. Read more in the glossary. A failed statement stops the run: the statements before it stay committed, and the rest do not run. Dot commands lists the shell and script commands, and Use the interactive shell covers the shell.
The path-first form with no statement differs only in the stdin case: it prints the top-level help and exits 0 without reading stdin, so a redirected script never runs. A script on stdin needs the word query.
| Input | Exit code | Message on stderr |
|---|---|---|
STATEMENT and -c together | 2 | Error: --command cannot be combined with a positional query |
| A second positional statement | 2 | Error: unexpected argument: <statement>, the usage line, and a --help hint |
| Empty stdin | 0 | None |
These examples run in a new, empty directory. This first command writes: it creates team.rl, a single-file store holding three people and two projects, and prints nothing, because a CREATE with no RETURN has no rows:
relate query --database ./team.rl "CREATE (ada:Person {name: 'Ada', role: 'engineer'}),
(grace:Person {name: 'Grace', role: 'engineer'}),
(noor:Person {name: 'Noor', role: 'maintainer'}),
(relate:Project {name: 'relate', language: 'Rust'}),
(tck:Project {name: 'opencypher-tck', language: 'Gherkin'}),
(ada)-[:WORKS_ON {since: 2024}]->(relate),
(grace)-[:WORKS_ON {since: 2023}]->(relate),
(grace)-[:WORKS_ON {since: 2022}]->(tck),
(noor)-[:MAINTAINS]->(relate),
(ada)-[:KNOWS]->(grace)"A oneshot read. Stdout is a pipe here, so the output mode is jsonl: one JSON object per row, then one line with the statement's timings and plan-cache outcome:
relate query --database ./team.rl --read-only "MATCH (p:Person) RETURN p.name AS name ORDER BY name"{"name":"Ada"}
{"name":"Grace"}
{"name":"Noor"}
{"planCache":"miss","timings":{"elapsed_ms":0.532833,"execute_ms":0.366083,"lex_parse_ms":0.028334,"lower_ms":0.042624999999999996,"parse_ms":0.104958,"plan_ms":0.052958,"result_generation_ms":0.000167,"rewrite_ms":0.008209000000000001}}-c with a ;-separated list prints one result set per statement, here as envelopes (--mode envelope):
relate query --database ./team.rl --read-only --mode envelope -c "MATCH (p:Person) RETURN count(p) AS people; MATCH (p:Project) RETURN count(p) AS projects"{"columnTypes":["INTEGER"],"columns":["people"],"notifications":[],"planCache":"miss","rows":[{"people":3}],"timings":{"elapsed_ms":0.46900000000000003,"execute_ms":0.299875,"lex_parse_ms":0.030875,"lower_ms":0.041832999999999995,"parse_ms":0.106041,"plan_ms":0.055,"result_generation_ms":0.000375,"rewrite_ms":0.008542000000000001},"truncated":false}
{"columnTypes":["INTEGER"],"columns":["projects"],"notifications":[],"planCache":"miss","rows":[{"projects":2}],"timings":{"elapsed_ms":0.032499999999999994,"execute_ms":0.004459,"lex_parse_ms":0.0055,"lower_ms":0.009209,"parse_ms":0.019167,"plan_ms":0.007541,"result_generation_ms":0.000084,"rewrite_ms":0.00041600000000000003},"truncated":false}The same two statements as a script on stdin:
printf 'MATCH (p:Person) RETURN count(p) AS people;\nMATCH (p:Project) RETURN count(p) AS projects;\n' | relate query --database ./team.rl --read-only --mode envelope{"columnTypes":["INTEGER"],"columns":["people"],"notifications":[],"planCache":"miss","rows":[{"people":3}],"timings":{"elapsed_ms":0.468375,"execute_ms":0.283959,"lex_parse_ms":0.028917,"lower_ms":0.052667000000000005,"parse_ms":0.1175,"plan_ms":0.058708,"result_generation_ms":0.00025,"rewrite_ms":0.008084},"truncated":false}
{"columnTypes":["INTEGER"],"columns":["projects"],"notifications":[],"planCache":"miss","rows":[{"projects":2}],"timings":{"elapsed_ms":0.043417000000000004,"execute_ms":0.003333,"lex_parse_ms":0.007666999999999999,"lower_ms":0.010875,"parse_ms":0.02575,"plan_ms":0.011916999999999999,"result_generation_ms":0.000083,"rewrite_ms":0.00075},"truncated":false}A script that fails at its second statement. The first statement's result prints, the stderr lines say how far the run got, and the error object names the statement:
printf 'MATCH (p:Person) RETURN count(p) AS people;\nRETURN 1/0 AS boom;\nRETURN 3 AS never;\n' | relate query --database ./team.rl --read-only --mode envelope
echo "exit=$?"{"columnTypes":["INTEGER"],"columns":["people"],"notifications":[],"planCache":"miss","rows":[{"people":3}],"timings":{"elapsed_ms":0.315917,"execute_ms":0.148167,"lex_parse_ms":0.028875,"lower_ms":0.042959,"parse_ms":0.104167,"plan_ms":0.055542,"result_generation_ms":0.00025,"rewrite_ms":0.008542000000000001},"truncated":false}
type error: / by zero
statement 2 of 3 failed; 1 completed and committed; 1 not run
{"error":{"code":"validation_error","committed":1,"exit_code":6,"kind":"type","message":"type error: / by zero","retryable":false,"statement":2,"statements":3}}
exit=6Output modes
Without an output flag, the mode depends on where stdout goes:
| stdout | Default mode |
|---|---|
| A terminal | table |
| A pipe or a file | jsonl |
| A pipe or a file, with agent mode on | toon |
--mode (alias --format) picks one of table, csv, json, jsonl, envelope, markdown, cypher, toon and speedscope; --json, --csv, --jsonl, --markdown and --toon are shortcuts. Of several output flags, the last one wins. A failed statement prints the error object on stdout in envelope, json, jsonl and speedscope; table, csv, markdown, cypher and toon print nothing on stdout; the stderr message and the exit code remain. Output modes shows each mode's output.
--mode table on the people in team.rl:
relate query --database ./team.rl --read-only --mode table "MATCH (p:Person) RETURN p.name AS name, p.role AS role ORDER BY name"+---------+--------------+
| name | role |
+---------+--------------+
| "Ada" | "engineer" |
| "Grace" | "engineer" |
| "Noor" | "maintainer" |
+---------+--------------+Parameters
A statement reads a parameter A named value a statement refers to as $name and the caller binds separately, such as with --param name=value on the CLI. Read more in the glossary as $name. Two flags bind them, and both repeat, one parameter each:
| Flag | Binds | Limits |
|---|---|---|
--param N=V | $N to V, parsed as JSON. A value that starts like JSON (a digit, -, ", [ or {) and does not parse exits 2; any other bare word is a string | A name bound twice keeps the last value |
--fetch-params N=SRC | $N to the JSON parsed from SRC: a file path, or an http or https URL | 64 MiB per source and 60 seconds per fetch. No URL allowlist: the fetch has the same trust as --param |
A statement that names a parameter no flag bound fails with semantic error: ParameterMissing: Expected parameter(s): <name> and exit code 6. Grace's projects, by parameter, against team.rl:
relate query --database ./team.rl --read-only --mode envelope --param name=Grace 'MATCH (p:Person {name: $name})-[w:WORKS_ON]->(r:Project) RETURN r.name AS project, w.since AS since ORDER BY since'{"columnTypes":["STRING","INTEGER"],"columns":["project","since"],"notifications":[],"planCache":"miss","rows":[{"project":"opencypher-tck","since":2022},{"project":"relate","since":2023}],"timings":{"elapsed_ms":0.473833,"execute_ms":0.281583,"lex_parse_ms":0.033209,"lower_ms":0.047208,"parse_ms":0.12095800000000001,"plan_ms":0.06224999999999999,"result_generation_ms":0.00029099999999999997,"rewrite_ms":0.008124999999999999},"truncated":false}Single quotes keep the shell from expanding $name. Script the CLI shows typed values and a JSON file.
Read-only opens
--read-only opens an existing store without writing or checkpointing it. It is off unless given, and it may appear once per run.
| Spelling | Opens | Refused for |
|---|---|---|
--read-only, --read-only=snapshot | The store as it was at open: a frozen snapshot. On a directory store it can open beside a writer; a .rl file opens only while no writer holds it | — |
--read-only=live | A live read-only open: it tails the WAL and follows the writer's commits | .rl files and :memory:: semantic error: live freshness (WAL follow) is only supported for native directory databases, exit code 1 |
--read-only live (a space) | Nothing: exit code 2 with Error: --read-only takes its value attached: --read-only=live | — |
A read-only open never creates a store. A missing directory fails with storage error: read-only open requires an existing database at <path> and a missing .rl file with storage error: database not found: <path>, each after Failed to open Relate: and with exit code 1. On :memory:, --read-only rejects writes and creates nothing. A write against a read-only open fails before it changes anything, with exit code 6:
relate query --database ./team.rl --read-only --mode envelope "CREATE (:Person {name: 'Zed'})"
echo "exit=$?"semantic error: WriteOnReadOnlyAccessDatabase: No write operations are allowed on this database. The database is in read-only mode on this Neo4j instance.
{"error":{"code":"validation_error","exit_code":6,"kind":"semantic","message":"semantic error: WriteOnReadOnlyAccessDatabase: No write operations are allowed on this database. The database is in read-only mode on this Neo4j instance.","retryable":false}}
exit=6Statement timeouts
--timeout DURATION bounds each statement's wall-clock time on its own. A bare number is seconds; ms, s and m suffixes and fractions are accepted; 0 turns the bound off. Unset, a statement has no time bound. A statement that runs longer is cancelled and exits 7; the error object's code is timeout and retryable is false:
relate query --read-only --mode envelope --timeout 100ms "UNWIND range(1, 20000) AS a UNWIND range(1, 20000) AS b RETURN count(*) AS pairs"
echo "exit=$?"Error: query timed out after 100ms
{"error":{"code":"timeout","exit_code":7,"kind":"execution","message":"query timed out after 100ms","retryable":false}}
exit=7A value that is not a duration exits 2 with Error: invalid --timeout: '<value>' is not a duration (try 500ms, 10s, 2m).
Errors and exit codes
A session exits with the code of the first statement that failed, or 0. An empty result is a success.
| Exit code | Meaning in a query session |
|---|---|
| 0 | Every statement ran, including one with no rows |
| 1 | Runtime failure: the store did not open, a capacity limit, an I/O or internal error |
| 2 | Usage error: unknown flag, bad or missing value, extra positional; nothing ran |
| 5 | Conflict: another process holds the store for writing, or a write-write conflict |
| 6 | The statement was rejected: syntax, semantic or type error, or a write on a read-only open |
| 7 | A statement exceeded --timeout |
The exit codes page has the error object's fields and a recorded run for each code.
Examples
Who works on what, written to a CSV file with a header row:
relate query --database ./team.rl --read-only --csv "MATCH (p:Person)-[w:WORKS_ON]->(r:Project) RETURN p.name AS person, r.name AS project, w.since AS since ORDER BY since" > who.csv
echo "exit=$?"
cat who.csvexit=0
person,project,since
Grace,opencypher-tck,2022
Grace,relate,2023
Ada,relate,2024See also
- CLI flags: each query-run flag with its environment variable
- Script the CLI: stdin scripts, parameters, timeouts, and exit codes in shell scripts
- Dot commands:
.begin,.commitand the other shell and script commands - Agent mode: the row cap and the
toondefault under an agent harness - relate agent-context: the flag names and exit codes as a compact briefing