Skip to content

26.9.1

Choose a tag to compare

@tae898 tae898 released this 06 Sep 02:52
· 3947 commits to main since this release

First stable release on the 26.9.1 line. The wheel bundles ArcadeDB engine 26.9.1, synced to upstream's release commit b6a9262355 and nothing after it. Upstream calls this its largest release (992 issues and pull requests under the milestone); the parts that reach an embedded Python user are below, and the full upstream notes are here.

pip install arcadedb-embedded==26.9.1
pip install "arcadedb-embedded[arrow]==26.9.1"   # optional, for to_arrow()

Read this before upgrading

No database is rewritten and no migration runs. These are behaviour changes that working code may depend on; each is deliberate upstream and links to its issue.

SQL

  • Out-of-range integral writes fail. SET n = 3000000000 on an INTEGER property raises a validation error where it used to store -1294967296.
  • sum/avg/min/max over zero matching rows return one row of None instead of an empty result set (#6680). Code that tested len(result) == 0 for "nothing matched" needs to test the value.
  • TRUNCATE TYPE inside a transaction is rolled back by ROLLBACK, and its index rebuild waits for commit (#6220).
  • CREATE PROPERTY ... DEFAULT <unparseable> fails at DDL time instead of storing the literal text on every record (#6134).
  • A function or method call with the wrong argument count or type is a validation error, where it used to throw from inside the engine.
  • A regex exceeding arcadedb.command.regexTimeout (1,000 ms per command) fails. Raise the setting for a legitimately slow MATCHES.
  • Expressions nested deeper than 200 levels are rejected in SQL and Cypher (arcadedb.sql.maxExpressionDepth, arcadedb.cypher.maxExpressionDepth).
  • arcadedb.command.timeout now aborts openCypher MATCH and non-SELECT SQL, where only SQL SELECT honoured it before.

openCypher

  • V and Vertex are ordinary labels. A vertex with no label reports the reserved sentinel ~NO_LABEL~, so labels(n) changes for vertices whose only label was V.
  • CREATE (n:A|B) and MERGE (n:A|B) raise instead of inventing an A~B type (#6338).
  • String, numeric and boolean functions reject the wrong type instead of coercing: toUpper(5) no longer returns "5".
  • AND/OR short-circuit (#5835).
  • DELETE t ... SET t.v = 99 fails and rolls back (#5795).
  • A whole-vertex projection no longer emits the type's declared properties as top-level None columns (#5613). Row dicts get smaller; code that read those keys must use .get().

Through the bindings

  • AsyncExecutor.scan_type() raises when any bucket scan fails instead of completing a silently partial scan (#6467). Pass error_callback to keep going per record.
  • get_property_names() on documents and results reads a snapshot upstream now; the bindings already copied it into a list, so nothing changes on the Python side.

Security

Upstream closed six advisories in this release. Two matter to embedded use without a server: the IMPORT DATABASE SSRF guard now extracts IPv6 hosts (GHSA-67m7-7w7g-mpmh), and the script-trigger sandbox's denied-class list is enforced as intended (GHSA-j57p-qmrh-v7xv). The other four are server-mode: per-type ACLs on TimeSeries and index-target access, on async edge-connect writes, and in the AI Chat tool. Pre-authentication denial of service on the Bolt, Redis and Postgres wire protocols is also closed. If you run create_server(), upgrade.

What changed in the engine you get

Vector search. Opening a database is constant-time in the size of its vector indexes again, about 1.4 s saved per open at 10M vectors (#6722). A session that inserts before its first search no longer pays a synchronous full rebuild on the search thread (#6857, #6858, #6859). The adaptive efSearch beam no longer collapses from 100 to 20 past 10,000 nodes, which had dropped recall@10 from 0.92 to 0.62. A RID allow-list makes search faster, not slower. Graph construction uses every core. A partial compaction of the sparse index can no longer resurrect deleted documents.

Storage. The defect family around records that outgrow a page is closed: a lost update between two transactions on a placeholder-backed record, a record returned twice by a scan, a 16% space leak, false conflicts, and a checker that reported a clean database after a broken chain.

SQL correctness. NOT IN on an indexed property returned the IN set; SELECT DISTINCT ... ORDER BY ... LIMIT n returned fewer than n; a multi-key GROUP BY grouped on the last key only. All fixed. Indexes are now used for a literal IN (...) list, a composite-index prefix with ORDER BY, BETWEEN, @rid IN [...], and Cypher edge-property filters.

Backup. A full backup is 27.6x faster and no longer suspends page flushing, so writers keep 77% of their throughput during it. Restore runs in parallel. New settings: arcadedb.backup.compressionLevel (default 1, was 9), arcadedb.backup.compressionThreads, arcadedb.pageSnapshotEnabled.

Two things we measured on this line that are not fixed here. The HNSW build cache default (graphBuildCacheMaxHeapPercent=25) budgets from available heap, so a server that ingested the corpus before building gets a third of the cache an embedded build gets and builds about 3.4x slower on the same jars (#7146, fixed upstream for 26.10.1). Until then, set graphBuildCacheSize to the corpus size for served fp32 builds, or graphBuildCacheMaxHeapPercent=75. INT8 ignores the percent on this line. Second, on a pre-release snapshot of this line the first search after a single insert started a full async rebuild and close() waited 5 s for it (#6798, follow-up); 26.9.1 carries ArcadeData#6859, which targets that path, and we have not yet verified it on the release.

Bindings changes since 26.8.1

  • db.import_documents(...) gains on_row_error="abort" | "skip", validated Python-side before the call reaches the engine.
  • The four GraphBatch builder knobs Python could not reach are exposed: commit_retries, commit_retry_delay_ms, chunk_cache_capacity, max_deferred_incoming_edges.
  • jar_fingerprint() says which engine an install carries, not just its version.
  • ResultSet column batching (to_dataframe(), to_arrow()) hardened against heterogeneous rows (upstream ArcadeData#6758).
  • The package is citable through CITATION.cff; the runtime Zenodo call is gone.
  • The bindings changelog file is retired; this page and git history are the record.

Wheels: CPython 3.10 to 3.14 on Linux x86_64, Linux arm64, macOS Apple Silicon and Windows x86_64 (20 wheels), each bundling the engine and a Corretto 25 JRE.