Query and results
What those options do
The controls live in the card above, beside the query they affect. This is the explanation, and the resolved shape the engine is actually running with.
Resolved options
Note temporal.dateFormat: it is flat going in and nested
coming out, which is the kind of thing a demo gets wrong quietly.
Date inspector
Two public functions, run live. detectTemporalFormat asks
does this match one of the built-in ISO shapes;
resolveTemporal asks
does it resolve to a real instant — and it also applies any
dateFormat you declare, which detect never
sees. So the two disagree in both directions, and each disagreement
means something different:
- ISO-shaped, resolves — an ordinary date.
-
ISO-shaped, does not resolve —
2021-02-29. This is the gap the whole design rests on: siftql refuses the query rather than falling back to comparing it as text, wherenew Date()would hand you 1 March. -
Not ISO-shaped, resolves —
01-06-2020once you pick a layout below. Declared layouts live insideresolveTemporal, sodetectreturnsnullfor them. Change the layout and watch that row's answer move between June and January. - Neither — not a date under any rule currently in force.
AST
The AST is a documented public contract and pure JSON — no RegExp, no
Date, no functions — so it survives structuredClone, a
cache key, or a worker boundary.
serialize(parse(query))
JSON round trip
Tree (locations stripped)
Regex race
^(a+)+$ against "a".repeat(n) + "!" — the
classic catastrophic pattern. siftql matches it on a linear-time
automaton. The native RegExp runs in a Web Worker with a
hard timeout, because otherwise it would freeze this tab and you would
never see the result.
Data
Editable. One caveat worth stating plainly: the seed is built in
JavaScript so that
created can hold an ISO string, epoch milliseconds and a
real Date across different rows. JSON cannot express the
third, so anything you paste here loses Date objects —
the ISO strings and epoch numbers still behave identically.
Self-test
Every worked example re-run against the data currently loaded, and
compared with the result recorded in presets.js. This is
what stops a caption from quietly becoming untrue after the dataset is
edited.