Omnigraph
Queries & search

Engine catalogue

The engine describes itself in GQ. Five built-in node types, spelled with

The engine describes itself in GQ. Five built-in node types, spelled with the @ prefix that already marks engine-owned metadata ($p.@id, $e.@type), hold the registries the running binary executes with: its physical operators, its planner passes, its session settings, its storage format and its logical plan kinds. The rows are derived from those registries at query time, so the list a reader sees is the list the engine runs on. Nothing is stored; a user schema cannot declare an @ type.

query operators() {
  match { $o: @Operator }
  return { $o.name, $o.inputs }
}

The declarations, one per type, are in catalogue.gq; ordinary schema show prints only the graph's reusable schema source; --json includes the built-in declarations in the separate catalogue_source field.

Where to run it

ScopeCommand
local binary, without a store or credentialsomnigraph catalogue -e '<gq>' --json
beside a graph's own typesomnigraph query --target <uri> -e '<gq>'
servedomnigraph query --target <name> --graph og_catalog -e '<gq>'

og_catalog is a reserved scope the binary serves without opening a store: no branch, no snapshot, no graph commit in the answer, and --branch or --snapshot is refused. The local catalogue command accepts -e '<gq>' or --query <file> and optional --json. It does not read operator configuration, including an explicit --operator-config, or access credentials or storage. It uses the binary's default table presentation unless --json is supplied. It accepts no target, profile, authentication profile, actor, graph, branch or snapshot selector. Operator version 1 has no catalogue target kind or magic --target og_catalog selector. Local ./og_catalog and file:// paths remain ordinary store addresses. The prefix og_ is reserved for system graph ids: a deployment cannot create a graph named og_….

Inside a graph scope the catalogue types sit beside the user types, so one query joins them:

query jobs_naming_no_operator() {
  match {
    $j: Job
    not { $o: @Operator $o.name = $j.uses }
  }
  return { $j.name }
}

A served read of og_catalog is authorized like a graph read: the policy bound to graph.og_catalog in cluster.yaml decides, with the resource og_catalog and no branch; without a bound policy the ordinary no-policy rules apply (static tokens may read, signed data credentials need a permit). See Authorization and actors.

What is refused

  • insert, update, delete and load targeting an @ type: the rows are the engine's.
  • search, fuzzy, match_text, bm25, nearest and rrf over a catalogue binding: catalogue rows have no index. Scalar predicates, projection, aggregation, ordering, limits and joins work as on any type.
  • Under og_catalog: any stored type, any write, blob, branch, commit, snapshot, export, change feed or stored query.

explain names the source: a catalogue scan reports source: catalogue, reads access sequential, is never counted from a manifest and never hydrated by row address.

The five types

@Operator: one row per distinct physical operator name the plan runner executes; inputs lists every number of children the operator admits. Two plan node kinds that report one name (Limit and Page both report Page) share one row. Scan admits [0, 1]: a table scan has no input, a dependent id lookup has one.

@Pass: one row per planner pass, position its place in the order explain reports passes. A run fires a subsequence of this order; the two scan-finalization passes key_to_id and scan_access come last.

@Setting: one row per session setting: kind spells the legal values (enum(…), integer(min..), integer(min..=max), text), default the value show reports before any set, scope whether any caller (request) or only the hosting process (process) may set it. The descriptive text of each setting stays in Session settings.

@Engine: the one row describing the binary: version is its release version, current_internal_schema_version the storage format it writes, min_supported_internal_schema_version the oldest stored format it still serves. A graph's own stored stamp is in omnigraph snapshot, not here.

@LogicalKind: one row per logical plan node kind with its routing coverage: routable or refused_by_name. Coverage governs change-feed and merge routing only. Read and load plans have their own admission checks.

Inventories

Generated from a built CLI with python3 scripts/check-catalogue-docs.py --binary target/debug/omnigraph --write; the same script without --write fails when these tables drift from the binary's rows.

nameinputs
Aggregate[1]
AntiJoin[2]
ClassifyThreeWay[1]
ContainsJoin[2]
CrossJoin[2]
CsvSource[0]
Expand[1]
Filter[1]
FragmentWrite[1]
HashJoin[2]
HydrateByAddress[1]
HydrateColumns[1]
MetadataCount[0]
OuterReference[0]
Page[1]
Projection[1]
RankFuse[2]
RowCompare[1]
Scan[0, 1]
Sort[1]
SortMergeJoin[2]
Validate[1]
positionname
0resolve
1predicate_pushdown
2aggregate_pushdown
3projection_pushdown
4fragment_scope
5address_short_circuit
6late_materialization
7join_algorithm
8expand_mode
9access_path
10anti_join_strategy
11key_to_id
12scan_access
namekinddefaultscope
ann_nprobesinteger(0..)20request
engineenum(v2)v2request
explain_dump_dirtextprocess
history_release_bytesinteger(1024..=262144)262144request
load_source_max_bytesinteger(1..)33554432request
merge_lineageenum(off, on, verify)onrequest
query_memory_bytesinteger(1..)157286400request
rrf_planenum(auto, force_prefilter, force_postfilter)autoprocess
stage_write_concurrencyinteger(1..=64)8process
traversal_work_limitinteger(1..=9223372036854775807)1000000request
write_max_bytesinteger(1..)33554432request
namecoverage
Aggregaterefused_by_name
AntiJoinrefused_by_name
CsvSourcerefused_by_name
Expandrefused_by_name
Filterroutable
FragmentWriterefused_by_name
Joinroutable
Limitroutable
MergeClassifyroutable
MetadataCountrefused_by_name
Nearestrefused_by_name
OuterReferencerefused_by_name
Projectionroutable
RankFuserefused_by_name
RowDiffroutable
Sortroutable
TableScanroutable
TextSearchrefused_by_name
Validaterefused_by_name

On this page