ArcadeDB 26.11.1
Overview
887 issues and pull requests closed under the 26.11.1 milestone - 651 issues and 236 pull requests - out of 483 pull requests merged and about 690 commits since 26.10.2. 468 of the closed issues are bug fixes, 28 of them rated critical.
The headline work is in six places:
- Transactions that behave like SQL - a statement that fails inside a transaction is now taken back on its own (statement-level savepoints) and the transaction goes on,
UPDATE ... SETreads the row as it was before the statement, an explicitNULLis stored asNULL, andCREATE INDEXno longer misses records other sessions have not committed yet. - Crash safety and durability - recovery after a power loss (Jepsen LazyFS) repairs torn pages and quarantines what it cannot recover instead of serving it, vector and sparse vector indexes survive a crash right after their build, and a growing record can no longer overwrite its neighbour on the page.
- Vector search - the Cypher 25
SEARCHclause, Neo4j'sCREATE VECTOR INDEX/CREATE FULLTEXT INDEXDDL, a pre-filter fordb.index.vector.queryNodes,PRODUCTandBINARYindexes that search on their compressed codes and re-rank, and a graph build 2.3x faster on largeINT8indexes. - Operations - databases nobody uses can close and reopen on demand, a database that is only read holds no WAL file, every Docker image runs as UID 1000, the native image states its CPU baseline (with a compatibility archive for older x86 CPUs) and is built at
-O3, and Claude Code can connect to your own server through the new ArcadeDB plugin. - Wire protocols - the PostgreSQL catalog answers what psql, pgjdbc and psqlodbc ask (
\d,\dt,\di,\dm,\df,\du, JDBC metadata), PostgreSQL results stream in chunks, Redis pipelining runs at 0.8-0.9x of Redis on one connection and 2x under heavy load, and every protocol re-resolves a database after a close, restore or drop. - Security hardening - the users, groups and API-token files are never replaced by a default on a bad reload, plugin routes answer only the method they declare, wrong Basic credentials answer 401, and the HA cluster token can no longer change silently on a rolling restart.
Upgrading is recommended for every deployment. This release changes several answers to be correct (SQL, Cypher temporals, string functions, HTTP status codes), changes the Docker user and drops the plain Kubernetes StatefulSet: read the Upgrade notes before upgrading.
Contents: New features · Highlights · Security · Performance · Major fixes and improvements · Upgrade notes · Dependency updates
New features
Vector and full-text search
- Cypher 25
SEARCHclause (#10776, #10783).MATCH (d:Doc) SEARCH d IN (VECTOR INDEX idx FOR $q [WHERE p] LIMIT k) SCORE AS sruns the vector search first and bindsdto theknearest records; the innerWHEREis tested on each candidate during the search, which widens until it haskmatching rows. It used to be parsed and dropped, answering everyDoc. - Neo4j index DDL in openCypher (#10678, #10864, #10914, #10994, #10915, #10992).
CREATE VECTOR INDEXandCREATE FULLTEXT INDEXbuildLSM_VECTORandFULL_TEXTindexes, withIF NOT EXISTS,OPTIONSfrom a map or a parameter, several labels or relationship types (FOR (n:Article|Post)) under one logical name, and a vector index that takes its dimension from the first vector it receives.SHOW INDEXESlists acreateStatementthat runs as written. Requested by @chetto1983. IS :: VECTOR<T>(n)property type constraint and avector(v, n, T)that builds the array of its coordinate type (#10862, #10918, #10917, #10991).- Pre-filter for
db.index.vector.queryNodes(#10685, #10808): an optional options map withwhereandfilter, tested during the search, so a multi-tenant query no longer returns fewer rows than asked.vector.neighborsandvector.sparseNeighborstake the samewhereoption, evaluated only on the candidates the search visits (#10169). PRODUCTandBINARYindexes search on their codes (#10514, #10968, #10975). The walk scores on the in-memory PQ codes (or the one-bit codes) and re-ranksk * rerankOversamplecandidates on the stored vectors, so the returned distances stay exact. New index settingsrerankOversampleandfusedPQ, a per-queryrerankoption, andpqTrainingLimitis now honoured. APRODUCTgraph file is about 8x smaller.- Full-text filters decided before the load (#11069): a condition on another indexed property next to
SEARCH_INDEX()/SEARCH_FIELDS()is checked against that index first; withLIMIT 10the reported query loads 10 records instead of about 2,000. Reported by @shaunpatterson.
Server and operations
- Close idle databases and reopen them on demand (#11068). Off by default:
arcadedb.server.databaseIdleTimeoutcloses a database after that long without activity,arcadedb.server.maxOpenDatabaseskeeps at most that many open (least recently used first), and the next request over any protocol (HTTP, gRPC, PostgreSQL, Bolt, Gremlin, MCP) reopens it. A database with an open transaction, a running query or async work, or under HA, is never closed. Requested by @singh-hovr. - WAL files and housekeeping on demand (#10234, #10218). One shared scheduler replaces a timer thread per database, a WAL file is opened by the first commit that needs it and released after 60 s idle (
arcadedb.txWalIdleTimeout), so a database that is only read holds no WAL file. A background warm-up afterONLINEcuts the first HTTP query from about 160 ms to 60 ms (arcadedb.server.queryWarmUp). - MCP for Claude Code (#11170). The repository is a Claude Code plugin marketplace (
claude plugin marketplace add ArcadeData/arcadedb --sparse .claude-plugin claude-plugin, thenclaude plugin install arcadedb@arcadedb) to connect Claude Code to your own server with an API token. Every MCP tool now carries read-only / destructive / open-world annotations, and thequeryandexecute_commandtools refuse scripting languages. - Native image: built at
-O3, about 25% faster on warm loops (#11070, contributed by @tae898); an explicit CPU baseline (x86-64-v3on amd64,armv8-aon arm64) with a "CPU requirements" section indocs/native-image.md(#10581, #10715); and a new linux/amd64-compatarchive built with-march=compatibilityfor CPUs below x86-64-v3 (#10623, #11253). arcadedb.fileSync(defaulttrue) skips every fsync when set tofalse, for test runs and throwaway databases; the unit-test lanes now run twice as fast (#11149).arcadedb.txWalGroupCommit(opt-in): concurrent commits share one WAL flush; about 4x the commits per second for writers into the same type (#10499).arcadedb.graph.ghostEdgeProbe: a database known to hold no dangling adjacency entries can skip the per-vertex probe of variable-length walks (#10658).arcadedb.bucketSelfDescribingChunkLinks(opt-in, defaultfalse): the new chunk-link format that lets a multi-page record link position 0. A database that stored it cannot be read by an older version (#10853, #10949).
Query languages and engine
- Time series samples can be deleted (#10342, #10428):
DELETE FROM <ts type> WHERE <time range> [AND tag = value]andTRUNCATE TYPEremove samples from the mutable and sealed storage, replicate under HA and refresh the continuous aggregates over the type. - Graph algorithms:
algo.personalizedPageRanktakesdirectionandweightProperty, andalgo.labelpropagationtakes pre-assigned labels (seedProperty,fixedSeeds) and refuses unknown keys (#11146, #11145, both reported by @chetto1983). - Statement-level savepoints (#10346), see Highlights.
sum()andavg()accept durations, in SQL too (#10198).
Studio
- The graph view keeps moving with live physics (node repulsion, edge springs, centre gravity), as Neo4j Browser does (#10705, contributed by @shaunpatterson).
- Charts are drawn with Apache ECharts instead of ApexCharts, which stopped being open source; all six charts resize with their panel and follow the theme (#10579).
- The Add Index dialog has a Build Mode option (
SORTED) forLSM_TREEindexes (#10363); "Copy to clipboard" works on plain-http pages (#10239, reported by @pwitherton); the GraphML export carries vertex and edge properties (#11236). - A default
crudserver group fills the gap betweenadminandreadonly(#10778, contributed by @gramian).
Highlights
Transactions: a failed statement is taken back, and SQL reads like SQL
- A statement that fails inside a transaction is undone on its own, and the transaction goes on (#10346, #10194, #10379). A multi-row
INSERT,UPDATE,DELETE,CREATE EDGE, openCypher orsqlscriptstatement that failed after writing part of its records used to leave them in the caller's transaction, and the commit published half a statement. The engine now rolls the statement back the way SQLite does: its records, unique, plain, vector and full-text index entries (with the BM25 counters), edges and both vertices' edge lists, page bytes, record counters and reserved slots. When it cannot be taken back exactly (abovearcadedb.txStatementSavepointMaxEntries, 100,000 by default, or a statement that touched a Graph Analytical View, dropped a file, or ran Gremlin), the commit is refused with aTransactionExceptionnaming the reason. UPDATE ... SETreads the row as it was before the statement (SET a = b, b = aswaps), and an explicitNULLis stored asNULL: aDEFAULTfills only a property that is left out (#10194).CREATE INDEXno longer leaves out a record another session wrote and has not committed (#10588): it stayed invisible to every index-backed query and aUNIQUEindex accepted a duplicate of its key. A transaction that began before the index now queues the entries it owes the index at commit. With it,CREATE INDEXin a transaction that wrote to the indexed type no longer loses every committed record on rollback (#10490), and a refusedDROP INDEXno longer leaves the index half dropped (#10589).- A UNIQUE key moved off its holder can be given to only one record (#10265), a
NOTUNIQUE_HASHkey changed away and back no longer lists the record twice (#10269), and a compactedNOTUNIQUELSM index no longer returns entries its records do not have (#10188). - A failed
transaction()block that joined the caller's transaction leaves it open instead of rolling back the caller's earlier work (#10135); deleting a missing or vetoed record over the remote drivers now throws (#10230). - An update of a record with an undecodable property is refused instead of saving the record back without that property (#10955), and an auto-commit gRPC
ExecuteCommandretries a transient conflict like HTTP does (#10942).
Crash safety, storage and HA
- Power loss: crash recovery repairs torn pages whose earlier versions are still in the WAL, so a recovered node no longer returns records with wrong or missing property names (#11151, #11153), and a database whose recovery did not complete is quarantined (
LOCAL_RECOVERY_INCOMPLETE,UNAVAILABLE_UNIQUE_INDEX) and resynced from the leader instead of serving half-recovered data (#11250). Found with the Jepsen LazyFS suite. - Vector indexes are durable at READY: a process killed right after
CREATE INDEXorREBUILD INDEXof anLSM_VECTORindex no longer reopens it empty or loses the transactions committed after it (#11238). CommittedLSM_SPARSE_VECTORpostings survive a crash through per-index posting logs, and every HA node answers with the postings the leader has not sealed yet (#11239, #11257). A full vector rebuild keeps the deletes and inserts committed while it reads the pages (#11099). - Records on a full page: growing a small record no longer writes its 9-byte pointer over the next record (#10617, #10637, #10669, #10859), a multi-page record can no longer be cut short at commit by a link to slot 0 of page 0 (#10701), and freeing a chunk chain no longer unlinks a live record (#10875).
- Restores: an overwrite restore extracts into a staging directory and keeps the old copy on failure, so a mistyped encryption key no longer destroys the target (#11050, #11058, #11041); while a restore replaces a database it refuses every write on every protocol, so nothing is acknowledged and then lost (#10689, #10533); and under HA it waits for the leader commits still replicating and refuses replica writes (#10881, #10965). A snapshot install checks the installed files against the leader's account before the backup is deleted (#11200, #11223).
- HA: an index compaction whose publication has an unknown outcome quarantines the leader instead of leaving its index silently short (#11240); a refused
CREATE INDEX ... UNIQUEno longer quarantines the leader (#10506, #10569); eight apply-path failures no longer let the checkpoint move past an entry this node skipped (#10086); one Gremlin write sent to a follower is no longer applied several times (#11182); a replicated apply publishes its pages under the publication sequence protocol (#10941). - A database opened
READ_ONLYwrites nothing when it closes (#10507), andschema.prev.jsonis a byte copy, never a hard link, so it stays readable on SeaweedFS and similar file systems (#11097).
Graph and openCypher correctness
- Concurrent edge deletes no longer leave an edge list naming a deleted edge or a reused RID (#10263, #10304), a lightweight-edge delete after reading an outdated list is no longer lost (#10302, #10315), a super-node delete removes exactly one twin (#10314), and an edge-list
Iterator.remove()no longer loses its removal at commit (#10375). - A
MutableVertextaken bymodify()no longer saves a stale edge list over edges appended through another handle (#10929);DROP TYPErefuses an edge type whose edges are all lightweight (#10923, #11142);REBUILD TYPE ... POLYMORPHIC WITH repartition = trueno longer rewrites subtype records as the scanned supertype (#11042, #11043, #11066). CHECK DATABASE FIXon a super-node no longer deletes its lightweight edges (#10377), and deleting a vertex no longer leaves its self-loop edge records behind (#10520).- openCypher: an explicit write of a lookup key makes the query eager, so a
MATCHfilter sees the graph as it was before the write (#11173, #11230); temporal values compare, add and construct as in Neo4j (#10198, #10199, #10200);DISTINCT,GROUP BY,UNION,min()andmax()keyBINARYandARRAY_OF_*values by content (#10380, #10195); dynamic labels inCREATE/MERGEare no longer dropped (#10683); and a long run of query-correctness reports from @YGY-001 is fixed (LIMIT 0afterWITH collect(),CALL { } IN TRANSACTIONSafter an empty batch,WITH *andFOREACHvisibility, among others: #10892, #10886, #10891, #10890, #10889, #10515, #10513, #10512, #11004, #11005, #11008). - Graph Analytical Views reach the commits in commit order (#10249), no longer count an edge twice after a background compaction (#11192), pin one snapshot per query (#10365), and need far less heap to build and restore: a 6M-edge view now builds in a 112 MB heap (#11011).
Time series
- Deletes,
TRUNCATEand late samples keep continuous aggregates right on every ingest path (SQL, Java API, async, line protocol, Prometheus remote write, gRPC, JSONL importer), under HA too (#10502, #10686, #10632, #10633, #10634, #10673). WHERE ts > 9223372036854775807no longer overflows to the whole range, whereDELETEremoved every sample (#10528); a type rename moves the engine's files (#10749);DROP TYPEserialises with a sealed-file merge (#10866, #10867);CREATE TIMESERIES TYPErefuses a sealed file already at its name (#10925).- Cypher, Gremlin and GraphQL refuse a time-series type instead of matching nothing (#10440, #10442), MongoDB QL reads it (#10468), and SQL
INSERTrefuses a number for aBOOLEANorSTRINGcolumn, as every other ingest path does (#10137).
Security
Authorization, input-bounds and hardening fixes found by audit and by reporters. The related GitHub security advisories are published with this release.
- MongoDB wire: a legacy
OP_QUERYon a collection no longer reaches documents without passing the authorization gate. - Per-type ACL: the first batch request to a closed database opened on demand now binds the per-type ACL; renaming a type with only
updateSchemano longer escapes the ACL of the type; three schema listings, the cluster endpoint and the gRPCgetDatabaseInfofilter what a user cannot read; full-text BM25 statistics respect bucket access control. - Security file reloads (#10321, #10326, #10383, #10403, #10451, #10460, #10404): a malformed, missing or unreadable
server-users.jsonl,server-groups.jsonor API-token file on a running server keeps the users, groups and tokens in force instead of replacing them with a default (a passwordlessroot, the default groups), keeps the bad file as an-errorcopy, and a replicated change whose write failed is no longer undone by the watcher. - Read-only paths: on the native image, writes nested in a
SELECT(andPROFILE INSERT) no longer pass the read-only query paths; analysing a Gremlin script no longer runs it, so the MCP read-only tool cannot commit a write (#11182); the MCP upsert tools honourallowSchemaChange, and MCP refusals no longer reveal which databases exist. - Plugin routes answer only the method they declare (#10157, #10296, #10385):
GET /api/v1/cluster/stepdownno longer steps the leader down, and a plugin can no longer silently replace another plugin's route or a core route. - Authentication: wrong Basic credentials answer 401, not 403 (#10109); a failed Bolt
LOGONno longer leaves the previous principal bound; the snapshot endpoint no longer falls back to Basic credentials on a wrong cluster token (#10827); a user'sresultSetLimitandreadTimeoutapply to that user only (#11248). - HA cluster token: a node refuses to start when the root password behind its derived cluster token changed, from the file or inline (#10601, #10924), and a sender can no longer force a Raft channel reset or take a throttle slot by naming this node in an unauthenticated header (#10144, #10225, #10299).
- Redis wire: an unauthenticated connection can no longer be held open at a trickle past the idle timeout, nor turn every junk byte into two SEVERE log records (40 KB of input wrote 6.2 MB of log) (#10597).
- Operator intent: a
/wssubscribe frame no longer reopens a database an operator closed (#10690).
Performance
- Graph: a Cypher triangle count written as one
MATCHtakes 5 ms on a Graph Analytical View and about 40 ms without one, where it took about 1,750 ms (#10255); variable-length hops with distinct endpoints walk the view, 6 hops from 222 ms to 6 ms (#10548);algo.bfsstops atmaxDepth(#10539);IN $listseeks the index with anOPTIONAL MATCH(#10354, contributed by @sainiteesh36). - Indexes and schema:
CREATE INDEX ... UNIQUEon a populated type is linear instead of quadratic (#10334), the sorted build runs beside pending writes to other types (#10466), and schema changes scale with the types (#10247). - Vectors: the
INT8/BINARYgraph build keeps the quantized rows instead of churning a float cache, 2.3x faster at 1M x 768 with about 50x less GC pause time (#10543);ARRAY_OF_FLOATSis stored fixed-width, 9 rows of 1536 dimensions per page instead of 7 (#10856); aPRODUCTrebuild keeps its PQ codebook (#10847) and reopens in 0.7 s instead of 2.6 s on 1M vectors (#10568); hybrid queries load each candidate once (#10129). - Storage and allocation: a bucket insert no longer walks every slot of its page, 19% of the CPU of a small insert (#10576); LSM lookups share one page view, 36-41% less allocation (#10654); a filtered scan reuses its rejected rows (#10655); variable-length number reads allocate nothing (#10656);
GraphBatchflushes one-bucket edge types in parallel (#10547). Several of these were contributed by @tae898. - Startup: the GraalVM polyglot engine is built only when a script language is used, so SQL and Cypher load no Truffle classes (#10245).
- PostgreSQL: a
SELECTof declared properties streams in chunks per fetch instead of being materialised whole (#6659, contributed by @GadiVenkatesh). - Redis: pipelined replies are sent together (0.35x to 0.8-0.9x of Redis on one connection, about 2x Redis with 200 connections), and in-memory commands bypass the query admission gate (#10499).
Major fixes and improvements
Wire protocols
- PostgreSQL catalog: psql
\dt,\d,\d+,\di,\dm,\df,\duand psqlodbcSQLColumns/SQLTablesanswer from the emulated catalog (#10228, #10473, #10691, #10591);pg_index,pg_depend,pg_matviews,pg_settingsand the JDBC type lookups are modelled (#10473, #10495, #10842, #10961); a statement that merely containedpg_catalogin a literal is executed again (#10695); a connection re-resolves its database after a close, restore or drop (#10692); text-format array parameters keep empty andNULLelements (#10870);format_type()andregtypeprint PostgreSQL's names (#10228). - Redis: a key starting with
$is no longer the same key as the one without it (#10694), inline commands are answered (#10597), and a command whose name is not a string gets an error instead of silence (#10845). - MongoDB: every command uses the instance currently open after a restore or reopen (#10562), and writes on a time-series collection are refused unless applied exactly (#10464).
- gRPC: graph projections and lists of a search hit arrive typed instead of as a Java
toStringor a JSON string (#11044, #11048, #11207),BeginTransactionrefusesSERIALIZABLE(#10386), and authentication faults are logged and counted (grpc.auth.faults.total) (#10142). - A closed database is reported as unavailable, not as a server fault, on every wire protocol (PostgreSQL
57P03, RedisLOADING, MongoDBTemporarilyUnavailable, gRPCUNAVAILABLE, BoltDatabaseUnavailable) (#10553, #10692). - HTTP: committing a session the server does not hold answers 404 instead of 204 (#10164);
POST /api/v1/beginvalidatesisolationLevel(#10295, #10337); the OpenAPI document works on the native image (#10573) and is accurate for the group listing (#11276).
SQL and functions
- String methods count Unicode characters, not UTF-16 code units, in SQL and openCypher (#10248, #10378, #10523, #10524).
=,<>,INandCONTAINScompare list and map elements as they compare scalars (#10595, #10448);DISTINCT,GROUP BY,min()andmax()compareBINARY, array, map and temporal values the way=does (#10696, #10697, #10710).- A
DATETIMEstring with an offset is stored as the UTC wall clock of the instant (#10489, #10596); a number into aDATEis a day count under everydateImplementation(#10910); invalid dates such as2021-02-30are refused (#10206). - On an edge,
outandinread the endpoints (#10684);shortestPath()maxDepthcounts edges (#10439), anddijkstra()/astar()bound the path (#10527);if,randomInt,pow()and the Cypher-style functions no longer truncate or wrap a number argument (#10699, #10850, #11047); positional and named parameters are counted, so an unbound placeholder is refused (#10721, #11098). INSERT INTO T FROM SELECT ... FROM Tno longer reads its own inserts (#10192), triggers fire for subtype records (#10207),REFRESH INCREMENTALviews follow writes to subtypes and joined types (#10205), and a refused schema statement changes nothing (#10317, #10412).
Packaging and deployment
- Every Docker image, JVM, native and custom distribution, runs as
1000:1000and declares the same five volumes (#10319, #10330, #10387); the compose quickstart persists all of them (#10402). - The Helm chart is the only supported Kubernetes deployment (#10542); a config directory moved off
<root>/config, or a volume mounted over it, is seeded with the shipped defaults (#10536, #10554); an HA node started with onlyarcadedb.server.rootPasswordPathforms a cluster (#10462). - The native image creates GEOSPATIAL indexes (#10423) and ships a parseable users template (#10320).
Importers and remote clients
- JSONL
EXPORT/IMPORT DATABASEround-trips declaredLIST/MAP OF DATE,BINARY,DOUBLEand record links (#10201, #10391, #10483, #10529); the JSON importer keeps integers and longs exact (#10756); GraphSON and GraphML export every property type (#10202). - The Java HTTP client reads
+/-InfinityandNaNfloats (#10899), sends aLocalDateparameter as a typed marker and readsLIST OF DATEitems back asLocalDate(#10865, #10908, #10909, reported by @TobiasJoseHermann). - Studio's record editor no longer discards edits or retypes untouched properties on save (#10082, #10083).
Build and CI
- CI runs Maven through
./mvnw, the slow and HA lanes run in parallel shards and the CI wall time dropped from 43 to 26 minutes (#10134, #11154, #11183, #11189, #10887, contributed by @agarg21); census tests enumerate from the authority they protect (#11199, #10982, contributed by @2748109647).
Upgrade notes
Each item links to the issue with the full migration detail; the complete write-up is in docs/release-26.11.1.md.
- Docker images run as UID 1000 (#10319, #10330). A volume written by an earlier native image (root on amd64, 65532 on arm64) or custom-distribution image (
100:101) must be handed over once withchown -R 1000:1000 <path>. Custom images now declareconfigandreplicationas volumes, and the compose quickstart mounts a named volume on all five: copy users, groups and tokens out of the old anonymousconfigvolume before recreating the stack (#10387, #10402). - Kubernetes:
config/arcadedb-statefulset.yamlis no longer shipped; move to the Helm chart at ArcadeData/arcadedb-helm (#10542). - HA cluster token: with a token derived from the root password (file or inline), the password can no longer be rotated with a rolling restart. Restart every node with
arcadedb.ha.clusterTokenAllowRotation=trueonce, or usearcadedb.ha.clusterTokenPath(#10601, #10924). - HTTP: wrong Basic credentials answer 401 (was 403) (#10109); committing an unknown or foreign session answers 404 (was 204) (#10164); plugin routes answer 405 on an undeclared method, and
registerAPI(HttpServer, PathHandler)is deprecated for removal (#10157, #10296); a plugin route that collides with another plugin's or a core route fails the server start (#10385). - Transactions: a failed statement inside a transaction is taken back and the commit publishes the rest (#10346); a failed joined
transaction()leaves the caller's transaction open (#10135);UPDATE ... SETreads the pre-statement row and an explicitNULLis stored asNULL, so aNOTNULLproperty with a default refuses it (#10194). - SQL and openCypher answers that changed:
- string functions count characters, not UTF-16 code units (#10248, #10378);
- Cypher durations are not comparable with
</>, alocaldatetime()is not adatetime(), duration arithmetic is exact and calendar units follow the local calendar (#10198, #10199, #10200); - a
DATETIMEstring with an offset is stored as UTC (values already stored are not rewritten), andasDateTime(format)/date(value, format)follow (#10489, #10596); - list and map elements compare as scalars,
[1] = ['1']istrue(#10595); on an edgeout/inare the endpoints (#10684);shortestPath()maxDepthcounts edges, lower it by one if you raised it as a workaround (#10439); - a fractional or out-of-range integer argument is refused by
if,randomInt,vector.sparseCreateand the Cypher-style functions (#10699, #10850, #10954); - a number into a
DATEis a day count under everydateImplementation(#10910), an impossible date such as2021-02-30is refused, and aDATEcompared with aDATETIMEis midnight of that day (#10206); - a SQL statement given more or fewer parameter values than it has placeholders is refused instead of dropping or binding
null(#10721, #11098); - Cypher, Gremlin and GraphQL fail on a time-series type instead of matching nothing (#10440, #10442), and SQL
INSERTinto a time series refuses a number for aBOOLEANorSTRINGcolumn (#10137).
- Indexes and storage: a transaction that gives one UNIQUE key to two records now fails (#10265); an update of a record with an undecodable property is refused (#10955); a
PRODUCTvector index ranks through PQ codes and re-ranks, raisererankorrerankOversampleif recall matters more than speed (#10514). - Remote drivers: deleting a missing or vetoed record throws
RecordNotFoundException/RecordVetoedException(#10230); aLocalDateparameter is sent as a typed marker, so upgrade client and server together (#10908); gRPCBeginTransactionrefusesSERIALIZABLE(#10386). - Wire protocols: PostgreSQL
format_type()andregtypeprintinteger,character varying(#10228); Redis closes a connection on a malformed message (#10597); MongoDB refuses updates and inexact deletes on a time-series collection (#10464). - HA: a compaction publication with an unknown outcome quarantines and resyncs the leader (#11240).
Dependency updates
About 75 dependency bumps landed in this cycle, almost all through Dependabot. The notable ones:
- Server and engine: gRPC 1.84.0, GraalVM Polyglot 25.4, jvector 4.0.2 (native vectorization off unless configured), Jackson 2.22.4, Micrometer 1.17.2, OpenTelemetry 1.67.0, Logback 1.6.6, Gson 2.15.0, jboss-threads 3.11.1, lz4-java 1.12.1, snappy-java 1.1.10.12, JLine 4.4.8 and swagger 3.0.0. Guava is pinned to 33.7.2-android (CVE-2026-102554) (#11237).
- Studio: Apache ECharts replaces ApexCharts, d3-force drives the live graph physics, cytoscape 3.34.4 and swagger-ui-dist 5.34.0; JSZip and the PDF export are gone, and the license check now fails the build on a package outside the allow-list (#10579, #10626).
- Build and test: Surefire/Failsafe 3.6.1, JaCoCo 0.8.16, GraalVM native-maven-plugin 1.1.16, ASM 9.11.1, testcontainers, the Neo4j drivers of the e2e suites and the Go module bumps.
- CI: GitHub Actions and pre-commit hook bumps.
To everyone who reported, reproduced, reviewed, tested and fixed - in particular @ruispereira, @tae898, @YGY-001, @chetto1983, @ItsDeadlyProgrammer, @shaunpatterson, @neomodular, @sainiteesh36, @YaeSakuraQ, @GadiVenkatesh, @agarg21, @gramian, @7487, @2748109647, @pwitherton, @TobiasJoseHermann, @FilBr, @singh-hovr, @shulei5831sl, @FEARIS2