Documentation
¶
Overview ¶
Integer-preserving arithmetic shared by every evaluation path.
tinySQL follows SQLite's rules: +, -, * and % on two integers yield an integer, and +, - and * fall back to REAL (float64) only when the exact result does not fit into 64 bits. A REAL operand makes the result REAL. Division deliberately keeps tinySQL's REAL quotient (7 / 2 = 3.5) instead of SQLite's truncating integer division; see docs/sql-feature-gaps.md.
The abstract syntax tree: one type per statement and per expression form. The parser builds these, the executor switches on them, and nothing else needs to know how SQL text is spelled.
Audit logging hook for Execute (see internal/storage/audit.go for the hash-chained log itself).
Execute receives a parsed Statement, not the original SQL text — there's no reliable way to reconstruct exact SQL from an AST (the trigger-body bug fixed earlier this session, where a from-scratch AST-to-SQL printer silently produced non-executable text, is exactly why this doesn't attempt that). Callers that already have the original text (cmd/server, internal/driver — both parse from a string themselves) can attach it via WithAuditText so the audit trail records the real query; callers that only ever construct/receive an AST get a best-effort "<*engine.Insert>" style fallback identifying the statement kind, which is still enough to see *that* a mutation happened even without the exact text.
Date and time functions, and the parsers behind them. Formats are accepted explicitly rather than guessed, so an unparseable value is an error instead of a silently wrong date.
Hash, encoding and identifier functions: MD5, SHA-1/256/512, Base64, hex, UUID and Soundex.
Numeric functions. The exact-decimal cases stay on big.Rat; the rest work in float64.
The scalar function registry: the name-to-handler table the evaluator looks up, and the thin adapters that give each function a uniform signature. The implementations live in the builtin_*.go files.
String, JSON and conditional scalar functions: case conversion, trimming, padding, substring and search, formatting, CAST, COALESCE/NULLIF/IF, and the JSON accessors.
Type inference and coercion. Every value entering a column passes through here, which is where SQLite's type affinities are applied.
Package engine provides SQL parsing, planning, and execution for tinySQL.
This file focuses on the query compilation cache:
- What: A lightweight in-memory LRU cache that stores parsed/compiled representations of SQL statements (CompiledQuery).
- How: Queries are keyed by their exact SQL string. The cache holds a Statement AST plus metadata (ParsedAt) and returns it to callers to avoid re-parsing. LRU eviction using container/list keeps the cache within a fixed size with O(1) eviction.
- Why: Parsing is comparatively expensive and often repeated in loops or hot paths. Caching reduces parse overhead, improves latency, and keeps the execution path predictable while remaining simple and thread-safe.
Parse-time constant folding for pure vector functions.
RAG queries almost always embed the query vector as a JSON literal:
SELECT ... FROM docs
ORDER BY VEC_COSINE_SIMILARITY(embedding, VEC_FROM_JSON('[0.1, ...]')) DESC
Without folding, VEC_FROM_JSON re-parses that literal for every row the expression is evaluated against — profiling showed ~85% of such a query's CPU time inside encoding/json. Folding the call to a Literal([]float64) once at parse time removes that per-row cost entirely, for every evaluation path (regular, raw fast path, WHERE, ORDER BY, table-function arguments).
Coordinate reference system identifiers and axis order helpers.
The functions in this file intentionally understand identifiers, not projections. A CRS can be named by an EPSG label, an OGC URN, or an OGC definition URI without tinySQL acquiring a dependency on a particular map service. Reprojection remains the separate responsibility of ST_TRANSFORM (or an external PROJ pipeline).
Aggregate evaluation over a group's rows: COUNT, SUM, AVG, MIN, MAX, MEDIAN, MIN_BY/MAX_BY and vector averaging, plus recognising which expressions are aggregates at all.
The general expression evaluator: recursive evaluation over literals, column references, unary and binary operators, IS NULL, BETWEEN, IN, LIKE, GLOB, SIMILAR TO, CASE, EXISTS and subqueries, against a row map.
Caching for WHERE/SELECT-list subqueries: EXISTS (...), scalar (SELECT ...) expressions, and the IN (SELECT ...) form (which reaches evalSubqueryExpr through evalExpr's generic *SubqueryExpr dispatch inside evalIn's value loop -- see eval_expr.go). Without this cache, evalExistsExpr and evalSubqueryExpr call executeSelect on the subquery's SELECT every single time they are evaluated, which for a subquery inside a WHERE clause means once per outer row (applyWhereClause in exec_join.go). Most such subqueries do not depend on the outer row at all -- e.g. "WHERE x IN (SELECT y FROM small_table)" -- so re-running them per row is pure waste.
The unsafe case is a genuinely correlated subquery, e.g. "WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.parent_id = outer.id)": caching its first result and reusing it for every subsequent outer row would silently produce wrong results. isSelectCorrelated below is the conservative, lexical safety check that keeps that from happening; see its doc comment for exactly what it checks and why unqualified references are not part of that check.
Window functions: LAG, LEAD, FIRST_VALUE, LAST_VALUE, moving aggregates, RANK, DENSE_RANK, PERCENT_RANK, CUME_DIST and NTILE, plus the partitioning and frame arithmetic they share.
Choropleth classification window functions: EQUAL_INTERVAL and NATURAL_BREAKS (Jenks). Quantile classification needs no new code here -- NTILE(n) OVER (ORDER BY kpi) (eval_window.go) already buckets a column into n roughly-equal-sized groups, exactly mapshaper's -classify "quantile" method.
NATURAL_BREAKS is the one window function in this file that cannot be O(1) per row the way every other window function here is: computing Jenks' variance-minimizing class boundaries needs a single O(len*n^2) dynamic-programming pass over the whole partition, and evalWindowFunction is invoked once per output row. Recomputing that DP on every row would turn an O(len*n^2) cost into O(len^2*n^2) for the query as a whole, which is not acceptable even at moderate partition sizes -- so its result is memoized per (window-function AST node, partition, n) in natBreaksCache, bounded and evicted the same way every other cache in this codebase is.
Package engine implements the tinySQL execution engine.
What: This module evaluates parsed SQL statements (AST) against the storage layer and produces ResultSets. It covers DDL/DML/SELECT, joins, grouping, aggregates, expression evaluation, simple functions (JSON_*, DATEDIFF, etc.), and a minimal tri-state boolean logic (true/false/unknown).
How: The executor converts tables to row maps with both qualified and unqualified column keys, applies WHERE/GROUP/HAVING/ORDER/LIMIT/OFFSET, and optionally combines results with UNION/EXCEPT/INTERSECT. Expression evaluation is recursive over a small algebra of literals, variables, unary/ binary ops, IS NULL, and function calls. Aggregate evaluation runs per- group with reusable helpers shared with the scalar evaluator.
Why: Keeping execution self-contained and data-structure driven (Row maps and simple slices) makes the engine easy to reason about and to extend with new functions, operators, and clauses without introducing heavy planners.
Common table expressions, including recursive ones. Recursion is bounded by a row cap so a CTE without a terminating condition fails instead of running until memory is gone.
ALTER TABLE.
Views, materialized views and the jobs that refresh them: CREATE, DROP and ALTER for each, the cache table a materialized view is backed by, and the scheduled-refresh registration that keeps it fresh.
DELETE, plus the helpers shared by all three DML statements: building a row map for expression evaluation, marking dependent materialized views stale, and projecting a RETURNING clause.
INSERT, the column defaults it applies, and the per-row constraint checks every mutating statement shares. The constraint-index cache lives here too: it is the lookup structure that makes PRIMARY KEY and UNIQUE enforcement something other than a full scan per row.
UPDATE, including the fast path for a triggerless update whose predicate and assignments can be evaluated straight off the stored row.
Fast path for grouped aggregation: accumulate COUNT/SUM/AVG/MIN/MAX directly off stored rows in a single scan, instead of buffering each group's rows and re-scanning them once per aggregate expression.
This also covers the ungrouped case (no GROUP BY at all, e.g. "SELECT COUNT(*) FROM t" or "SELECT SUM(x), AVG(y) FROM t WHERE ..."), which used to be excluded here and fall all the way back to the general path: resolveFromClause materializes a dual-key Row map for every row of the table via rowsFromTable before aggregation even begins, for a query shape that is arguably the most common one in SQL. The accumulator machinery below already treats "zero group-by columns" as one implicit group (see executeSimpleMultiGroupAggregate), so the only genuinely new piece is synthesizing that one group's output row when no input row matched — a whole-table aggregate must still return exactly one row over zero matching rows (COUNT(*) = 0, SUM/AVG/MIN/MAX = NULL), whereas a real "GROUP BY x" correctly returns zero rows in that case. See the identical contract and its rationale in processAggregateQuery (exec_group.go).
Fast path for a two-table equi-join: compile the join keys, filters and projection once, then evaluate them against stored rows without building a row map per input row.
Fast path for the single most common join+aggregate shape: a two-table equi-join (one "ON left.col = right.col" condition, no other join predicates) combined with a single-column GROUP BY whose key is a column from either input table. Without this, that shape falls through the plain join fast path (exec_fastpath_join.go excludes any GroupBy) and the plain aggregate fast path (exec_fastpath_aggregate.go excludes any Joins), so it always takes the generic Row-map join (exec_join.go) followed by processAggregateQuery (exec_group.go), which buffers every joined row per group and re-scans each group's buffer once per aggregate expression.
This file adds a new, separate, narrowly-scoped fast path rather than loosening either existing eligibility check: it reuses the join mechanics (simpleJoinPlan, evalJoinRawExpr et al.) from exec_fastpath_join.go and the per-group accumulator (simpleAggregateState, accumulate/finalize helpers) from exec_fastpath_aggregate.go, mirroring executeSimpleAggregateFastPath's one-column strategy of using the grouped value itself as a map key. Any query shape outside this narrow case -- multi-column GROUP BY, non-equi joins, multiple join conditions, HAVING, more than two tables, ORDER BY, LIMIT/OFFSET, DISTINCT -- is rejected by simpleJoinAggregateEligibleSelect and falls through unchanged to the two existing fast paths (which already reject it) and ultimately the generic path.
Fast path for a single-table SELECT: an unfiltered scan, a filtered scan, and an ordered scan that degenerates to a bounded top-N heap when LIMIT is present. The float-keyed variant keeps the sort key unboxed.
Resolving a FROM clause to rows: physical tables, subqueries, CTE results, table-valued functions, views, materialized views and the sys.* catalog views.
GROUP BY, HAVING and PIVOT, and the projection of both aggregate and non-aggregate queries, followed by OFFSET/LIMIT.
Joins over row maps: inner, left, right and full outer, plus the WHERE filter applied to their output. This is the general path; exec_fastpath_join.go handles the shape it can compile.
Compiling a SELECT into a plan, and caching that plan across executions of the same statement text. Also index selection: which secondary or constraint index a predicate can seek, and whether seeking it beats scanning.
Evaluating expressions directly against a stored row, for the fast paths. The generic evaluator in eval_expr.go handles the same algebra over row maps.
Compiling a WHERE clause into a closure over stored rows.
Each builder returns a filter specialised for the shapes it recognises — column against literal, integer comparison, compiled LIKE, IN over a value set — and falls back to the generic expression evaluator for anything it does not. A nil filter means "not compilable", which disqualifies the fast path rather than producing a wrong answer.
Projections and column addressing for the raw-row fast paths, and the test for whether an expression can be evaluated against a stored row at all (which is what makes a query eligible for those paths).
SELECT: the statement entry point, and the plan types the fast paths below compile a query into.
UNION, UNION ALL, EXCEPT and INTERSECT.
ORDER BY. Sorting either sorts the whole result or, when a LIMIT bounds it, keeps only the rows that can still make the cut in a bounded heap. The heap implementations are written against their concrete element type rather than container/heap, whose any-typed interface costs one allocation per row.
Package engine provides helper functions for the YAML, URL, HASH, BITMAP, and BLOB extra column types added to tinySQL.
Note: MD5 and SHA1 are provided for compatibility and checksum use cases only. They are cryptographically broken and must NOT be used for security-sensitive operations (passwords, signatures, etc.). Prefer SHA256 or SHA512 instead.
Package engine: foreign key referential action enforcement.
Before this, FOREIGN KEY constraints only protected the child side: an INSERT/UPDATE into a table with a FOREIGN KEY column checked that the referenced row existed (validateRowConstraints in exec.go), but nothing checked the parent side — DELETE (or UPDATE of a referenced column) on the parent table silently orphaned any referencing child rows, regardless of an ON DELETE/ON UPDATE clause (which didn't even parse). This file adds that missing half: RESTRICT (the default when no clause is given, matching how tinySQL checks constraints immediately rather than deferring them), CASCADE, and SET NULL.
Package engine provides a lightweight Full-Text Search (FTS) engine inspired by SQLite FTS5.
Design:
- CREATE VIRTUAL TABLE t USING fts(col1, col2) creates a regular tinySQL table with FTS indexing enabled.
- FTS_SEARCH builds a tokenized-document cache and an inverted index (term postings) lazily per searched column set, invalidated by table.Version — append and update deltas are applied lazily; structural changes rebuild.
- FTS_MATCH(text, query) – boolean match check with phrase/boolean query support
- FTS_RANK(text, query) – BM25-like relevance score
- FTS_SNIPPET(text, query [, before, after, ellipsis, max_tokens]) – highlighted snippet
- FTS_HIGHLIGHT(text, query [, before, after]) – full-text highlighting alias
- BM25(text, query) – alias for FTS_RANK
- FTS_SEARCH table-valued function for corpus-level k-nearest search
- CONTAINS_ALL(text, term1, term2, ...) – true iff every term is a substring of text
- CONTAINS_ANY(text, term1, term2, ...) – true iff any term is a substring of text
- CONTAINS_SCORE(text, term1, term2, ...) – count of the given terms found in text
Query syntax supported by FTS_MATCH / FTS_RANK:
word – single term "phrase" – exact phrase (consecutive tokens) word* – wildcard term (* / % = any sequence, ? / _ = one character) A AND B – both terms must match A OR B – either term must match NOT A – term must not match A B – implicit AND (same as A AND B)
FTS_MATCH / FTS_RANK vs. CONTAINS_ALL / CONTAINS_ANY / CONTAINS_SCORE: FTS_MATCH and FTS_RANK tokenize, stem, and strip stop words from both the text and the query, and support a rich boolean query language (phrases, prefix wildcards, NOT, nested AND/OR) — they're the right choice for natural-language search boxes. CONTAINS_ALL, CONTAINS_ANY, and CONTAINS_SCORE instead do a raw case-insensitive substring match against a fixed list of literal terms, with no tokenizing, stemming, or query syntax — they're the right choice for exact codes/IDs/numbers (which stemming would mangle), or for a simple "must contain all/any of these words" filter without learning FTS_MATCH's query grammar.
FTS_WARM — eager warm-up for full-text retrieval structures.
Usage:
SELECT * FROM FTS_WARM('table_name' [, 'column_name'...])
FTS_SEARCH builds a tokenized document directory, term dictionary and inverted postings lazily on its first query for a table/column set. That is ideal for one-off searches, but a serving process should not make its first user wait for an O(corpus) build. FTS_WARM moves that work to an explicit, observable lifecycle step. It uses the exact same column-set semantics and cache key as FTS_SEARCH, so the first real query can reuse the warmed entry without changing retrieval behavior.
Geometry-collecting aggregate functions: GEO_DISSOLVE/GEO_UNION_AGG/ ST_UNION (dispatch by geometry type; polygons go through geo_dissolve.go's shared-edge-cancellation dissolve, points/lines are trivially concatenated into a Multi* geometry), GEO_BBOX_AGG (fold every row's own bounding box), and GEO_CENTROID_AGG (optionally weighted centroid, folding the existing per-row GEO_CENTROID rather than re-deriving its area/length-weighting rules).
These are registered as aggregates the same way every other one is in this codebase: added to isAggregate()'s name switch (so they trigger aggregation even without an unrelated GROUP BY forcing it) and to evalAggregateFuncCall()'s dispatch switch (both in eval_aggregate.go).
GEO_CLIP/ST_CLIP(geometry, boundary_polygon [, allow_nonconvex]): Sutherland-Hodgman polygon clipping.
Sutherland-Hodgman is only guaranteed correct when the *clip* boundary is convex -- clipping against a non-convex boundary with the plain algorithm can produce a wrong shape. This is validated by default (protect first, explicit override for advanced use, matching GEO_SMOOTH's iteration cap and GEO_AFFINE's anchor requirement elsewhere in this file family) and left as an opt-in best-effort via a third `allow_nonconvex` argument rather than refused outright, since clipping to a bbox or a convex-hull region -- both very common BI operations ("clip this layer to my dashboard's current map viewport") -- is exactly what it's for.
GEO_DISSOLVE's polygon-merging core: a shared-edge-cancellation dissolve.
Two adjacent, topologically-clean polygons that share a boundary segment traverse that segment in *opposite* directions -- each ring's own winding keeps its own polygon's interior on its own side of the edge. Cancelling exact-reverse directed-edge pairs therefore removes every interior boundary between adjacent input polygons and leaves only the true outer (and inner, i.e. hole) boundary of their union.
This is correct for topologically-clean, vertex-aligned adjacent polygons -- real GIS boundary data, or this project's own dissolve output fed back in -- and deliberately NOT a general polygon-boolean-union: overlapping but not edge-aligned polygons would need a true Weiler-Atherton/ Greiner-Hormann boolean union, which is out of scope here. That is a documented v1 limitation, the same kind of honest scope cut GEO_IS_VALID (no self-intersection check) and plan_range_index.go (no R-tree) already make elsewhere in this codebase.
OGC GeoPackageBinary scalar helpers. These functions operate on a BLOB and therefore work independently of where it came from: a GeoPackage file, an HTTP API, a message queue, or an ordinary tinySQL column.
Geohash: encode/decode a lon/lat point to/from the base-32 string Gustavo Niemeyer's geohash.org popularized, plus the neighbor and bounding-box helpers that make it useful as a coarse spatial-locality key (e.g. a GROUP BY or index prefix column that clusters nearby points together without needing GEO_SEARCH's grid index).
The algorithm is the standard interleaved-bit one: alternately halve a longitude range and a latitude range, appending a 1 bit each time the point falls in the upper half, and packing every 5 bits into one base-32 character using the same non-alphabetic-lookalike alphabet (0-9b-hjkmnp-z, omitting a, i, l, o) the reference implementation uses.
A direct encoder for the geometry objects GIS functions return.
json.Marshal of a map[string]any holding nested []any and boxed float64 values cost as much as the geometry work that produced it. marshalGeoJSON writes the same bytes without reflection for the small set of value types geometry results are built from, and hands anything else -- an unexpected type, a NaN or infinity, a string that would need escaping -- to json.Marshal unchanged, so output and errors are identical either way. geo_json_encode_test.go compares the two encoders byte for byte.
A small, allocation-lean decoder for the GeoJSON every GIS function reads.
GEO_* and ST_* functions take geometries as GeoJSON text and decode them on every call. encoding/json (on current Go a layer over json/v2, reflecting into map[string]any) made that decode more than half of the CPU time of a typical GIS query; the geometry arithmetic itself is tiny by comparison.
The decoders here accept only the plain, compact subset that tinySQL itself writes (see canonicalGeoJSON): ASCII strings without escapes, JSON-grammar numbers. Typed geometry headers reject duplicate members; the generic object decoder keeps the last value like encoding/json. These decoders report ok=false for anything else, and the callers then run the original encoding/json path -- so malformed input, exotic input and every error message stay exactly what they were. When a decoder does accept a value, it is the value encoding/json would have produced; geo_json_fast_test.go checks that differentially.
MBTILES_TILE, MBTILES_TILES and MBTILES_METADATA let a SQL query read directly from an .mbtiles file's own SQLite storage, without the GEO_FROM_WKT-style step of first running a separate Go-API import/open call (ImportMBTiles, OpenMBTiles, ImportMBTilesArtifact -- all in internal/importer, and all still the right tool when the goal is *persisting* a tileset into tinySQL rather than reading it in place from one query).
This file adds no SQLite-reading code of its own: it is a thin bridge from the SQL layer to internal/importer's existing, already-hardened mbtiles readers (mbtiles_open.go's OpenMBTiles for the bulk/metadata cases, mbtiles_lookup.go's LookupMBTilesTile for the single-tile case). Those are gated behind the sqliteimport build tag with a same-signature "not supported in this build" stub for every other target (js/wasm/ baremetal, or sqliteimport simply not requested) -- calling into them unconditionally here, with no build tag on this file itself, means these three SQL functions degrade the exact same way on those targets: they exist and can be called, and return that same clear error, rather than being silently absent from the function registry.
A small cache of parsed polygons for constant arguments.
ST_WITHIN(pt, <region>) and ST_CONTAINS(<region>, pt) are almost always evaluated with one constant region over many rows. The region is an argument like any other, so it was decoded from GeoJSON for every row: for a 5,000-vertex border that is hundreds of microseconds and a megabyte of allocation per row, far more than the point-in-polygon test itself.
The cache holds the last few large polygon texts together with their parsed form and bounding box. A lookup is a handful of string comparisons -- Go compares equal strings with a pointer check first, so the same constant string is an O(1) hit -- and the read path takes no lock. Parsed polygons are shared between callers and must be treated as read-only.
ST_TOUCHES, ST_COVERS/ST_COVEREDBY and ST_PERIMETER round out geo_relate.go's ST_INTERSECTS/ST_DISJOINT/ST_EQUALS trio with the other DE-9IM predicates GIS users reach for most. Same engineering stance as that file: exact, non-epsilon comparisons, and a documented sampling-based approximation (vertices plus edge midpoints, rather than a full DE-9IM matrix) wherever exactness would require a general polygon-arrangement algorithm this codebase does not otherwise need. See the package doc comment on getGeoRelateFunctions for the same judgment call already made about self-intersecting input.
ROUTE_SHORTEST_PATH and ROUTE_DISTANCE run Dijkstra's algorithm over an ordinary edge-list table -- exactly the shape ImportRoutingGraph (internal/importer/routing_graph.go) already produces (source/target/ cost columns, one row per edge) but not tied to that importer: any table with a source column, a target column and a non-negative numeric weight column works.
This follows GEO_SEARCH's table-valued-function convention (table name and column names passed as string arguments, not identifiers the parser resolves) rather than adding graph traversal to the query planner, which only ever recognizes per-row predicates -- see spatial_index.go's doc comment for the same reasoning GEO_SEARCH already gives. Like GEO_SEARCH, the derived adjacency structure is cached by tenant, table version, column set and direction. Repeated routes therefore pay only the shortest-path search, while writes invalidate through Table.Version and DROP/rollback purge the derived graph eagerly.
Only non-negative edge weights are accepted (Dijkstra's own precondition); a graph with negative weights needs Bellman-Ford, which is out of scope here the same way a general reprojection engine is out of scope for ST_TRANSFORM (geo_transform.go) -- both are real features with a real algorithmic cost this codebase has no present need to carry.
ST_TRANSFORM reprojects a geometry between WGS84 (SRID 4326, the lon/lat degrees every other geo function in this engine assumes) and Web Mercator (SRID 3857, the projection every XYZ/Slippy-map tile server -- and this engine's own TILE_* functions, see tile_functions.go -- uses). These two are supported because they are the pair that actually shows up in practice for a tile-serving engine: a table of WGS84 geometry needs to become Mercator meters to compute a tile bounding box or measure a screen-space quantity, and a value pulled from a Mercator-native source (e.g. an MVT tile, or a system that stores 3857 natively) needs to become WGS84 to interoperate with everything else here.
A general reprojection engine (arbitrary EPSG codes, datum shifts, PROJ pipelines) is out of scope: that needs a large parameter database this project has no appetite for vendoring (see the project's own minimal-dependencies stance), and every other geo function already assumes -- and only makes sense for -- WGS84 degrees. ST_TRANSFORM's job here is narrowly to get a geometry to or from the one other SRID this codebase's tile support cares about, not to become a general GIS reprojection layer.
WKB (Well-Known Binary) input and output, the binary sibling of geo_wkt.go's text format. Same role: a converter at the edges between tinySQL's GeoJSON-text storage and a foreign wire format, here one that typically arrives as a BLOB (e.g. a value read out of another database's geometry column, or produced by a client library's ST_AsBinary).
The standard uncompressed OGC WKB encoding is implemented: 1 byte byte- order marker, a 4-byte geometry type, then coordinates. Both EWKB Z/M/SRID flag bits and the ISO SQL/MM +1000/+2000/+3000 Z/M/ZM type codes are accepted. M is consumed and dropped because GeoJSON has no measure ordinate; Z is preserved.
WKT (Well-Known Text) input and output for the GeoJSON geometries every other geo_*.go file operates on. tinySQL stores geometry as GeoJSON text (see canonicalGeoJSON in geo_functions.go), so these functions are pure converters at the edges: ST_GEOMFROMTEXT parses foreign text *into* that representation and ST_ASTEXT renders it back out. Nothing in between ever sees WKT, which is why there is no WKT-native code path anywhere else -- adding one would mean maintaining every predicate twice.
Scope notes, all deliberate:
- EWKT's "SRID=4326;" prefix is accepted on input. Since tinySQL's geo layer is WGS84 lon/lat throughout, a non-WGS84 SRID is rejected with a pointer to ST_TRANSFORM rather than silently relabelled -- see geoRequireWGS84SRID.
- The M (measure) ordinate is parsed and discarded: a GeoJSON position is [lon, lat] or [lon, lat, z] and has nowhere to put it. Z is preserved end to end.
- "EMPTY" round-trips through GeoJSON's empty-coordinates form ({"type":"Point","coordinates":[]}). That form is deliberately *not* accepted by a GEOMETRY column (validateGeometryShape requires a real position), so an empty geometry can be read, inspected and re-rendered but not stored. Erroring out mid-import on a single EMPTY row -- which real-world WKT dumps do contain -- would be the worse trade.
JSON path evaluation for JSON_GET and JSON_SET.
Package engine contains the SQL lexer used by the parser.
What: A minimal, whitespace- and comment-aware tokenizer that recognizes identifiers, keywords, numeric and string literals, and symbols. How: Single-pass rune-based scanner supporting -- and /* */ comments, uppercasing keywords, and preserving identifier case. Keywords are a fixed allow-list tailored to tinySQL features. Why: A compact lexer reduces parser complexity and keeps error messages local and actionable without external dependencies.
Parsing a column definition and its constraints: NOT NULL, DEFAULT, PRIMARY KEY, UNIQUE, REFERENCES and the referential actions on a foreign key.
Parsing a declared column type and mapping it to a storage type and a SQLite type affinity.
Parsing CREATE and DROP for tables, triggers, virtual tables, indexes and scheduled jobs.
Parsing ALTER, for tables, views and materialized views.
Parsing CREATE, DROP and REFRESH for views and materialized views, including a materialized view's refresh schedule and staleness options.
Parsing INSERT, UPDATE, DELETE and the RETURNING clause they share.
Parsing the operand levels of an expression: additive and multiplicative arithmetic, unary operators, and the primaries — literals, column references, parenthesised expressions, subqueries and CASE.
Parsing the predicate levels of an expression, loosest first: OR, AND, NOT, IS NULL, and the comparisons — including BETWEEN, IN, LIKE, REGEXP and SIMILAR TO.
Parsing a function call, and the OVER clause that turns one into a window function: PARTITION BY, ORDER BY and the frame.
Parsing SELECT: common table expressions, DISTINCT, the projection list, FROM, joins, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT/OFFSET, PIVOT and the set operations that combine two selects.
The statement dispatcher, and the statements small enough to parse in one place: CALL, EXPLAIN, ANALYZE and PRAGMA.
Package engine provides a hand-written SQL parser for tinySQL.
What: It parses a practical subset of SQL into an AST (statements and expressions) used by the execution engine. Supported features include DDL, DML, SELECT with JOIN/GROUP/HAVING/ORDER/LIMIT/OFFSET, and set ops. How: A straightforward recursive-descent parser over a small token stream from the lexer. It favors clarity and precise error messages. Ident-like parsing accepts keywords as identifiers to keep the grammar practical for common column names. Why: A small, readable parser is easy to extend and reason about, enabling rapid iteration on language features without a complex generator toolchain.
RAG_SEARCH composes VEC_SEARCH, FTS_SEARCH, and RAG_CONTEXT_FROM's neighbor-expansion logic into a single table-valued function, so a typical RAG retrieval workflow — vector search, optional hybrid text fusion, optional neighboring-chunk expansion — no longer requires callers to hand-write the multi-primitive pipeline documented in docs/rag-guide.md.
Usage:
SELECT * FROM RAG_SEARCH('chunks', 'embedding', query_vector, 5)
SELECT * FROM RAG_SEARCH('chunks', 'embedding', query_vector, 5, '{
"text_columns": ["heading", "chunk_text"],
"text_query": "what is the capital of France",
"key_columns": ["doc_id", "chunk_index"],
"expand_before": 1,
"expand_after": 1,
"doc_id_column": "doc_id",
"chunk_index_column": "chunk_index"
}')
RBAC enforcement for Execute (see internal/storage/rbac.go for the underlying users/roles/grants model).
The acting user travels via context.Context (WithUser/UserFromContext), not as an Execute parameter — adding a parameter would break every existing caller's signature (internal/driver, cmd/server, every test in this module). A context key is the idiomatic Go way to thread an optional, cross-cutting value like this without an API break, and it composes with context.WithTimeout/WithCancel that callers already use.
Enforcement itself is opt-in at the database level: checkPermission is a no-op unless db.IsRBACEnabled() is true (which itself is false until the first CreateUser call), so every existing embedder and test that never creates a user sees zero behavior change. Call db.SetRBACEnabled(false) to force enforcement off even after users/roles have been created — for a setup that provisions accounts ahead of time but isn't ready to enforce yet, or a dev/test environment that wants audit-log attribution via WithUser without access checks getting in the way.
Parser and AST for RBAC DDL: CREATE/DROP/ALTER USER, CREATE/DROP ROLE, and GRANT/REVOKE. Enforcement lives in rbac.go; the underlying users/roles/grants model is internal/storage/rbac.go.
Grammar (see parser_test-style examples in rbac_parser_test.go):
CREATE USER name WITH PASSWORD 'secret' [ROLE role1 [, role2 ...]] DROP USER name ALTER USER name ENABLE | DISABLE ALTER USER name WITH PASSWORD 'newsecret' CREATE ROLE name DROP ROLE name GRANT perm [, perm ...] ON [schema.]table TO ROLE role GRANT perm [, perm ...] ON * TO ROLE role REVOKE perm [, perm ...] ON [schema.]table FROM ROLE role GRANT ROLE role TO USER user REVOKE ROLE role FROM USER user
Row plumbing: turning a stored table into row maps, merging rows for joins, building group and DISTINCT keys, and comparing rows.
A lazy, version-invalidated spatial index for GEO_SEARCH, following the exact same shape as the Vector index (vector_index.go) and FTS's doc cache (fts.go): tinySQL has no R-tree and no CREATE INDEX ... USING clause, so a fundamentally different index structure is bolted on the side as a table-valued-function-scoped cache rather than wired into the query planner (which today only ever recognizes *Binary comparisons in a WHERE clause, never a *FuncCall predicate like GEO_DWITHIN).
The structure itself is a fixed-size equirectangular lon/lat grid: each row's geometry is bucketed into every cell its bounding box touches, by its own bounding box (not just its centroid), so a geometry spanning several cells is a candidate from all of them. Candidate selection is deliberately a superset filter -- GEO_SEARCH always re-verifies every candidate against the exact, unmodified GEO_WITHIN_BBOX/GEO_DWITHIN math (geo_search.go), the same "index narrows, per-row function call verifies" division of labor plan_range_index.go already documents for its own 1-D range seeks.
Package engine provides plaintext/fulltext utility functions and table-valued functions for RAG (Retrieval-Augmented Generation) workloads.
TEXT_CHUNKS(text, chunk_size [, overlap [, unit]])
Splits text into overlapping chunks suitable for embedding and retrieval. Parameters: text – the source document text chunk_size – maximum tokens (words) per chunk (default 100) overlap – number of tokens shared between adjacent chunks (default 20) unit – 'words' (default) or 'chars' Returns columns: chunk_index INT, chunk_text TEXT, start_pos INT, end_pos INT
TEXT_WORD_COUNT(text) – count of whitespace-separated words TEXT_CHAR_COUNT(text) – count of Unicode characters TEXT_TRUNCATE(text, max_len [, ellipsis]) – truncate to max_len chars
Web Mercator tile addressing, for working with MBTiles tilesets in SQL.
Two coordinate conventions meet in a tileset, and confusing them is the classic MBTiles bug:
- XYZ ("slippy map", what web clients and /{z}/{x}/{y}.png URLs use) counts rows from the *top*: row 0 is the northernmost.
- TMS (what the MBTiles specification stores in tiles.tile_row) counts rows from the *bottom*: row 0 is the southernmost.
They differ by tile_row = 2^zoom - 1 - y. A tileset served with the flip missing looks plausible — right tiles, wrong places, mirrored vertically — which is why every function here states which convention it speaks, and why TILE_FLIP_Y exists as the one explicit conversion.
Functions taking or returning a y value use XYZ, because that is what callers have when serving a map request. Only TILE_FLIP_Y and the MBTiles helpers mention TMS.
Package engine implements trigger execution for tinySQL. Triggers fire BEFORE or AFTER INSERT, UPDATE, and DELETE operations. NEW refers to the new row (INSERT/UPDATE), OLD refers to the old row (UPDATE/DELETE).
SQL value semantics: NULL, three-valued boolean logic, and comparison and ordering across the storage types. Everything that decides what "equal", "true" and "less than" mean lives here, so those rules can be read in one place rather than inferred from their call sites.
Package engine provides vector/embedding functions for tinySQL, enabling RAG (Retrieval-Augmented Generation) workloads and vector similarity search.
Supported functions:
VEC_FROM_JSON(json_string) – parse "[1.0, 2.0, 3.0]" → []float64
VEC_TO_JSON(vector) – serialize vector → JSON string
RECENCY_SCORE(ts, half_life_days [, now]) – exponential decay score in [0, 1]
RAG_HYBRID_SCORE(similarity, ts, half_life_days [, sim_weight, now]) – blend of
normalized similarity and recency
RAG_RANK_SCORE(similarity, ts, half_life_days, quality [, sim_w, recency_w, quality_w, now])
– weighted RAG score over similarity, freshness and quality
VEC_DIM(vector) – number of dimensions
VEC_NORM(vector) – L2 (Euclidean) norm
VEC_NORMALIZE(vector) – unit-length normalised copy
VEC_ADD(v1, v2) – element-wise addition
VEC_SUB(v1, v2) – element-wise subtraction
VEC_MUL(v1, v2) – element-wise multiplication (Hadamard)
VEC_SCALE(vector, scalar) – scalar multiplication
VEC_DOT(v1, v2) – dot / inner product
VEC_COSINE_SIMILARITY(v1, v2) – cosine similarity ∈ [-1, 1]
VEC_COSINE_DISTANCE(v1, v2) – 1 - cosine similarity ∈ [0, 2]
VEC_L2_DISTANCE(v1, v2) – Euclidean distance
VEC_MANHATTAN_DISTANCE(v1, v2) – L1 / Manhattan distance
VEC_DISTANCE(v1, v2 [, metric]) – generic distance, metric = 'cosine' | 'l2' | 'manhattan' | 'dot'
VEC_SLICE(vector, start, length) – sub-vector extraction
VEC_CONCAT(v1, v2) – vector concatenation
VEC_QUANTIZE(vector, bits) – quantize to reduced precision (8/16 bit simulation)
VEC_RANDOM(dimensions [, seed]) – random unit vector of given dimension
Package engine provides a VEC_SEARCH table-valued function for k-nearest neighbor (k-NN) vector search — the core building block for Retrieval-Augmented Generation (RAG) workloads in tinySQL.
Usage:
SELECT * FROM VEC_SEARCH('table_name', 'vector_column', query_vector, k [, 'metric' [, 'index']])
Parameters:
table_name – name of the table containing vectors vector_column – column storing VECTOR ([]float64) values query_vector – the search vector ([]float64 or JSON string) k – number of nearest neighbors to return metric – optional distance metric: 'cosine' (default), 'l2', 'manhattan', 'dot' index – optional index mode: 'flat' (default exact), 'ivf', 'hnsw'
Returns all original columns plus:
_vec_distance – computed distance from query_vector (lower = closer)
_vec_similarity – similarity derived from the distance (higher = closer);
feed this, not _vec_distance, into RAG_HYBRID_SCORE /
RAG_RANK_SCORE, which expect a similarity input
_vec_rank – 1-based rank (1 = closest)
The results are returned in ascending order of distance (closest first).
VEC_WARM — eager warm-up for vector search structures.
Usage:
SELECT * FROM VEC_WARM('table_name', 'vector_column' [, 'metric' [, 'index']])
Prebuilds the vector column cache (and, for cosine, the L2 norms) plus the requested ANN index (ivf or hnsw). This shifts the one-time O(n log n) index-build cost from the first query to an explicit warm-up step — e.g. right after a nightly bulk load — so serving queries never pay it.
Returns a single row describing what was warmed:
table_name, column_name, metric, index_mode, row_count, vector_count, dims, distinct_dims, excluded_rows
distinct_dims counts how many different vector lengths were seen among the valid rows (e.g. during an embedding-model migration where old and new dimensionalities briefly coexist in the same column). The ANN index is only ever built for the first-seen dims; excluded_rows reports how many otherwise-valid rows were left out of that index because their vector's length did not match dims, so callers can detect a mixed-dimensionality column instead of silently getting a partial index.
Automatic WAL logging for INSERT/UPDATE/DELETE, for both WAL implementations tinySQL supports.
tinySQL has two WAL implementations — the basic WALManager (whole-table snapshot diffing, used by ModeWAL) and AdvancedWAL (row-level, LSN-based, with real REDO/recovery, used by ModeAdvancedWAL) — but historically nothing in the engine's own INSERT/UPDATE/DELETE path called either one. Both were only driven by internal/driver's explicit BeginTx/Commit and autocommit paths. A caller using ModeWAL or ModeAdvancedWAL and writing through the ordinary tinysql.Execute API (not through internal/driver's connection machinery — e.g. cmd/server, or any direct embedder) got no durability logging at all: a silent gap, since nothing errored or warned about it, and DB.HealthCheck() still reported WALActive/AdvancedWALActive as true.
walAuto wraps each mutating statement in its own implicit, autocommitted AdvancedWAL transaction (LogBegin before the row loop, LogCommit after) and logs every row change as it happens. maybeLogToWALManager instead diffs the statement's pre-execution snapshot against the now-mutated DB and logs the resulting table-level changes to WALManager, mirroring what internal/driver's commitTx/execStatement already do for driver-mediated access. Both are complete no-ops — zero calls, zero overhead beyond a nil check — when the corresponding WAL isn't attached.
Index ¶
- Constants
- Variables
- func ConfigureVectorCache(cfg VectorCacheConfig)
- func DecodeWKBGeometry(data []byte) (map[string]any, error)
- func IsReadOnlyStatement(stmt Statement) bool
- func MayStreamIncrementally(stmt Statement) bool
- func RegisterExternalTableFunc(fn ExternalTableFunc)
- func RegisterStoredProcedure(name string, fn StoredProcedureFunc) error
- func RegisterStoredProcedureWithOptions(name string, options StoredProcedureOptions, fn StoredProcedureFunc) error
- func RegisterTableFunc(fn TableFunction)
- func SplitStatements(script string) []string
- func StatementComplete(script string) bool
- func UnregisterStoredProcedure(name string) bool
- func UserFromContext(ctx context.Context) (string, bool)
- func Version() string
- func WithAuditText(ctx context.Context, sqlText string) context.Context
- func WithUser(ctx context.Context, username string) context.Context
- type AlterJob
- type AlterMaterializedViewToView
- type AlterTable
- type AlterUser
- type AlterViewMaterialize
- type Analyze
- type BetweenExpr
- type Binary
- type CSVTableFunc
- type CTE
- type CallProcedure
- type CaseExpr
- type CaseWhen
- type ColumnarResultSet
- type CompiledQuery
- func (cq *CompiledQuery) Execute(ctx context.Context, db *storage.DB, tenant string) (*ResultSet, error)
- func (cq *CompiledQuery) Stream(ctx context.Context, db *storage.DB, tenant string) (*ResultStream, error)
- func (cq *CompiledQuery) StreamWithOptions(ctx context.Context, db *storage.DB, tenant string, opts StreamOptions) (*ResultStream, error)
- type CreateIndex
- type CreateJob
- type CreateMaterializedView
- type CreateRole
- type CreateTable
- type CreateTrigger
- type CreateUser
- type CreateView
- type Delete
- type DropIndex
- type DropJob
- type DropMaterializedView
- type DropRole
- type DropTable
- type DropTrigger
- type DropUser
- type DropView
- type ExecEnv
- type ExistsExpr
- type Explain
- type Expr
- type ExternalTableFunc
- type FTSSearchFilteredTableFunc
- type FTSSearchTableFunc
- type FTSWarmTableFunc
- type FromItem
- type FuncCall
- type GeoSearchTableFunc
- type GrantPrivilege
- type GrantRoleStmt
- type HashJoinOptimizer
- type HybridSearchTableFunc
- type InExpr
- type IndexAdvisor
- type IndexAdvisorOptions
- type IndexRecommendation
- type Insert
- type IsNull
- type JSONLinesTableFunc
- type JSONTableFunc
- type JoinClause
- type JoinCondition
- type JoinType
- type LikeExpr
- type Literal
- type MBTilesMetadataTableFunc
- type MBTilesTilesTableFunc
- type OptimizedJoinType
- type OrderItem
- type OverClause
- type Parser
- type PivotClause
- type PivotValue
- type Pragma
- type ProcedureContext
- func (pc ProcedureContext) Context() context.Context
- func (pc ProcedureContext) Execute(stmt Statement) (*ResultSet, error)
- func (pc ProcedureContext) ExecuteSQL(sql string) (*ResultSet, error)
- func (pc ProcedureContext) ExecuteSQLArgs(sql string, args ...any) (*ResultSet, error)
- func (pc ProcedureContext) Tenant() string
- type QueryCache
- type QueryChange
- type QuerySubscription
- type RAGContextFromTableFunc
- type RAGContextTableFunc
- type RAGSearchTableFunc
- type RAGWarmTableFunc
- type RefreshMaterializedView
- type RegexpExpr
- type ResultSet
- type ResultStream
- func (s *ResultStream) Close() error
- func (s *ResultStream) Columns() []string
- func (s *ResultStream) Done() <-chan struct{}
- func (s *ResultStream) Err() error
- func (s *ResultStream) Next() bool
- func (s *ResultStream) ReleaseRow(row Row)
- func (s *ResultStream) Row() Row
- func (s *ResultStream) Stats() StreamStats
- type RevokePrivilege
- type RevokeRoleStmt
- type RouteDistanceMatrixTableFunc
- type RouteReachableTableFunc
- type RouteShortestPathAStarTableFunc
- type RouteShortestPathTableFunc
- type RouteWarmTableFunc
- type Row
- type Select
- type SelectItem
- type Statement
- type StoredProcedureFunc
- type StoredProcedureInfo
- type StoredProcedureOptions
- type StoredProcedureParameter
- type StreamOptions
- type StreamStats
- type SubqueryExpr
- type SubscriptionOptions
- type SubscriptionStats
- type TableFuncCall
- type TableFunction
- type TextChunksTableFunc
- type TileCoverTableFunc
- type Unary
- type UnionClause
- type UnionType
- type Update
- type VarRef
- type VecSearchFilteredTableFunc
- type VecSearchTableFunc
- type VecTopKTableFunc
- type VecWarmTableFunc
- type VectorCacheConfig
- type VectorCacheStats
- type VectorQueryEvent
- type WindowFrame
- type XMLTableFunc
Constants ¶
const DefaultResultStreamBuffer = 64
DefaultResultStreamBuffer is the number of produced rows that can wait for a consumer when callers use ExecuteStream. It keeps the convenient API responsive without letting an abandoned or slow consumer retain an unbounded result in memory.
const MaxBlobBytes = 64 << 20
MaxBlobBytes bounds a single BLOB accepted by the SQL executor. It avoids integer/codec overflows and accidental unbounded allocations while staying comfortably above normal compressed MVT payloads.
Variables ¶
var BuildVersion = "dev"
BuildVersion can be set with -ldflags -X at release build time. Keep the default suitable for local development; Version below falls back to Go's module metadata when a consuming application has not injected it.
Functions ¶
func ConfigureVectorCache ¶ added in v0.19.0
func ConfigureVectorCache(cfg VectorCacheConfig)
func DecodeWKBGeometry ¶ added in v0.48.0
DecodeWKBGeometry exposes the standard WKB decoder to sibling internal packages such as the service-independent GeoPackage importer. Callers are responsible for CRS handling before treating the resulting coordinates as RFC 7946 longitude/latitude.
func IsReadOnlyStatement ¶ added in v0.48.0
IsReadOnlyStatement reports the engine's current lock classification. CALL statements use their registered StoredProcedureOptions; unknown procedures remain conservatively mutating until execution reports the lookup error.
func MayStreamIncrementally ¶ added in v0.48.0
MayStreamIncrementally reports whether stmt has a shape for which ExecuteStream may produce rows directly from the source scan. It is a deliberately conservative syntactic test: a true result can still fall back to materialization when the runtime source is a view or another source the simple plan cannot handle, while false guarantees that ExecuteStream would only add a goroutine and channel around an already materialized ResultSet.
The database/sql adapter uses this distinction to keep genuine large-result streaming while returning blocking shapes such as ORDER BY, GROUP BY, DISTINCT, joins, CTEs and EXPLAIN synchronously.
func RegisterExternalTableFunc ¶ added in v0.8.0
func RegisterExternalTableFunc(fn ExternalTableFunc)
RegisterExternalTableFunc wraps fn in an adapter and registers it so that it can be used in SQL FROM clauses and JOINs.
func RegisterStoredProcedure ¶ added in v0.14.0
func RegisterStoredProcedure(name string, fn StoredProcedureFunc) error
RegisterStoredProcedure registers an in-memory stored procedure by name. Names are case-insensitive. Re-registering the same name replaces the previous handler. Procedures are process-local and are not persisted.
func RegisterStoredProcedureWithOptions ¶ added in v0.48.0
func RegisterStoredProcedureWithOptions(name string, options StoredProcedureOptions, fn StoredProcedureFunc) error
RegisterStoredProcedureWithOptions registers a procedure with argument, concurrency, rollback and catalog metadata. Names are case-insensitive; replacing a registration also resets its invocation statistics.
func RegisterTableFunc ¶ added in v0.5.1
func RegisterTableFunc(fn TableFunction)
RegisterTableFunc registers a table-valued function globally
func SplitStatements ¶ added in v0.57.0
SplitStatements splits a SQL script into its statements with the engine's own lexer, so semicolons inside string and BLOB literals, quoted identifiers and comments never end a statement. CREATE TRIGGER bodies stay intact: semicolons between BEGIN and its matching END (including CASE ... END expressions inside the body) belong to the trigger.
Statements are returned without their terminating semicolon and without surrounding whitespace. Leading comments before a statement are dropped; empty statements are skipped. Splitting never validates syntax: each returned statement is parsed and reported individually by its executor.
func StatementComplete ¶ added in v0.57.0
StatementComplete reports whether script ends with a complete statement: its last token is a semicolon that terminates a statement, outside string literals, quoted identifiers, comments and CREATE TRIGGER bodies. It is the equivalent of SQLite's sqlite3_complete and lets interactive shells decide when buffered input is ready to execute. Syntax is not validated.
func UnregisterStoredProcedure ¶ added in v0.14.0
UnregisterStoredProcedure removes a procedure. It returns true when a registered procedure existed.
func UserFromContext ¶ added in v0.12.0
UserFromContext returns the username set by WithUser, if any.
func Version ¶ added in v0.5.4
func Version() string
Version returns the tinySQL module version from build metadata and falls back to "dev". When tinySQL is embedded in another executable, the main module is the application rather than tinySQL, so look through dependencies instead of accidentally reporting the host application's version.
func WithAuditText ¶ added in v0.13.0
WithAuditText attaches the original SQL text of the statement about to be executed, for the audit log to record verbatim. Compose with WithUser: engine.WithAuditText(engine.WithUser(ctx, user), sqlText).
Types ¶
type AlterMaterializedViewToView ¶ added in v0.11.0
type AlterMaterializedViewToView struct {
Name string
}
AlterMaterializedViewToView represents ALTER MATERIALIZED VIEW ... TO VIEW.
type AlterTable ¶ added in v0.3.0
type AlterTable struct {
Table string
AddColumn *storage.Column // For ADD COLUMN
RenameColumnFrom string
RenameColumnTo string
}
AlterTable represents an ALTER TABLE statement.
type AlterUser ¶ added in v0.12.0
AlterUser represents ALTER USER name {ENABLE|DISABLE|WITH PASSWORD '...'}. Exactly one of SetEnabled/NewPassword is set per statement (the grammar only allows one clause); both nil would be a no-op, which the parser never produces.
type AlterViewMaterialize ¶ added in v0.11.0
type AlterViewMaterialize struct {
Name string
WithData bool
StaleAfterMs int64
RefreshEveryMs int64
DailyAt string
Timezone string
InvalidateOnChange bool
}
AlterViewMaterialize represents ALTER VIEW ... MATERIALIZE.
type Analyze ¶ added in v0.21.0
type Analyze struct {
Table string
}
Analyze refreshes persisted planner statistics for one table, or every table in the current tenant when Table is empty.
type BetweenExpr ¶ added in v0.12.0
BetweenExpr represents "expr [NOT] BETWEEN lo AND hi" when expr is not a plain column or literal. Unlike the desugared form (expr >= lo AND expr <= hi) it evaluates expr exactly once, which is faster for expensive expressions and correct for non-deterministic ones (e.g. RANDOM() BETWEEN 1 AND 10).
type CSVTableFunc ¶ added in v0.5.1
type CSVTableFunc struct{}
CSVTableFunc implements table_from_csv(source, options)
func (*CSVTableFunc) Name ¶ added in v0.5.1
func (f *CSVTableFunc) Name() string
func (*CSVTableFunc) ValidateArgs ¶ added in v0.5.1
func (f *CSVTableFunc) ValidateArgs(args []Expr) error
type CTE ¶
type CTE struct {
Name string
Columns []string
Select *Select
// Recursive is true only when this CTE actually references itself. WITH
// RECURSIVE permits recursion; it does not make every CTE recursive.
Recursive bool
}
CTE represents a Common Table Expression (WITH clause)
type CallProcedure ¶ added in v0.14.0
CallProcedure represents CALL proc_name(arg1, arg2, ...).
type CaseExpr ¶ added in v0.3.0
CaseExpr represents a CASE ... WHEN ... THEN ... [ELSE ...] END expression.
type ColumnarResultSet ¶ added in v0.54.0
ColumnarResultSet stores one positional value slice per output column. Values[column][row] addresses a cell; NULL is nil. Cols preserves the same names and order as ResultSet. RowCount is explicit for zero-column results. The slices belong to the caller and are never pooled or reused by execution. As with ResultSet, nested cell values (e.g. BLOBs) are not deep-copied. This is a compact result format, not an Arrow buffer or a disk storage mode.
func ExecuteColumnar ¶ added in v0.54.0
func ExecuteColumnar(ctx context.Context, db *storage.DB, tenant string, stmt Statement) (*ColumnarResultSet, error)
ExecuteColumnar executes a SELECT with the usual authorization, statement locking and SQL semantics. Simple unordered scans project directly into columns without allocating Row maps. Other SELECT shapes use the existing executor and transpose its final result, so their intermediate memory use is unchanged. Non-SELECT statements are rejected without executing them.
type CompiledQuery ¶
CompiledQuery represents a pre-parsed and cached SQL query.
func (*CompiledQuery) Execute ¶
func (cq *CompiledQuery) Execute(ctx context.Context, db *storage.DB, tenant string) (*ResultSet, error)
Execute runs a compiled query against the database.
func (*CompiledQuery) Stream ¶ added in v0.44.0
func (cq *CompiledQuery) Stream(ctx context.Context, db *storage.DB, tenant string) (*ResultStream, error)
Stream executes a compiled query and returns an incremental result stream.
func (*CompiledQuery) StreamWithOptions ¶ added in v0.45.0
func (cq *CompiledQuery) StreamWithOptions(ctx context.Context, db *storage.DB, tenant string, opts StreamOptions) (*ResultStream, error)
StreamWithOptions executes a compiled query with explicit stream producer/consumer settings.
type CreateIndex ¶ added in v0.3.0
type CreateIndex struct {
Name string
Table string
Columns []string
Unique bool
IfNotExists bool
// contains filtered or unexported fields
}
CreateIndex represents a CREATE INDEX statement.
type CreateJob ¶ added in v0.5.1
type CreateJob struct {
Name string
ScheduleType string // CRON, INTERVAL, ONCE
CronExpr string
IntervalMs int64
RunAt *time.Time
Timezone string
MaxRuntimeMs int64
NoOverlap bool
CatchUp bool
Enabled bool
SQLText string
}
CreateJob represents a CREATE JOB statement.
type CreateMaterializedView ¶ added in v0.11.0
type CreateMaterializedView struct {
Name string
Select *Select
SQLText string
IfNotExists bool
OrReplace bool
WithData bool
StaleAfterMs int64
RefreshEveryMs int64
DailyAt string
Timezone string
InvalidateOnChange bool
}
CreateMaterializedView represents a CREATE MATERIALIZED VIEW statement.
type CreateRole ¶ added in v0.12.0
type CreateRole struct {
Name string
}
CreateRole represents CREATE ROLE name.
type CreateTable ¶
type CreateTable struct {
Name string
Cols []storage.Column
IsTemp bool
AsSelect *Select
IfNotExists bool // IF NOT EXISTS clause
VirtualTable bool // CREATE VIRTUAL TABLE
Using string // e.g. "fts"
FTSColumns []string // columns passed to fts(...)
}
CreateTable represents a CREATE TABLE statement.
type CreateTrigger ¶ added in v0.9.0
type CreateTrigger struct {
Name string
Timing string // "BEFORE", "AFTER", "INSTEAD OF"
Event string // "INSERT", "UPDATE", "DELETE"
Table string
ForEachRow bool
WhenExpr Expr // optional WHEN condition
WhenText string // original WHEN expression text, for persisted triggers
Body []Statement // trigger body statements, parsed once to validate syntax at CREATE TRIGGER time
BodyText string // verbatim source text of the body (between BEGIN and END), stored for re-parsing on each fire
IfNotExists bool
}
CreateTrigger represents a CREATE TRIGGER statement.
type CreateUser ¶ added in v0.12.0
CreateUser represents CREATE USER name WITH PASSWORD '...' [ROLE ...].
type CreateView ¶ added in v0.3.0
type CreateView struct {
Name string
Select *Select
SQLText string
IfNotExists bool
OrReplace bool
}
CreateView represents a CREATE VIEW statement.
type Delete ¶
type Delete struct {
Table string
Where Expr
Returning []SelectItem
}
Delete represents a DELETE statement.
type DropIndex ¶ added in v0.3.0
type DropIndex struct {
Name string
Table string // Optional: some DBs require table name
IfExists bool
}
DropIndex represents a DROP INDEX statement.
type DropJob ¶ added in v0.5.1
type DropJob struct {
Name string
}
DropJob represents DROP JOB <name>
type DropMaterializedView ¶ added in v0.11.0
DropMaterializedView represents a DROP MATERIALIZED VIEW statement.
type DropRole ¶ added in v0.12.0
type DropRole struct {
Name string
}
DropRole represents DROP ROLE name.
type DropTrigger ¶ added in v0.9.0
DropTrigger represents a DROP TRIGGER statement.
type DropUser ¶ added in v0.12.0
type DropUser struct {
Name string
}
DropUser represents DROP USER name.
type ExistsExpr ¶ added in v0.10.0
type ExistsExpr struct {
Select *Select
}
ExistsExpr represents "EXISTS (subquery)".
type ExternalTableFunc ¶ added in v0.8.0
type ExternalTableFunc interface {
Name() string
ValidateArgCount(n int) error
Execute(ctx context.Context, args []any) (*ResultSet, error)
}
ExternalTableFunc is the public interface for domain-specific table-valued functions (e.g. FSQL filesystem functions). Its Execute method receives pre-evaluated argument values rather than raw AST nodes.
type FTSSearchFilteredTableFunc ¶ added in v0.46.0
type FTSSearchFilteredTableFunc struct{}
FTSSearchFilteredTableFunc exposes FTS pre-filtering without making the existing FTS_SEARCH(column...) suffix ambiguous.
FTS_SEARCH_FILTERED(table, query, k, options_json [, column1, column2...])
func (*FTSSearchFilteredTableFunc) Name ¶ added in v0.46.0
func (f *FTSSearchFilteredTableFunc) Name() string
func (*FTSSearchFilteredTableFunc) ValidateArgs ¶ added in v0.46.0
func (f *FTSSearchFilteredTableFunc) ValidateArgs(args []Expr) error
type FTSSearchTableFunc ¶ added in v0.11.0
type FTSSearchTableFunc struct{}
FTSSearchTableFunc implements FTS_SEARCH(table, query, k [, columns...]). Usage:
SELECT * FROM FTS_SEARCH('table_name', 'query text', 10)
Returns all columns from the source table plus:
_fts_score – BM25 relevance score _fts_rank – 1-based rank (1 = most relevant)
func (*FTSSearchTableFunc) Name ¶ added in v0.11.0
func (f *FTSSearchTableFunc) Name() string
func (*FTSSearchTableFunc) ValidateArgs ¶ added in v0.11.0
func (f *FTSSearchTableFunc) ValidateArgs(args []Expr) error
type FTSWarmTableFunc ¶ added in v0.46.0
type FTSWarmTableFunc struct{}
FTSWarmTableFunc implements FTS_WARM(table [, columns...]).
func (*FTSWarmTableFunc) Name ¶ added in v0.46.0
func (f *FTSWarmTableFunc) Name() string
func (*FTSWarmTableFunc) ValidateArgs ¶ added in v0.46.0
func (f *FTSWarmTableFunc) ValidateArgs(args []Expr) error
type FromItem ¶
type FromItem struct {
Table string // Tabellenname (wenn echte Tabelle)
Alias string // Alias für Tabelle oder Subselect
Subquery *Select // Falls abgeleitete Tabelle: das Select-Statement
TableFunc *TableFuncCall // Wenn FROM eine table-valued function ist
}
FromItem kann eine echte Tabelle oder ein Subselect (Derived Table) sein.
type FuncCall ¶
type FuncCall struct {
Name string
Args []Expr
Star bool
Distinct bool // For COUNT(DISTINCT col)
Over *OverClause // For window functions
// contains filtered or unexported fields
}
FuncCall represents a function call, optionally with a star (COUNT(*)).
type GeoSearchTableFunc ¶ added in v0.27.0
type GeoSearchTableFunc struct{}
GeoSearchTableFunc implements GEO_SEARCH(table, geom_col, mode, ...), a table-valued function following VEC_SEARCH's exact calling convention (one function name, a mode string argument selects the internal structure) rather than one function per mode -- see vector_search.go's VecSearchTableFunc for the precedent this mirrors.
GEO_SEARCH indexes each row by its geometry's centroid/bbox (spatial_index.go), so it is exact for Point columns -- the dominant BI case (store locations, sensor readouts, event feeds) -- but for polygon/line columns it answers "is this shape's bounding area within the query window." Use bbox_intersects for GIS layers whose polygon/line extent must overlap the viewport; bbox retains the legacy centroid-within behavior. True shape-overlap search belongs to ST_INTERSECTS (geo_relate.go) run as an ordinary per-row filter after bbox_intersects has narrowed the candidates.
func (*GeoSearchTableFunc) Name ¶ added in v0.27.0
func (f *GeoSearchTableFunc) Name() string
func (*GeoSearchTableFunc) ValidateArgs ¶ added in v0.27.0
func (f *GeoSearchTableFunc) ValidateArgs(args []Expr) error
type GrantPrivilege ¶ added in v0.12.0
type GrantPrivilege struct {
Permissions []storage.Permission
Schema string // "*" for "every schema"
Table string // "*" for "every table"
RoleName string
}
GrantPrivilege represents GRANT perm[,...] ON target TO ROLE role.
type GrantRoleStmt ¶ added in v0.12.0
GrantRoleStmt represents GRANT ROLE role TO USER user.
type HashJoinOptimizer ¶ added in v0.3.1
type HashJoinOptimizer struct {
// contains filtered or unexported fields
}
HashJoinOptimizer provides hash-based join optimizations
func (*HashJoinOptimizer) ProcessOptimizedJoin ¶ added in v0.3.1
func (h *HashJoinOptimizer) ProcessOptimizedJoin(leftRows, rightRows []Row, condition Expr, joinType OptimizedJoinType) ([]Row, error)
OptimizedJoinProcessor handles optimized join operations
type HybridSearchTableFunc ¶ added in v0.25.0
type HybridSearchTableFunc struct {
// contains filtered or unexported fields
}
HYBRID_SEARCH is the search-box-oriented form of RAG_SEARCH:
HYBRID_SEARCH(table, vector_column, text_column, search_term,
query_vector, k [, options_json])
search_term and query_vector represent the same user input: callers create query_vector with the embedding model that was used for vector_column. HYBRID_SEARCH uses the string for BM25/wildcard retrieval and the vector for semantic retrieval, then reciprocal-rank-fuses both candidate lists.
func (*HybridSearchTableFunc) Name ¶ added in v0.25.0
func (f *HybridSearchTableFunc) Name() string
func (*HybridSearchTableFunc) ValidateArgs ¶ added in v0.25.0
func (f *HybridSearchTableFunc) ValidateArgs(args []Expr) error
type IndexAdvisor ¶ added in v0.54.0
type IndexAdvisor struct {
// contains filtered or unexported fields
}
func NewIndexAdvisor ¶ added in v0.54.0
func NewIndexAdvisor(db *storage.DB, options IndexAdvisorOptions) (*IndexAdvisor, error)
NewIndexAdvisor creates a DB-scoped observer. Only queries executed through its Execute method are observed; the ordinary Execute path has no overhead.
func (*IndexAdvisor) Apply ¶ added in v0.54.0
func (a *IndexAdvisor) Apply(ctx context.Context, tenant, name string) error
Apply builds a known, ready recommendation using ordinary CREATE INDEX authorization, rollback, auditing and durability. Limits and schema are rechecked under that statement's content write lock.
func (*IndexAdvisor) Execute ¶ added in v0.54.0
func (a *IndexAdvisor) Execute(ctx context.Context, tenant string, stmt Statement) (*ResultSet, error)
Execute observes successful simple SELECT equality filters. If enabled, at most one non-unique index is built synchronously after the query completes. A build failure is recorded in LastError, never substituted for a successful query result. Use Apply to receive build errors directly. There is no worker.
func (*IndexAdvisor) Recommendations ¶ added in v0.54.0
func (a *IndexAdvisor) Recommendations() []IndexRecommendation
Recommendations returns a detached, deterministically ordered snapshot.
func (*IndexAdvisor) SetAutoCreate ¶ added in v0.54.0
func (a *IndexAdvisor) SetAutoCreate(enabled bool)
SetAutoCreate changes the opt-in mode. Enabling it does not immediately build pending recommendations; the next observed eligible query can build one.
type IndexAdvisorOptions ¶ added in v0.54.0
type IndexAdvisorOptions struct {
AutoCreate bool
MinExecutions int // default 20 successful SELECTs
MinTableRows int // default 1024
MaxTableRows int // default 100000; checked again under the DDL write lock
MaxIndexesPerTable int // default 3, including manually created indexes
MaxCandidates int // default 256 across tenants/tables/columns
}
IndexAdvisorOptions bounds opt-in workload observation and index creation. Zero limits use defaults. Automatic creation is disabled by default.
type IndexRecommendation ¶ added in v0.54.0
type IndexRecommendation struct {
Tenant, Table, Column, Name string
Executions uint64
TotalDuration time.Duration // query wall time, including lock wait
TableRows, SampleDistinct int
Status, LastError string
}
IndexRecommendation contains aggregate counters, never SQL or literal values. Status is collecting, ready, covered, created, skipped or failed.
type Insert ¶
type Insert struct {
Table string
Cols []string
Rows [][]Expr
Select *Select // INSERT INTO ... SELECT ...
OnConflictDoNothing bool
Returning []SelectItem
}
Insert represents an INSERT statement.
type JSONLinesTableFunc ¶ added in v0.5.1
type JSONLinesTableFunc struct{}
JSONLinesTableFunc implements table_from_json_lines(source)
func (*JSONLinesTableFunc) Name ¶ added in v0.5.1
func (f *JSONLinesTableFunc) Name() string
func (*JSONLinesTableFunc) ValidateArgs ¶ added in v0.5.1
func (f *JSONLinesTableFunc) ValidateArgs(args []Expr) error
type JSONTableFunc ¶ added in v0.5.1
type JSONTableFunc struct{}
JSONTableFunc implements table_from_json(source, spec)
func (*JSONTableFunc) Name ¶ added in v0.5.1
func (f *JSONTableFunc) Name() string
func (*JSONTableFunc) ValidateArgs ¶ added in v0.5.1
func (f *JSONTableFunc) ValidateArgs(args []Expr) error
type JoinClause ¶
JoinClause holds a JOIN type with the right side and join condition.
type JoinCondition ¶ added in v0.3.1
JoinCondition represents a parsed join condition
type JoinType ¶
type JoinType int
const ( // JoinInner represents INNER JOIN. JoinInner JoinType = iota // JoinLeft represents LEFT (OUTER) JOIN. JoinLeft // JoinRight represents RIGHT (OUTER) JOIN. JoinRight // JoinFull represents FULL (OUTER) JOIN. JoinFull // JoinCross represents CROSS JOIN (unconditional Cartesian product; no ON clause). JoinCross )
type LikeExpr ¶ added in v0.3.0
type LikeExpr struct {
Expr Expr
Pattern Expr
Escape Expr // Optional ESCAPE character
Negate bool // For NOT LIKE / NOT ILIKE / NOT GLOB
CaseInsensitive bool // For ILIKE
GlobStyle bool // For GLOB (* and ? wildcards instead of % and _)
}
LikeExpr represents "expr LIKE pattern [ESCAPE char]"
type Literal ¶
type Literal struct {
Val any
Parameter bool // bound positional parameter; value may change between executions
}
Literal holds a constant value (number, string, bool, NULL).
type MBTilesMetadataTableFunc ¶ added in v0.48.0
type MBTilesMetadataTableFunc struct{}
func (*MBTilesMetadataTableFunc) Name ¶ added in v0.48.0
func (f *MBTilesMetadataTableFunc) Name() string
func (*MBTilesMetadataTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *MBTilesMetadataTableFunc) ValidateArgs(args []Expr) error
type MBTilesTilesTableFunc ¶ added in v0.48.0
type MBTilesTilesTableFunc struct{}
func (*MBTilesTilesTableFunc) Name ¶ added in v0.48.0
func (f *MBTilesTilesTableFunc) Name() string
func (*MBTilesTilesTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *MBTilesTilesTableFunc) ValidateArgs(args []Expr) error
type OptimizedJoinType ¶ added in v0.3.1
type OptimizedJoinType int
OptimizedJoinType defines the type of join operation for optimizations
const ( OptimizedJoinTypeInner OptimizedJoinType = iota OptimizedJoinTypeLeft OptimizedJoinTypeRight )
type OverClause ¶ added in v0.5.0
type OverClause struct {
PartitionBy []Expr // PARTITION BY expressions
OrderBy []OrderItem // ORDER BY items
Frame *WindowFrame // ROWS/RANGE frame specification
}
OverClause represents the OVER clause for window functions.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser holds the lexer and current/peek tokens for recursive-descent parsing.
func (*Parser) ParseStatement ¶
ParseStatement parses exactly one complete SQL statement into an AST. A single trailing semicolon is accepted; any remaining token is an error so a valid DML prefix can never silently ignore and execute before junk input.
type PivotClause ¶ added in v0.12.0
type PivotClause struct {
AggFunc string // e.g. SUM, COUNT, AVG, MIN, MAX
ValueExpr Expr
PivotCol string
Values []PivotValue
}
PivotClause represents "PIVOT (agg(value_expr) FOR pivot_col IN (v1 [AS a1], v2 [AS a2], ...))". It reshapes the WHERE-filtered row set: each distinct value listed in the IN-list becomes its own output column (named by its alias, or by the value's literal text if no alias is given), holding agg(value_expr) over the rows where pivot_col equals that value. Every other selected column acts as an implicit GROUP BY key, matching standard SQL PIVOT semantics.
Scope: a single aggregate function and a static (literal) value list — no dynamic pivot driven by a subquery. This covers the overwhelmingly common case (a known, fixed set of categories to spread into columns) without the complexity of a fully dynamic PIVOT.
type PivotValue ¶ added in v0.12.0
type PivotValue struct {
Expr Expr
Alias string // output column name; defaults to the value's text form
}
PivotValue is one entry in a PIVOT's IN (...) list.
type ProcedureContext ¶ added in v0.14.0
type ProcedureContext struct {
// contains filtered or unexported fields
}
ProcedureContext is passed to registered in-memory stored procedures. It lets procedures run SQL against the same DB/tenant without re-entering Execute's content lock.
func (ProcedureContext) Context ¶ added in v0.14.0
func (pc ProcedureContext) Context() context.Context
Context returns the statement context passed to Execute.
func (ProcedureContext) Execute ¶ added in v0.14.0
func (pc ProcedureContext) Execute(stmt Statement) (*ResultSet, error)
Execute executes a parsed statement inside the current CALL.
func (ProcedureContext) ExecuteSQL ¶ added in v0.14.0
func (pc ProcedureContext) ExecuteSQL(sql string) (*ResultSet, error)
ExecuteSQL parses and executes sql inside the current CALL. It reuses the current statement lock, so procedures can compose ordinary tinySQL statements without deadlocking.
func (ProcedureContext) ExecuteSQLArgs ¶ added in v0.48.0
func (pc ProcedureContext) ExecuteSQLArgs(sql string, args ...any) (*ResultSet, error)
ExecuteSQLArgs safely substitutes positional ? parameters and executes the resulting statement inside the current CALL. Placeholders inside quoted SQL strings are left untouched. Values are rendered as SQL literals with string escaping and BLOB/JSON support, so handlers do not need fmt.Sprintf-based SQL construction.
func (ProcedureContext) Tenant ¶ added in v0.14.0
func (pc ProcedureContext) Tenant() string
Tenant returns the tenant/schema namespace used by the CALL statement.
type QueryCache ¶
type QueryCache struct {
// contains filtered or unexported fields
}
QueryCache manages compiled queries with LRU eviction.
func NewQueryCache ¶
func NewQueryCache(maxSize int) *QueryCache
NewQueryCache creates a new query cache with the specified maximum size.
func (*QueryCache) Compile ¶
func (qc *QueryCache) Compile(sql string) (*CompiledQuery, error)
Compile parses and caches a SQL query for reuse.
func (*QueryCache) MustCompile ¶
func (qc *QueryCache) MustCompile(sql string) *CompiledQuery
MustCompile is like Compile but panics on error (similar to regexp.MustCompile).
func (*QueryCache) Size ¶
func (qc *QueryCache) Size() int
Size returns the number of cached queries.
func (*QueryCache) Stats ¶
func (qc *QueryCache) Stats() map[string]interface{}
Stats returns cache statistics.
type QueryChange ¶ added in v0.54.0
type QueryChange struct {
Initial bool
Cols []string
Added []Row
Removed []Row
// ScannedRows counts candidates evaluated for this change, useful for
// observing incremental versus fallback execution. It is -1 when the
// general SELECT executor does not expose a candidate count.
ScannedRows int
}
QueryChange is a multiset delta: remove one occurrence for every Removed row, then add each Added row. Initial replaces the entire result. There is no row ordering contract. Slow readers may observe several commits as one delta.
type QuerySubscription ¶ added in v0.54.0
type QuerySubscription struct {
Changes <-chan QueryChange
// contains filtered or unexported fields
}
QuerySubscription owns one worker and a one-element output queue. Close or cancel the context when done. Errors terminate Changes and are available in Err.
func SubscribeSQL ¶ added in v0.54.0
func SubscribeSQL(ctx context.Context, db *storage.DB, tenant, query string) (*QuerySubscription, error)
SubscribeSQL delivers result deltas for SELECTs, including views, joins, aggregates, CTEs and set operations. Simple physical-table queries update incrementally; other queries are re-executed on database change notifications. ORDER BY affects LIMIT/OFFSET membership, but deltas have no ordering contract.
func SubscribeSQLWithOptions ¶ added in v0.54.0
func SubscribeSQLWithOptions(ctx context.Context, db *storage.DB, tenant, query string, opts SubscriptionOptions) (*QuerySubscription, error)
func (*QuerySubscription) Close ¶ added in v0.54.0
func (s *QuerySubscription) Close()
func (*QuerySubscription) Err ¶ added in v0.54.0
func (s *QuerySubscription) Err() error
func (*QuerySubscription) Stats ¶ added in v0.54.0
func (s *QuerySubscription) Stats() SubscriptionStats
type RAGContextFromTableFunc ¶ added in v0.11.0
type RAGContextFromTableFunc struct{}
RAG_CONTEXT_FROM expands multiple retrieval hits into neighboring chunks.
Usage:
WITH topk AS (...)
SELECT * FROM RAG_CONTEXT_FROM('chunks', 'doc_id', 'chunk_index',
'topk', 'doc_id', 'chunk_index', 1 [, 1])
func (*RAGContextFromTableFunc) Name ¶ added in v0.11.0
func (f *RAGContextFromTableFunc) Name() string
func (*RAGContextFromTableFunc) ValidateArgs ¶ added in v0.11.0
func (f *RAGContextFromTableFunc) ValidateArgs(args []Expr) error
type RAGContextTableFunc ¶ added in v0.11.0
type RAGContextTableFunc struct{}
RAG_CONTEXT loads neighboring chunks for a single retrieved chunk.
Usage:
SELECT * FROM RAG_CONTEXT('chunks', 'doc_id', 'chunk_index', 'doc-1', 7, 2 [, 1])
Arguments:
source table/CTE, document id column, chunk index column, document id, center chunk index, chunks before, optional chunks after.
func (*RAGContextTableFunc) Name ¶ added in v0.11.0
func (f *RAGContextTableFunc) Name() string
func (*RAGContextTableFunc) ValidateArgs ¶ added in v0.11.0
func (f *RAGContextTableFunc) ValidateArgs(args []Expr) error
type RAGSearchTableFunc ¶ added in v0.24.0
type RAGSearchTableFunc struct{}
RAGSearchTableFunc implements the RAG_SEARCH table-valued function.
func (*RAGSearchTableFunc) Name ¶ added in v0.24.0
func (f *RAGSearchTableFunc) Name() string
func (*RAGSearchTableFunc) ValidateArgs ¶ added in v0.24.0
func (f *RAGSearchTableFunc) ValidateArgs(args []Expr) error
type RAGWarmTableFunc ¶ added in v0.48.0
type RAGWarmTableFunc struct{}
RAG_WARM builds the independent vector and lexical retrieval structures in parallel, shifting corpus-dependent startup work out of the first request. It intentionally reuses the exact caches populated by VEC_WARM/FTS_WARM.
func (*RAGWarmTableFunc) Name ¶ added in v0.48.0
func (f *RAGWarmTableFunc) Name() string
func (*RAGWarmTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *RAGWarmTableFunc) ValidateArgs(args []Expr) error
type RefreshMaterializedView ¶ added in v0.11.0
RefreshMaterializedView represents REFRESH MATERIALIZED VIEW.
type RegexpExpr ¶ added in v0.10.0
type RegexpExpr struct {
Expr Expr
Pattern Expr
Negate bool // For NOT REGEXP / NOT RLIKE / NOT SIMILAR TO
SimilarTo bool // Pattern uses SQL SIMILAR TO syntax (% and _ wildcards)
}
RegexpExpr represents "expr REGEXP/RLIKE pattern" and "expr SIMILAR TO pattern".
type ResultSet ¶
ResultSet holds the column order and the returned rows from a query. Cols preserve the display order; Rows store values in a case-insensitive map.
func Execute ¶
func Execute(ctx context.Context, db *storage.DB, tenant string, stmt Statement) (*ResultSet, error)
Execute runs a parsed SQL statement against the given storage DB and tenant. It dispatches to handlers per statement kind and returns a ResultSet for SELECT (nil for DDL/DML). The context is checked at safe points to support cancellation.
Concurrency: storage.DB's own mutex only protects the tenant->table map structure, not the contents of a *storage.Table (Rows/Cols/Version) once a caller holds one — INSERT/UPDATE/DELETE mutate Table.Rows with no lock of their own, so two goroutines calling Execute concurrently on the same DB would otherwise race on that slice (a real data race, not just stale reads: concurrent unsynchronized slice append + range is undefined behavior in Go). Execute closes that gap with a single coarse read/write lock around the whole statement: SELECT/EXPLAIN/PRAGMA take a shared read lock (so concurrent reads still run in parallel with each other), everything else takes an exclusive write lock. This is coarser than per-table locking — a write to table A blocks a concurrent read of unrelated table B — but it is correct and simple to audit, which matters more for a safety fix than maximum parallelism.
type ResultStream ¶ added in v0.44.0
type ResultStream struct {
Cols []string
// contains filtered or unexported fields
}
ResultStream incrementally exposes query rows. Next blocks until another row is available, the query finishes, or its context is cancelled. Row is valid until the next call to Next. Call Close when abandoning a stream early so the producer can release its database read lock promptly.
Simple single-table SELECTs without ORDER BY, GROUP BY, DISTINCT, joins or set operations stream directly from the scan. Shapes that need the complete input before their first result retain their existing semantics and begin yielding after materialization.
func ExecuteStream ¶ added in v0.44.0
func ExecuteStream(ctx context.Context, db *storage.DB, tenant string, stmt Statement) (*ResultStream, error)
ExecuteStream starts a statement and returns as soon as its result columns are known. See ResultStream for which SELECT shapes produce rows before the full query has completed.
func ExecuteStreamWithOptions ¶ added in v0.45.0
func ExecuteStreamWithOptions(ctx context.Context, db *storage.DB, tenant string, stmt Statement, opts StreamOptions) (*ResultStream, error)
ExecuteStreamWithOptions starts a statement with explicit producer/consumer backpressure settings. It otherwise has the same semantics as ExecuteStream.
func (*ResultStream) Close ¶ added in v0.44.0
func (s *ResultStream) Close() error
Close stops production and waits until any held database read lock has been released. It is safe to call repeatedly.
func (*ResultStream) Columns ¶ added in v0.44.0
func (s *ResultStream) Columns() []string
Columns returns the result columns in display order.
func (*ResultStream) Done ¶ added in v0.45.0
func (s *ResultStream) Done() <-chan struct{}
Done is closed after the producer has stopped and no longer accesses the statement or database. Consumers can use it to release resources that only need to outlive production rather than buffered-row consumption.
func (*ResultStream) Err ¶ added in v0.44.0
func (s *ResultStream) Err() error
Err reports the terminal producer or context error. Closing a stream explicitly is not an error.
func (*ResultStream) Next ¶ added in v0.44.0
func (s *ResultStream) Next() bool
Next advances to the next result row, blocking while the producer continues scanning. It returns false at EOF or on error; inspect Err to distinguish the two. Next and Row are intended to be called by one consumer goroutine.
func (*ResultStream) ReleaseRow ¶ added in v0.52.0
func (s *ResultStream) ReleaseRow(row Row)
ReleaseRow returns row -- which must be the value most recently returned by Row, and which the caller must not use again after this call -- to the producer's row pool for reuse. It is always safe to call (a no-op if pooling isn't in effect for this stream's plan shape; see rawRowPool's doc comment in exec_raw_eval.go), but only useful for a caller that, like database/sql's driver, is finished with a row's values before it calls Next again.
func (*ResultStream) Row ¶ added in v0.44.0
func (s *ResultStream) Row() Row
Row returns the row selected by the most recent successful Next call.
func (*ResultStream) Stats ¶ added in v0.45.0
func (s *ResultStream) Stats() StreamStats
Stats returns a snapshot of stream progress. It is safe to call while Next is blocked or while another goroutine is producing rows.
type RevokePrivilege ¶ added in v0.12.0
type RevokePrivilege struct {
Permissions []storage.Permission
Schema string
Table string
RoleName string
}
RevokePrivilege represents REVOKE perm[,...] ON target FROM ROLE role.
type RevokeRoleStmt ¶ added in v0.12.0
RevokeRoleStmt represents REVOKE ROLE role FROM USER user.
type RouteDistanceMatrixTableFunc ¶ added in v0.48.0
type RouteDistanceMatrixTableFunc struct{}
ROUTE_DISTANCE_MATRIX computes the Cartesian product of source and target JSON arrays. Sources are grouped so each distinct source performs at most one search, and repeated matrix calls reuse the ordinary pair-distance cache.
func (*RouteDistanceMatrixTableFunc) Name ¶ added in v0.48.0
func (f *RouteDistanceMatrixTableFunc) Name() string
func (*RouteDistanceMatrixTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *RouteDistanceMatrixTableFunc) ValidateArgs(args []Expr) error
type RouteReachableTableFunc ¶ added in v0.48.0
type RouteReachableTableFunc struct{}
ROUTE_REACHABLE returns nodes in nondecreasing shortest-cost order, bounded by max_cost and optionally by result count. It is the graph-side primitive for service areas, isochrones and "nearest by travel time" queries.
func (*RouteReachableTableFunc) Name ¶ added in v0.48.0
func (f *RouteReachableTableFunc) Name() string
func (*RouteReachableTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *RouteReachableTableFunc) ValidateArgs(args []Expr) error
type RouteShortestPathAStarTableFunc ¶ added in v0.48.0
type RouteShortestPathAStarTableFunc struct{}
func (*RouteShortestPathAStarTableFunc) Name ¶ added in v0.48.0
func (f *RouteShortestPathAStarTableFunc) Name() string
func (*RouteShortestPathAStarTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *RouteShortestPathAStarTableFunc) ValidateArgs(args []Expr) error
type RouteShortestPathTableFunc ¶ added in v0.48.0
type RouteShortestPathTableFunc struct{}
func (*RouteShortestPathTableFunc) Name ¶ added in v0.48.0
func (f *RouteShortestPathTableFunc) Name() string
func (*RouteShortestPathTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *RouteShortestPathTableFunc) ValidateArgs(args []Expr) error
type RouteWarmTableFunc ¶ added in v0.48.0
type RouteWarmTableFunc struct{}
ROUTE_WARM eagerly builds the versioned CSR graph after imports or bulk updates, moving cold-build latency out of the first user-facing request.
func (*RouteWarmTableFunc) Name ¶ added in v0.48.0
func (f *RouteWarmTableFunc) Name() string
func (*RouteWarmTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *RouteWarmTableFunc) ValidateArgs(args []Expr) error
type Row ¶
Row represents a single result row mapped by lower-cased column name. Keys include both qualified (table.column) and unqualified (column) names to simplify expression evaluation and projection.
type Select ¶
type Select struct {
Distinct bool
DistinctOn []Expr
From FromItem
Joins []JoinClause
Projs []SelectItem
Where Expr
Pivot *PivotClause
GroupBy []Expr
Having Expr
OrderBy []OrderItem
Limit *int
Offset *int
Union *UnionClause // For UNION operations
CTEs []CTE // Common Table Expressions
// contains filtered or unexported fields
}
Select represents a SELECT query and its clauses.
type SelectItem ¶
SelectItem represents a projection item, optionally with alias or *.
type Statement ¶
type Statement interface{}
Statement is the root interface for all parsed SQL statements.
type StoredProcedureFunc ¶ added in v0.14.0
type StoredProcedureFunc func(ctx ProcedureContext, args []any) (*ResultSet, error)
StoredProcedureFunc is the Go handler signature for in-memory stored procedures registered with RegisterStoredProcedure.
type StoredProcedureInfo ¶ added in v0.14.0
type StoredProcedureInfo struct {
Name string
Description string
Parameters []StoredProcedureParameter
MinArgs int
MaxArgs int
ReadOnly bool
Atomic bool
RegisteredAt time.Time
Calls uint64
Errors uint64
LastCalledAt time.Time
TotalRuntime time.Duration
}
StoredProcedureInfo describes one registered procedure.
func ListStoredProcedures ¶ added in v0.14.0
func ListStoredProcedures() []StoredProcedureInfo
ListStoredProcedures returns registered in-memory procedures sorted by name.
type StoredProcedureOptions ¶ added in v0.48.0
type StoredProcedureOptions struct {
Description string
Parameters []StoredProcedureParameter
// ReadOnly lets concurrent CALLs use the database content read lock. The
// ProcedureContext enforces the promise for every nested statement.
ReadOnly bool
// Atomic takes a full statement rollback point for a mutating procedure,
// restoring all nested table/catalog changes when its handler returns an
// error. Read-only procedures never need this option.
Atomic bool
}
StoredProcedureOptions controls validation, scheduling and rollback.
type StoredProcedureParameter ¶ added in v0.48.0
StoredProcedureParameter describes one positional CALL argument. Required parameters must precede optional parameters. A nil Parameters slice on StoredProcedureOptions keeps legacy unchecked arity; a non-nil empty slice declares an exact zero-argument procedure.
type StreamOptions ¶ added in v0.45.0
type StreamOptions struct {
Buffer int
}
StreamOptions controls the producer/consumer boundary of a ResultStream.
Buffer is the maximum number of produced rows waiting for a consumer. Zero is intentionally valid and provides strict backpressure: a producer waits for every call to Next. ExecuteStream uses DefaultResultStreamBuffer; use ExecuteStreamWithOptions to select zero or another capacity explicitly.
type StreamStats ¶ added in v0.45.0
type StreamStats struct {
BufferOccupancy int
BlockedSends uint64
SendWait time.Duration
StartedAt time.Time
FirstRowAt time.Time
CompletedAt time.Time
RowsScanned uint64
RowsProduced uint64
BufferCapacity int
Materialized bool
Complete bool
}
StreamStats is a point-in-time, concurrency-safe snapshot of a query stream. RowsScanned is populated for direct simple-scan streams (while a stream is running it may trail by up to 63 candidates to avoid adding an atomic operation to every hot-loop iteration); a materialized query cannot in general expose the executor's intermediate candidate count and reports zero for that field. RowsProduced is the number of result rows accepted by the stream's producer.
type SubqueryExpr ¶ added in v0.3.0
type SubqueryExpr struct {
Select *Select
}
SubqueryExpr wraps a SELECT used as an expression (scalar subquery).
type SubscriptionOptions ¶ added in v0.54.0
SubscriptionOptions bounds retained/published results, not executor working memory. Zero leaves a limit disabled. Bytes count JSON-encoded row payloads.
type SubscriptionStats ¶ added in v0.54.0
type TableFuncCall ¶ added in v0.5.1
TableFuncCall represents a table function call in a FROM clause
type TableFunction ¶ added in v0.5.1
type TableFunction interface {
// Name returns the function name (e.g., "table_from_json")
Name() string
// Execute evaluates the TVF and returns a result set (columns + rows)
Execute(ctx context.Context, args []Expr, env ExecEnv, row Row) (*ResultSet, error)
// ValidateArgs checks if the provided arguments are valid
ValidateArgs(args []Expr) error
}
TableFunction represents a table-valued function that can be used in FROM clauses Example: SELECT * FROM table_from_json(http('...'), spec)
func GetTableFunc ¶ added in v0.5.1
func GetTableFunc(name string) (TableFunction, bool)
GetTableFunc retrieves a registered table function by name
type TextChunksTableFunc ¶ added in v0.11.0
type TextChunksTableFunc struct{}
TextChunksTableFunc implements TEXT_CHUNKS(text, chunk_size [, overlap [, unit]]).
func (*TextChunksTableFunc) Name ¶ added in v0.11.0
func (f *TextChunksTableFunc) Name() string
func (*TextChunksTableFunc) ValidateArgs ¶ added in v0.11.0
func (f *TextChunksTableFunc) ValidateArgs(args []Expr) error
type TileCoverTableFunc ¶ added in v0.48.0
type TileCoverTableFunc struct{}
func (*TileCoverTableFunc) Name ¶ added in v0.48.0
func (f *TileCoverTableFunc) Name() string
func (*TileCoverTableFunc) ValidateArgs ¶ added in v0.48.0
func (f *TileCoverTableFunc) ValidateArgs(args []Expr) error
type UnionClause ¶
type UnionClause struct {
Type UnionType
Right *Select
Next *UnionClause // For chaining multiple UNIONs
}
UnionClause represents a set operation chaining RIGHT select with current one.
type Update ¶
type Update struct {
Table string
Sets map[string]Expr
Where Expr
Returning []SelectItem
}
Update represents an UPDATE statement.
type VecSearchFilteredTableFunc ¶ added in v0.46.0
type VecSearchFilteredTableFunc struct{}
VecSearchFilteredTableFunc exposes exact, pre-filtered vector retrieval without overloading VEC_SEARCH's legacy positional metric/index arguments.
VEC_SEARCH_FILTERED(table, column, query_vector, k, options_json) options_json accepts metric, index (documented but filter-safe searches use exact flat ranking), and a required pre_filter object.
func (*VecSearchFilteredTableFunc) Name ¶ added in v0.46.0
func (f *VecSearchFilteredTableFunc) Name() string
func (*VecSearchFilteredTableFunc) ValidateArgs ¶ added in v0.46.0
func (f *VecSearchFilteredTableFunc) ValidateArgs(args []Expr) error
type VecSearchTableFunc ¶ added in v0.5.4
type VecSearchTableFunc struct{}
VecSearchTableFunc implements the VEC_SEARCH table-valued function.
func (*VecSearchTableFunc) Name ¶ added in v0.5.4
func (f *VecSearchTableFunc) Name() string
func (*VecSearchTableFunc) ValidateArgs ¶ added in v0.5.4
func (f *VecSearchTableFunc) ValidateArgs(args []Expr) error
type VecTopKTableFunc ¶ added in v0.5.4
type VecTopKTableFunc struct {
// contains filtered or unexported fields
}
VecTopKTableFunc implements VEC_TOP_K — alias/alternative API for k-NN search. Usage: SELECT * FROM VEC_TOP_K('table', 'column', query_vec, k [, 'metric'])
func (*VecTopKTableFunc) Name ¶ added in v0.5.4
func (f *VecTopKTableFunc) Name() string
func (*VecTopKTableFunc) ValidateArgs ¶ added in v0.5.4
func (f *VecTopKTableFunc) ValidateArgs(args []Expr) error
type VecWarmTableFunc ¶ added in v0.11.0
type VecWarmTableFunc struct{}
VecWarmTableFunc implements the VEC_WARM table-valued function.
func (*VecWarmTableFunc) Name ¶ added in v0.11.0
func (f *VecWarmTableFunc) Name() string
func (*VecWarmTableFunc) ValidateArgs ¶ added in v0.11.0
func (f *VecWarmTableFunc) ValidateArgs(args []Expr) error
type VectorCacheConfig ¶ added in v0.19.0
type VectorCacheConfig struct {
// ResultCacheEntries bounds cached result sets. Zero disables the cache.
ResultCacheEntries int
// ResultCacheTTL expires cached result sets. A positive entry limit with a
// non-positive TTL uses the conservative default of 30 seconds.
ResultCacheTTL time.Duration
// Analytics enables the bounded in-memory recent-query window.
Analytics bool
// AnalyticsWindow limits how long query events remain visible.
AnalyticsWindow time.Duration
// AnalyticsMaxEvents bounds retained query events independently of time.
AnalyticsMaxEvents int
}
VectorCacheConfig controls the optional process-wide VEC_SEARCH result cache. The existing column/ANN caches remain active independently.
func DefaultVectorCacheConfig ¶ added in v0.19.0
func DefaultVectorCacheConfig() VectorCacheConfig
DefaultVectorCacheConfig returns the conservative profile: caching and analytics are opt-in, while bounded values are ready for enabled features.
type VectorCacheStats ¶ added in v0.19.0
type VectorCacheStats struct {
Enabled bool `json:"enabled"`
Entries int `json:"entries"`
Hits uint64 `json:"hits"`
Misses uint64 `json:"misses"`
Evictions uint64 `json:"evictions"`
ApproxBytes int64 `json:"approx_bytes"`
HeapAlloc uint64 `json:"heap_alloc_bytes"`
RecentQueries []VectorQueryEvent `json:"recent_queries,omitempty"`
}
VectorCacheStats is a snapshot suitable for embedding applications and the server analytics endpoint. Query names exclude vector contents.
func VectorCacheAnalytics ¶ added in v0.19.0
func VectorCacheAnalytics() VectorCacheStats
type VectorQueryEvent ¶ added in v0.19.0
type VectorQueryEvent struct {
At time.Time `json:"at"`
Table string `json:"table"`
Column string `json:"column"`
Metric string `json:"metric"`
Index string `json:"index"`
K int `json:"k"`
CacheHit bool `json:"cache_hit"`
// Duration covers the vector-search stage, including a cache lookup.
Duration time.Duration `json:"duration"`
}
type WindowFrame ¶ added in v0.5.0
type WindowFrame struct {
Mode string // "ROWS" or "RANGE"
StartType string // "UNBOUNDED", "CURRENT", or "OFFSET"
StartValue int // Offset value for PRECEDING/FOLLOWING
EndType string // "UNBOUNDED", "CURRENT", or "OFFSET"
EndValue int // Offset value for PRECEDING/FOLLOWING
}
WindowFrame represents ROWS/RANGE BETWEEN frame specification.
type XMLTableFunc ¶ added in v0.5.1
type XMLTableFunc struct{}
XMLTableFunc implements table_from_xml(source, record_name)
func (*XMLTableFunc) Name ¶ added in v0.5.1
func (f *XMLTableFunc) Name() string
func (*XMLTableFunc) ValidateArgs ¶ added in v0.5.1
func (f *XMLTableFunc) ValidateArgs(args []Expr) error
Source Files
¶
- aggregate_groups.go
- arith.go
- ast.go
- audit.go
- builtin_datetime.go
- builtin_hash.go
- builtin_math.go
- builtin_registry.go
- builtin_string.go
- coerce.go
- columnar.go
- compile.go
- const_fold.go
- crs_functions.go
- delayed_inserts.go
- dependencies.go
- distinct_set.go
- dml_row_arena.go
- eval_aggregate.go
- eval_expr.go
- eval_subquery_cache.go
- eval_window.go
- eval_window_classify.go
- exec.go
- exec_aggregate_batch.go
- exec_cte.go
- exec_ddl_alter.go
- exec_ddl_table.go
- exec_ddl_view.go
- exec_dispatch.go
- exec_dml_delete.go
- exec_dml_insert.go
- exec_dml_update.go
- exec_empty_columns.go
- exec_fastpath_aggregate.go
- exec_fastpath_join.go
- exec_fastpath_join_aggregate.go
- exec_fastpath_select.go
- exec_from.go
- exec_group.go
- exec_having.go
- exec_join.go
- exec_limit.go
- exec_plan.go
- exec_plan_choices.go
- exec_raw_eval.go
- exec_raw_filter.go
- exec_raw_project.go
- exec_select.go
- exec_setops.go
- exec_sort.go
- exec_specialized_table.go
- exec_statement.go
- explain.go
- extended_functions.go
- extra_types.go
- foreign_keys.go
- fts.go
- fts_index.go
- fts_parallel_build.go
- fts_query_cache.go
- fts_query_plan_cache.go
- fts_snippet_cache.go
- fts_warm.go
- geo_aggregate.go
- geo_clip.go
- geo_dissolve.go
- geo_editing.go
- geo_functions.go
- geo_geopackage.go
- geo_hash.go
- geo_json_encode.go
- geo_json_fast.go
- geo_mbtiles.go
- geo_poly_cache.go
- geo_quality.go
- geo_relate.go
- geo_relate_extra.go
- geo_route.go
- geo_route_astar.go
- geo_route_batch.go
- geo_route_warm.go
- geo_search.go
- geo_simplify.go
- geo_transform.go
- geo_wkb.go
- geo_wkt.go
- html_escape.go
- hybrid_search.go
- index_advisor.go
- index_seek_safety.go
- io_functions.go
- io_functions_http.go
- join_candidates.go
- json_path.go
- lexer.go
- like_cache.go
- like_matcher.go
- optimizations.go
- parse_column_def.go
- parse_column_type.go
- parse_ddl.go
- parse_ddl_alter.go
- parse_ddl_view.go
- parse_dml.go
- parse_expr_operand.go
- parse_expr_predicate.go
- parse_func_window.go
- parse_select.go
- parse_statement.go
- parser.go
- plan_range_index.go
- procedures.go
- rag_context.go
- rag_filtered_ann.go
- rag_prefilter.go
- rag_search.go
- rag_warm.go
- rbac.go
- rbac_parser.go
- regex_cache.go
- regexp_matcher.go
- retrieval_intersection.go
- row_helpers.go
- runtime_metrics.go
- spatial_index.go
- split_statements.go
- sqlite_compat.go
- stream.go
- stream_plan.go
- stream_snapshot.go
- subscribe.go
- subscribe_dependencies.go
- subscribe_full.go
- subscribe_limits.go
- suggest.go
- table_functions.go
- text_columns.go
- text_functions.go
- tile_cover.go
- tile_functions.go
- triggers.go
- value_semantics.go
- vector_functions.go
- vector_index.go
- vector_persistent.go
- vector_query_cache.go
- vector_search.go
- vector_warm.go
- virtual_tables.go
- wal_logging.go
- web_functions.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package sqlval holds the small, self-contained value-semantics helpers that both the SQL engine and its retrieval subpackage need.
|
Package sqlval holds the small, self-contained value-semantics helpers that both the SQL engine and its retrieval subpackage need. |