Status: Alpha. This page describes the standalone Rust Engine, not SQL sent by Studio to registered databases. Registered-source SQL compatibility is determined by the selected database and Kaveon's API guardrails.
| SQL feature | State | Notes |
|---|---|---|
SELECT |
Alpha | Local and object-store Parquet, Delta, and Iceberg tables resolved through the Engine catalog |
EXPLAIN |
Alpha | Plan-only logical, optimized, and distributed/physical views through the native and Trino statement routes; TYPE IO returns the physical-plan projection because runtime IO statistics are not available before execution. EXPLAIN ANALYZE executes the statement once and returns the optimized plan plus measured output-row, analysis, planning, and execution timings. Unsupported output formats are rejected explicitly; plan-only forms do not start scans or worker tasks |
ANALYZE catalog.schema.table |
Alpha | Admin-only on the coordinator; publishes exact metadata row counts bound to the catalog and immutable storage-source identity through the ADLS catalog head |
Catalog DDL: CREATE CATALOG, CREATE SCHEMA, CREATE TABLE … WITH (location, format [, partitioned_by]), CALL system.register_table, ALTER TABLE … SET LOCATION, `DROP CATALOG |
SCHEMA | TABLE, SHOW CREATE TABLE, DESCRIBE, SHOW CATALOGS |
| Column projection and aliases | Alpha | Projection is strict; unknown or duplicate requested columns fail |
WHERE comparisons and boolean expressions |
Alpha | Row-level filter operator is implemented |
GROUP BY |
Alpha | Local and distributed columnar hash aggregation: partials on several threads that flush on memory pressure, a hybrid final merge that spills sub-partitions; GROUP BY without an aggregate is DISTINCT over the keys |
SUM, COUNT, AVG, MIN, MAX, COUNT(DISTINCT ...) |
Alpha | Weighted AVG and exact DISTINCT states are mergeable across workers |
LIMIT, OFFSET, FETCH FIRST/NEXT … ROWS [PERCENT] [WITH TIES] |
Alpha | Physical limit and offset operators; LIMIT ALL is an explicit no-limit form; ordinary FETCH plans as bounded TopN, PERCENT lowers through a full-row-count window and ceiling threshold, and WITH TIES lowers through a global RANK() boundary and preserves offset semantics; literal percentages are validated in the inclusive 0–100 range and conflicting LIMIT/FETCH forms are rejected explicitly |
| Qualified table names | Alpha | catalog.schema.table resolution is supported by the catalog |
ORDER BY, NULLS FIRST/LAST, TopN |
Alpha | Local/distributed execution; Sort/TopN support bounded external merge runs |
| Equi joins | Alpha | INNER/LEFT/RIGHT/FULL locally and distributed (hash repartition or broadcast of the small side from exact statistics); typed INT32, INT64, UInt64, Date32, UTF-8, and LargeUtf8 keys use exact single-key hash indexes, while other supported key types use the typed composite path; comma joins with WHERE equalities become hash joins through the binder; ON conditions route like WHERE and an outer join filters its non-preserved side by single-side conjuncts |
| Residual outer joins | Alpha | LEFT/RIGHT/FULL joins evaluate additional ON predicates before null extension, preserving SQL TRUE/FALSE/UNKNOWN semantics; equality-key joins use distributed hash candidates, while residual-only joins use an explicit broadcast candidate path and are not claimed as repartitioned joins |
| Cross joins | Alpha | Local Cartesian semantics and distributed broadcast-build path |
| Semi/anti joins | Alpha | IN/NOT IN/EXISTS/NOT EXISTS subqueries, locally and distributed; equality-key forms hash-partition both sides and emit only the matching (semi) or non-matching (anti) left rows, with a bounded broadcast fallback when a key cannot be resolved; correlated EXISTS/NOT EXISTS on one equality are decorrelated by the binder |
| Scalar subqueries | Alpha | Uncorrelated scalar subqueries in WHERE/HAVING (an ungrouped aggregate, as a single-row cross join); correlated scalar aggregates, including COUNT, on one or two equalities; COUNT uses a left join and zero-fills unmatched keys; a bounded non-aggregate scalar OFFSET n LIMIT 1 with equality-only correlations is decorrelated with per-key ROW_NUMBER() paging. Residual correlations, offset-only scalars, multi-row limits, and general Apply/lateral forms remain rejected explicitly |
| Prepared statements | Alpha | Principal-owned POST /v1/prepare, describe, execute, and close lifecycle; execution reuses typed positional/named parameter binding and the normal query path. The Trino route also supports SQL-level PREPARE, EXECUTE, DEALLOCATE, DESCRIBE INPUT, and DESCRIBE OUTPUT; input metadata reports discovered positions/names, infers explicit CAST and PostgreSQL-style ::type annotations, and leaves unresolved types as unknown, while output metadata reports projection names plus planner-inferred or explicit types |
| CTEs and derived tables | Alpha | Non-recursive CTEs; derived tables in FROM and joined with commas |
| Arithmetic expressions | Alpha | Compatible numeric coercion for supported primitive numeric types |
HAVING |
Alpha | Post-aggregation filter |
Aggregate FILTER (WHERE ...) |
Alpha | Supported on aggregate functions, including COUNT, SUM, and COUNT_IF; the predicate is evaluated with SQL three-valued semantics before the aggregate state is updated |
| Window functions | Alpha | ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, aggregates with OVER (PARTITION BY … ORDER BY …) and ROWS/RANGE/GROUPS frames |
QUALIFY |
Alpha | Filters supported window results after window evaluation; partitioned ROW_NUMBER shapes are qualified across local and distributed execution |
| Set operations | Alpha | UNION [ALL], INTERSECT, EXCEPT, INTERSECT ALL, and EXCEPT ALL; distributed exact duplicate-count semantics are covered by the differential sweep |
| Date/time | Alpha | EXTRACT, DATE_TRUNC over DATE calendar units and second/millisecond/microsecond/nanosecond timestamps with unit and timezone preservation, DATE_PART, DATE_DIFF from nanoseconds through weeks plus calendar month/quarter/year boundaries, TO_CHAR, FROM_UNIXTIME, TO_UNIXTIME, NOW, CURRENT_DATE, CURRENT_TIMESTAMP, DATE '…' and TIMESTAMP '…' literals, typed timestamp ± INTERVAL 'n' HOUR/MINUTE/SECOND and typed DATE/timestamp ± INTERVAL 'n' DAY/WEEK/MONTH/QUARTER/YEAR; month/year shifts use calendar arithmetic and clamp month-end days |
| Conditional, comparison and strings | Alpha | CASE, IF/IIF, COALESCE, GREATEST, LEAST, NULLIF, BETWEEN, IN, IS DISTINCT FROM, IS NOT DISTINCT FROM, LIKE/ILIKE (Arrow kernels), REGEXP_REPLACE, REGEXP_COUNT, REGEXP_EXTRACT, REGEXP_EXTRACT_ALL, REGEXP_SPLIT, CHR, CODEPOINT, STRPOS, CAST, TRY_CAST, TRY(CAST(...)), TRY(JSON_PARSE(...)), CONCAT_WS, TRANSLATE, concatenation, UPPER/LOWER/LENGTH/TRIM/SUBSTR/SPLIT/SPLIT_PART/REVERSE/REPEAT/REPLACE/LPAD/RPAD; LEFT, RIGHT, LPAD, RPAD, REVERSE, REPEAT, STARTS_WITH, and ENDS_WITH preserve nullable LargeUtf8 columns and count Unicode scalars; CHR and CODEPOINT operate on Unicode code points and preserve NULLs; CODEPOINT rejects values containing anything other than one code point; STRPOS and POSITION accept Utf8/LargeUtf8 inputs, support Unicode character positions, and STRPOS supports positive and negative occurrence indexes; zero occurrences fail explicitly; CONCAT_WS skips NULL value arguments and returns NULL for a NULL separator; TRANSLATE maps Unicode code points by position, keeps unmapped source characters, and removes source characters without a corresponding target; SPLIT returns a typed text array (preserving LargeUtf8 input width), preserves NULL inputs, supports a positive limit whose final element contains the remainder, and splits into characters for an empty delimiter; REGEXP_COUNT counts non-overlapping matches and preserves NULL inputs; REGEXP_EXTRACT_ALL returns a typed text array of non-overlapping matches, or capture group 1 when present, and preserves NULL inputs; REGEXP_SPLIT returns a typed text array and preserves trailing empty fields; SPLIT_PART preserves LargeUtf8 input width, uses one-based indexes, returns NULL out of range, and rejects non-positive indexes; GREATEST and LEAST preserve the common input type and return NULL when any argument is NULL; REGEXP_EXTRACT(string, pattern[, group]) returns capture group 0 by default or the requested zero-based group, and returns NULL for a non-match or missing capture |
ROW(...), MAP(...), and MAP_FROM_ENTRIES(...) constructors |
Alpha | Produces typed Arrow StructArray/MapArray values from list inputs with null-preserving child values; MAP_FROM_ENTRIES accepts ARRAY[ROW(key, value)], preserves NULL outer rows, and rejects NULL or duplicate keys; SPLIT_TO_MAP parses delimited text into typed text maps, rejects empty delimiters and duplicate keys, and preserves NULL rows; SPLIT_TO_MULTIMAP groups repeated keys into ordered text arrays; 32-bit and 64-bit-offset list arrays, including mixed-offset comparisons, share the same semantics; ROW(...).field, row equality and lexicographic ordering, null-preserving element-wise array equality/inequality and lexicographic ordering, order-independent map equality, map subscript lookup, MAP_KEYS, MAP_VALUES, and Trino-compatible MAP_CONTAINS_KEY(map, key) (plus the legacy CONTAINS_KEY alias) expose typed projections; ordered map comparison remains open |
| Array and map functions/subscripts | Alpha | Numeric, text, and boolean ARRAY[...] literals preserve typed elements, including signed and unsigned 8/16/32/64-bit integers, Float32, and microsecond/nanosecond TIME; SEQUENCE builds bounded BIGINT ranges with inferred or explicit direction; ZIP builds typed row arrays and pads shorter inputs with NULL; ARRAY_FIRST and ARRAY_LAST return typed elements or NULL for empty/NULL arrays; FLATTEN concatenates nested typed arrays and preserves outer NULLs; TRIM_ARRAY removes a validated non-negative suffix count; ARRAY_REPEAT repeats typed numeric, text, boolean, date, and time scalars with a bounded non-negative count and preserves NULL elements; ARRAY_UNION, ARRAY_INTERSECT, and ARRAY_EXCEPT deduplicate typed values with Trino-compatible NULL equality and preserve list offsets; ARRAY_CONCAT accepts two or more matching typed lists; CARDINALITY over arrays and maps, CONTAINS, ARRAYS_OVERLAP, ARRAY_POSITION, ARRAY_JOIN, ARRAY_APPEND, ARRAY_PREPEND, ARRAY_REMOVE, ARRAY_DISTINCT, ARRAY_SORT, ARRAY_REVERSE, positive and negative-stride array slices, and one-based/negative ELEMENT_AT over numeric, text, and boolean lists/maps; ARRAY_HISTOGRAM preserves integer, floating-point, decimal, date, timezone-less timestamp, boolean, and UTF-8 key types with deterministic ordering and null-element omission; 64-bit-offset lists are normalized for the supported scalar functions when their offsets fit the 32-bit execution representation; date, decimal, and second/millisecond/microsecond/nanosecond timestamp arrays preserve their element types with qualified CARDINALITY/ARRAY_POSITION coverage; broader element types and function combinations remain open |
| Literals against columns | Alpha | Integer literals push down to narrow integer and Date32 columns; integer and decimal literals meet double columns; text literals against Date32 columns are coerced on every reader |
SUM(DISTINCT), AVG(DISTINCT) |
Alpha | Exact mergeable distinct state |
APPROX_COUNT_DISTINCT (APPROX_DISTINCT), APPROX_PERCENTILE |
Alpha | Sketch-answered estimates with the error stated on the query record; from the table's statistics without a scan when they carry sketches at the pinned version, else computed over the rows. See Approximate aggregates |
JSON_ARRAY_CONTAINS(json_array, value) supports boolean, integer,
floating-point, and text needles. It preserves NULL inputs, returns NULL for
malformed JSON, and returns false for valid non-array JSON values.
JSON_ARRAY(...) constructs a JSON array from scalar arguments and preserves
SQL NULL arguments as JSON null; its bounded ABSENT ON NULL form omits
NULL elements. JSON_OBJECT(key : value, ...) (or the
equivalent key VALUE value form) constructs an object from scalar pairs; the
bounded surface also accepts comma-separated key/value pairs, preserves SQL
NULL values as JSON null, supports ABSENT ON NULL, and rejects null or
duplicate keys. JSON_PARSE validates a text document,
JSON_FORMAT emits canonical JSON,
and JSON_QUERY/JSON_EXTRACT preserve object and array results. Their paths
support dotted keys, quoted bracket keys, numeric array indexes, and array
wildcards ([*]); a wildcard result is collected as a JSON array. JSON_VALUE
and JSON_EXTRACT_SCALAR return only scalar values and therefore return NULL
for object, array, or wildcard-array results. JSON_EXISTS reports whether a
supported path resolves, including a path that resolves to JSON null. Full
SQL/JSON coercion, error/empty clauses, recursive descent, and the broader
Trino path grammar remain outside the qualified surface.
Two aggregates answer with an estimate from a mergeable sketch, and say
so: every query record whose result includes one carries
execution.approximate, a list of {function, argument, sketch, error, error_kind}. Exact COUNT(DISTINCT) and every other function are
unchanged; nothing is approximated unless the statement writes an
APPROX_* function or sets approximate = true.
| Function | Result | Sketch | Error stated |
|---|---|---|---|
APPROX_COUNT_DISTINCT(col) — APPROX_DISTINCT(col) is Trino's name for the same function |
BIGINT (UInt64): the estimated number of distinct non-null values |
HyperLogLog, p = 12 (4 096 six-bit registers; the DLM's register layout and PostgreSQL's hash_bytes_extended over the value's canonical text, so a sketch built here merges with a stored one) |
error_kind: relative_standard_error, 1.04 / √4096 = 1.6 % of the true count (one standard error) |
APPROX_PERCENTILE(col, p) |
DOUBLE: the value at fraction p of the column's distribution |
KLL, k = 200 | error_kind: rank_error, 2.446 / k^0.9433 = 1.65 %: the value returned has a true rank within this of p, with about 99 % confidence |
APPROX_PERCENTILE(col, ARRAY[p, …]) |
List(Float64): one value per fraction, in the order written (a JSON array inline; an Arrow list on a page) |
KLL, k = 200 | As above, per value |
APPROX_COUNT_DISTINCT_STATE(col) |
VARCHAR: the HyperLogLog sketch itself — its compact bytes, base64, the encoding the statistics document stores — so a client merges it with others (register-wise maximum; merges are exact, whatever the partitioning) |
HyperLogLog, p = 12 | None: the state is exact; its estimate carries the error above |
COLUMN_STATISTICS(col) |
VARCHAR: the column's read profile over the rows aggregated as JSON — nulls, min, max (exact), distinct (HyperLogLog, base64), quantiles (KLL, base64; null for booleans and text) — what ANALYZE … WITH (sketches = true) records per column, over any group |
HyperLogLog p = 12, KLL k = 200 | None: the profile is the state |
colis a column reference (*is refused).APPROX_COUNT_DISTINCT,APPROX_COUNT_DISTINCT_STATEandCOLUMN_STATISTICStake any sketchable type — booleans, integers, floats, decimals, text, dates, timestamps, and dictionaries over them;APPROX_PERCENTILEtakes integers, floats and decimals (dates and timestamps are refused). The two state-returning functions are whatANALYZEruns on the workers; their results are not estimates, so the record'sexecution.approximatedoes not list them. The fractions are numeric constants in[0, 1];DISTINCTinside anAPPROX_*call is refused. Over no non-null values the count is0and a percentile is null.- From statistics. An ungrouped statement over one table with no
predicate whose statistics are current for the statement's pinned
source version and carry the column's sketch (
ANALYZE … WITH (sketches = true)) answers with no scan:execution.mode = "context",execution.detail = "statistics at <version> (hyperloglog p=12, kll k=200)". WhenANALYZE … WITH (distinct = true | columns = …)counted the column exactly, the exact count answers and the note readssketch: "exact count", error: 0. Statistics for another version, a predicate, a grouping, a join, or a missing sketch take the computed path; the statistics object holds one sketch per column for the whole table, so a grouped or filtered statement is never answered from it. - Computed. Otherwise the aggregate builds its sketch over the scanned rows — a partial sketch per worker thread, merged on the final stage through the same encoded partial state every aggregate uses, memory accounted like any other state — and returns the estimate. HyperLogLog registers merge exactly, so a distinct count is the same on every execution path; a KLL sketch merged from partials compacts differently from one built in sequence, so a percentile agrees across paths within its rank error (the differential sweep compares approximate results within a tolerance rather than as text).
approximate = true(settings.approximateorSET SESSION approximate = true) lets the planner answer a plainCOUNT(DISTINCT col)from a HyperLogLog sketch exactly asAPPROX_COUNT_DISTINCTwould, under COUNT's output name; the record's note names the function as written (COUNT). Off by default.use_statistics = falsestands every answer from statistics aside:APPROX_*computes over the rows andCOUNT(*)/MIN/MAXscan;execution.detailends withstatistics bypassedwhen the statistics would have answered. File skipping by the statistics' bounds still applies.
- Correlated subqueries beyond one or two equalities: a correlated non-equality
(TPC-H Q21's
l2.l_suppkey <> l1.l_suppkey),LIMIT/set operations inside a correlated subquery,EXISTScorrelated on more than one column, or multi-key correlatedIN; each is refused by name. - Residual outer joins are supported for the qualified local and distributed
shapes described above; unqualified outer join forms outside that binder
surface, recursive CTEs, ordered map and JSON comparison remain unsupported.
Column-key
GROUPING SETS,CUBE, andROLLUP(including the grand-totalGROUPING SETS (())form) lower to typedUNION ALLaggregate branches; grouping metadataGROUPING(column)andGROUPING_ID(...)are materialized for those expanded branches. Expansion is bounded at 4,096 aggregate branches so a query cannot construct an unbounded UNION plan; CUBE expansions with 16 or more keys remain unsupported and are rejected explicitly rather than silently treated as a plainGROUP BY; typed numeric, text, and booleanARRAY[...]literals supportCARDINALITY,CONTAINS,ARRAY_POSITION,ARRAY_DISTINCT,ARRAY_SORT,ARRAY_REVERSE,ELEMENT_AT, and positive or negative-stride slices; date, timestamp, and decimal arrays are currently qualified for selected scalar operations, andARRAY_CONCAT,ARRAY_APPEND,ARRAY_PREPEND, andARRAY_REMOVEpreserve nested list, row, and map elements; broader array element types and function combinations remain open; approximate aggregates beyondAPPROX_COUNT_DISTINCTandAPPROX_PERCENTILE—APPROX_MOST_FREQUENThas no heavy-hitter sketch in the statistics object yet. - Table-creating DDL and row DML:
CREATE TABLE AS,INSERT,UPDATE,DELETE,ALTER TABLE ADD/DROP COLUMN. Catalog DDL registers tables that already exist in storage. The separate product transaction API accepts a bounded, revisioned metadata-record DML subset; it is not arbitrary OLTP SQL. - Scalar optimizer statistics beyond row count. Native
ANALYZEpersists the exact row count and an immutable statistics document, but histogram/selectivity planning is not yet implemented. - Dynamic filtering beyond the qualified scan paths. Build-side keys are propagated for supported single-key and composite-key joins into Parquet, Delta, Iceberg, and object-store readers before decode; exact-result local and distributed regressions cover those paths. A representative cloud dataset with measurable file or row-group pruning, broader type/exchange coverage, and cross-coordinator snapshot qualification remain open.
DATE_DIFFis supported for fixed units from nanoseconds through weeks and for calendar month, quarter, and year boundaries over DATE and all supported timestamp units. Month-family differences count complete calendar boundaries and preserve the sign for reverse ranges.
The Engine exposes an authenticated transaction API at /v1/transaction.
This is a deliberately bounded product-metadata contract, not a PostgreSQL
server or a general row-store protocol.
| Existing operation | Behavior |
|---|---|
BEGIN |
Creates an owner-isolated transaction session against the current product snapshot |
INSERT |
One or more explicit (id, document_json) records into a supported kaveon.product family; all rows stage under one transaction commit |
UPDATE |
Revision-checked replacement of one product document; id and revision are required in WHERE |
DELETE |
Revision-checked deletion of one product document; id and revision are required in WHERE |
COMMIT |
Publishes a prepared immutable catalog snapshot through the configured product store |
ROLLBACK |
Discards the session without publishing its staged changes |
Each request carries one statement and a transaction ID after BEGIN. Product
operations are authenticated, owner-isolated, revision-checked, and limited to
the supported product families. Multi-row VALUES are expanded into bounded
typed commands and committed atomically. INSERT ... SELECT,
RETURNING, ON CONFLICT, savepoints, transaction modifiers, arbitrary user
tables, and lake-table DML are rejected explicitly. Statement execution and the
authenticated product transaction endpoint accept typed positional ($1, ?)
and named (:name) scalar or JSON-array parameters through the HTTP API; values
are bound before parsing/planning and are never interpolated into SQL. Missing
or extra positional and named values fail before execution. Nested arrays and
null array elements lower to typed
ARRAY[...] expressions; JSON objects with string keys lower to typed MAP
values (duplicate keys and malformed values are rejected before planning).
The Trino adapter also accepts scalar and ARRAY[...] EXECUTE name USING
values carried by
X-Trino-Prepared-Statement, including validated DATE 'YYYY-MM-DD' literals
that remain text until the target column's Date32 coercion. Compound values
are still limited to the supported array forms. The raw Trino statement route
also accepts owner-scoped SQL PREPARE name FROM ..., EXECUTE name, and
DEALLOCATE PREPARE name; prepared SQL still passes through the normal parser
and typed binder. SHOW SESSION on that route returns the Engine's supported
session settings (query_memory_limit_bytes, admission_wait_seconds,
result_cache, approximate, and use_statistics) in Trino's tabular
metadata shape. SHOW SESSION LIKE 'pattern' applies the same wildcard
filtering to session settings. SHOW FUNCTIONS and SHOW FUNCTIONS LIKE 'pattern' return
the Engine's supported scalar and aggregate function metadata in Trino's
standard six-column shape. Compound values beyond arrays,
timestamps, intervals, and the complete prepare/describe/bind wire lifecycle
remain explicitly unsupported. EXECUTE IMMEDIATE 'sql' USING ... is supported
for a quoted SQL literal with the same typed binder. USE catalog.schema and
USE schema emit Trino's session-update response headers.
The current product transaction contract
does not provide PostgreSQL MVCC isolation, row-level indexes, foreign-key
enforcement, or crash-recovery parity.
The native CLI provides metadata commands over the Engine HTTP API:
SHOW CATALOGS, SHOW SCHEMAS [IN catalog], SHOW TABLES [IN schema],
SHOW COLUMNS FROM table, DESCRIBE table, USE [catalog.]schema, and
single-quoted LIKE filters. These commands resolve catalog definitions and
are not emulations of PostgreSQL's pg_catalog or information_schema.
The coordinator answers the same SHOW and DESCRIBE statements on
POST /v1/statement, and kaveon catalog|schema|table … submits the catalog
DDL from the command line (CLI guide).
The CLI currently has no PostgreSQL wire-protocol, JDBC, or ODBC compatibility
claim.
Every metadata statement is answered for the session's identity against
the catalogs it was granted (catalog access):
SHOW CATALOGS lists granted catalogs; SHOW SCHEMAS, SHOW TABLES,
DESCRIBE, SHOW CREATE TABLE, SHOW STATS FOR and DESCRIBE DETAIL
on an ungranted catalog answer catalog 'x' not found, the same text
and code as for a catalog that does not exist; a table reference in a
query fails at bind the same way. There is no information_schema in the
Engine today; when one is added it is subject to the same projection —
it lists what the caller may see, never an administrator's view of hidden
objects.
Unsupported syntax should be treated as unsupported even if the upstream SQL parser accepts it. The executable contract is the intersection of parsing, logical planning, and physical operator construction.
POST /v1/statement returns synchronously and materializes the root result before JSON serialization unless the client requests paged delivery. A statement is admitted through the memory admission queue, bound against the catalog, and, where the stage planner can express the shape, run as dependency-gated stages with versioned worker fragments and streamed Arrow IPC exchanges; otherwise the coordinator runs it and records why (execution.detail). A statement whose normalized text, catalog snapshot, pinned Delta versions and time zone match a cached result is served from the coordinator's result cache unless the request sets settings.result_cache = false. Query IDs identify retained records; cancellation removes a queued statement or propagates to active worker tasks; history remains process-local. Native ANALYZE returns the qualified table and exact row count; capability discovery reports it only when the coordinator has a durable product-catalog authority configured. Coverage records: ../qualification/tpch/coverage.md (21 of 22) and ../qualification/clickbench-2026-09-16.md.
The result cache is an analytical execution cache, not the source of truth for product state. It stores complete finished coordinator results with bounded byte, TTL, and LRU eviction; paged responses are not cached, workers do not retain a second result copy, and administrators can clear it. KaveonDB transaction commits and replays invalidate affected analytical entries, while revision/CAS state remains authoritative. Repeated analytical reads are faster without allowing a stale result to change transactional visibility or commit semantics.
See Architecture, HTTP API, and Operations and troubleshooting.