Changelog
All notable changes to ElyraSQL are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.9.2 - 2026-07-10
MySQL client & driver compatibility release, driven by testing real GUI tools
and a Rust sqlx client against ElyraSQL. No on-disk format change.
Query engine
LIKE/ILIKEinWHEREare now supported (they were rejected before):%/_wildcards,ESCAPE,NOT LIKE, case-insensitive under the default collation — so contains/prefix search works.- Numeric/string comparison coercion: comparing a numeric column to a string
literal (
id = '5',IN ('5','6'),price = '10.50',id > '4') now coerces per MySQL rules. This also fixes bound parameters not matching numeric columns (drivers render params as string literals). - Expressions over aggregates:
ROUND(SUM(x),2),SUM(a)/COUNT(*),SUM(qty*price),COALESCE(SUM(x),0)+n, and scalar expressions over group columns likeUPPER(status)— with or withoutGROUP BY. - Positional
ORDER BY(ORDER BY 2,ORDER BY 1 DESC). VERSION(),DATABASE(),USER(),CURRENT_USER(),CONNECTION_ID(),CURRENT_ROLE()work as scalar functions in any context (not just as an exact-match intercept).CREATE/DROP DATABASEandSCHEMAare accepted as no-ops (single-file database), so tools and migrations that issue them proceed.
Introspection
information_schema: addedengines,schemata,views,events,routines,triggers;KEY_COLUMN_USAGEgainedPOSITION_IN_UNIQUE_ CONSTRAINTandREFERENCED_TABLE_SCHEMA/NAME/COLUMN_NAME(foreign-key discovery). Database name unified toelyra.SHOW:VARIABLES,STATUS,COLLATION,DATABASES,WARNINGS,TABLE STATUS,FUNCTION/PROCEDURE STATUS(incl. theWHEREform), andPROCESSLIST(now handled in-engine, so it works over the prepared path too).mysql.userlists accounts (always including the built-inroot).
Drivers
- Opt-in prepared-statement column description (
ELYRASQL_STMT_DESCRIBE, default off): describes a simpleSELECT's result columns atPREPAREtime so drivers like sqlx resolve result columns by name. Off by default because strictlibmysqlclient-based clients mishandle it; verified with a real sqlx harness that it enables by-name resolution and survives multiple prepares on one connection.
0.9.1 - 2026-07-10
MySQL client compatibility release. Real GUI tools (DBeaver, Workbench) and drivers fire a cluster of introspection queries on connect and to populate their schema tree; ElyraSQL now answers them, and a few everyday query forms that errored now work. No on-disk format change.
Session / introspection queries
SHOW [GLOBAL|SESSION] VARIABLES [LIKE ...]returns a MySQL 8.0-compatible system-variable set (character sets, collations, timeouts,max_allowed_packet,lower_case_table_names,sql_mode,version*, ...) withLIKEfiltering.SHOW STATUS,SHOW COLLATION,SHOW DATABASES,SHOW WARNINGS/ERRORS,SHOW TABLE STATUS, andSHOW FUNCTION/PROCEDURE STATUS(including theWHEREform, which the SQL parser rejects, handled pre-parse).
information_schema virtual tables
- Added
engines,schemata,views,events,routines, andtriggers(views/routines/triggers reflect the actual stored objects). The reported database name is now consistentlyelyra(matchingTABLE_SCHEMAandTables_in_elyra).
Query engine
- Expressions over aggregates:
ROUND(SUM(x), 2),SUM(a)/COUNT(*),SUM(qty*price),COALESCE(SUM(x), 0) + n, and scalar expressions over group columns likeUPPER(status)— with or withoutGROUP BY, and over an empty input (yieldsNULL). Previously these errored. - Positional
ORDER BY(ORDER BY 2,ORDER BY 1 DESC) in both the aggregated and plain paths.
Dependencies
- Applied safe in-range dependency updates; pinned crates that define the
on-disk format / SQL parsing / SIMD API (bincode, redb, sqlparser, wide) and
the opensrv-pinned rustls stack against breaking Dependabot bumps. Bumped the
Alpine runtime image and GitHub Actions. The four
rustls-webpkiadvisories are not reachable (server-only TLS, no client-cert/CRL validation) and are transitively pinned byopensrv-mysql.
0.9.0 - 2026-07-10
Robustness, correctness & security hardening release. A broad review of the query engine, transaction layer, vector search, privilege model and network/ disk I/O, tightening production safety without changing the on-disk format.
Correctness
- Signed-zero / NaN grouping.
GROUP BY,DISTINCTand hash joins now canonicalize float keys, so-0.0and+0.0group together (as SQL requires) and all NaNs collapse to one key. - Total ordering.
Value::total_cmp's fallback no longer comparesDebugstrings (which allocated per comparison and sorted10.0before2.0); it uses a numeric / stable per-type order. - Full-text stemming. Replaced the ad-hoc suffix stripper (which mangled
string→str,running→runn) with the Snowball algorithms (rust-stemmers); multilingual viaELYRASQL_FULLTEXT_LANGUAGE(defaultenglish;nonedisables stemming). - Transaction ORDER BY now uses the disk-spilling sorter inside transactions too (via the snapshot+overlay cursor), not just in autocommit.
- GROUP BY consults column statistics to go straight to the spilling path
when a large group count is predicted, avoiding a wasted in-memory pass and
re-scan (run
ANALYZE TABLEto benefit).
Stability
- JSON validator depth limit (
MAX_JSON_DEPTH) stops deeply nested input from overflowing the thread stack. - O(1) savepoints.
SAVEPOINTrecords an undo-log marker instead of cloning the whole staged write set (previously O(writes × savepoints));ROLLBACK TOreverts only changes since the savepoint. - Bounded transaction buffer. Uncommitted writes past
ELYRASQL_TXN_MAX_BYTES(default 1 GiB) are rejected with an error instead of exhausting memory. - Single-flight vector index rebuilds. A burst of queries after a write now triggers exactly one HNSW rebuild while the rest await and share it, instead of a thundering-herd of parallel full-table scans.
- Temp-file hygiene. Sort/aggregation spill files are size-guarded on read (a corrupt file can't trigger a giant allocation) and stale files from a SIGKILLed process are reclaimed at startup (only confirmed-dead PIDs).
Security
- Fine-grained global privileges.
GRANT/REVOKE ON *.*now add/remove individual privileges as a set, so revoking one privilege no longer collapses an admin account to read-only.SHOW GRANTSlists the exact set. - DROP USER purges the account's global, per-table, per-column and role grants, so a recreated same-name user can't inherit stale privileges.
- Constant-time password comparison (
ct_eq) closes a hash timing side channel. - Bounded frame/record reads. Every length-prefixed read (cluster,
replication, binlog, spill files) rejects oversized lengths before allocating,
via the configurable
ELYRASQL_MAX_FRAME_MB(default 1024 MiB), turning a corrupt file or malicious packet into an error instead of an OOM crash.
Performance
- HNSW visited-set pooling removes an O(N) heap allocation per vector search.
- SIMD distance kernels (
wide::f32x8, 8-wide) accelerate L2 / inner-product / cosine on the hot ANN path. - Cooperative yielding (
yield_now) in stored-procedureWHILE/LOOP/REPEATloops keeps a long procedure from starving the async runtime.
Known limitations (documented)
- Multi-table joins still materialize before sort/group (streaming join output
is planned); an unanalyzed high-cardinality
GROUP BYmay still fall back with a second scan; internal cluster/replication traffic is authenticated (ELYRASQL_CLUSTER_SECRET) but not yet encrypted (mTLS is planned — use a private network/VPN meanwhile).
0.8.10 - 2026-07-10
Consensus hardening & security release — making the Raft write path production- viable and strengthening password handling.
Raft write-path throughput
- The leader holds persistent
AppendEntriesconnections to followers (reused across rounds,TCP_NODELAY) instead of a fresh connection per round. - The Raft log is now append-only (fsync only new entries; the whole log is no longer rewritten per write), and the leader fsyncs a round's entries once.
- Committed entries are applied together through the DB group commit.
- Together these lift concurrent cluster write throughput from ~60/s to ~500/s (16 connections) / ~800/s (32); a single sequential write stays fsync-latency-bound.
Leader lease (liveness + linearizable leader reads)
- The leader renews a lease each round it confirms a quorum and steps down if it cannot within the lease window (below the election timeout). A leader partitioned from its quorum now relinquishes leadership — in-flight writes fail fast and a healthy majority elects a new leader — rather than hanging. A lease-valid leader is guaranteed to be the leader, so its local reads are linearizable without a quorum round-trip.
Raft log compaction
- The replicated log no longer grows unbounded: once entries are applied and replicated to every member, each node discards them (keeping the snapshot boundary term for the consistency check); the applied state machine is the snapshot. Compaction advances only to the slowest member's replicated index.
Password hardening
- New passwords must satisfy a strength policy (
ELYRASQL_PASSWORD_MIN_LEN, default 8;ELYRASQL_PASSWORD_REQUIRE_MIXED, default on;ELYRASQL_PASSWORD_POLICY=offto disable). - Repeated failed logins trigger a temporary account lockout
(
ELYRASQL_AUTH_MAX_FAILURES, default 10;ELYRASQL_AUTH_LOCKOUT_SECS, default 60), logged.
0.8.9 - 2026-07-09
Consensus release: the Raft log is now on the live cluster write path.
Raft replicated-log write path (pre-commit / 2-phase)
- In
clustermode, every write is proposed through the Raft log: the leader appends the entry, replicates it viaAppendEntries, commits it once a quorum has durably logged it, and only then applies it and acknowledges the client. Followers append (with the AppendEntries consistency check + conflicting-suffix truncation) and apply up to the leader's commit index. - Votes use the §5.4.1 election restriction on the log, so failover is no-data-loss: an acknowledged write is on a quorum's durable log and any elected leader already has it. A write cannot be acknowledged without a quorum.
- New plumbing:
elyra_storage::WriteOp+Consensustrait +Db.set_consensus/apply_op_local; the single-node write path is unchanged when no consensus layer is installed. - Known limitation: a leader partitioned from its quorum blocks writes (until it can replicate or the client times out) rather than stepping down proactively (no leader lease yet).
Verified
- 3-node cluster: writes commit via quorum and replicate; followers reject writes; killing the leader preserves all acknowledged writes on the new leader (no data loss); no commit without a quorum.
0.8.8 - 2026-07-09
Partitioning release.
Partitioning
CREATE TABLE ... PARTITION BY RANGE|LIST|HASH (<pk column>) (...)records a partitioning scheme (managed primary-key ranges), exposed ininformation_schema.partitions.ALTER TABLE t DROP PARTITION p/TRUNCATE PARTITION pcheaply delete a partition's rows (range/INdelete with index cleanup). Queries with a PK predicate prune automatically via clustered range scans.- Also fixed a stale docs line:
ON UPDATEreferential actions are enforced.
Notes / deferred
- Partitioning is single-node (managed PK ranges, not physical files, not enforced on INSERT). Horizontal write scale-out across nodes would require distributed sharding and is out of scope by design.
- Wiring the Raft log into the live cluster write path (leader append →
quorum commit → apply, for pre-commit 2-phase durability) is intentionally
not bundled here: it is a correctness-critical change that warrants a
dedicated release with partition/failover testing (the tested log core landed
in 0.8.6). Today's HA remains async replication + quorum/
--sync-strict+ the LSN-aware election restriction (no data loss for acknowledged writes).
0.8.7 - 2026-07-09
SQL-surface & usability release.
Named windows
SELECT ... OVER w ... WINDOW w AS (PARTITION BY ... ORDER BY ...), includingOVER (w ...)that inherits a named window and adds local clauses.
Materialized-view auto-refresh
- Materialized views now auto-refresh on read when a base table has changed since the last refresh (detected via per-table write counters). This is a full recompute, not incremental delta maintenance.
Notes
caching_sha2_passwordremains unimplemented: the latest publishedopensrv-mysql(0.7.0, what we use) does not drive its multi-round auth exchange. MySQL 8 clients negotiate down tomysql_native_password.
0.8.6 - 2026-07-09
Programmability, security & consensus-foundation release.
Materialized views
CREATE MATERIALIZED VIEW v AS <select>materializes the result into a real table;REFRESH MATERIALIZED VIEW vrecomputes it;DROP MATERIALIZED VIEW vremoves it. Refresh is explicit (no auto-refresh).
Per-column privileges
GRANT SELECT(col, ...) ON t TO urestricts a user to reading only those columns oft; querying an ungranted column (via the projection,SELECT *, or aWHERE/ORDER BYreference) is denied. Enforced for single-base-table selects; a restricted table in a join/subquery is denied (deny-safe).
Raft log core (consensus foundation)
- New unit-tested
raftlog: an ordered persistent log with the AppendEntries consistency check + conflicting-suffix truncation, the quorum/current-term commit rule, apply-only-when-committed, and the §5.4.1 election restriction. Routing the live cluster write path through it (for pre-commit 2-phase durability) is the remaining integration step.
Notes
caching_sha2_passwordremains unimplemented: the MySQL-protocol library does not drive its multi-round auth exchange. MySQL 8 clients negotiate down tomysql_native_password.
0.8.5 - 2026-07-09
Planner, security, and durability release.
Histogram-based cardinality
ANALYZE TABLEbuilds an equi-height histogram per column (reservoir sample), exposed as a JSONHISTOGRAMininformation_schema.column_statistics. The planner estimates WHERE-predicate selectivity from histograms to order joins by estimated (not just raw) row counts.
Roles, per-database grants & audit log
CREATE ROLE/DROP ROLE,GRANT <role> TO <user>/REVOKE <role> FROM <user>; users inherit the global and per-table grants of their roles.GRANT ... ON db.*is accepted (maps to a global grant, single database).--audit-log <path>appends one line per executed statement (timestamp conn_id user OK|ERR sql).
LOAD DATA INFILE & auth hardening
LOAD DATA INFILE '<server path>' INTO TABLE t [FIELDS/LINES TERMINATED BY] [IGNORE n LINES] [(cols)]bulk-loads a server-side file (ADMIN required;\N= NULL).- Connection salts now use the OS CSPRNG. (
caching_sha2_passwordis not implemented — the wire library lacks its multi-round exchange; MySQL 8 clients negotiate down tomysql_native_password.)
Crash-safe cluster elections
- Election state (current term + vote) is persisted to
<data>.raftstate, so a restarted node never double-votes in a term (Raft safety). Full Raft log replication (pre-commit 2-phase durability) remains a dedicated milestone.
0.8.4 - 2026-07-09
High-availability & query-planner release.
Zero-data-loss failover (election restriction)
- Cluster leader election now enforces the Raft election restriction: a node
only votes for a candidate at least as up-to-date (by LSN) as itself, so an
elected leader holds every quorum-acknowledged write. Together with
--sync-strictthis makes failover no-data-loss for acknowledged writes. (The sync barrier still runs after the local commit; this is not a pre-commit 2-phase protocol.)
Dynamic cluster membership
- Add/remove cluster members at runtime with
elyrasql cluster-ctl --node <addr> --action add|remove --peer id@host:port. The leader advertises the membership in heartbeats and followers adopt it. Add one node at a time and start it before adding.
Cost-based JOIN reordering + merge join
- Explicit INNER-join chains over base tables are reordered cost-based (drive from the smallest relation, extend along equi-join predicates; alias-aware).
- Large INNER equi-joins whose inputs are already sorted on the join key (clustered primary-key scans) use a streaming merge join.
Stored procedures: cursors & handlers
DECLARE ... CURSOR FOR,OPEN,FETCH ... INTO,CLOSE, andDECLARE {CONTINUE|EXIT} HANDLER FOR {NOT FOUND | SQLEXCEPTION | SQLSTATE '...' | <code>} <action>.
0.8.3 - 2026-07-09
Scalability & robustness release — hardening the write path and high availability.
Pessimistic locking
LOCK TABLES t READ|WRITE/UNLOCK TABLEStake real blocking table locks (aWRITElock blocks other readers and writers; aREADlock blocks writers). Conflicting statements from other sessions block until release, or fail with1205(lock wait timeout).LOCK IN SHARE MODEis accepted as a synonym forFOR SHARE. Zero overhead when no explicit lock is held.
Quorum / synchronous replication
--sync-replicas Nmakes each commit wait forNreplica acknowledgements;--sync-strictfails the commit-confirmation on timeout instead of silently degrading to asynchronous (no silent data-loss window). Per-replica ack tracking replaces the single high-water mark.
Incremental replica catch-up
- A reconnecting replica streams only the binlog delta since its last applied LSN instead of re-copying the whole database, falling back to a full snapshot only when the binlog is disabled or the needed segments were purged. Replicas reconnect transparently on stream drops. The LSN counter is resumed from the binlog across restarts (correct binlog ordering + working catch-up).
Write throughput
- Validated transactional commits are now group-committed: many concurrent transactions fold into one write transaction (one fsync) instead of one fsync each, while preserving first-committer-wins ordering and write-write conflict detection. (The single writer remains inherent to the ACID single-file design; there are no parallel writers or sharding.)
0.8.2 - 2026-07-09
High-availability & feature-completeness release.
Automatic failover
clustermode: Raft-style leader election (terms, majority votes, heartbeats, step-down). The elected leader accepts writes and serves replication; followers are read-only and replicate from it. On leader failure a surviving node is automatically elected. Leader-only writes provide fencing; a majority quorum avoids split-brain. Data replication remains asynchronous.
Stored procedures
IN/OUT/INOUTparameters, session@uservariables, and full control flow:LOOP,REPEAT ... UNTIL, labeledLEAVE/ITERATE(in addition toIF/WHILE).
Full-text search
CREATE FULLTEXT INDEXbuilds a persistent inverted index maintained on INSERT/UPDATE/DELETE and used to accelerateMATCH ... AGAINST; light English stemming folds regular word forms.
Spatial
POINT/GEOMETRYcolumns (WKT) withPOINT,ST_X,ST_Y,ST_Distance,ST_AsText,ST_GeomFromText.
0.8.1 - 2026-07-09
Programmability release: triggers, procedural stored procedures, and full-text search.
Triggers
- Row-level
CREATE TRIGGER name {BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON t FOR EACH ROW <body>/DROP TRIGGER, withNEW.col/OLD.col. BEFORE bodies supportSET NEW.col = expr; AFTER bodies run arbitrary DML per affected row. Firing is depth-guarded against runaway recursion.
Stored procedures
- Parameters (
IN), local variables (DECLARE,SET), and control flow (IF/ELSEIF/ELSE,WHILE), interpreted over the procedure body.
Full-text search
MATCH(col, ...) AGAINST('terms' [IN BOOLEAN MODE])— scan-based relevance scoring (natural-language OR-of-terms, or boolean+/-).
Fixed
- The fast INSERT path now persists the
AUTO_INCREMENTcounter, so consecutive auto-increment inserts no longer reuse ids.
0.8.0 - 2026-07-09
Programmability & log-management release.
Binary log management
- The binlog is now a directory of rotating segment files, rotating at
ELYRASQL_BINLOG_SEGMENT_MB(default 128 MB). SHOW BINARY LOGSlists segments and sizes;PURGE BINARY LOGS TO '<name>'deletes older segments.--binlogandbinlog-replaynow take a directory.
Stored procedures
CREATE [OR REPLACE] PROCEDURE name() BEGIN ...; END,CALL name(), andDROP PROCEDURE— statement-list macros executed through the engine, with a recursion-depth guard. (Parameters, variables and control flow are not yet supported.)
0.7.0 - 2026-07-09
Durability & recovery release: point-in-time recovery, richer statistics, and semi-synchronous replication.
Point-in-time recovery
- Optional append-only binlog (
--binlog) records every committed write-set with an LSN and timestamp. elyrasql binlog-replay --data <f> --binlog <f> [--until-lsn N | --until-time-ms T]replays onto a restored backup (or an empty file) up to a chosen point — exact, idempotent recovery.
Statistics
ANALYZE TABLEnow collects per-column statistics (distinct-value count, null count, min/max), exposed viainformation_schema.column_statistics.- The planner drives a comma cross-join from the smallest analyzed table.
Replication
- Semi-synchronous mode (
--semi-sync-ms): a commit waits for a replica to acknowledge before returning, degrading to asynchronous on timeout or when no replica is attached. Replication is now bidirectional (replicas acknowledge applied LSNs).
0.6.0 - 2026-07-09
Scale & availability release: replication, partitioned aggregation spill, cost-based joins with statistics, and a Prometheus metrics endpoint.
Replication & HA
- Asynchronous primary → replica replication. A primary streams LSN-tagged
committed write-sets (
--replication-listen); a replica bootstraps from a snapshot and applies the stream (elyrasql replica), serving read-only queries. Idempotent, ordered application means replicas never diverge; failover is manual (a replica file is a complete database).
Aggregation
GROUP BYwith many distinct groups now falls back to partitioned spill aggregation (bounded memory) instead of erroring, completing the OOM-safety story alongsideORDER BYspill.
Query planning
- Equi hash joins now cover INNER / LEFT / RIGHT with a cost-based build side (INNER builds the smaller relation; RIGHT no longer degrades to nested-loop).
ANALYZE TABLErecords row-count statistics, surfaced asinformation_schema.tables.TABLE_ROWS.
Observability
- Prometheus/OpenMetrics endpoint (
--metrics-listen,GET /metrics) exposing the server counters, plus a/healthprobe.
0.5.0 - 2026-07-09
Operations & data-model release: observability, memory-bounded sorts, per-column collation, and scoped privileges.
Observability
SHOW STATUS/SHOW GLOBAL STATUScounters (uptime, connections, Questions/Queries,Com_*, Errors, Slow_queries), withLIKE 'prefix%'.SHOW [FULL] PROCESSLISTlisting live connections and their current query.- Slow-query log:
--slow-query-ms/ELYRASQL_SLOW_QUERY_MSlogs statements at or above the threshold with their duration.
Memory safety
ORDER BYis now memory-bounded: a top-N heap forORDER BY ... LIMIT, and an external merge sort that spills to temp files for large sorts (ELYRASQL_SORT_MAX_ROWS).GROUP BYfails gracefully pastELYRASQL_GROUP_MAX_GROUPSinstead of risking an out-of-memory crash.
Collation
- Per-column
COLLATE ..._bin/BINARYopt-in to case-sensitive behavior forWHEREcomparisons,UNIQUE,PRIMARY KEYand secondary indexes (text is still case-insensitive by default).ORDER BY/GROUP BY/joins still use the default collation.
Access control & integrity
- Per-table
GRANT/REVOKE(ON <table>): raises a read-only account's level for specific tables; reads stay globally allowed. Deny-safe when a target is indeterminate.SHOW GRANTSlists global and per-table grants. ON UPDATEreferential actions enforced (CASCADE / SET NULL / RESTRICT) when a parent's referenced key changes.
0.4.0 - 2026-07-09
Production-readiness release: backup, real user management, and a MySQL-style case-insensitive default collation.
Backup & restore
- Hot backup with
BACKUP TO '<path>'(admin): copies the whole database from a consistent MVCC snapshot into a fresh file without blocking writers. - Offline
elyrasql backupandelyrasql restoreCLI subcommands. - The backup is a complete database file — start a server on it or copy it back.
Users & access control
- Persistent accounts stored in the database file (survive restarts):
CREATE USER,DROP USER,ALTER USER/SET PASSWORD,GRANT,REVOKE,SHOW GRANTS. - New accounts start read-only;
GRANTraises them,REVOKElowers them. Privileges map to the coarse global read/write/admin levels (the object clause is parsed but not scoped). Passwords stored asSHA1(SHA1(pw)). - Authentication consults startup bootstrap accounts plus persistent accounts; open dev mode applies only when no account exists.
Collation
- Default case-insensitive collation for text, applied consistently across
comparisons,
ORDER BY, indexing,GROUP BY,DISTINCT, joins, set operations, andUNIQUE/PRIMARY KEY. - On-disk change: text key encoding is now case-folded. Databases created before 0.4.0 that use text primary keys or text indexes should be reloaded.
0.3.0 - 2026-07-09
Data-integrity release: the constraints a production database must enforce.
Constraints
- UNIQUE constraints are now enforced (previously stored but not checked).
Column-level
UNIQUE, table-levelUNIQUE(...), andCREATE UNIQUE INDEXall reject duplicates (error1062), including duplicates within a single statement; multipleNULLs are allowed. - FOREIGN KEY constraints are enforced. INSERT/UPDATE require a matching
parent row (primary key or unique index, error
1452); DELETE on the parent appliesRESTRICT/NO ACTION(block),ON DELETE CASCADE(delete children), orON DELETE SET NULL. - CHECK constraints (column- and table-level) are enforced on INSERT and UPDATE, passing on TRUE or NULL per SQL semantics.
Transactions
- SAVEPOINT, ROLLBACK TO SAVEPOINT, and RELEASE SAVEPOINT.
- SELECT ... FOR UPDATE / FOR SHARE: optimistic row locking — a locked row changed by another transaction aborts the locking transaction at commit (lost-update prevention without blocking).
Fixed
- Three-valued logic for comparisons:
NULL = x,x >= NULL, etc. now evaluate to NULL (UNKNOWN) instead of false. WHERE still excludes them, CHECK passes, and SELECT shows NULL — matching SQL semantics.
0.2.1 - 2026-07-09
Performance and robustness pass, verified on Linux (1,000,000-row workloads).
Performance
- Bulk
INSERT~5-6x faster (~33k → ~190k rows/s in a container, ~240k on fast-fsync storage). The 0.2.0 duplicate-key check did one storage read per row (each opening its own read transaction); it now:- detects duplicates inside the write transaction itself for plain
INSERT(redb returns the previous value — no existence read), and - batches the existence check into a single read for
IGNORE/REPLACE/ON DUPLICATE KEY UPDATE.
- detects duplicates inside the write transaction itself for plain
- Group commit for
INSERT: the writer coalesces queued plain/insert jobs into one transaction (one fsync), falling back to per-statement application only when a group contains a duplicate — so concurrent write throughput is preserved. GROUP BY~3.4x faster on low-cardinality groups (~927ms → ~273ms over 1M rows): the group key is a compact binary encoding instead ofDebug-formatting every row's key columns.- Statement dispatch inspects only a short prefix instead of lowercasing the whole (possibly large) SQL text.
0.2.0 - 2026-07-09
A large expansion of SQL coverage on top of the 0.1.0 foundation, turning ElyraSQL into a broadly MySQL-compatible engine.
Queries
- Subqueries in
WHEREand the SELECT list — uncorrelated and correlated, including correlated subqueries over joins (IN, scalar,EXISTS). - Derived tables (
FROM (SELECT ...) AS t). - Common table expressions (
WITH), including chained CTEs andWITH RECURSIVE. - Window functions (
OVER):ROW_NUMBER,RANK,DENSE_RANK, running and partitionSUM/COUNT/AVG/MIN/MAX,LAG/LEAD, and explicitROWS/RANGEframes. HAVING.- Set operations:
UNION,UNION ALL,INTERSECT,EXCEPT. FROM-lessSELECT(e.g.SELECT 1,SELECT NOW()).
DML
INSERT ... SELECT.- Upserts:
REPLACE,INSERT IGNORE, andON DUPLICATE KEY UPDATE(with correct secondary-index maintenance and duplicate-key error1062). - Subqueries in
UPDATE/DELETEWHERE(uncorrelated and correlated). - Multi-table
UPDATEandDELETE(joins in mutations).
DDL
CREATE TABLE ... AS SELECT,CREATE TABLE ... LIKE,TRUNCATE TABLE.CREATE VIEW/DROP VIEW(including column lists and views over views).ALTER TABLE ... MODIFY/CHANGE COLUMN, andALTER COLUMN SET/DROP DEFAULTandSET/DROP NOT NULL(with data re-coercion on type change).- Column
DEFAULT(constants and functions),AUTO_INCREMENT, and stored generated columns. ENUM/SET,BINARY/VARBINARY, andBITcolumn types.
Functions
- Date/time:
NOW/CURRENT_TIMESTAMP/CURDATE/CURTIME,YEAR/MONTH/DAY/HOUR/MINUTE/SECOND,QUARTER/DAYOFWEEK/DAYOFYEAR,EXTRACT,DATE_ADD/DATE_SUB/TIMESTAMPADD,DATEDIFF/TIMESTAMPDIFF,WEEK/YEARWEEK,DATE_FORMAT,STR_TO_DATE,LAST_DAY, and thed + INTERVAL n UNIToperator. - String:
CONCAT/CONCAT_WS,UPPER/LOWER,SUBSTRING/SUBSTRING_INDEX,LEFT/RIGHT,TRIMfamily,REPLACE/REVERSE/REPEAT,LPAD/RPAD,INSTR/LOCATE,FIELD/ELT, andREGEXP/RLIKE. - Math, conditional (
COALESCE/IFNULL/NULLIF/IF/CASE),CAST(including exactDECIMALandBINARY),UUID(). - JSON:
JSON_EXTRACT/->/->>,JSON_ARRAY/JSON_OBJECT,JSON_SET/JSON_INSERT/JSON_REPLACE/JSON_REMOVE,JSON_CONTAINS/JSON_LENGTH/JSON_KEYS/JSON_TYPE/JSON_VALID/JSON_QUOTE. - Aggregates:
GROUP_CONCAT, conditional aggregates (SUM(CASE ...)),COUNT(DISTINCT expr). - Bitwise
&,|,^.
Transactions
- Write-conflict detection (first-committer-wins, MySQL error
1213). - Opt-in serializable isolation with read-set and scanned-range validation.
Introspection
SHOW TABLES,SHOW COLUMNS,DESCRIBE/DESC,SHOW CREATE TABLE,SHOW INDEX/SHOW KEYS.- Queryable
INFORMATION_SCHEMA:tables,columns,statistics,key_column_usage.
Numerics & wire protocol
- Exact
DECIMALarithmetic (+,-,*) and exactSUM(DECIMAL). - Value-driven result column typing (computed columns report the right wire
type; no spurious
.0). DATE/DATETIME/TIMEprepared-statement parameters decoded from the binary protocol.
Fixed
DateTimevsDATEcomparison (previously always false).DROP TABLEleft orphaned secondary-index entries.INSERTaffected-row count included index-entry writes.
Docs & project
- MkDocs Material documentation site, contributing guide, issue/PR templates, security and conduct policies, Dependabot configuration.
0.1.0
Initial release: single-file ACID storage (.edb), MySQL wire protocol,
core CRUD with WHERE/ORDER BY/LIMIT, indexes, aggregation and GROUP BY,
joins, prepared statements, authentication and TLS, vector search (exact +
HNSW), parallel OLAP aggregation, and transactions with snapshot isolation.