Prerequisites
- A Linux x86-64 host. This is the only packaged platform today.
- A Firebolt database you can write to, plus a service account (client id and secret) and your account name. Firebolt is the first supported backend — and the only one in the current release.
- A C++ toolchain. Sumatra compiles each program into a small native
binary on your host, so it needs
g++(C++17),pkg-config, and the libcurl development headers:
The toolchain is only exercised when something actually compiles. A host
that only runs already-compiled stored procedures from its cache never
needs
g++ installed.Install
Sumatra ships as a single tarball,sumatra-<version>-linux-amd64.tar.gz.
Unpack it and run it in place:
sumatra on your PATH, symlink it — do not copy the binary
out of the directory:
Create a DSN file
The shell connects with a DSN file: a plain text file containing one connection string. Createmy.dsn:
my.dsn
<database>— the Firebolt database to run against. Required: programs and stored procedures live per-database.account_name,client_id,client_secret— your Firebolt account and service-account credentials.engine— optional; omit it to use the system engine.
Create a table to work on
Run this in your Firebolt database (SQL workspace or any client) — the same table the programs in Learning by example build on:Your first program
Sumatra source lives in files, conventionally with a.sumatra
extension. Create expire.sumatra:
expire.sumatra
--starts a comment, to the end of the line.BEGIN ... END;brackets the program body. There are no variables here, so noDECLAREsection is needed.- The
UPDATEis plain SQL in Firebolt’s own dialect. A write that is already set-shaped stays set-shaped — Sumatra runs it server-side as-is and adds no machinery around it. COMMIT;ends the transaction. Commits are always explicit in Sumatra — where you placeCOMMITdefines exactly what becomes durable together.- Every statement ends with
;, including the finalEND;.
Run it
Point the shell at your DSN file and submit the file with@:
- Compiled
expire.sumatraagainst the live catalog of the connected database — the database itself is the schema; there are no schema files to maintain. - Generated C++ for the program and built it with
g++in a temporary directory. (The first build in a session also checks thatg++,pkg-config, and libcurl headers are present, and fails loudly with an install hint if not.) - Ran the binary, which connected using the same DSN file and executed the transaction.
- Discarded the binary. A file submitted with
@is compile-and-run, never stored — stored procedures are the persistent form.
expired, session 2
is untouched.
A program with per-row logic
Set-DML is the trivial case. Sumatra earns its keep when the logic is procedural — when each row needs branching, state, or arithmetic that is awkward to express in one SQL statement. Create an orders table and a few rows:prioritize.sumatra:
prioritize.sumatra
FOR batch IN (SELECT ...)opens a read block. The parenthesized query is ordinary Firebolt SQL — filter, join, aggregate as you like.batchis a name you choose.ORDER KEY (order_id)declares a strict total order for the read. It is required whenever the read is fetched in chunks, so results are deterministic and a re-run walks rows in the same order.BATCH SIZE 10000fetches the result in chunks of up to 10,000 rows. Each batch is processed, written, and committed as a unit.FOR rec IN batch LOOPiterates the current batch row by row, in memory.rec’s fields are the columns of your SELECT, and they are assignable.:=is Sumatra assignment (plain=is SQL’s comparison/SET, used only inside SQL statements).UPDATE ... SET ROW = rec WHERE order_id = rec.order_id;writes the whole record back — every column except the key it matches on. You never writeMERGEor staging tables yourself; the compiler batches the captured row writes and emits one set-based statement per batch.COMMIT;inside the batch loop makes each batch a durable checkpoint as soon as it is written.
Exit codes
Every program run finishes in exactly one of three ways:
The distinction between
2 and 1 is deliberate: 2 means the program
anticipated the fault and shut down gracefully with a valid committed
prefix; 1 means something needs a human. Scripts and schedulers can
branch on it directly.
Where next
- Programs and batches — the full anatomy of a program: read blocks, write routing, and commit grains.
- Learning by example — small annotated programs, from a running balance to exception handling.
- Stored procedures — name a program, store it in
the database, and run it with
EXECfrom anywhere. - The sumatra shell — the complete command-line reference.
