Documentation
¶
Overview ¶
Package storeexec adapts github.com/stergiotis/boxer/public/keelson/data/chclient to github.com/stergiotis/boxer/public/storage/recordstore.ExecutorI, the seam a generated record store (ADR-0100) uses to reach ClickHouse.
This is ADR-0105 D1. The adapter lives on the keelson side so the dependency direction stays one-way: keelson imports recordstore, never the reverse. Its sibling github.com/stergiotis/boxer/public/storage/recordstore/chexec.LocalExecutor covers tests and local tooling by shelling out to `clickhouse-local`; this one talks to a server over HTTP and is what a long-running keelson service binds.
Reads stream ¶
QueryArrow appends ` FORMAT ArrowStream` to the caller's statement and decodes the response as it arrives, so a large result never materializes in full. That is the streaming implementation the ExecutorI iterator shape was written for; the buffered LocalExecutor satisfies the same contract by iterating a materialized slice.
Two preconditions ride on the appended clause, both of which fail loudly (ClickHouse answers with a syntax error carrying the offending text):
- The statement must not carry its own FORMAT clause. Generated stores never emit one — they end at a SETTINGS clause, and FORMAT sits after SETTINGS in ClickHouse's grammar.
- The statement must be a single statement. The HTTP interface rejects a multi-statement script outright ("Multi-statements are not allowed", verified against 26.7.3). A generated EnsureTable honours this — it issues its CREATE DATABASE and CREATE TABLE one per Exec (recordstore.ProvisioningStatements) — so a store may provision itself through this executor; before 2026-08-15 it shipped the embedded script whole and could not. Callers issuing their own DDL send one statement per Exec.
What a mid-result failure looks like ¶
ClickHouse has already answered 200 by the time rows stream, so a server-side failure part way through a result arrives as a corrupt Arrow stream — an Arrow decode error from the iterator, not an HTTP status. The `wait_end_of_query=1` setting would trade streaming (and server memory) for a clean error code; it is deliberately not set here.
Concurrency ¶
A Client is goroutine-safe and so is this wrapper, but a generated store is single-goroutine (ADR-0100) and ADR-0105 D4 confines it to one owner. One executor may back several confined stores.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var PackageProps = packageprops.Props{ WASMWASI: packageprops.WASMBlocked, WASMJS: packageprops.WASMBlocked, WASMFreestanding: packageprops.WASMBlocked, }
PackageProps records this package's curated properties (ADR-0080). Blocked for the same reason chclient is: net/http plus the arrow dependency do not build under the WASM targets.
Functions ¶
This section is empty.
Types ¶
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor moves statements and Arrow batches between a generated record store and a ClickHouse server over HTTP.
func (*Executor) Exec ¶
Exec runs sql for its side effect. See the package comment on single statements.
It returns once the server has *accepted* the statement, which is not quite the same as having completed it: a failure raised after ClickHouse has answered 200 rides in a response body that github.com/stergiotis/boxer/public/keelson/data/chclient.Client.Exec discards, so it reads here as success. That doc carries the detail and the reason nothing catches it yet.
func (*Executor) InsertArrow ¶
func (inst *Executor) InsertArrow(ctx context.Context, table string, records []arrow.RecordBatch) (err error)
InsertArrow appends records to table and returns once the insert is acknowledged. The records are not retained; the caller releases them after return.
func (*Executor) QueryArrow ¶
func (inst *Executor) QueryArrow(ctx context.Context, sql string) iter.Seq2[arrow.RecordBatch, error]
QueryArrow runs sql with ArrowStream output and yields the decoded batches as they arrive.
Ownership of each yielded batch transfers to the consumer, which must Release it — including the batch it breaks on. Batches never yielded stay this implementation's to release. An error ends the sequence as a final (nil, err) pair.