querytable

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package querytable compiles a frontend QueryState into parameterized SQL, validated against a server-defined field schema. It is the Go projection of @pythia-software/query-table-core: the wire types here mirror the TS shapes exactly so a base64url ?q= token (or a JSON request body) round-trips without translation.

Safety model: the column expression for each field comes from the schema, never from request input. An unknown field is a compile error before any SQL is built. Values reach SQL only as bound placeholders ($N). The validated operator and the schema-defined expression are the only request-influenced tokens in the SQL text.

Index

Constants

View Source
const (
	// MaxQueryLimit is the largest row limit representable by this platform.
	// The package does not impose a smaller application-level row cap; consumers
	// and their databases own any operational limit appropriate for the dataset.
	MaxQueryLimit    = int(^uint(0) >> 1)
	MaxQueryOffset   = 1_000_000
	MaxSelectColumns = 200
	MaxWhereClauses  = 100
	MaxOrderByTerms  = 20
	MaxAggregations  = 20
	MaxGroupByFields = 20
)

Structural limits mirror @pythia-software/query-table-core. Compile and DecodeWireQuery both enforce them so callers are protected whether a query came from a URL token or was decoded from a JSON request body elsewhere.

View Source
const ComputedColumnsDDL = `` /* 349-byte string literal not displayed */
View Source
const DistributionPrecision = "exact-linear"

DistributionPrecision is the protocol method emitted by the box compiler.

View Source
const MaxExpressionBytes = 10000
View Source
const MaxExpressionNodes = 512
View Source
const MaxRelativeTimeMilliseconds int64 = 8_640_000_000_000_000

MaxRelativeTimeMilliseconds matches the portable datetime range used by local executors. Multiplication and summation are checked before arithmetic.

View Source
const SQLiteComputedColumnsDDL = `` /* 401-byte string literal not displayed */

SQLiteComputedColumnsDDL stores canonical definitions. Hosts opt into v2 execution separately by registering the v2 descriptors and executor. Requires SQLite 3.38+ (RETURNING).

View Source
const SQLiteExpressionProfile = "qt-sqlite-v1"

SQLiteExpressionProfile has distinct numeric/storage/collation semantics from PostgreSQL. Requires SQLite 3.38+ and both v1 and v2 function descriptors.

View Source
const SQLiteMaxBoxSamples = SQLiteMaxMedianSamples

SQLiteMaxBoxSamples bounds exact box memory per group, including Tukey tails. Larger populations produce resource_limit, never sampled quartiles.

View Source
const SQLiteMaxFunctionTextBytes = 1 << 20
View Source
const SQLiteMaxMedianSamples = 100000

SQLiteMaxMedianSamples bounds exact MEDIAN memory per group. Larger inputs return resource_limit rather than an approximate or truncated result.

View Source
const ServerExpressionProfile = "qt-postgres-v1"

Variables

View Source
var ErrComputedConflict = errors.New("computed definition changed; reload before saving")

Functions

func MetricExpression added in v0.6.0

func MetricExpression(spec AggSpec) string

func NewComputedColumnsHandler

func NewComputedColumnsHandler(repo ComputedColumnRepository, authorize func(*http.Request, string, bool) (string, error)) http.Handler

NewComputedColumnsHandler implements the TypeScript httpComputedColumnStore protocol. Authorize MUST validate the authenticated caller's dataset access, write permission and (for cookie-authenticated writes) CSRF protection. Return a stable tenant/user scope; it must never come directly from request input. Empty scope or nil authorization always denies access.

Types

type AggCompileResult

type AggCompileResult struct {
	SelectExprs []string
	GroupBySQL  string
}

AggCompileResult holds the SQL fragments for one metric's GROUP BY query. The caller splices them into its own FROM/JOIN, sharing the rows query's WHERE so the metric covers the same filtered set (scope = whole set, no paging). Use the same now passed to CompileAt for the rows query when compiling this WHERE:

SELECT <SelectExprs joined by ", ">
FROM   <caller FROM/JOIN>
[WHERE <CompileAt(WireQuery{Where: req.Where}, …, now).WhereSQL>]
[GROUP BY <GroupBySQL>]

SelectExprs is, in order: one `expr AS "g0"/"g1"/…` per group field, then the aggregate `AS "value"`, then `COUNT(*) AS "count"`. GroupBySQL lists the same group expressions (empty string ⇒ a single grand-total row, no GROUP BY).

func CompileAggregation

func CompileAggregation(spec AggSpec, schema Schema) (AggCompileResult, error)

CompileAggregation validates one AggSpec against the schema allowlist and emits its SELECT + GROUP BY fragments. Like Compile, the only request-influenced tokens that reach SQL are the validated op and the schema-defined field expressions — never request input. No bound args are produced (aggregations carry no values; the shared WHERE is compiled separately via CompileAt using the rows query's clock).

Errors on: unknown op, unknown measure/group field, a missing measure for an op that needs one, or an op not allowed for the measure field's kind.

func CompileSQLiteAggregation added in v0.6.0

func CompileSQLiteAggregation(a AggSpec, s Schema) (AggCompileResult, error)

CompileSQLiteAggregation supports the six basic aggregate operations. Modern expressions, scopes, distributions and paired metrics are explicitly refused. Numeric measures are checked before and after reductions; unsafe integers, non-finite values, and nonnumeric SQLite storage fail rather than becoming 0.

type AggSpec

type AggSpec struct {
	Diagnostics  []string            `json:"diagnostics,omitempty"`
	Display      *MetricDisplayHint  `json:"display,omitempty"`
	Expression   string              `json:"expression,omitempty"`
	ExpressionY  string              `json:"expressionY,omitempty"`
	Scope        string              `json:"scope,omitempty"`
	Sort         []MetricSort        `json:"sort,omitempty"`
	GroupLimit   int                 `json:"groupLimit,omitempty"`
	Distribution *MetricDistribution `json:"distribution,omitempty"`
	ID           string              `json:"id"`
	Op           string              `json:"op"`
	Field        string              `json:"field,omitempty"`
	GroupBy      []string            `json:"groupBy,omitempty"`
}

AggSpec mirrors @pythia-software/query-table-core AggregationClause: one aggregate op over one measure column (Field; empty ⇒ COUNT(*)), broken down by zero or more group columns. Compiled by CompileAggregation; the metric panel runs one per spec over the WHERE-filtered set (no paging).

type CompileResult

type CompileResult struct {
	// WhereSQL is "" when no filters apply, else "(c1) AND (c2) ...". Never
	// includes the WHERE keyword, so callers AND it into their own predicates.
	WhereSQL string
	// OrderSQL is "" to use the schema default, else
	// "expr DIR NULLS x, expr2 DIR2 NULLS y, <tiebreak...>".
	OrderSQL string
	// SelectExprs are "<expr> AS <safe_alias>" for each requested backend field.
	SelectExprs []string
	// Args are the $N bound values, in placeholder order starting at startIdx.
	Args []any
	// SQLite-only parameter partitions, for composing count and row statements.
	WhereArgs []any
	OrderArgs []any
}

CompileResult holds the SQL fragments plus their ordered bound args.

func Compile

func Compile(q WireQuery, schema Schema, startIdx int) (CompileResult, int, error)

Compile validates q against schema and emits SQL fragments. startIdx is the 1-based pgx placeholder index for the first bound value, so callers can interleave their own params; the returned int is the next free index.

Errors (never a panic) on: unknown field, an operator not allowed for a field's kind or per-field operator allowlist, a filter on a non-server-filterable field, a sort on a non-sortable field, an unknown select field, or a value that fails coercion.

func CompileAt added in v0.6.0

func CompileAt(q WireQuery, schema Schema, startIdx int, now time.Time) (CompileResult, int, error)

CompileAt captures relative datetime values using one explicit reference time. Share now across row/count/metric compilations for a consistent snapshot. Relative values are resolved to bound UTC timestamps, never interpolated SQL.

func CompileSQLite added in v0.6.0

func CompileSQLite(q WireQuery, s Schema, o SQLiteOptions) (CompileResult, error)

CompileSQLite emits fragments with anonymous ? parameters. Args are ordered for WHERE followed by ORDER BY; SELECT expressions contain no parameters. FROM/JOIN and field expressions are trusted host input, never query input. Requires SQLite 3.38+ with JSON and the functions from SQLiteFunctions. This is a v1 row/basic-aggregation adapter, not the qt-postgres-v1 v2 profile.

type ComputedColumn

type ComputedColumn struct {
	ID         string             `json:"id"`
	Label      string             `json:"label"`
	Expression ComputedExpression `json:"expression"`
	Revision   string             `json:"revision"`
}

type ComputedColumnRepository

type ComputedColumnRepository interface {
	List(ctx context.Context, scope, dataset string) ([]ComputedColumn, error)
	Save(ctx context.Context, scope, dataset string, request SaveComputedColumnRequest) (ComputedColumn, error)
}

type ComputedExpression

type ComputedExpression struct {
	Language string `json:"language"`
	Version  int    `json:"version"`
	Source   string `json:"source"`
}

type DefinitionResolver added in v0.6.0

type DefinitionResolver interface {
	ResolveComputed(context.Context, string) (ComputedColumn, error)
}

DefinitionResolver must read the authorized catalogue in one coherent snapshot. IDs have no @computed/ prefix. Implementations must not trust a client source.

type DefinitionResolverFunc added in v0.6.0

type DefinitionResolverFunc func(context.Context, string) (ComputedColumn, error)

func (DefinitionResolverFunc) ResolveComputed added in v0.6.0

func (f DefinitionResolverFunc) ResolveComputed(c context.Context, id string) (ComputedColumn, error)

type DistinctCompile

type DistinctCompile struct {
	Expr      string
	SearchSQL string // "" when search is empty
	Args      []any
}

DistinctCompile holds the fragments for an autocomplete distinct-values query. The caller assembles them into its own FROM/JOIN tree:

SELECT DISTINCT <Expr> AS v FROM ... WHERE <Expr> IS NOT NULL [AND <SearchSQL>]
ORDER BY v LIMIT <n+1>   -- fetch one extra to compute hasMore

func CompileDistinct

func CompileDistinct(field, search string, schema Schema, startIdx int) (DistinctCompile, int, error)

CompileDistinct builds the fragments to back filter-value autocomplete for a field (design feedback: every field is an autocomplete by default). The search is a literal case-insensitive substring (no wildcard injection).

type DistinctHasNullCompile

type DistinctHasNullCompile struct {
	IsNullExpr string
}

func CompileDistinctHasNull

func CompileDistinctHasNull(field string, schema Schema) (DistinctHasNullCompile, error)

CompileDistinctHasNull builds the nullability expression for the same field-aware distinct path used by value autocomplete. It is intended for a lightweight metadata query that answers “does this field have any nulls?” without another independent field lookup path in callers.

type ExecutionPlan added in v0.6.0

type ExecutionPlan struct {
	Rows              SQLPlan
	Metrics           MetricBatchPlan
	ResolvedRevisions map[string]string
	Fingerprint       string
}

ExecutionPlan binds the union of row and metric definition revisions. The caller must submit identical filters/order/windows in Rows and Metrics when they represent one table view. Different SQL statements still require a shared database snapshot; Fingerprint is an identity, not an authorization.

func CompileExecution added in v0.6.0

func CompileExecution(ctx context.Context, rows WireQuery, metrics MetricQuery, s Schema, o PlanOptions) (ExecutionPlan, error)

func CompileSQLiteExecution added in v0.6.0

func CompileSQLiteExecution(ctx context.Context, rows WireQuery, metrics MetricQuery, s Schema, o PlanOptions) (ExecutionPlan, error)

CompileSQLiteExecution shares one clock and resolver cache across row/metric plans. The host executes them in the resolver's SQLite transaction; use SQLiteV2Dataset.ExecuteV2In for bounded execution and wire-format results.

type FieldKind

type FieldKind int

FieldKind picks the value-coercion + operator-validation path.

const (
	FieldText FieldKind = iota
	FieldNumber
	FieldDatetime
	FieldBool
	FieldEnum
	FieldTextArray
)

type FieldSpec

type FieldSpec struct {
	// ExpressionNumeric certifies a SQL numeric binding eligible for the bounded
	// v2 profile. Values outside +/-1e100 produce numeric_range, never DB overflow.
	ExpressionNumeric bool
	// SQLiteDatetimeFormat: rfc3339 (default), utc-millis, unix-seconds, or unix-millis.
	SQLiteDatetimeFormat string
	// SQLiteSortField preserves the target storage kind/format for sort.field.
	SQLiteSortField string
	// AggregateOps nil uses defaults; an empty slice disables aggregation.
	AggregateOps []string
	Groupable    *bool // nil defaults to text/enum/bool grouping in v2
	Name         string
	Kind         FieldKind
	Expr         string
	Synthetic    bool
	ServerFilter bool // false → field is client-only; Compile rejects filters on it
	// ArrayCaseSensitive preserves exact text-array membership keys. Default false.
	ArrayCaseSensitive bool
	// FilterOps is nil for the type's default matrix; a non-nil slice is the
	// field's explicit operator allowlist. An empty slice disables every op.
	FilterOps []string
	Sortable  bool
	SortExpr  string // expr to ORDER BY when it differs from Expr (FieldDef.sort.field → that field's Expr)
}

FieldSpec is one field's server binding. Expr is the server-defined SQL expression (from the document's bindings.postgres.expr) and is the injection boundary: it is never built from request input.

type MetricBatchPlan added in v0.6.0

type MetricBatchPlan struct {
	Metrics                []MetricSQLPlan
	RequiresSharedSnapshot bool
}

func CompileMetrics added in v0.6.0

func CompileMetrics(ctx context.Context, q MetricQuery, s Schema, o PlanOptions) (MetricBatchPlan, error)

CompileMetrics compiles every requested metric or returns an error. Each plan is one statement; execute the batch in one repeatable-read snapshot. X/Y are always reduced together using one grouped relation, never positionally joined.

func CompileSQLiteMetrics added in v0.6.0

func CompileSQLiteMetrics(ctx context.Context, q MetricQuery, s Schema, o PlanOptions) (MetricBatchPlan, error)

CompileSQLiteMetrics validates the entire v2 batch before returning any plans. Execute every plan and resolve definitions in the same SQLite transaction. SourceSQL uses numbered ?1..?N parameters reserved for SourceArgs.

type MetricBoxDistribution added in v0.6.0

type MetricBoxDistribution struct {
	Kind    string            `json:"kind"`
	Summary *MetricBoxSummary `json:"summary"`
}

type MetricBoxSummary added in v0.6.0

type MetricBoxSummary struct {
	N            int64     `json:"n"`
	Min          float64   `json:"min"`
	Q1           float64   `json:"q1"`
	Median       float64   `json:"median"`
	Q3           float64   `json:"q3"`
	Max          float64   `json:"max"`
	Mean         float64   `json:"mean"`
	Low          float64   `json:"low"`
	High         float64   `json:"high"`
	Outliers     []float64 `json:"outliers"`
	OutlierCount int64     `json:"outlierCount"`
	Whiskers     string    `json:"whiskers"`
	Method       string    `json:"method"`
}

type MetricDisplayHint added in v0.6.0

type MetricDisplayHint struct {
	Kind string `json:"kind"`
}

MetricDisplayHint retains only the paired-mode validation hint; all visual settings are ignored.

type MetricDistribution added in v0.6.0

type MetricDistribution struct {
	Kind     string `json:"kind"`
	Input    string `json:"input"`
	Whiskers string `json:"whiskers,omitempty"`
	Bins     int    `json:"bins,omitempty"`
}

type MetricDistributionResult added in v0.6.0

type MetricDistributionResult interface {
	// contains filtered or unexported methods
}

MetricDistributionResult is the v2 wire union supported by both renderers.

type MetricHistogramDistribution added in v0.6.0

type MetricHistogramDistribution struct {
	Kind   string    `json:"kind"`
	Edges  []float64 `json:"edges"`
	Counts []int64   `json:"counts"`
	N      int64     `json:"n"`
}

type MetricQuery added in v0.6.0

type MetricQuery struct {
	Profile           string            `json:"profile,omitempty"`
	ExpectedRevisions map[string]string `json:"expectedRevisions,omitempty"`
	PlanToken         string            `json:"planToken,omitempty"`
	Snapshot          string            `json:"snapshot,omitempty"`
	Version           int               `json:"version"`
	Where             []WhereTerm       `json:"where"`
	OrderBy           []OrderBy         `json:"orderBy"`
	Limit             int               `json:"limit"`
	Offset            int               `json:"offset"`
	Metrics           []AggSpec         `json:"metrics"`
	Diagnostics       []any             `json:"diagnostics,omitempty"`
}

MetricQuery is the v2 computation-only request. Presentation is intentionally ignored by the compiler. Diagnostics/residual filters must never be discarded.

type MetricSQLPlan added in v0.6.0

type MetricSQLPlan struct {
	ID string
	SQLPlan
}

type MetricSort added in v0.6.0

type MetricSort struct {
	Key   string `json:"key"`
	Dir   string `json:"dir"`
	Nulls string `json:"nulls,omitempty"`
}

type OrderBy

type OrderBy struct {
	Field   string        `json:"field"`
	Dir     string        `json:"dir"`             // "asc" | "desc"
	Nulls   string        `json:"nulls,omitempty"` // "first" | "last" | "" (default last)
	Extract *RegexExtract `json:"extract,omitempty"`
}

OrderBy mirrors @pythia-software/query-table-core OrderByClause.

type OrderBys

type OrderBys []OrderBy

OrderBys is a slice of OrderBy that also accepts a single object on decode (legacy compatibility) and a base64url `c`/`s` is handled at the WireQuery level via DecodeWireQuery.

func (*OrderBys) UnmarshalJSON

func (o *OrderBys) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts either `[{...},{...}]` (current) or `{...}` (legacy).

type OutputColumn added in v0.6.0

type OutputColumn struct{ Field, ValueAlias, ErrorAlias, Type string }

type PlanDiagnostic added in v0.6.0

type PlanDiagnostic struct {
	Code, Message, Field string
	Offset               int
}

PlanDiagnostic is a machine-readable capability or validation failure. Offset is a UTF-8 byte offset into canonical source, not a browser UTF-16 position.

func (*PlanDiagnostic) Error added in v0.6.0

func (d *PlanDiagnostic) Error() string

type PlanOptions added in v0.6.0

type PlanOptions struct {
	// ComputedGroupable is a trusted host allowlist of computed IDs permitted as group keys.
	ComputedGroupable map[string]bool
	// ValidatePlanToken must verify the host token against the current actor, dataset, profile, snapshot and expiry.
	ValidatePlanToken func(context.Context, string) error
	// ValidateSnapshot verifies and binds a requested snapshot to the active transaction.
	ValidateSnapshot  func(context.Context, string) error
	SourceSQL         string
	SourceArgs        []any
	Resolver          DefinitionResolver
	ExpectedRevisions map[string]string // required for every reached computed ID
	Now               time.Time
	// Identity binds the fingerprint to actor/dataset/schema and data snapshot.
	Identity string
}

PlanOptions contains trusted host configuration. SourceSQL is a SELECT whose output exposes the aliases used by Schema field bindings (normally alias r). SourceArgs occupy $1..$N for PostgreSQL or ?1..?N for SQLite. SourceSQL must include authorization predicates.

type RegexExtract

type RegexExtract struct {
	Regex string `json:"regex"`
}

RegexExtract transforms a sort value before comparison. PostgreSQL's substring(text FROM regex) returns the first capture group when present and the whole match otherwise; a non-match is NULL.

type SQLComputedColumnStore

type SQLComputedColumnStore struct{ DB *sql.DB }

func (SQLComputedColumnStore) List

func (s SQLComputedColumnStore) List(ctx context.Context, scope, dataset string) ([]ComputedColumn, error)

func (SQLComputedColumnStore) Save

type SQLComputedDefinitionResolver added in v0.6.0

type SQLComputedDefinitionResolver struct {
	Tx             *sql.Tx
	Scope, Dataset string
}

SQLComputedDefinitionResolver resolves canonical definitions in a host-owned transaction. Begin a read-only REPEATABLE READ transaction and use that same transaction to execute the resulting row/metric plans. Scope and Dataset must come from authorization, not an unvalidated request. It does not own Tx.

func (SQLComputedDefinitionResolver) ResolveComputed added in v0.6.0

type SQLPlan added in v0.6.0

type SQLPlan struct {
	SQL                         string
	Args                        []any
	Stages                      []SQLStage
	Columns                     []OutputColumn
	Dependencies                []string
	ResolvedRevisions           map[string]string
	Profile, Fingerprint, Scope string
	// A host executing row/metric plans together must provide one data snapshot.
	RequiresSnapshot bool
}

func CompileComputedRows added in v0.6.0

func CompileComputedRows(ctx context.Context, q WireQuery, s Schema, o PlanOptions) (SQLPlan, error)

CompileComputedRows resolves SELECT and hidden ORDER BY dependencies before applying the globally ordered page window. Computed filters are not admitted.

func CompileRowExpression added in v0.6.0

func CompileRowExpression(ctx context.Context, source string, s Schema, o PlanOptions) (SQLPlan, error)

CompileRowExpression builds a standalone typed value/error projection over an authorized source, useful for host-side definition validation and previews.

func CompileRowsV2 added in v0.6.0

func CompileRowsV2(ctx context.Context, q ServerQueryV2, s Schema, o PlanOptions) (SQLPlan, error)

func CompileSQLiteComputedRows added in v0.6.0

func CompileSQLiteComputedRows(ctx context.Context, q WireQuery, s Schema, o PlanOptions) (SQLPlan, error)

func CompileSQLiteRowExpression added in v0.6.0

func CompileSQLiteRowExpression(ctx context.Context, source string, s Schema, o PlanOptions) (SQLPlan, error)

func CompileSQLiteRowsV2 added in v0.6.0

func CompileSQLiteRowsV2(ctx context.Context, q ServerQueryV2, s Schema, o PlanOptions) (SQLPlan, error)

func (SQLPlan) String added in v0.6.0

func (p SQLPlan) String() string

SQLPlan.String deliberately omits bound values and SQL source (which may contain host authorization details). Use SQL and Args explicitly to execute.

type SQLStage added in v0.6.0

type SQLStage struct {
	Name, SQL    string
	Materialized bool
}

type SQLiteAggregateDescriptor added in v0.6.0

type SQLiteAggregateDescriptor struct {
	Name  string
	Arity int
	New   func() SQLiteAggregateFunction
}

func SQLiteV2Aggregates added in v0.6.0

func SQLiteV2Aggregates() []SQLiteAggregateDescriptor

SQLiteV2Aggregates uses exact decimal accumulators for SUM/AVG, independent of visitation order and SQLite's integer overflow. SUM conservatively rejects an absolute input sum above MAX_SAFE_INTEGER. MEDIAN uses exact linear midpoint. Box plots use bounded exact samples; histograms retain shared-edge bin counters.

type SQLiteAggregateFunction added in v0.6.0

type SQLiteAggregateFunction interface {
	Step([]driver.Value) error
	Value() (driver.Value, error)
}

SQLiteAggregateFunction is one independent aggregate invocation. Drivers must create a fresh instance for each group, call Step, then Value, and release it. These descriptors are ordinary aggregates, not sliding window functions.

type SQLiteAggregationRequest added in v0.6.0

type SQLiteAggregationRequest struct {
	Where        []WhereTerm `json:"where"`
	Aggregations []AggSpec   `json:"aggregations"`
	Diagnostics  []any       `json:"diagnostics,omitempty"`
}

func (*SQLiteAggregationRequest) UnmarshalJSON added in v0.6.0

func (r *SQLiteAggregationRequest) UnmarshalJSON(data []byte) error

type SQLiteAggregationResult added in v0.6.0

type SQLiteAggregationResult struct {
	Metrics []SQLiteMetric `json:"metrics"`
}

type SQLiteBucket added in v0.6.0

type SQLiteBucket struct {
	Keys  []any `json:"keys"`
	Value any   `json:"value"`
	Count int64 `json:"count"`
}

type SQLiteComputedColumnStore added in v0.6.0

type SQLiteComputedColumnStore struct{ DB *sql.DB }

SQLiteComputedColumnStore implements ComputedColumnRepository. Hosts supply a configured database and authorize the scope through NewComputedColumnsHandler. Saves use an atomic revision predicate; concurrent edits cannot overwrite one another. SQLITE_BUSY is a database failure, never a revision conflict.

func (SQLiteComputedColumnStore) List added in v0.6.0

func (s SQLiteComputedColumnStore) List(ctx context.Context, scope, dataset string) ([]ComputedColumn, error)

func (SQLiteComputedColumnStore) Save added in v0.6.0

type SQLiteComputedDefinitionResolver added in v0.6.0

type SQLiteComputedDefinitionResolver struct {
	Tx             *sql.Tx
	Scope, Dataset string
}

SQLiteComputedDefinitionResolver uses the same caller-owned transaction as v2 execution. Scope/Dataset must come from host authorization.

func (SQLiteComputedDefinitionResolver) ResolveComputed added in v0.6.0

type SQLiteComputedExecution added in v0.6.0

type SQLiteComputedExecution struct {
	Profile           string                                   `json:"profile"`
	PlanToken         string                                   `json:"planToken"`
	ResolvedRevisions map[string]string                        `json:"resolvedRevisions"`
	Fields            map[string]SQLiteComputedFieldCapability `json:"fields"`
	Fingerprint       string                                   `json:"fingerprint,omitempty"`
	Snapshot          string                                   `json:"snapshot,omitempty"`
}

A fingerprint is not authorization. Hosts may attach a signed planToken and a snapshot only when they actually bind subsequent requests to that snapshot.

type SQLiteComputedFieldCapability added in v0.6.0

type SQLiteComputedFieldCapability struct {
	Type    string `json:"type"`
	Select  bool   `json:"select"`
	Sort    bool   `json:"sort"`
	Measure bool   `json:"measure"`
	Group   bool   `json:"group"`
}

type SQLiteComputedRow added in v0.6.0

type SQLiteComputedRow struct {
	ID     any                            `json:"id"`
	Values map[string]SQLiteComputedValue `json:"values"`
}

type SQLiteComputedValue added in v0.6.0

type SQLiteComputedValue struct {
	Value any               `json:"value"`
	Error *SQLiteValueError `json:"error,omitempty"`
}

type SQLiteDataset added in v0.6.0

type SQLiteDataset struct {
	Schema       Schema
	FromSQL      string
	BaseWhereSQL string
	BaseArgs     []any
	// Zero uses 10000 rows / 2000 groups. Exceeding a limit is an error; groups
	// are never silently truncated. Counts and metrics cover all matching rows.
	MaxLimit  int
	MaxGroups int
}

SQLiteDataset is trusted host configuration. FromSQL includes FROM/JOIN (e.g. "FROM runs r"); BaseWhereSQL is an always-applied authorization/scope predicate without WHERE, with anonymous ? parameters in BaseArgs. Never fill these strings from request data. IDField must identify rows uniquely across the complete join. The caller owns driver registration, pool configuration, authorization, cancellation deadlines and indexes.

func (SQLiteDataset) Aggregations added in v0.6.0

func (SQLiteDataset) AggregationsIn added in v0.6.0

func (SQLiteDataset) Distinct added in v0.6.0

func (d SQLiteDataset) Distinct(ctx context.Context, db *sql.DB, field, search string, limit int) (SQLiteDistinctResult, error)

func (SQLiteDataset) DistinctIn added in v0.6.0

func (d SQLiteDataset) DistinctIn(ctx context.Context, tx *sql.Tx, field, search string, limit int) (SQLiteDistinctResult, error)

func (SQLiteDataset) FieldStats added in v0.6.0

func (d SQLiteDataset) FieldStats(ctx context.Context, db *sql.DB, names []string) (map[string]SQLiteFieldStat, error)

FieldStats returns non-NULL distinct counts and numeric/datetime extrema in one transaction. Array fields have no scalar distinct statistic and are refused.

func (SQLiteDataset) FieldStatsIn added in v0.6.0

func (d SQLiteDataset) FieldStatsIn(ctx context.Context, tx *sql.Tx, names []string) (map[string]SQLiteFieldStat, error)

func (SQLiteDataset) Rows added in v0.6.0

Rows reads the count and page in one short transaction. For a shared snapshot across multiple adapter operations, begin a transaction and use RowsIn etc.

func (SQLiteDataset) RowsIn added in v0.6.0

type SQLiteDistinctCompile added in v0.6.0

type SQLiteDistinctCompile struct {
	Expr       string
	SearchSQL  string
	Args       []any
	ArraySQL   string
	IsNullExpr string
}

SQLiteDistinctCompile describes a literal autocomplete query. ArraySQL is a CROSS JOIN of individual JSON text-array elements, empty for scalar fields. Hosts reserve aliases beginning _qt_. IsNullExpr describes source nullity, before the element join, so empty arrays still contribute to hasNull.

func CompileSQLiteDistinct added in v0.6.0

func CompileSQLiteDistinct(field, search string, s Schema) (SQLiteDistinctCompile, error)

type SQLiteDistinctResult added in v0.6.0

type SQLiteDistinctResult struct {
	Values  []string `json:"values"`
	HasMore bool     `json:"hasMore"`
	HasNull bool     `json:"hasNull"`
}

type SQLiteFieldStat added in v0.6.0

type SQLiteFieldStat struct {
	Distinct int64 `json:"distinct"`
	Min      any   `json:"min,omitempty"`
	Max      any   `json:"max,omitempty"`
}

type SQLiteMetric added in v0.6.0

type SQLiteMetric struct {
	ID      string         `json:"id"`
	Buckets []SQLiteBucket `json:"buckets"`
}

type SQLiteMetricCapabilities added in v0.6.0

type SQLiteMetricCapabilities struct {
	Version        int    `json:"version"`
	Expressions    bool   `json:"expressions"`
	ShownRows      bool   `json:"shownRows"`
	Distributions  bool   `json:"distributions"`
	ComputedFields bool   `json:"computedFields"`
	MaxGroups      int    `json:"maxGroups"`
	Profile        string `json:"profile"`
}

type SQLiteMetricV2 added in v0.6.0

type SQLiteMetricV2 struct {
	ID            string                 `json:"id"`
	Buckets       []SQLiteMetricV2Bucket `json:"buckets"`
	Scope         string                 `json:"scope"`
	ProcessedRows int64                  `json:"processedRows"`
	GroupCount    int64                  `json:"groupCount"`
	Coverage      string                 `json:"coverage"`
}

type SQLiteMetricV2Bucket added in v0.6.0

type SQLiteMetricV2Bucket struct {
	Distribution    MetricDistributionResult `json:"distribution,omitempty"`
	NullCount       *int64                   `json:"nullCount,omitempty"`
	InputErrorCount *int64                   `json:"inputErrorCount,omitempty"`
	Keys            []any                    `json:"keys"`
	Value           any                      `json:"value"`
	Count           int64                    `json:"count"`
	Error           string                   `json:"error,omitempty"`
	Y               *any                     `json:"y,omitempty"`
	YError          string                   `json:"yError,omitempty"`
}

type SQLiteMetricsV2Result added in v0.6.0

type SQLiteMetricsV2Result struct {
	Metrics []SQLiteMetricV2 `json:"metrics"`
}

type SQLiteOptions added in v0.6.0

type SQLiteOptions struct{ Now time.Time }

SQLiteOptions captures one clock for filters in rows, counts, and metrics. Zero Now captures time.Now once per compilation. Share it across a batch.

type SQLiteRowsResult added in v0.6.0

type SQLiteRowsResult struct {
	Rows  []map[string]any `json:"rows"`
	Total int64            `json:"total"`
}

type SQLiteRowsV2Result added in v0.6.0

type SQLiteRowsV2Result struct {
	Version   int                     `json:"version"`
	Rows      []map[string]any        `json:"rows"`
	Total     int64                   `json:"total"`
	Computed  []SQLiteComputedRow     `json:"computed"`
	Execution SQLiteComputedExecution `json:"execution"`
}

type SQLiteScalarFunction added in v0.6.0

type SQLiteScalarFunction struct {
	Name  string
	Arity int
	Call  func([]driver.Value) (driver.Value, error)
}

SQLiteScalarFunction is a deterministic, NULL-aware function to register on every physical connection, before opening a pool. The compiler has no driver dependency. Hosts adapt Call to their driver's registration API.

func SQLiteFunctions added in v0.6.0

func SQLiteFunctions() []SQLiteScalarFunction

SQLiteFunctions returns independent function descriptors with a shared, concurrency-safe LRU of at most 128 compiled Go/RE2 patterns. It never changes SQLite's built-in functions or collations. Retain one set for the host.

func SQLiteV2Functions added in v0.6.0

func SQLiteV2Functions() []SQLiteScalarFunction

SQLiteV2Functions supplements SQLiteFunctions. Register both sets before opening connections. Ordinary formula failures are returned as error codes, allowing IF/COALESCE/AND/OR to preserve lazy error semantics.

type SQLiteV2Dataset added in v0.6.0

type SQLiteV2Dataset struct {
	Schema            Schema
	SourceSQL         string
	SourceArgs        []any
	Scope, Dataset    string
	ComputedGroupable map[string]bool
	// Zero defaults to 10000 rows, 2000 groups and 250000 matching source rows.
	// Limits fail explicitly; no approximate or silently truncated populations.
	MaxRows, MaxGroups, MaxPopulation int
}

SQLiteV2Dataset executes plans over a host-authorized SELECT. SourceArgs use numbered ?1..?N bindings. Scope/Dataset select the authorized definition store. The host owns authentication, token signing, timeouts, indexes, and pool setup.

func (SQLiteV2Dataset) Capabilities added in v0.6.0

func (d SQLiteV2Dataset) Capabilities() SQLiteMetricCapabilities

func (SQLiteV2Dataset) DescribeComputedIn added in v0.6.0

func (d SQLiteV2Dataset) DescribeComputedIn(ctx context.Context, tx *sql.Tx, ids []string, o PlanOptions) (SQLiteComputedExecution, error)

DescribeComputedIn validates current canonical definitions and their transitive graph in a host-owned snapshot. IDs come from the authorized catalogue. Hosts sign the returned envelope if plan tokens are part of their protocol.

func (SQLiteV2Dataset) ExecuteV2 added in v0.6.0

ExecuteV2 executes any row/metric combination atomically in one short read transaction. To join other host operations, use ExecuteV2In with their Tx.

func (SQLiteV2Dataset) ExecuteV2In added in v0.6.0

func (d SQLiteV2Dataset) ExecuteV2In(ctx context.Context, tx *sql.Tx, rows *ServerQueryV2, metrics *MetricQuery, o PlanOptions) (SQLiteV2ExecutionResult, error)

type SQLiteV2ExecutionResult added in v0.6.0

type SQLiteV2ExecutionResult struct {
	Rows    *SQLiteRowsV2Result    `json:"rows,omitempty"`
	Metrics *SQLiteMetricsV2Result `json:"metrics,omitempty"`
}

type SQLiteValueError added in v0.6.0

type SQLiteValueError struct {
	Code string `json:"code"`
}

type SQLiteWhereResult added in v0.6.0

type SQLiteWhereResult struct {
	SQL  string
	Args []any
}

SQLiteWhereResult can be composed with host-owned FROM trees and optimized count/rollup queries. It requires only bindings for fields actually filtered; a row identity and row ordering are not needed for predicate compilation.

func CompileSQLiteWhere added in v0.6.0

func CompileSQLiteWhere(terms []WhereTerm, s Schema, o SQLiteOptions) (SQLiteWhereResult, error)

type SaveComputedColumnRequest

type SaveComputedColumnRequest struct {
	Column           ComputedColumn `json:"column"`
	ExpectedRevision *string        `json:"expectedRevision"`
}

type Schema

type Schema struct {
	Name         string
	IDField      string
	Fields       map[string]FieldSpec
	DefaultSort  []OrderBy
	TiebreakSort []OrderBy
}

Schema is the compiled, server-side field allowlist for one dataset.

func LoadSQLiteSchema added in v0.6.0

func LoadSQLiteSchema(doc []byte) (Schema, error)

LoadSQLiteSchema reads only bindings.sqlite; it never falls back to Postgres SQL.

func LoadSchema

func LoadSchema(doc []byte) (Schema, error)

LoadSchema parses + validates a JSON schema document (the bytes of a schema/*.schema.json file) into a Schema, reading the `postgres` binding for each backend field. Fields without a postgres binding (derived / render-only) are skipped — they're never filtered, sorted, or selected on the server.

type ServerQueryV2 added in v0.6.0

type ServerQueryV2 struct {
	WireQuery
	Version           int               `json:"version"`
	Profile           string            `json:"profile"`
	ExpectedRevisions map[string]string `json:"expectedRevisions"`
	PlanToken         string            `json:"planToken,omitempty"`
	Snapshot          string            `json:"snapshot,omitempty"`
	Diagnostics       []any             `json:"diagnostics,omitempty"`
}

ServerQueryV2 mirrors the core computed-row request. HTTP authorization and plan-token validation remain host responsibilities, distinct from revisions.

func (*ServerQueryV2) UnmarshalJSON added in v0.6.0

func (q *ServerQueryV2) UnmarshalJSON(data []byte) error

type ValueSQL added in v0.6.0

type ValueSQL struct{ Value, Error, Type string }

type WhereClause

type WhereClause struct {
	Field   string `json:"field"`
	Op      string `json:"op"`
	Value   string `json:"value"`
	Negated bool   `json:"negated,omitempty"`
}

WhereClause mirrors @pythia-software/query-table-core WhereClause. Negated wraps the predicate in a null-exclusive NOT; it is set only for ops without a complementary operator (contains/starts_with/ends_with/includes), matching the frontend's negateClause.

type WhereTerm

type WhereTerm struct {
	Field   string        `json:"field,omitempty"`
	Op      string        `json:"op,omitempty"`
	Value   string        `json:"value,omitempty"`
	Negated bool          `json:"negated,omitempty"`
	Any     []WhereClause `json:"any,omitempty"`
}

WhereTerm is one conjunct of the WHERE (mirrors the TS WhereTerm = WhereClause | OrGroup). It is either a single predicate (Field/Op/Value set, Any nil) or an OR group (Any set). The two shapes are disjoint on the wire — a literal carries "field", a group carries "any" — so the default JSON (un)marshaling distinguishes them with no custom code. WHERE is the AND of these terms, i.e. conjunctive normal form.

func (WhereTerm) IsGroup

func (t WhereTerm) IsGroup() bool

IsGroup reports whether the term is an OR group rather than a single predicate.

func (WhereTerm) Literal

func (t WhereTerm) Literal() WhereClause

Literal returns the predicate a non-group term represents.

func (WhereTerm) Predicates

func (t WhereTerm) Predicates() []WhereClause

Predicates returns the literals the term contributes: itself for a single predicate, or its members for a group.

type WireQuery

type WireQuery struct {
	Select       []string    `json:"select,omitempty"`
	Where        []WhereTerm `json:"w,omitempty"`
	OrderBy      OrderBys    `json:"o,omitempty"`
	Limit        int         `json:"l,omitempty"`
	Offset       int         `json:"f,omitempty"`
	Aggregations []AggSpec   `json:"g,omitempty"`
}

WireQuery is the server-bound subset of QueryState (the TS ServerQuery / the {s,w,o,...} `?q=` payload). View-only state (column widths) never arrives.

OrderBy unmarshals from BOTH the new array form and the legacy single-object form, so legacy links keep compiling.

func DecodeSQLiteQuery added in v0.6.0

func DecodeSQLiteQuery(data []byte) (WireQuery, error)

DecodeSQLiteQuery decodes JSON in readable or compact v1 wire form. Use this at a SQLite HTTP boundary rather than decoding a v2 envelope into WireQuery, which would discard fields that do not belong to the v1 wire contract.

func DecodeWireQuery

func DecodeWireQuery(token string) (WireQuery, error)

DecodeWireQuery decodes the base64url-encoded JSON `?q=` token produced by @pythia-software/query-table-core encodeQuery. The select tuples carry widths the server ignores; only the field names are extracted. Mirrors the charset/padding fix-ups so a bookmark round-trips bit-for-bit.

func (*WireQuery) UnmarshalJSON

func (q *WireQuery) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts both the readable ServerQuery property names emitted by @pythia-software/query-table-core and the compact names used inside a URL token. It validates resource limits before returning, so a normal json.Decoder is a safe API boundary even when the caller does not use DecodeWireQuery.

func (WireQuery) Validate

func (q WireQuery) Validate() error

Validate rejects malformed query shapes. A zero Limit is allowed so an omitted value can be replaced by the caller's default; a negative value is never allowed. Values too large for the platform fail during JSON decoding.

Jump to

Keyboard shortcuts

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