Repository navigation
v0.6.2
ChalkQL v0.6.2
A patch release with two fixes found by a new sample, and the sample itself: a live trade blotter that reads PostgreSQL live, lays a bounded tail of streamed rows over each page, and keeps its filters and alerts as standing views. A DateTime too far in the future for a nanosecond timestamp is now refused rather than wrapped into the past, and text compared with a number it cannot be read as is refused as the statement's mistake rather than reported as the planner's.
Targets .NET 10. A JDK 21 or newer is needed only to run the planner locally. Assemblies and namespaces retain the Chalk.* names.
NuGet packages:
POCO timestamps past 2262 are refused
A DateTime member of a POCO table maps to TIMESTAMP(9) by default: a 64-bit count of nanoseconds since 1970, which reaches 1677-09-21 to 2262-04-11. The conversion multiplied ticks by 100 without a check, so a later instant wrapped silently. 9999-12-31, a common "never", was stored as 1816-03-29, and every comparison with it was wrong: until > TIMESTAMP '2030-01-01' matched none of them.
- The POCO source refuses such an instant where the table is built or refreshed, naming the table and member, and saying to declare it
[ChalkColumn(Precision = 6)]. Microseconds reach any instant aDateTimeholds. ClrStorage.UnitsOfrefuses it too, so nothing that converts a tick count to a nanosecond lane wraps. The engine's lane codec already refused it.
Text beside a number is the statement's mistake
qty = 'x', where qty is a DOUBLE, failed with "Planner internal error … AssertionError: cannot convert CHAR literal to class java.lang.Double", coded Internal. The assertion was the planner's own: its selectivity estimate asked Calcite for the text as the column's type.
- Text a number cannot read is refused while the statement is validated, at the text, with its position: "the text 'x' cannot be read as a DOUBLE, which qty is: compare qty with a number, such as 1.5, or with text that reads as one", coded
SqlValidation. The same holds for<>,<,<=,>,>=,IN,NOT INandBETWEEN, either side, and for whole numbers:'1.5'cannot be aBIGINT. Text that reads as the number,qty = '1.5', is a number written in quotes and stands. - Text beside a date or a time is read by ChalkQL's cast when the statement runs, which reads more than Calcite's literals do.
ts = '2026-01-08 12:00:00+02:00'failed with the same internal error before and now runs; as before, a cast toTIMESTAMPkeeps the wall-clock time and leaves the offset. Text the cast cannot read fails there, naming it. - Wherever Calcite cannot read a text literal, the planner refuses it as a validation error rather than an internal one, and the estimate falls back to its default guess.
A virtual blotter sample
dotnet/samples/Chalk.Sample.Blotter is a trade blotter in Blazor Server and QuickGrid over millions of client orders and fills in PostgreSQL, which it starts and seeds itself or takes from a connection string.
- Bolted on. It expects no watermark of the source: it reads
orders_currentlive, keeps what the streams send until the database is seen to hold it, and lays that tail over each page, each order once at its newest version. One gap fill, after a haircut for what is in transit when it subscribes, covers what was sent before. - ChalkQL holds the live part. Each tab and filter in use is a standing view over the tail. Alerts are conditions in SQL, with a CodeMirror editor that completes and checks them through ChalkQL, kept as incremental views over the host's tables: as rows arrive, once the database is too far behind them, or on how many match in a sliding window, at least so many or none.
- One small budget. The tail, the views and recent reads are held to one memory budget, 8 MB to start, stepped up to 16, 32 and 64 MB rather than refuse when no budget is chosen.
- Traffic shaping. On a slow link the grid keeps pace with the browser.
- Tested against an oracle. Pages read while the market runs keep their invariants, and pages held still match PostgreSQL's own answer row for row. Every rule a clock decides is tested at its boundary on a fake clock.
The sample's alert sounds are not part of ChalkQL and not under its licence; they may not be used commercially (wwwroot/sounds/NOTICE.md).
Changed
- A POCO
DateTimepast 2262 at the default precision is refused where it used to be stored as a wrong instant. Declare such a member[ChalkColumn(Precision = 6)]. - Text a number cannot read is a
SqlValidationerror, where it wasInternal. - Text with an offset beside a timestamp runs, where it failed.
- CI runs the sample's tests, in the integration job, against the image's PostgreSQL.
Compatibility
- No breaking changes A 0.6.1 planner serves a 0.6.2 client, without the new refusals, and a 0.6.2 planner serves a 0.6.1 client.
- A host that keeps a far-future "never" in a POCO
DateTimestops at its table until the member is declared in microseconds. Its comparisons were wrong before.
Full Changelog: v0.6.1...v0.6.2
Licence and attribution
ChalkQL is source available under the Elastic License 2.0 (ELv2).
Apache Calcite and its JVM dependencies are bundled into the planner artefact distributed with ChalkQL. Their licences and attribution are recorded in THIRD-PARTY-NOTICES.txt.