Skip to main content
Version: 0.3

Syntax

This page describes the grammar rules for composing ROSQL queries. For individual clause details, see Command Reference. For practical recipes, see Cookbook.


Query forms

ROSQL has three top-level query shapes:

Standard form

SQL-like. Clauses can appear in any order (the parser is order-independent).

SELECT AVG(duration) FROM traces
WHERE status = 'ERROR'
SINCE 1 hour ago
FACET robot_id
ORDER BY avg_dur DESC
LIMIT 10

Pipeline form

Pipe-separated stages, processed left-to-right. FROM must be the first stage. Each stage is introduced by its keyword.

FROM traces
| WHERE status = 'ERROR'
| SELECT AVG(duration)
| SINCE 1 hour ago
| FACET robot_id
| ORDER BY avg_dur DESC
| LIMIT 10

Standard and pipeline forms produce identical results — they are two ways to write the same query.

Compound form

Self-contained commands with fixed structure. These are ROSQL-specific and do not follow the SELECT/FROM pattern.

TRACE 'a3f1c9d2'
HEALTH() FOR ROBOT 'robot_42'
SHOW SPAN SUMMARY SINCE 1 hour ago

Clause composition

Every clause is optional except FROM in standard/pipeline form. Clauses compose freely — multiple FOR clauses AND together.

ClauseRequired?StandardPipelineNotes
FROMYesFirst stageData source
SELECTNoDefault: all fields
WHERENoRow filter; stacks in pipeline
FORNoScope (robot/fleet/version/env/session); composable
SINCE / BETWEENNoTime range
USINGNoClock basis (ROS_TIME / WALL_TIME)
FACETNoGroup by dimension
ORDER BYNoSort
LIMIT / OFFSETNoPagination
TIMESERIESNoTime-bucketed aggregation
COMPARE TONoBaseline comparison
DURING()NoTemporal correlation subquery
FORMATNoOverride output format

Data sources

SourceUnderlying tableNotes
tracesotel_traces
logsotel_logs
metricsotel_metrics
topicstopic_messages
recordingsmcap_metadata
odomtopic_messagesalias — filters topic_name = '/odom'
joint_statestopic_messagesalias — filters topic_name = '/joint_states'
batterytopic_messagesalias — filters topic_name = '/battery_state'
cmd_veltopic_messagesalias — filters topic_name = '/cmd_vel'
imutopic_messagesalias — filters topic_name = '/imu/data'

Custom topic aliases can also be defined in your schema profile.


Expressions

Expressions appear in SELECT lists, WHERE conditions, and aggregation arguments.

KindSyntaxExample
Bare fieldidentifierduration, status, robot_id
Dotted patha.bros.node
Map / JSON accessfield['key']fields['http.method']
Array-indexedfield['name[n]']fields['position[0]']
Integer literalbare number100, -3
Float literaldecimal3.14, -0.5
String literalsingle-quoted'ERROR', '/navigate_to_pose'
BooleankeywordTRUE, FALSE
NullkeywordNULL
Unit valuenumber + unit suffix500 ms, 2 m, 45 deg
Arithmetica + b, a - b, a * b, a / bduration / 1000000
Aggregation callFN(expr)AVG(duration), COUNT(*)
Aliasexpr AS nameAVG(duration) AS avg_dur

Unit values are automatically normalized to SI base units at parse time (e.g., 500 ms becomes 500000000 nanoseconds internally). See Physical units.


Operators and precedence

Comparison

= != < > <= >=

Logical

Evaluated in this order (highest to lowest precedence):

  1. NOT
  2. AND
  3. OR

Use parentheses to override:

-- AND binds tighter than OR, so these are equivalent:
WHERE a = 1 AND b = 2 OR c = 3
WHERE (a = 1 AND b = 2) OR c = 3

-- Use parens to change grouping:
WHERE a = 1 AND (b = 2 OR c = 3)

Special predicates

OperatorExample
IN (...)WHERE status IN ('ERROR', 'TIMEOUT')
LIKE '...'WHERE action_name LIKE '/nav%'
BETWEEN ... AND ...WHERE duration BETWEEN 100 ms AND 2 s
IS NULLWHERE parent_span_id IS NULL
IS NOT NULLWHERE error_message IS NOT NULL

Arithmetic

+, -, *, / are all evaluated at the same precedence level, left-to-right. Use parentheses to enforce order.


Quoting rules

UseQuote styleExample
String valuesSingle quotes '...''robot_42', 'ERROR'
Identifiers (fields, sources)No quotesduration, traces

ROSQL does not support double quotes or backticks. String literals cannot contain embedded single quotes.


Time expressions

Time expressions are used with SINCE, BETWEEN, and lifecycle anchors.

Relative

SINCE 30 minutes ago
SINCE 1 hour ago
SINCE 7 days ago
SINCE yesterday

Supported units: nanoseconds, microseconds, milliseconds, seconds, minutes, hours, days, weeks and their SI abbreviations (ns, us, ms, s, min, h).

Absolute (ISO 8601)

SINCE '2026-03-25T00:00:00Z'
BETWEEN '2026-03-01T00:00:00Z' AND '2026-04-01T00:00:00Z'

Unix epoch

Bare integers are auto-detected by digit count: 10 digits = seconds, 13 = milliseconds, 19 = nanoseconds.

Lifecycle anchors

SINCE last deployment
SINCE last robot restart
SINCE last action failure
SINCE last topic drop
SINCE last diagnostic warning

Time basis

Append USING ROS_TIME or USING WALL_TIME to select which clock to use. Default is wall time.

FROM topics WHERE topic_name = '/odom' SINCE 1 hour ago USING ROS_TIME

Physical units

A numeric literal followed by a unit suffix is a unit value. The parser normalizes it to the SI base unit at parse time — the stored value is always in SI, so comparisons work across unit systems.

WHERE duration > 500 ms    -- parsed as: duration > 500000000 (nanoseconds)
WHERE distance < 2 km -- parsed as: distance < 2000 (meters)
WHERE angle < 45 deg -- parsed as: angle < 0.785398 (radians)

Supported unit categories:

CategoryUnitsSI base
Timens us ms s min h dayss
Distancemm cm m km in ft mi nmim
Velocitymm/s cm/s m/s km/h mph knotsm/s
Angledeg rad mrad °rad
Angular velocityrad/s deg/s rpmrad/s
FrequencyHz kHzHz
ElectricalmV V kV mA A mW W kWV / A / W
Temperature°C °F KK
MemoryB KB MB GBB
BandwidthB/s KB/s MB/s GB/sB/s
PressurePa kPa MPa bar psiPa
Force / TorqueN kN Nm lb-ftN / Nm
Geographiclat lon lng(dimensionless)

Pipeline equivalence

Standard and pipeline forms compile to the same AST. Use whichever reads more naturally for your use case.

-- Standard form
SELECT AVG(duration) AS avg_dur FROM traces
WHERE status = 'ERROR'
FOR ROBOT 'scout_1'
SINCE 1 hour ago
FACET action_name
ORDER BY avg_dur DESC
LIMIT 5

-- Pipeline form (identical result)
FROM traces
| WHERE status = 'ERROR'
| FOR ROBOT 'scout_1'
| SINCE 1 hour ago
| SELECT AVG(duration) AS avg_dur
| FACET action_name
| ORDER BY avg_dur DESC
| LIMIT 5

Comments

Single-line comments only. Use -- through the end of the line. Block comments are not supported.

-- Find slow navigation actions in the last hour
FROM traces
WHERE action_name = '/navigate_to_pose' -- ROS2 Nav2 action
AND duration > 2 s
SINCE 1 hour ago

Case sensitivity

ElementCase-sensitive?
Keywords (SELECT, FROM, WHERE, …)No
Data source names (traces, logs, …)No
String values ('ERROR', 'robot_1', …)Yes
Field names (duration, robot_id, …)Yes

Read-only language

ROSQL is strictly read-only. Mutation keywords are rejected at parse time:

KeywordError
INSERT, UPDATE, DELETE, DROP, CREATEMutationRejected
ALERT, DEFINE, SLO, WHENReservedSyntax (planned features)