storeexec

package
v0.0.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 13 Imported by: 0

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

View Source
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 New

func New(client *chclient.Client, alloc memory.Allocator) (inst *Executor, err error)

New wraps client. A nil alloc takes the Go allocator, matching chexec.

func (*Executor) Exec

func (inst *Executor) Exec(ctx context.Context, sql string) (err error)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL