Skip to main content
The toolchain ships two binaries. sumatra is the shell — the one command you use day to day: it compiles programs against your live database, builds them, runs them, and manages stored procedures. sumatra-compile is an offline inspector for looking at what a program compiles into, and is never required to run anything.

The sumatra binary

There are exactly two flags: There are no subcommands and no environment-variable configuration — statements do everything.

Interactive mode

Run sumatra --dsn my.dsn with no statement and you get a prompt:
One statement per line. There is no multi-line input, no paste mode, and no statement terminator at the prompt — source code always lives in files, never typed into the shell. There is also no SQL passthrough: the shell speaks Sumatra statements only, and you keep using your normal SQL client alongside it for queries. Leave with exit, quit, or Ctrl-D.

One-shot mode

Anything after the flags is joined with spaces and parsed as one prompt line; the process runs it and exits with the statement’s outcome:
This is the form for scripts and cron — the exit code is the program’s outcome (see below), so schedulers can branch on it without parsing output. Quote values that contain spaces exactly as you would at the prompt: "EXEC p('North America')".

The statement set

The help statement prints the whole surface:

@prog.sumatra [args…]

Submits a file. For an ordinary program: compile against the live catalog → build with g++ in a temporary directory → run → discard the binary. Nothing is stored; @ is the run-once form. Arguments after the file name are the program’s PARAM values, in declaration order. Double quotes group a value containing spaces (@p.sumatra "North America"); "" is a legal empty value. If the file’s program is a CREATE OR REPLACE PROCEDURE, submitting it stores the procedure instead of running anything — the file is the CREATE statement. A CREATE submission takes no arguments; argument values belong to EXEC.

EXEC name(lits…)

Runs a stored procedure. Parentheses are always required — EXEC p() means zero arguments. Arguments are positional literals only:
  • bare tokens: 42, 3.14, 2026-01-01, TRUE
  • single-quoted text: 'july', 'North America'
There is no escape mechanism for quotes in the current release: a text value containing ' cannot be passed and is rejected loudly. EXEC is one statement with no trailing semicolon. Keywords are case-insensitive and procedure names fold to lowercase.

DROP PROCEDURE name

Deletes the stored procedure’s database record and this host’s cached binaries for it. Dropping a name that does not exist is a loud error, never a silent no-op.

Exit codes

Shell-side failures (bad flags, unreadable files) also exit 1.
There is one internal code you may observe indirectly: a compiled stored procedure refuses to run if the database schema changed since it was compiled. The shell reacts by announcing [sumatra] compiling <name> (schema changed), recompiling the stored source, and rerunning once — see stored procedures. You do not need to handle this case yourself.

DSN files

A DSN file is one line of text naming the target database:
  • The URL scheme selects the backend. firebolt is the only registered backend in the current release; an unknown scheme is an immediate, loud error.
  • The database path is required — programs compile against that database’s catalog, and stored procedures live in it.
  • engine is optional; without it the system engine is used.
  • The file holds a credential: chmod 600 my.dsn. In the current release the DSN is a plain file — there is no encrypted-DSN or stdin-secret mechanism yet.
The shell connects with this DSN to compile and to manage procedures; each compiled program binary makes its own connection from the same file when it runs.

Toolchain preflight

Before the first build in a session, the shell verifies the host can compile: g++ on PATH, pkg-config, libcurl development headers, and the runtime/ + exec/ directories sitting next to the real sumatra binary. Each missing piece fails with a specific install hint, e.g.:
The check is lazy: a host that only runs already-cached stored procedures never compiles, so it never needs the toolchain.

sumatra-compile: the offline inspector

sumatra-compile runs entirely offline — no DSN, no connection. It compiles against a built-in sample schema (the tables of the example corpus: sumatra_orders, sumatra_customers, sumatra_sessions, and friends), so it is a way to inspect what programs lower to, not a way to compile against your own tables — the sumatra shell does that against the live catalog. - as the file name reads source from stdin. Compile errors exit 1; an unknown -emit value exits 2.

Diagnostics

Errors are positioned and specific. The shapes you will see:
Positions are line:column, 1-based. In the shell the same errors are prefixed with the file name: sumatra: prog.sumatra: <error>. Semantic errors favor prose that names the rule and the fix — for example, a variable read before it is ever assigned, or an ORDER KEY missing from a chunked read.

Debugging a running program

Setting the environment variable SUMATRA_TRACE (to any value) makes a compiled program dump each request to stderr: the head of the SQL, the HTTP status, and up to 2000 bytes of the response body. The shell’s child processes inherit it:
The trace includes SQL text and raw engine responses — treat the output as sensitive, and use it as a diagnostic aid only.