ChronoSQL: SQL-style plugin for ChronoLog (#354)#629
Open
iameneko wants to merge 6 commits intodevelop-3.xfrom
Open
ChronoSQL: SQL-style plugin for ChronoLog (#354)#629iameneko wants to merge 6 commits intodevelop-3.xfrom
iameneko wants to merge 6 commits intodevelop-3.xfrom
Conversation
ChronoSQL is a new client-side plugin that exposes chronicles and stories
through a SQL-shaped interface targeting YCSB-compatible workloads. No
client changes are required; the plugin is built entirely on top of the
existing ChronoLog client API.
Storage model:
- database ↔ chronicle (ChronoSQLChronicle by default)
- table ↔ story (one per table)
- row ↔ event whose log_record is a JSON object of column values
- schema/table-list ↔ a reserved __chronosql_metadata story whose events
encode CREATE/DROP operations and are replayed on first use
Two coupled APIs:
- Programmatic: createTable / dropTable / listTables / insert /
selectByKey / selectRange / selectAll
- SQL string facade: ChronoSQL::execute(sql) parses a YCSB-shaped subset
(CREATE TABLE, DROP TABLE, INSERT, SELECT with WHERE col=val or
WHERE __ts BETWEEN n AND n) via a hand-rolled tokenizer + recursive
descent parser
The implicit __ts pseudo-column maps directly to the ChronoLog event
timestamp and lowers __ts BETWEEN to ReplayStory ranges.
Constructors mirror the chronokvs pattern: default + (config_path) so the
plugin can target distributed deployments via a ChronoLog client config
file. Failures to load the config throw std::runtime_error before any
RPC connection is attempted.
Tests:
- chronosql_unit_test: 27 cases covering parser, JSON row codec, and
metadata replay/idempotency
- chronosql_config_test: throws on missing/section-less config files
- chronosql_integration_test: MANUAL TRUE end-to-end YCSB-shaped workload
(CREATE TABLE / INSERT x100 / SELECT * / SELECT WHERE = / SELECT WHERE
__ts BETWEEN); not run in CI
Examples:
- chrono-chronosql-example-writer / -reader, both accept --config/-c
The integration test aborted in CI because ChronoSQL's first call after construction is a read (getSchema), which triggers a replay of the __chronosql_metadata story. On a fresh deployment that story has no events yet, the player never marks the query complete, and the client hits its 180s replay timeout (CL_ERR_QUERY_TIMED_OUT). The exception propagated past main() and the process was reported as Subprocess aborted. - Add a tolerate_timeout flag to ChronoSQLClientAdapter::replayEvents. When set, CL_ERR_QUERY_TIMED_OUT is logged as a warning and the call returns an empty event list. Used only for the metadata replay path, so data-story replays still surface real failures. - Bump the integration test's post-INSERT propagation wait from 2s to 120s, matching the ChronoKVS integration test. The previous wait was not long enough for the player to make events visible. - Wrap main() in try/catch so connection failures exit cleanly (test treated as skipped, mirroring ChronoKVS) and other exceptions return EXIT_FAILURE instead of aborting the subprocess.
The first replay against an unwritten story blocks for the player's hardcoded 180s replay-timeout before returning, and the test then waits 120s for data propagation before the SELECT roundtrips. The previous 300s ctest timeout was too tight and the test was killed mid-run.
Mirror the chronokvs follow-up to PR #628: confManager is a remnant of the old ConfigurationManager class. Use a clearer client-facing name.
…te() factory Mirror the chronokvs follow-up to PR #628: throwing exceptions across a client-library boundary forces callers to wrap construction in try/catch without an obvious set of exception types to catch. Convert the public ChronoSQL API to a factory pattern instead: - Make ChronoSQL constructors private. - Add static std::unique_ptr<ChronoSQL> Create(...) noexcept overloads that catch any construction-path exception, log it via the configured log level, and return nullptr to signal failure. - Update examples, integration test, and unit tests to use the factory and check for nullptr instead of catching std::runtime_error. Internal layers (ChronoSQLMapper, ChronoSQLClientAdapter) keep using exceptions for clarity; they are now caught at the library boundary inside Create() rather than escaping to user code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #354.
This adds ChronoSQL, a new client-side plugin that lets you talk to ChronoLog using a SQL-shaped interface aimed at YCSB-style workloads. It maps databases to chronicles, tables to stories, and rows to events whose payload is a JSON object of column values; schema state lives in a reserved metadata story that gets replayed on first use, so we don't depend on chronicle attrs or ShowStories (which aren't reliable yet). The plugin sits entirely on top of the existing client API — no client changes needed — and constructors follow the same pattern as chronokvs so it can target distributed deployments via a JSON config.
The SQL surface is intentionally small: CREATE/DROP TABLE, INSERT, and SELECT with either an equality filter or a
__ts BETWEENrange that lowers to ReplayStory. Joins, aggregates, ORDER BY, LIMIT, and INSERT-time type checking are explicitly out of scope for v0.1, and DROP TABLE only removes the metadata mapping since the underlying event log is append-only. Coverage includes unit tests for the parser, row codec, and metadata replay, a config-loading test, and a manual integration test that exercises the full YCSB-shaped path against a live stack.