Skip to content
OnchainQueries

OQ — Q00 · Query engine

OnchainQueries accepts OnchainQL over typed Solana tables, translates the forms it can execute safely, and refuses the ones whose namesakes behave differently. A query that runs is a query whose semantics were checked — not one that happened to parse.

Engine classes
3
Explicit translations
11
Parameter types
13
Result expiry
24h
OQ — Q01Read-only by construction

Every request must be exactly one query beginning with SELECT or WITH. Data modification, schema changes, session configuration, system tables and external table functions are rejected before a source query is ever issued.

One statement

exactly one SQL statement

Multiple statements and misplaced semicolons are refused. There is no batch mode, so there is no ambiguity about what ran.

No writes, ever

INSERT · UPDATE · DROP

Data and schema modification, grants and administrative statements are all rejected. The source database is never mutated.

No escape hatches

s3 · url · file · remote

External table functions and the execution layer's internal tables are unavailable, as are user-controlled FORMAT and SETTINGS.

OQ — Q02Sizing

OnchainQueries reads the shape of your query and gives it the resources it needs. A filtered lookup gets a small share and returns fast; a windowed join over a CTE gets the room and the hours to finish. There is no dial to tune and no capacity to plan.

SmallFiltered read
Chosen when your query has
A filtered read with no grouping or ordering
Execution limit
2 minutes
Suited to
Filtered lookups and simple scans
MediumGrouped aggregate
Chosen when your query has
GROUP BY, ORDER BY, or a long statement
Execution limit
30 minutes
Suited to
Grouping, ordering and moderate analytics
LargeWindow over a CTE
Chosen when your query has
A join, a window function, or UNNEST
Execution limit
6 hours
Suited to
Joins, windows, unnesting and heavy analytics
OQ — Q03Compatibility

OnchainQL rewrites these forms explicitly. Other function names pass through untranslated — which is not the same as being supported, and the docs say so.

Explicit translations11 forms
  • date_truncdateTrunc
  • count_ifcountIf
  • approx_percentilequantileTDigest
  • from_base58 / to_base58base58Decode / base58Encode
  • json_extractJSON_QUERY
  • json_extract_scalarJSON_VALUE
  • CAST(x AS VARBINARY)CAST(x AS String)
  • UNNESTARRAY JOIN
Deliberately refusednot compatibility-safe

These have same-named functions underneath with different semantics. OnchainQueries fails loudly rather than returning a different number than you expect.

  • element_at
  • filter
  • reduce
  • transform
  • zip_with
  • map
  • map_filter
  • map_transform_keys
  • map_transform_values
  • json_parse
  • json_array_length
OQ — Q04Consistency

OnchainQueries records the catalog hash and high-watermark slot used to plan a query, then fingerprints source partitions before and after execution. If anything relevant changed mid-flight, it retries rather than publishing a mixed result.

manifest.json (excerpt)
{  "state": "complete",  "selected_engine": "medium",  "row_count": 128441,  "source_coverage": {    "tables": ["prod_solana_eventstream.pump_fun_trade_event"]  },  "catalog_hash": "9f2c...a41e",  "high_watermark_slot": 372140688,  "parts": [    { "name": "part-00000.parquet", "bytes": 6488064, "sha256": "..." }  ],  "expires_at": "2026-08-29T09:14:22Z"}

The manifest is written last, so a directory containing it is a complete result. Every part is checksummed before it gets its final name, and rerunning against the same directory reuses parts that already match.

source_coverage.tables is the honest answer to “what did this number actually come from”. Read it whenever coverage matters.

OQ — Q05Questions

Can I bring a query over from another SQL platform?

For the core analytical surface, usually. If you know analytical SQL you already know OnchainQL. Higher-order array functions, map constructors, ASOF JOIN, MATCH_RECOGNIZE, PIVOT, recursive CTEs and LATERAL are not implemented and will fail explicitly. Port incrementally and add features one at a time.

Why refuse a function instead of just running it?

Because element_at, filter, reduce, map and friends all exist underneath with different semantics. Running them would produce a number that looks right and is wrong. An explicit error costs you five minutes; a silently different result costs you the analysis.

Can I use SHOW TABLES or DESCRIBE?

Not currently. There is no catalog browser in the CLI. Use the dataset pages here, or ask the service operator for the table list and schemas. Only tables in the live catalog are queryable, and unknown names fail before a source query is issued.

How large can a query be?

Submit requests, including SQL and parameter JSON, are limited to 2 MiB. Execution is bounded by the engine class: 2 minutes on small, 30 minutes on medium, 6 hours on large.

The SQL contract, the translation table and every error shape are documented in full.