engine

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package engine wraps the embedded DuckDB instance that does all of Veritix's measuring.

Everything the profiler, the checks, and the agent want to know about a dataset is expressed as a SQL aggregate over tables in this engine. Keeping that in one place means there is exactly one component that touches data, one place where resource limits are enforced, and one place where the SQL that backs a finding can be re-run to verify it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Ident

func Ident(name string) string

Ident quotes a table or column name for use in a statement.

func Idents

func Idents(names []string) string

Idents quotes a list of names and joins them with ", ".

func Literal

func Literal(s string) string

Literal quotes a string for use as a SQL literal. Prefer a bound parameter; this exists for the handful of places DuckDB does not accept one, such as SET statements and table functions taking file paths.

func Qualify

func Qualify(table, column string) string

Qualify renders table.column with both parts quoted.

func SafeName

func SafeName(s string) string

SafeName turns an arbitrary string, typically a file or worksheet name, into a readable identifier. The result is only a suggestion: it still goes through Ident before reaching SQL, and the ingest layer resolves collisions.

Types

type Analysis

type Analysis struct {
	// Aggregate reports, per output column, whether the expression producing it
	// is built only from aggregates and constants and therefore cannot be a
	// value out of a row.
	//
	// It is conservative in the safe direction: an expression the parser
	// describes in a way this code does not recognize is reported as not an
	// aggregate, so it is shaped rather than disclosed.
	Aggregate []bool
}

Analysis is what DuckDB's parser says about a statement.

It exists because model-authored SQL needs two questions answered before its results can be shown to anybody: is this one read-only statement, and which of its output columns are statistics rather than cell contents. Both are answered by parsing, not by matching patterns in the text — a regex that decides what SQL does is a regex somebody will eventually get past.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine is a handle on one DuckDB database.

func Open

func Open(ctx context.Context, path string, cfg config.Engine, log *slog.Logger) (*Engine, error)

Open starts an engine. An empty path gives a transient in-memory database; a path gives a DuckDB file that survives the process, which is how the server caches an ingested dataset between runs.

func OpenReadOnly

func OpenReadOnly(ctx context.Context, path string, cfg config.Engine, log *slog.Logger) (*Engine, error)

OpenReadOnly opens an existing database file with writes refused by DuckDB itself, which is how a finished run's dataset is reopened to serve a finding's rows.

It is not what protects the database from the agent: the agent queries the live engine mid-run, when the file is already open for writing by this process. Lockdown is that boundary.

func (*Engine) AnalyzeSelect

func (e *Engine) AnalyzeSelect(ctx context.Context, query string) (*Analysis, error)

AnalyzeSelect parses a statement and describes it, refusing anything that is not a single SELECT.

The refusal is DuckDB's, not Veritix's: json_serialize_sql only serializes SELECT statements, so a COPY, an ATTACH, a DDL statement, or two statements separated by a semicolon fail here without Veritix needing an opinion about what those look like. What that does *not* cover — a SELECT that reads a file through a table function — is covered by Lockdown instead.

func (*Engine) Close

func (e *Engine) Close() error

Close releases the database.

func (*Engine) Collect

func (e *Engine) Collect(ctx context.Context, query string, maxRows int, args ...any) (*ResultSet, error)

Collect runs a query and reads the entire result, refusing to return more than maxRows. A maxRows of zero or less means "use the engine's configured cap"; the cap always applies, because an unbounded result from an agent-authored query is a way to exhaust memory.

func (*Engine) CountRows

func (e *Engine) CountRows(ctx context.Context, table string) (int64, error)

CountRows returns the row count of a table.

func (*Engine) DB

func (e *Engine) DB() *sql.DB

DB exposes the underlying handle for callers that need database/sql directly, such as bulk loading.

func (*Engine) Exec

func (e *Engine) Exec(ctx context.Context, query string, args ...any) error

Exec runs a statement that returns no rows.

func (*Engine) Lockdown

func (e *Engine) Lockdown(ctx context.Context) error

Lockdown takes away DuckDB's access to the filesystem and then locks the configuration so it cannot be given back.

It is called once the dataset is loaded and before any model-authored SQL is executed. Without it, a single SELECT is a way out of the process: `read_text('/etc/passwd')` reads a file the audit was never pointed at, and `COPY orders TO '/tmp/x.csv'` writes customer data somewhere the egress guard cannot see it. Neither is prevented by opening the database read-only, because both are about the host's filesystem rather than the database's.

This is DuckDB refusing, not Veritix pattern-matching the query text, which is the only version of "read-only" worth relying on when the query was written by a language model. The statement guard in agent/tools is the second layer, not the first.

It is irreversible by design: lock_configuration means that a later SET enable_external_access = true is rejected, so an agent that talks Veritix into running one gains nothing.

func (*Engine) LockedDown

func (e *Engine) LockedDown() bool

LockedDown reports whether Lockdown has been applied.

func (*Engine) Path

func (e *Engine) Path() string

Path reports the backing file, or "" for an in-memory database.

func (*Engine) ReadOnly

func (e *Engine) ReadOnly() bool

ReadOnly reports whether DuckDB will refuse writes on this handle.

func (*Engine) ScanOne

func (e *Engine) ScanOne(ctx context.Context, query string, dest []any, args ...any) error

ScanOne runs a query expected to yield exactly one row and scans it.

func (*Engine) TableExists

func (e *Engine) TableExists(ctx context.Context, name string) (bool, error)

TableExists reports whether a table of that name is present.

type QueryError

type QueryError struct {
	Query string
	Err   error
}

QueryError carries the statement that failed. Veritix builds a lot of SQL, and an error without the offending statement is close to undebuggable.

func (*QueryError) Error

func (e *QueryError) Error() string

func (*QueryError) Unwrap

func (e *QueryError) Unwrap() error

type ResultSet

type ResultSet struct {
	Columns []string
	Types   []string
	Rows    [][]any
	// Truncated reports that the query produced more rows than the cap
	// allowed, so a caller does not mistake a partial answer for a whole one.
	Truncated bool
}

ResultSet is a fully-read query result. Results are materialized rather than streamed because they are small by construction: every caller either caps rows or is running an aggregate that returns a handful of them.

Jump to

Keyboard shortcuts

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