diff --git a/Directory.Build.props b/Directory.Build.props index eaf8f959..a8618289 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -29,7 +29,7 @@ $(NoWarn);CS8629;CA1416;CS0649 - preview diff --git a/Directory.Packages.props b/Directory.Packages.props index 4ba61bf1..1fc8447f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,7 +2,7 @@ true true - 2.1.0 + 2.1.1 diff --git a/NuGet.README.md b/NuGet.README.md index 7fee4b43..108ee268 100644 --- a/NuGet.README.md +++ b/NuGet.README.md @@ -11,7 +11,7 @@ ## πŸš€ Overview -**SharpCoreDB.Graph.Advanced** (v2.1.0) extends SharpCoreDB with advanced graph analytics capabilities: +**SharpCoreDB.Graph.Advanced** (v2.1.1) extends SharpCoreDB with advanced graph analytics capabilities: - βœ… **Community Detection**: Louvain, Label Propagation, Connected Components - βœ… **Centrality Metrics**: Degree, Betweenness, Closeness, Eigenvector @@ -35,21 +35,21 @@ ```bash # Install SharpCoreDB core -dotnet add package SharpCoreDB --version 2.1.0 +dotnet add package SharpCoreDB --version 2.1.1 # Install graph extensions -dotnet add package SharpCoreDB.Graph --version 2.1.0 +dotnet add package SharpCoreDB.Graph --version 2.1.1 # Install advanced analytics (includes GraphRAG) -dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.0 +dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.1 # Optional: Vector search for GraphRAG -dotnet add package SharpCoreDB.VectorSearch --version 2.1.0 +dotnet add package SharpCoreDB.VectorSearch --version 2.1.1 ``` **Requirements:** - .NET 11.0+ -- SharpCoreDB 2.1.0+ +- SharpCoreDB 2.1.1+ --- diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 955a7e30..e849ddcd 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,9 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -> **Where this bucket ends.** The `v2.1.0` tag was cut from this line's `HEAD` on 2026-10-10, so every -> entry this bucket had collected up to that tag β€” the net11.0 line's work since `2.0.0.3` β€” **shipped in -> `[2.1.0]`** below; the entries dated 2026-10-11 are the only still-unreleased ones (`git log v2.1.0..HEAD`). +> **Where this bucket ends.** `2.1.1` was cut from this line's `HEAD` on 2026-10-25, so every entry this +> bucket had collected since the `v2.1.0` tag β€” the list below β€” **shipped in `[2.1.1]`**. New entries +> start here. + +## [2.1.1] - 2026-10-25 + +> **What this release is.** A patch release with no API changes, cut from `v2.1.0..HEAD`. The SQL vector +> surface works end to end for the first time in a published package: a bound `float[]` parameter reaches +> a `VECTOR(n)` column as a vector, and `ORDER BY vec_distance_*() LIMIT k` reaches the vector index +> instead of scanning. The entries the `[Unreleased]` bucket had collected since `v2.1.0` ship here too. ### Added @@ -48,6 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- **`ORDER BY vec_distance_cosine(...) LIMIT k` never reached the vector index and `CREATE VECTOR INDEX` never built one β€” two independent breaks, either of which alone leaves the symptom.** (1) **The planner branch was a stub:** `SqlParser.TryExecuteVectorOptimized` returned `null` unconditionally with four unused parameters; `e220461e` had a working implementation (argument extractor included) and `997103be` replaced it, while `VectorQueryOptimizer` itself stayed intact β€” only the call path was gone. (2) **Nothing was ever wired to the parser:** `SqlParser.VectorQueryOptimizer` was an `internal static` property no engine code assigned and no other assembly *could* assign (the parser is `internal`), and `SharpCoreDB.VectorSearch` only registers the optimizer with the DI container β€” so both null-conditional consumers, the ranking branch *and* `CREATE VECTOR INDEX`, were dead, which is why the whole SQL surface looked like "the optimizer declined". `Database.GetSharedSqlParser` now resolves `IVectorQueryOptimizer` from the service provider (the pattern `IGraphRagProvider` already used) and attaches it per parser instance through `SetVectorQueryOptimizer`, the duplicate `new SqlParser(...)` in the `ExecuteCompiledQuery` fallback routes through `GetSharedSqlParser` so there is one construction point, and the restored planner projects onto the SELECT list (`SELECT *`, aliases and the distance expression substituted), accepts an `ORDER BY` that names either the alias or the function, and refuses `DESC` and a non-empty `WHERE` β€” an ascending top-k cannot answer those, and returning a plausible-but-wrong shape silently is what made the original bug hard to see, so those two fall back to a scan. A `float[]` argument is sent unquoted as `[1,0,0,0]`, and the argument splitter tracks bracket and brace nesting instead of parentheses only, since a query vector is not a call argument. The existing `VectorQueryOptimizer` unit tests stayed green through all of this because they exercise the optimizer directly and never through `Database`; the new `SqlVectorQueryTests` go through `AddVectorSupport()` + `Database` + SQL β€” the only level where the wiring is observable β€” and cover the index built by `CREATE VECTOR INDEX`, `ORDER BY vec_distance_cosine` with a literal and with a parameter vector, the alias form, the `SELECT *` form, `DESC` and `WHERE` falling back to a scan, and a query against an index that does not exist. VectorSearch 255/255, core 2137/2137 (16 skipped), 0 errors. - **The ubuntu leg of `CI/CD Pipeline` was red on `master`, and the `Coverage (net11.0)` job withheld its verdict with it, because two documentation links carried the wrong case.** `docs/Vectors/VECTOR_MIGRATION_GUIDE.md` pointed its *Documentation* and *API Reference* links at `../vectors/README.md` while the directory is `docs/Vectors`: a path that resolves on Windows and macOS β€” the windows and macos legs were green β€” and 404s on a case-sensitive host, where the link guard `DocumentationMarkdownLinks_ShouldResolveToExistingFiles` (added in this line's own documentation audit, commit `bdb4e094`, which ran on Windows and macOS) failed with `Collection: ["Vectors/VECTOR_MIGRATION_GUIDE.md:793 -> ../vector…", ":794 -> ../vector…"]`, so `tools/measure-coverage.ps1` exited 2 (`FAILED SUITES: SharpCoreDB.Tests - coverage verdict withheld`) instead of evaluating the 18 % floor. Both links now read `../Vectors/README.md` β€” the form every other vector link in `docs/` already used β€” and the guard no longer depends on the host filesystem's case sensitivity: both copies of that resolution (the link sweep and `DocumentationIndex_ShouldOnlyReferenceExistingDocumentationFiles`) go through one `PathExistsWithExactCase` helper that matches every path segment ordinally, so a wrong-case link fails on Windows too instead of only in CI. Verified redβ†’green: with only the helper in place the test failed locally with exactly the two entries above, and passes after the link fix (documentation tests 9/0; core suite **2032 / 0 failed**, VectorSearch 248/0, EF Core 116/0, linq2DB 24/0). - **A `VECTOR(N)` column stored nothing that could be read back: the vector case was missing from eight copies of the per-type row codec, five value tokenizers, the single-file JSON reader and both parameter binders, so a `float[]` was persisted as the literal text `"System.Single[]"`.** The breakage had three independent layers, each confirmed against the source before it was touched. (1) **Row codecs:** `DataType.Vector` was absent from every per-type switch β€” `Table.Serialization`'s fixed-size map, `WriteTypedValueToSpan`/`ReadTypedValueFromSpan`, `GetEncodedSize`, `EncodeVariablePayload`/`DecodeVariablePayload`, and the same switch again in `FixedWidthRecordLayout`, `InsertBatchOptimized` (writer *and* size estimate), `StreamingRowEncoder`, `BulkInsertValuePipeline`, `BinaryRowDecoder`, `PageBasedDataWriter`, `ColumnarDataReader`, `StructRow` (write, `DeserializeValue` and `DeserializeValueBoxed`), `Table.ParallelScan` and `Table.GetColumnSize` β€” so a vector fell through to `default`, where the writers store `value.ToString()`. (2) **Tokenizers:** the VALUES literal splitter (`SqlParser.DML.ParseInsertValues`), the UPDATE `SET` splitter, `Database.Batch.ParseValues`, `SingleFileDatabase.Batch.ParseValueList` and `SqlParserExtensions.ExtractValues` all split on every comma outside quotes, so the bracketed literal `[0.5, 0.25, 0.125, 0.0625]` arrived at the value parser as `[0.5` and raised `Invalid value '[0.5' for data type Vector: The input is not a valid Base-64 string`. `ParseInsertValues`' fast path and its documented reference loop now both honour a bracketed literal, and the string-based splitters share one `SqlInPredicate.SplitTopLevelComma`. (3) **Binding:** `ParameterBinder.FormatParameter` (and `CompiledQueryExecutor`) rendered a `float[]` parameter as `'System.Single[]'`, and the single-file store β€” which writes rows as JSON β€” read a vector back as a `JsonElement` (`"[0.5,0.25]"`) because `SingleFileTable.FromSerializableRow` converted by JSON kind only. Fixing the cause rather than nine symptoms, the format and the coercion now have one definition: `SharpCoreDB.DataStructures.VectorBinaryCodec` owns the `VEC\0` blob (`docs/Vectors/TECHNICAL_SPEC.md` Β§7 β€” magic, version 1, flags, 2 reserved bytes, LE dimension count, float32 payload), the length-prefixed framing the row codecs store, and the accepted representations (`float[]`, `Memory`/`ReadOnlyMemory`, `IEnumerable`, `double[]`, `byte[]` blob or raw float32, JSON array, base64, `0x` hex); `SharpCoreDB.VectorSearch.VectorSerializer` now delegates to it, so the engine and the HNSW/FLAT index cannot disagree about the layout. A value that is not a vector is now a type error naming the accepted forms instead of being stored as text. Two further copies were fixed on the way: the fixed-width codec's string fast path wrote raw UTF-8 into a VECTOR slot where the reader expects the blob (`types[i] is not (DataType.Blob or DataType.Vector)` now, mirroring the Blob exclusion), and `SharpCoreDB.Client`'s `GetFieldType` advertised `double[]` for a VECTOR column while every other surface produces `float[]`. Round trips are pinned by `VectorColumnStorageTests` (9), `VectorColumnRegressionTests` (11 β€” literal insert, binary `VEC\0` bytes present in the file, JSON-string/`float[]`/`ReadOnlyMemory`/`double[]` parameters, base64, quoted JSON, multi-row VALUES, UPDATE with two assignments, `InsertBatch`, the `StreamingRowEncoder`β†’`BinaryRowDecoder` pair, NULL, the single-file reopen matrix, and the two loud-failure cases) and `VectorBinaryCodecTests` (8); the storage round trips were red before the fix (8 of the 9 cases failed, first failure `Invalid value '[0.5' for data type Vector`), the 28 are green after it, and the 248-test VectorSearch suite is unchanged by the delegation. diff --git a/docs/analytics/README.md b/docs/analytics/README.md index f9b246b6..fff63daa 100644 --- a/docs/analytics/README.md +++ b/docs/analytics/README.md @@ -32,7 +32,7 @@ The SharpCoreDB Analytics Engine provides high-performance data aggregation, win ### Installation ```bash -dotnet add package SharpCoreDB.Analytics --version 2.1.0 +dotnet add package SharpCoreDB.Analytics --version 2.1.1 ``` ### Basic Aggregation diff --git a/docs/cqrs/README.md b/docs/cqrs/README.md index cb17731b..c1bdf88f 100644 --- a/docs/cqrs/README.md +++ b/docs/cqrs/README.md @@ -54,7 +54,7 @@ Non-goals: ## 2. Installation ```bash -dotnet add package SharpCoreDB.CQRS --version 2.1.0 +dotnet add package SharpCoreDB.CQRS --version 2.1.1 ``` --- diff --git a/docs/graphrag/README.md b/docs/graphrag/README.md index d75be33c..3ececa68 100644 --- a/docs/graphrag/README.md +++ b/docs/graphrag/README.md @@ -49,9 +49,9 @@ For package-level mapping, see `../FEATURE_MATRIX.md`. ## Quick start ```bash -dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.0 -dotnet add package SharpCoreDB.Graph --version 2.1.0 -dotnet add package SharpCoreDB.VectorSearch --version 2.1.0 +dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.1 +dotnet add package SharpCoreDB.Graph --version 2.1.1 +dotnet add package SharpCoreDB.VectorSearch --version 2.1.1 ``` ```csharp diff --git a/docs/manual/quickstart.md b/docs/manual/quickstart.md index f105e9f7..8ea34ff8 100644 --- a/docs/manual/quickstart.md +++ b/docs/manual/quickstart.md @@ -8,7 +8,7 @@ ## 1.1 Install ```bash -dotnet add package SharpCoreDB --version 2.1.0 +dotnet add package SharpCoreDB --version 2.1.1 ``` The engine targets **.NET 11** and **C# 15**. No native dependencies, no external processes β€” diff --git a/docs/scdb/PRODUCTION_GUIDE.md b/docs/scdb/PRODUCTION_GUIDE.md index 8a555a4d..fd4008f7 100644 --- a/docs/scdb/PRODUCTION_GUIDE.md +++ b/docs/scdb/PRODUCTION_GUIDE.md @@ -46,7 +46,7 @@ This guide covers deploying SharpCoreDB with the **SCDB (SharpCore DataBase)** s dotnet --version # Should show 11.0 or higher # NuGet Package -dotnet add package SharpCoreDB --version 2.1.0 +dotnet add package SharpCoreDB --version 2.1.1 ``` The 2.0.x servicing line on `release/v2.0` targets .NET 10 instead; match the runtime to the package diff --git a/src/SharpCoreDB.Analytics/NuGet.README.md b/src/SharpCoreDB.Analytics/NuGet.README.md index be798c63..e63428aa 100644 --- a/src/SharpCoreDB.Analytics/NuGet.README.md +++ b/src/SharpCoreDB.Analytics/NuGet.README.md @@ -53,7 +53,7 @@ Unlock enterprise-grade analytics with 100+ aggregate functions, window function ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Analytics --version 2.1.0 +dotnet add package SharpCoreDB.Analytics --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+ diff --git a/src/SharpCoreDB.Analytics/SharpCoreDB.Analytics.csproj b/src/SharpCoreDB.Analytics/SharpCoreDB.Analytics.csproj index 983795fb..e85c6750 100644 --- a/src/SharpCoreDB.Analytics/SharpCoreDB.Analytics.csproj +++ b/src/SharpCoreDB.Analytics/SharpCoreDB.Analytics.csproj @@ -4,7 +4,7 @@ net11.0 enable enable - 2.1.0 + 2.1.1 SharpCoreDB.Analytics @@ -13,7 +13,7 @@ SharpCoreDB.Analytics Analytics extensions for SharpCoreDB: aggregates, window functions, SIMD-accelerated analytics, and time-series helpers for .NET 11. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md analytics;aggregates;window-functions;statistics;timeseries;database;sharpcoredb;net11;csharp15 MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.Aspire.Hosting/SharpCoreDB.Aspire.Hosting.csproj b/src/SharpCoreDB.Aspire.Hosting/SharpCoreDB.Aspire.Hosting.csproj index 8a50f75b..2a7bd042 100644 --- a/src/SharpCoreDB.Aspire.Hosting/SharpCoreDB.Aspire.Hosting.csproj +++ b/src/SharpCoreDB.Aspire.Hosting/SharpCoreDB.Aspire.Hosting.csproj @@ -16,7 +16,7 @@ SharpCoreDB.Aspire.Hosting - 2.1.0 + 2.1.1 .NET Aspire hosting integration for the SharpCoreDB network server @@ -33,7 +33,7 @@ SharpCoreDB.jpg true snupkg - v2.1.0 (2026-10-10): .NET Aspire hosting package for SharpCoreDB.Server - container image ghcr.io/mpcoredeveloper/sharpcoredb-server with HTTPS gRPC (5001) and HTTPS REST API (8443) endpoints. Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/server/ASPIRE_INTEGRATION.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): .NET Aspire hosting package for SharpCoreDB.Server - container image ghcr.io/mpcoredeveloper/sharpcoredb-server with HTTPS gRPC (5001) and HTTPS REST API (8443) endpoints. Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/server/ASPIRE_INTEGRATION.md diff --git a/src/SharpCoreDB.CQRS/NuGet.README.md b/src/SharpCoreDB.CQRS/NuGet.README.md index f075f116..9d1f4cbb 100644 --- a/src/SharpCoreDB.CQRS/NuGet.README.md +++ b/src/SharpCoreDB.CQRS/NuGet.README.md @@ -28,7 +28,7 @@ CQRS and outbox primitives for `SharpCoreDB`. ## Installation ```bash -dotnet add package SharpCoreDB.CQRS --version 2.1.0 +dotnet add package SharpCoreDB.CQRS --version 2.1.1 ``` ## Documentation diff --git a/src/SharpCoreDB.CQRS/SharpCoreDB.CQRS.csproj b/src/SharpCoreDB.CQRS/SharpCoreDB.CQRS.csproj index 462c0af5..92b1ae3d 100644 --- a/src/SharpCoreDB.CQRS/SharpCoreDB.CQRS.csproj +++ b/src/SharpCoreDB.CQRS/SharpCoreDB.CQRS.csproj @@ -11,7 +11,7 @@ $(NoWarn);1591;SA1101;SA1633;SA1309 SharpCoreDB.CQRS - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.CQRS @@ -24,7 +24,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.Client.Protocol/SharpCoreDB.Client.Protocol.csproj b/src/SharpCoreDB.Client.Protocol/SharpCoreDB.Client.Protocol.csproj index 31d25091..2b483600 100644 --- a/src/SharpCoreDB.Client.Protocol/SharpCoreDB.Client.Protocol.csproj +++ b/src/SharpCoreDB.Client.Protocol/SharpCoreDB.Client.Protocol.csproj @@ -9,7 +9,7 @@ SharpCoreDB.Client.Protocol - 2.1.0 + 2.1.1 Client-side protocol implementation for SharpCoreDB (gRPC, binary) @@ -26,7 +26,7 @@ SharpCoreDB.jpg true snupkg - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.Client/NuGet.README.md b/src/SharpCoreDB.Client/NuGet.README.md index 2e47719f..8be2f102 100644 --- a/src/SharpCoreDB.Client/NuGet.README.md +++ b/src/SharpCoreDB.Client/NuGet.README.md @@ -27,7 +27,7 @@ ## Installation ```bash -dotnet add package SharpCoreDB.Client --version 2.1.0 +dotnet add package SharpCoreDB.Client --version 2.1.1 ``` ## Documentation diff --git a/src/SharpCoreDB.Client/SharpCoreDB.Client.csproj b/src/SharpCoreDB.Client/SharpCoreDB.Client.csproj index 9ce74bf4..15cc0662 100644 --- a/src/SharpCoreDB.Client/SharpCoreDB.Client.csproj +++ b/src/SharpCoreDB.Client/SharpCoreDB.Client.csproj @@ -9,7 +9,7 @@ SharpCoreDB.Client - 2.1.0 + 2.1.1 .NET client library for SharpCoreDB network server (ADO.NET-like API) diff --git a/src/SharpCoreDB.Data.Provider/NuGet.README.md b/src/SharpCoreDB.Data.Provider/NuGet.README.md index c66f7c51..76ce3ae4 100644 --- a/src/SharpCoreDB.Data.Provider/NuGet.README.md +++ b/src/SharpCoreDB.Data.Provider/NuGet.README.md @@ -57,7 +57,7 @@ while (reader.Read()) ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Data.Provider --version 2.1.0 +dotnet add package SharpCoreDB.Data.Provider --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+ diff --git a/src/SharpCoreDB.Data.Provider/SharpCoreDB.Data.Provider.csproj b/src/SharpCoreDB.Data.Provider/SharpCoreDB.Data.Provider.csproj index 561187b1..75998472 100644 --- a/src/SharpCoreDB.Data.Provider/SharpCoreDB.Data.Provider.csproj +++ b/src/SharpCoreDB.Data.Provider/SharpCoreDB.Data.Provider.csproj @@ -16,7 +16,7 @@ https://github.com/MPCoreDeveloper/SharpCoreDB https://github.com/MPCoreDeveloper/SharpCoreDB ado.net;database;data-provider;sharpcoredb - 2.1.0 + 2.1.1 git NuGet.README.md SharpCoreDB.jpg @@ -24,7 +24,7 @@ snupkg SharpCoreDB.Data.Provider Data provider layer for SharpCoreDB on .NET 11. - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md false diff --git a/src/SharpCoreDB.Distributed/NuGet.README.md b/src/SharpCoreDB.Distributed/NuGet.README.md index 0b0d8a03..001fe3eb 100644 --- a/src/SharpCoreDB.Distributed/NuGet.README.md +++ b/src/SharpCoreDB.Distributed/NuGet.README.md @@ -167,7 +167,7 @@ Multi-master replication, distributed transactions, and automatic sharding - Pha ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Distributed --version 2.1.0 +dotnet add package SharpCoreDB.Distributed --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+ diff --git a/src/SharpCoreDB.Distributed/SharpCoreDB.Distributed.csproj b/src/SharpCoreDB.Distributed/SharpCoreDB.Distributed.csproj index 639037d3..d3e3d3d0 100644 --- a/src/SharpCoreDB.Distributed/SharpCoreDB.Distributed.csproj +++ b/src/SharpCoreDB.Distributed/SharpCoreDB.Distributed.csproj @@ -15,7 +15,7 @@ SharpCoreDB.Distributed - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Distributed @@ -28,7 +28,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.EntityFrameworkCore/NuGet.README.md b/src/SharpCoreDB.EntityFrameworkCore/NuGet.README.md index e8c6cb58..3fb2117c 100644 --- a/src/SharpCoreDB.EntityFrameworkCore/NuGet.README.md +++ b/src/SharpCoreDB.EntityFrameworkCore/NuGet.README.md @@ -67,7 +67,7 @@ var users = await context.Users.Where(u => u.IsActive).ToListAsync(); ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.EntityFrameworkCore --version 2.1.0 +dotnet add package SharpCoreDB.EntityFrameworkCore --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+, EntityFrameworkCore v8.0+ diff --git a/src/SharpCoreDB.EntityFrameworkCore/SharpCoreDB.EntityFrameworkCore.csproj b/src/SharpCoreDB.EntityFrameworkCore/SharpCoreDB.EntityFrameworkCore.csproj index 558c8083..58c82450 100644 --- a/src/SharpCoreDB.EntityFrameworkCore/SharpCoreDB.EntityFrameworkCore.csproj +++ b/src/SharpCoreDB.EntityFrameworkCore/SharpCoreDB.EntityFrameworkCore.csproj @@ -8,13 +8,13 @@ SharpCoreDB.EntityFrameworkCore - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.EntityFrameworkCore - Entity Framework Core provider for SharpCoreDB encrypted database engine. Built for .NET 11 with C# 15. Supports Windows, Linux, macOS, Android, iOS, and IoT/embedded devices with platform-specific optimizations. Compatible with SharpCoreDB 2.1.0. + Entity Framework Core provider for SharpCoreDB encrypted database engine. Built for .NET 11 with C# 15. Supports Windows, Linux, macOS, Android, iOS, and IoT/embedded devices with platform-specific optimizations. Compatible with SharpCoreDB 2.1.1. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md sharpcoredb;entityframeworkcore;efcore;database;encryption;net11;csharp15;android;ios;mobile;iot;arm64;x64 MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.EventSourcing/NuGet.README.md b/src/SharpCoreDB.EventSourcing/NuGet.README.md index 2da7c648..60a869d2 100644 --- a/src/SharpCoreDB.EventSourcing/NuGet.README.md +++ b/src/SharpCoreDB.EventSourcing/NuGet.README.md @@ -28,7 +28,7 @@ Event store primitives for `SharpCoreDB`. ## Installation ```bash -dotnet add package SharpCoreDB.EventSourcing --version 2.1.0 +dotnet add package SharpCoreDB.EventSourcing --version 2.1.1 ``` ## Documentation diff --git a/src/SharpCoreDB.EventSourcing/SharpCoreDB.EventSourcing.csproj b/src/SharpCoreDB.EventSourcing/SharpCoreDB.EventSourcing.csproj index 4f9f4004..a08a8293 100644 --- a/src/SharpCoreDB.EventSourcing/SharpCoreDB.EventSourcing.csproj +++ b/src/SharpCoreDB.EventSourcing/SharpCoreDB.EventSourcing.csproj @@ -14,7 +14,7 @@ $(NoWarn);1591;SA1101;SA1633;SA1309 SharpCoreDB.EventSourcing - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.EventSourcing @@ -27,7 +27,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) with optimistic-concurrency conditional appends - IEventStore.TryAppendEventsAsync / TryAppendEventAsync with an expectedVersion, returning ConditionalAppendResult (Conflict carries the expected and actual stream lengths). This is the append-only ledger's compare-and-set primitive: a writer that lost the race is told so and nothing is written. + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) with optimistic-concurrency conditional appends - IEventStore.TryAppendEventsAsync / TryAppendEventAsync with an expectedVersion, returning ConditionalAppendResult (Conflict carries the expected and actual stream lengths). This is the append-only ledger's compare-and-set primitive: a writer that lost the race is told so and nothing is written. diff --git a/src/SharpCoreDB.Extensions/NuGet.README.md b/src/SharpCoreDB.Extensions/NuGet.README.md index f4f9ec34..459de356 100644 --- a/src/SharpCoreDB.Extensions/NuGet.README.md +++ b/src/SharpCoreDB.Extensions/NuGet.README.md @@ -81,7 +81,7 @@ var userId = connection.QuerySingle( ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Extensions --version 2.1.0 +dotnet add package SharpCoreDB.Extensions --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+ diff --git a/src/SharpCoreDB.Extensions/SharpCoreDB.Extensions.csproj b/src/SharpCoreDB.Extensions/SharpCoreDB.Extensions.csproj index f0de2bb8..f04347a2 100644 --- a/src/SharpCoreDB.Extensions/SharpCoreDB.Extensions.csproj +++ b/src/SharpCoreDB.Extensions/SharpCoreDB.Extensions.csproj @@ -8,13 +8,13 @@ SharpCoreDB.Extensions - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Extensions Extensions for SharpCoreDB including Dapper integration and ASP.NET Core health checks. Built for .NET 11 with C# 15. Supports Windows, Linux, macOS, Android, iOS, and IoT/embedded devices with platform-specific optimizations. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md sharpcoredb;database;dapper;healthchecks;extensions;net11;csharp15;android;ios;mobile;iot;arm64;x64 MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.Functional.Dapper/SharpCoreDB.Functional.Dapper.csproj b/src/SharpCoreDB.Functional.Dapper/SharpCoreDB.Functional.Dapper.csproj index e2abf357..6bb55a39 100644 --- a/src/SharpCoreDB.Functional.Dapper/SharpCoreDB.Functional.Dapper.csproj +++ b/src/SharpCoreDB.Functional.Dapper/SharpCoreDB.Functional.Dapper.csproj @@ -7,13 +7,13 @@ enable SharpCoreDB.Functional.Dapper - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Functional.Dapper Dapper adapter for SharpCoreDB.Functional with zero-dependency Option/Fin APIs and fluent functional composition for .NET 11 and C# 15. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md sharpcoredb;functional;dapper;option;fin;net11;csharp15 MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.Functional.EntityFrameworkCore/SharpCoreDB.Functional.EntityFrameworkCore.csproj b/src/SharpCoreDB.Functional.EntityFrameworkCore/SharpCoreDB.Functional.EntityFrameworkCore.csproj index fe2d59f4..221287e1 100644 --- a/src/SharpCoreDB.Functional.EntityFrameworkCore/SharpCoreDB.Functional.EntityFrameworkCore.csproj +++ b/src/SharpCoreDB.Functional.EntityFrameworkCore/SharpCoreDB.Functional.EntityFrameworkCore.csproj @@ -7,13 +7,13 @@ enable SharpCoreDB.Functional.EntityFrameworkCore - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Functional.EntityFrameworkCore Entity Framework Core adapter for SharpCoreDB.Functional with zero-dependency Option/Fin APIs and fluent functional composition for .NET 11 and C# 15. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md sharpcoredb;functional;entityframeworkcore;efcore;option;fin;net11;csharp15 MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.Functional.Linq2DB/SharpCoreDB.Functional.Linq2DB.csproj b/src/SharpCoreDB.Functional.Linq2DB/SharpCoreDB.Functional.Linq2DB.csproj index 93e85afc..b920ac20 100644 --- a/src/SharpCoreDB.Functional.Linq2DB/SharpCoreDB.Functional.Linq2DB.csproj +++ b/src/SharpCoreDB.Functional.Linq2DB/SharpCoreDB.Functional.Linq2DB.csproj @@ -7,13 +7,13 @@ enable SharpCoreDB.Functional.Linq2DB - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Functional.Linq2DB Production-ready linq2db adapter for SharpCoreDB.Functional. Zero-dependency Option/Fin/Seq APIs, compile-time LINQ safety, BulkCopy batching, full type mappings (ULID/GUID), and low-overhead queries. Perfect for AI/agentic and GraphRAG workloads on .NET 11 / C# 15. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md sharpcoredb;functional;linq2db;linq;option;fin;net11;csharp15;aot MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.Functional/SharpCoreDB.Functional.csproj b/src/SharpCoreDB.Functional/SharpCoreDB.Functional.csproj index f1ca9cc1..d633a3bd 100644 --- a/src/SharpCoreDB.Functional/SharpCoreDB.Functional.csproj +++ b/src/SharpCoreDB.Functional/SharpCoreDB.Functional.csproj @@ -7,13 +7,13 @@ enable SharpCoreDB.Functional - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Functional Functional facade for SharpCoreDB with zero-dependency Option, Fin, Seq, and Unit types, fluent composition, and low-allocation wrappers for .NET 11 and C# 15. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md sharpcoredb;functional;option;result;fin;monad;net11;csharp15 MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.Graph.Advanced/NuGet.README.md b/src/SharpCoreDB.Graph.Advanced/NuGet.README.md index 8e973d01..54c59259 100644 --- a/src/SharpCoreDB.Graph.Advanced/NuGet.README.md +++ b/src/SharpCoreDB.Graph.Advanced/NuGet.README.md @@ -28,7 +28,7 @@ Advanced graph analytics and GraphRAG package for `SharpCoreDB`. ## Installation ```bash -dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.0 +dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.1 ``` ## Documentation diff --git a/src/SharpCoreDB.Graph.Advanced/SharpCoreDB.Graph.Advanced.csproj b/src/SharpCoreDB.Graph.Advanced/SharpCoreDB.Graph.Advanced.csproj index 9db8ca42..c0e7d07f 100644 --- a/src/SharpCoreDB.Graph.Advanced/SharpCoreDB.Graph.Advanced.csproj +++ b/src/SharpCoreDB.Graph.Advanced/SharpCoreDB.Graph.Advanced.csproj @@ -6,7 +6,7 @@ preview SharpCoreDB.Graph.Advanced SharpCoreDB.Graph.Advanced - 2.1.0 + 2.1.1 SharpCoreDB.Graph.Advanced MPCoreDeveloper MPCoreDeveloper diff --git a/src/SharpCoreDB.Graph/NuGet.README.md b/src/SharpCoreDB.Graph/NuGet.README.md index 2a418c79..303906b8 100644 --- a/src/SharpCoreDB.Graph/NuGet.README.md +++ b/src/SharpCoreDB.Graph/NuGet.README.md @@ -53,7 +53,7 @@ A* pathfinding and graph algorithms **30-50% faster than alternatives** with pur ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Graph --version 2.1.0 +dotnet add package SharpCoreDB.Graph --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+ diff --git a/src/SharpCoreDB.Graph/SharpCoreDB.Graph.csproj b/src/SharpCoreDB.Graph/SharpCoreDB.Graph.csproj index 86d07bb0..2a6ca1ad 100644 --- a/src/SharpCoreDB.Graph/SharpCoreDB.Graph.csproj +++ b/src/SharpCoreDB.Graph/SharpCoreDB.Graph.csproj @@ -13,7 +13,7 @@ $(NoWarn);1591;SA1101;SA1633;SA1309 SharpCoreDB.Graph - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Graph @@ -26,7 +26,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.HybridSearch/SharpCoreDB.HybridSearch.csproj b/src/SharpCoreDB.HybridSearch/SharpCoreDB.HybridSearch.csproj index 88ab6348..24acf2cc 100644 --- a/src/SharpCoreDB.HybridSearch/SharpCoreDB.HybridSearch.csproj +++ b/src/SharpCoreDB.HybridSearch/SharpCoreDB.HybridSearch.csproj @@ -12,7 +12,7 @@ $(NoWarn);1591;SA1101;SA1633;SA1309 SharpCoreDB.HybridSearch - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.HybridSearch @@ -25,7 +25,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview). Fuses the BM25 lexical leg and the vector leg by RANK (never by raw score), with per-leg ranks carried on every hit. + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview). Fuses the BM25 lexical leg and the vector leg by RANK (never by raw score), with per-leg ranks carried on every hit. diff --git a/src/SharpCoreDB.Identity/SharpCoreDB.Identity.csproj b/src/SharpCoreDB.Identity/SharpCoreDB.Identity.csproj index 3f7f3fcf..d74512cf 100644 --- a/src/SharpCoreDB.Identity/SharpCoreDB.Identity.csproj +++ b/src/SharpCoreDB.Identity/SharpCoreDB.Identity.csproj @@ -8,7 +8,7 @@ true SharpCoreDB.Identity - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Identity diff --git a/src/SharpCoreDB.Projections/NuGet.README.md b/src/SharpCoreDB.Projections/NuGet.README.md index e53f8f44..61a47923 100644 --- a/src/SharpCoreDB.Projections/NuGet.README.md +++ b/src/SharpCoreDB.Projections/NuGet.README.md @@ -28,7 +28,7 @@ Projection primitives for `SharpCoreDB.EventSourcing`. ## Installation ```bash -dotnet add package SharpCoreDB.Projections --version 2.1.0 +dotnet add package SharpCoreDB.Projections --version 2.1.1 ``` ## Documentation diff --git a/src/SharpCoreDB.Projections/SharpCoreDB.Projections.csproj b/src/SharpCoreDB.Projections/SharpCoreDB.Projections.csproj index 2613c81c..58ab88b5 100644 --- a/src/SharpCoreDB.Projections/SharpCoreDB.Projections.csproj +++ b/src/SharpCoreDB.Projections/SharpCoreDB.Projections.csproj @@ -11,7 +11,7 @@ $(NoWarn);1591;SA1101;SA1633;SA1309 SharpCoreDB.Projections - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Projections @@ -24,7 +24,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.Provider.Sync/NuGet.README.md b/src/SharpCoreDB.Provider.Sync/NuGet.README.md index ec2d6485..ec7fd884 100644 --- a/src/SharpCoreDB.Provider.Sync/NuGet.README.md +++ b/src/SharpCoreDB.Provider.Sync/NuGet.README.md @@ -71,7 +71,7 @@ Console.WriteLine($"Synced {result.TotalChangesDownloaded} changes from cloud"); ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Provider.Sync --version 2.1.0 +dotnet add package SharpCoreDB.Provider.Sync --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+, Dotmim.Sync.Core v1.3.0+ diff --git a/src/SharpCoreDB.Provider.Sync/SharpCoreDB.Provider.Sync.csproj b/src/SharpCoreDB.Provider.Sync/SharpCoreDB.Provider.Sync.csproj index e698bacc..072454ac 100644 --- a/src/SharpCoreDB.Provider.Sync/SharpCoreDB.Provider.Sync.csproj +++ b/src/SharpCoreDB.Provider.Sync/SharpCoreDB.Provider.Sync.csproj @@ -9,7 +9,7 @@ SharpCoreDB.Provider.Sync - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Provider.Sync diff --git a/src/SharpCoreDB.Provider.YesSql/NuGet.README.md b/src/SharpCoreDB.Provider.YesSql/NuGet.README.md index c600789b..fcabf070 100644 --- a/src/SharpCoreDB.Provider.YesSql/NuGet.README.md +++ b/src/SharpCoreDB.Provider.YesSql/NuGet.README.md @@ -36,7 +36,7 @@ YesSql ORM integration with SharpCoreDB's encryption and performance for documen ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Provider.YesSql --version 2.1.0 +dotnet add package SharpCoreDB.Provider.YesSql --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+, YesSql.Core v5.4.7+ diff --git a/src/SharpCoreDB.Provider.YesSql/SharpCoreDB.Provider.YesSql.csproj b/src/SharpCoreDB.Provider.YesSql/SharpCoreDB.Provider.YesSql.csproj index 6498b29e..cb49012e 100644 --- a/src/SharpCoreDB.Provider.YesSql/SharpCoreDB.Provider.YesSql.csproj +++ b/src/SharpCoreDB.Provider.YesSql/SharpCoreDB.Provider.YesSql.csproj @@ -8,13 +8,13 @@ SharpCoreDB.Provider.YesSql - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Provider.YesSql YesSql provider for SharpCoreDB encrypted database engine. Built for .NET 11 with C# 15. Supports Windows, Linux, macOS, Android, iOS, and IoT/embedded devices with platform-specific optimizations. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md sharpcoredb;yessql;database;orm;net11;csharp15;android;ios;mobile;iot;arm64;x64 MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/src/SharpCoreDB.Search/SharpCoreDB.Search.csproj b/src/SharpCoreDB.Search/SharpCoreDB.Search.csproj index 52d8b071..e1318f2e 100644 --- a/src/SharpCoreDB.Search/SharpCoreDB.Search.csproj +++ b/src/SharpCoreDB.Search/SharpCoreDB.Search.csproj @@ -12,7 +12,7 @@ $(NoWarn);1591;SA1101;SA1633;SA1309 SharpCoreDB.Search - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Search @@ -25,7 +25,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview). Munarium-inspired lexical stack: a classifying tokenizer (numbers, sign absorption, hyphen compounds), PostgreSQL-16 English stop words, an English word-only stemmer and a BM25 inverted index with positions. + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview). Munarium-inspired lexical stack: a classifying tokenizer (numbers, sign absorption, hyphen compounds), PostgreSQL-16 English stop words, an English word-only stemmer and a BM25 inverted index with positions. diff --git a/src/SharpCoreDB.Serilog.Sinks/NuGet.README.md b/src/SharpCoreDB.Serilog.Sinks/NuGet.README.md index 578647af..6e811497 100644 --- a/src/SharpCoreDB.Serilog.Sinks/NuGet.README.md +++ b/src/SharpCoreDB.Serilog.Sinks/NuGet.README.md @@ -53,7 +53,7 @@ Log.Error(ex, "An error occurred"); ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.Serilog.Sinks --version 2.1.0 +dotnet add package SharpCoreDB.Serilog.Sinks --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+, Serilog v2.13+ diff --git a/src/SharpCoreDB.Serilog.Sinks/SharpCoreDB.Serilog.Sinks.csproj b/src/SharpCoreDB.Serilog.Sinks/SharpCoreDB.Serilog.Sinks.csproj index 45760444..58e19c1d 100644 --- a/src/SharpCoreDB.Serilog.Sinks/SharpCoreDB.Serilog.Sinks.csproj +++ b/src/SharpCoreDB.Serilog.Sinks/SharpCoreDB.Serilog.Sinks.csproj @@ -7,7 +7,7 @@ SharpCoreDB.Serilog.Sinks - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.Serilog.Sinks @@ -24,7 +24,7 @@ false true snupkg - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.Server.Core/SharpCoreDB.Server.Core.csproj b/src/SharpCoreDB.Server.Core/SharpCoreDB.Server.Core.csproj index 55e4d5fe..0f55a5fa 100644 --- a/src/SharpCoreDB.Server.Core/SharpCoreDB.Server.Core.csproj +++ b/src/SharpCoreDB.Server.Core/SharpCoreDB.Server.Core.csproj @@ -9,7 +9,7 @@ SharpCoreDB.Server.Core - 2.1.0 + 2.1.1 Core server infrastructure for SharpCoreDB network server @@ -26,7 +26,7 @@ SharpCoreDB.jpg true snupkg - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.Server.Protocol/SharpCoreDB.Server.Protocol.csproj b/src/SharpCoreDB.Server.Protocol/SharpCoreDB.Server.Protocol.csproj index 565ff7a7..5e77c1b3 100644 --- a/src/SharpCoreDB.Server.Protocol/SharpCoreDB.Server.Protocol.csproj +++ b/src/SharpCoreDB.Server.Protocol/SharpCoreDB.Server.Protocol.csproj @@ -9,7 +9,7 @@ SharpCoreDB.Server.Protocol - 2.1.0 + 2.1.1 Network protocol definitions for SharpCoreDB server (gRPC, binary, HTTP) @@ -26,7 +26,7 @@ SharpCoreDB.jpg true snupkg - v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): net11.0-only (C# 15 preview) release line - 2,897 tests green across 16 suites; the fixed-width inline capacity ships at 16 by default on both storage paths (batched multi-row INSERT measured +12 to +19 percent); the overflow arena writes a row's payloads in one append instead of one file open per value; and in-place UPDATE/DELETE with deferred index maintenance put the fixed-width fair-PK layout ahead of SQLite on UPDATE (0.8x) and DELETE (0.5x). Full details: https://github.com/MPCoreDeveloper/SharpCoreDB/blob/master/docs/CHANGELOG.md diff --git a/src/SharpCoreDB.Server/NuGet.README.md b/src/SharpCoreDB.Server/NuGet.README.md index 4e0a8600..c08c79b5 100644 --- a/src/SharpCoreDB.Server/NuGet.README.md +++ b/src/SharpCoreDB.Server/NuGet.README.md @@ -35,7 +35,7 @@ Network database server package for `SharpCoreDB`. ## Installation ```bash -dotnet add package SharpCoreDB.Server.Core --version 2.1.0 +dotnet add package SharpCoreDB.Server.Core --version 2.1.1 ``` ## Documentation diff --git a/src/SharpCoreDB.Server/SharpCoreDB.Server.csproj b/src/SharpCoreDB.Server/SharpCoreDB.Server.csproj index 356c23a6..5ebecfd2 100644 --- a/src/SharpCoreDB.Server/SharpCoreDB.Server.csproj +++ b/src/SharpCoreDB.Server/SharpCoreDB.Server.csproj @@ -19,7 +19,7 @@ sharpcoredb-server SharpCoreDB Network Server SharpCoreDB network database server with gRPC and HTTP support - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB Copyright (c) 2026 MPCoreDeveloper diff --git a/src/SharpCoreDB.VectorSearch/NuGet.README.md b/src/SharpCoreDB.VectorSearch/NuGet.README.md index ff89e095..5964c307 100644 --- a/src/SharpCoreDB.VectorSearch/NuGet.README.md +++ b/src/SharpCoreDB.VectorSearch/NuGet.README.md @@ -54,7 +54,7 @@ Semantic search and similarity matching **50-100x faster than SQLite** using HNS ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB.VectorSearch --version 2.1.0 +dotnet add package SharpCoreDB.VectorSearch --version 2.1.1 ``` **Requires:** SharpCoreDB v1.9.5+ diff --git a/src/SharpCoreDB.VectorSearch/SharpCoreDB.VectorSearch.csproj b/src/SharpCoreDB.VectorSearch/SharpCoreDB.VectorSearch.csproj index 8ec47277..c2a2944f 100644 --- a/src/SharpCoreDB.VectorSearch/SharpCoreDB.VectorSearch.csproj +++ b/src/SharpCoreDB.VectorSearch/SharpCoreDB.VectorSearch.csproj @@ -15,7 +15,7 @@ SharpCoreDB.VectorSearch - 2.1.0 + 2.1.1 MPCoreDeveloper SharpCoreDB SharpCoreDB.VectorSearch @@ -28,7 +28,7 @@ git SharpCoreDB.jpg NuGet.README.md - v2.1.0 (2026-10-10): Munarium-inspired native C# features - DiskAnn index type, content-verified artifacts (canonical manifest + SHA256 artifact_id + verification), hybrid fusion weights, C# 15 record-based BuildResult for strict error handling. All changes are pure managed .NET 11 / C# 15 on the release/v2.1.0.0 branch. See docs/Vectors/MUNARIUM_INSPIRATION_PLAN.md. + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): Munarium-inspired native C# features - DiskAnn index type, content-verified artifacts (canonical manifest + SHA256 artifact_id + verification), hybrid fusion weights, C# 15 record-based BuildResult for strict error handling. All changes are pure managed .NET 11 / C# 15 on the release/v2.1.0.0 branch. See docs/Vectors/MUNARIUM_INSPIRATION_PLAN.md. diff --git a/src/SharpCoreDB/Database/Core/Database.Core.cs b/src/SharpCoreDB/Database/Core/Database.Core.cs index 89f99847..52012fed 100644 --- a/src/SharpCoreDB/Database/Core/Database.Core.cs +++ b/src/SharpCoreDB/Database/Core/Database.Core.cs @@ -57,6 +57,7 @@ public partial class Database : IDatabase, IDisposable, IAsyncDisposable private QueryPlanCache? planCache; // βœ… Lazy-initialized query plan cache private SqlParser? _sharedSqlParser; // βœ… Reusable SqlParser for compiled queries private IGraphRagProvider? _cachedGraphRagProvider; // v2: cached DI resolution (avoids per-call GetService) + private IVectorQueryOptimizer? _cachedVectorQueryOptimizer; // resolved once, same reason /// /// v2 (Native AOT readiness): metadata JSON options. resolves the diff --git a/src/SharpCoreDB/Database/Execution/Database.Execution.cs b/src/SharpCoreDB/Database/Execution/Database.Execution.cs index 18639a5c..4b52c430 100644 --- a/src/SharpCoreDB/Database/Execution/Database.Execution.cs +++ b/src/SharpCoreDB/Database/Execution/Database.Execution.cs @@ -31,21 +31,47 @@ private SqlParser GetSharedSqlParser() { _sharedSqlParser = new SqlParser(tables, _dbPath, storage, isReadOnly, queryCache, config); _sharedSqlParser.Database = this; + AttachOptionalProviders(_sharedSqlParser); + } - // v2: resolve the optional GRAPH_RAG provider once and cache it for the parser - // lifetime. Previously this DI lookup ran on every ExecuteSQL/ExecuteQuery call. - if (_cachedGraphRagProvider is null) - { - _cachedGraphRagProvider = _serviceProvider.GetService(typeof(IGraphRagProvider)) as IGraphRagProvider; - } + return _sharedSqlParser; + } - if (_cachedGraphRagProvider is not null) - { - _sharedSqlParser.SetGraphRagProvider(_cachedGraphRagProvider); - } + /// + /// Attaches the optional SQL extensions that live in separate assemblies and are therefore + /// resolved from the service provider instead of being referenced directly: the GRAPH_RAG + /// provider and the vector query optimizer. + /// + /// The vector optimizer used to be attached nowhere at all. SqlParser.VectorQueryOptimizer + /// was an internal static property that no code inside this assembly ever set and no other + /// assembly could set (the type is internal), so both of its consumers were permanent no-ops: + /// CREATE VECTOR INDEX built no index, and the ORDER BY vec_distance_*(...) LIMIT k + /// planner branch was never entered. Resolving here β€” the same + /// way the GRAPH_RAG provider is resolved β€” is what makes AddVectorSupport() reach the + /// planner. Both lookups are cached on the database, so a parser rebuild costs nothing when the + /// extension is registered and resolves to null only once when it is not. + /// + /// + /// The parser instance to configure. + private void AttachOptionalProviders(SqlParser parser) + { + if (_cachedGraphRagProvider is null) + { + _cachedGraphRagProvider = _serviceProvider.GetService(typeof(IGraphRagProvider)) as IGraphRagProvider; } - return _sharedSqlParser; + if (_cachedGraphRagProvider is not null) + { + parser.SetGraphRagProvider(_cachedGraphRagProvider); + } + + _cachedVectorQueryOptimizer ??= + _serviceProvider.GetService(typeof(IVectorQueryOptimizer)) as IVectorQueryOptimizer; + + if (_cachedVectorQueryOptimizer is not null) + { + parser.SetVectorQueryOptimizer(_cachedVectorQueryOptimizer); + } } @@ -469,14 +495,11 @@ public List> ExecuteCompiledQuery(DataStructures.Prep return executor.Execute(stmt.CompiledPlan, parameters); } - // βœ… Fallback: Lazy-initialize shared SqlParser (thread-safe via Interlocked) - if (_sharedSqlParser is null) - { - _sharedSqlParser = new SqlParser(tables, _dbPath, storage, isReadOnly, queryCache, config); - _sharedSqlParser.Database = this; - } - - return _sharedSqlParser.ExecuteQuery(stmt.Plan, parameters); + // βœ… Fallback: the shared parser created by GetSharedSqlParser() (which also attaches the + // optional GRAPH_RAG provider and vector optimizer). This block used to build its own + // SqlParser, so a compiled query falling back here got a parser without either extension β€” + // the second of the two creation sites is exactly how an extension point loses its wiring. + return GetSharedSqlParser().ExecuteQuery(stmt.Plan, parameters); } /// diff --git a/src/SharpCoreDB/NuGet.README.md b/src/SharpCoreDB/NuGet.README.md index fa43fe8c..c8ca961a 100644 --- a/src/SharpCoreDB/NuGet.README.md +++ b/src/SharpCoreDB/NuGet.README.md @@ -1,8 +1,8 @@ -# SharpCoreDB 2.1.0 β€” Performance-First Database Engine +# SharpCoreDB 2.1.1 β€” Performance-First Database Engine **High-Performance Embedded AND Networked Database for .NET 11 (C# 15 preview)** -> **This is the 2.1.0 release line** β€” it targets **net11.0 only** with +> **This is the 2.1.x release line (current: 2.1.1)** β€” it targets **net11.0 only** with > **C# 15 preview** (`LangVersion=preview`). The net10.0 / C# 14 packages are the v2.0 stable > line, parked on `release/v2.0`. See `docs/net11/UPGRADE.md` for what the .NET 11 line adds. @@ -14,6 +14,26 @@ SharpCoreDB is a modern, encrypted, file-based database engine with SQL support, [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![SonarCloud Quality Gate](https://img.shields.io/sonar/quality_gate/MPCoreDeveloper_SharpCoreDB?server=https%3A%2F%2Fsonarcloud.io&logo=sonarcloud)](https://sonarcloud.io/dashboard?id=MPCoreDeveloper_SharpCoreDB) +## What's New in 2.1.1 + +**A patch release with no API changes**, cut from the commits since the `v2.1.0` tag: + +- **A `float[]` parameter bound to a `VECTOR(n)` column now arrives as a vector.** It used to be + formatted as the literal text `"System.Single[]"`, and a `VECTOR(N)` column stored nothing that + could be read back (the vector case was missing from eight row codecs, five tokenizers, the + single-file JSON reader and both parameter binders). +- **`ORDER BY vec_distance_*() LIMIT k` now reaches the vector index**, and `CREATE VECTOR INDEX` + builds one. The planner branch had been stubbed out and was never wired to `SqlParser`, so both + paths silently declined and every query scanned. What an ascending top-k cannot answer β€” a `DESC` + order, a non-empty `WHERE` β€” still falls back to a full scan instead of returning a wrong shape. +- **`information_schema` is answered by the engine itself**, so the embedded API and the REST + endpoint see the same catalog the PostgreSQL handshake does. +- **The 18 % coverage floor is measured and enforced in CI** (`.github/workflows/ci.yml` + + `tools/measure-coverage.ps1`), instead of being carried unmeasured. +- **Re-verified on the 2.1.1 tree:** build 0 errors, `pack` produces 27 packages, and **2,532 tests + / 0 failed** across the four CI suites (core 2,137 Β· VectorSearch 255 Β· EF Core 116 Β· linq2db 24). +- Full list: `docs/CHANGELOG.md` β€Ί `[2.1.1]`. + ## What's New in 2.1.0 - **The fixed-width inline capacity now ships at 16 by default on both storage paths.** A @@ -230,16 +250,16 @@ db.Flush(); // Persist to disk ## πŸ“¦ Installation ```bash -dotnet add package SharpCoreDB --version 2.1.0 +dotnet add package SharpCoreDB --version 2.1.1 ``` **Optional companion packages:** ```bash -dotnet add package SharpCoreDB.Functional --version 2.1.0 -dotnet add package SharpCoreDB.Functional.Dapper --version 2.1.0 -dotnet add package SharpCoreDB.Functional.EntityFrameworkCore --version 2.1.0 -dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.0 +dotnet add package SharpCoreDB.Functional --version 2.1.1 +dotnet add package SharpCoreDB.Functional.Dapper --version 2.1.1 +dotnet add package SharpCoreDB.Functional.EntityFrameworkCore --version 2.1.1 +dotnet add package SharpCoreDB.Graph.Advanced --version 2.1.1 ``` ## πŸ”„ Upgrading from v1.9 diff --git a/src/SharpCoreDB/Services/SqlParser.Core.cs b/src/SharpCoreDB/Services/SqlParser.Core.cs index 4ea9d69b..abe76ee9 100644 --- a/src/SharpCoreDB/Services/SqlParser.Core.cs +++ b/src/SharpCoreDB/Services/SqlParser.Core.cs @@ -118,12 +118,33 @@ internal SqlParser(Dictionary tables, string dbPath, bool isRead private List> _pendingQueryResults = []; /// - /// Optional vector query optimizer registered by the VectorSearch module. - /// When set, the query planner detects ORDER BY vec_distance_*() + LIMIT patterns - /// and routes them to a vector index instead of a full table scan. - /// Thread-safe: set once during Database initialization, read from any thread. + /// Optional vector query optimizer supplied by the VectorSearch module. + /// + /// When set, the planner detects ORDER BY vec_distance_*(col, vector) LIMIT k and + /// CREATE VECTOR INDEX routes them to a vector index instead of a full table scan. + /// + /// + /// This is a per-parser instance member, not a static one. It used to be + /// internal static, which made the extension point unreachable in practice: an + /// internal static on an internal class cannot be assigned by another assembly + /// (SharpCoreDB.VectorSearch registers with the DI + /// container, it cannot see this type), and no code inside this assembly ever assigned it + /// either. Every call site was therefore a null-conditional no-op, in both directions: + /// CREATE VECTOR INDEX built nothing and ORDER BY vec_distance_* never reached + /// the optimizer. resolves the registered optimizer from its service + /// provider and attaches it here (see Database.GetSharedSqlParser). + /// /// - internal static IVectorQueryOptimizer? VectorQueryOptimizer { get; set; } + internal IVectorQueryOptimizer? VectorQueryOptimizer { get; private set; } + + /// + /// Attaches the optional vector query optimizer for this parser instance. + /// Called by once, when the shared parser is created, with the + /// registered by AddVectorSupport() (if any). + /// + /// The optimizer to use, or for none. + internal void SetVectorQueryOptimizer(IVectorQueryOptimizer? optimizer) + => this.VectorQueryOptimizer = optimizer; /// public void Execute(string sql, IWAL? wal = null) diff --git a/src/SharpCoreDB/Services/SqlParser.DDL.cs b/src/SharpCoreDB/Services/SqlParser.DDL.cs index 788e8735..f7c880ae 100644 --- a/src/SharpCoreDB/Services/SqlParser.DDL.cs +++ b/src/SharpCoreDB/Services/SqlParser.DDL.cs @@ -1157,7 +1157,7 @@ private void ExecuteCreateVectorIndex(string sql, string[] parts, IWAL? wal) // Phase 5.4: Build live in-memory index if optimizer is registered // Supports DISKANN via VectorIndexManager / DiskAnnIndex - SqlParser.VectorQueryOptimizer?.BuildIndex(table, tableName, columnName, indexType); + this.VectorQueryOptimizer?.BuildIndex(table, tableName, columnName, indexType); wal?.Log(sql); } @@ -1191,7 +1191,7 @@ private void ExecuteDropVectorIndex(string sql, string[] parts, IWAL? wal) table.RemoveMetadata($"vector_index:{colName}:sql"); // Phase 5.4: Drop live in-memory index if optimizer is registered - SqlParser.VectorQueryOptimizer?.DropIndex(tableName, colName); + this.VectorQueryOptimizer?.DropIndex(tableName, colName); found = true; break; diff --git a/src/SharpCoreDB/Services/SqlParser.DML.cs b/src/SharpCoreDB/Services/SqlParser.DML.cs index 9a8af7a4..3a432609 100644 --- a/src/SharpCoreDB/Services/SqlParser.DML.cs +++ b/src/SharpCoreDB/Services/SqlParser.DML.cs @@ -1074,10 +1074,14 @@ private List> ExecuteSelectQuery(string sql, string[] TrackColumnUsage(tableName, whereStr); - // Phase 5.4: Detect ORDER BY vec_distance_*(col, query) LIMIT k β†’ route to vector index + // Phase 5.4: Detect ORDER BY vec_distance_*(col, query) LIMIT k β†’ route to vector index. + // The scan below stays the answer whenever the index cannot reproduce it exactly; see + // TryExecuteVectorOptimized for the two cases it refuses. if (limit.HasValue && limit.Value > 0 && VectorQueryOptimizer is not null) { - var vectorResult = TryExecuteVectorOptimized(sql, selectClause, tableName, orderBy, limit.Value, noEncrypt); + var vectorResult = TryExecuteVectorOptimized( + sql, selectClause, tableName, whereStr, orderBy, asc, limit.Value, noEncrypt); + if (vectorResult is not null) return vectorResult; } @@ -1108,6 +1112,395 @@ private List> ExecuteSelectQuery(string sql, string[] } + /// + /// The distance functions a vector index can answer. Kept in sync with + /// SharpCoreDB.VectorSearch.VectorQueryOptimizer; a name the optimizer does not know is + /// rejected by anyway. + /// + private static readonly string[] VectorDistanceFunctions = + [ + "VEC_DISTANCE_COSINE", + "VEC_DISTANCE_L2", + "VEC_DISTANCE_DOT", + ]; + + /// + /// Answers SELECT ... ORDER BY vec_distance_*(col, vector) LIMIT k from the vector index + /// instead of scanning and sorting the table. + /// + /// Returns β€” meaning "take the scan path" β€” unless the index can produce + /// exactly the rows, in exactly the shape, the query asks for. The implementation this replaces + /// returned every column plus a distance key no matter what the SELECT list said, and did + /// so for DESC and WHERE queries too, so an optimized query and an unoptimized one + /// returned different results for the same SQL. The rows are now projected like any other SELECT, + /// and the two shapes an ascending top-k index cannot answer fall through to the scan. + /// + /// + /// The full statement (the ORDER BY region is parsed from here). + /// The SELECT list, used for the distance alias and the projection. + /// The table being selected from. + /// The WHERE clause, if any, so a filtered query can be refused. + /// The single token the legacy parser read after ORDER BY. + /// False when ORDER BY ... DESC was requested. + /// The LIMIT value (k). + /// Whether to read ciphertext. + /// Projected rows, or null when the query must be answered by a scan. + private List>? TryExecuteVectorOptimized( + string sql, + string selectClause, + string tableName, + string? whereStr, + string? orderBy, + bool ascending, + int limit, + bool noEncrypt) + { + if (VectorQueryOptimizer is null || string.IsNullOrEmpty(orderBy) || limit <= 0) + { + return null; + } + + // An index scan returns the k nearest rows. That is not the answer to the other two shapes + // SQL allows here, and returning it anyway is how an "optimization" becomes a wrong result: + // * ORDER BY ... DESC asks for the k farthest, which reversing the nearest k does not give; + // * a WHERE clause would have to be applied after the index already chose its k, and + // post-filtering a limited set drops matching rows instead of fetching more of them. + if (!ascending || !string.IsNullOrWhiteSpace(whereStr)) + { + return null; + } + + var orderStart = sql.IndexOf(SqlConstants.ORDER, StringComparison.OrdinalIgnoreCase); + var orderCall = orderStart >= 0 ? FindVectorDistanceCall(sql, orderStart) : null; + var selectCall = FindVectorDistanceCall(selectClause, 0); + + // ORDER BY either re-states the distance function or names the alias the SELECT gave it. + var distanceAlias = selectCall is { } projection ? ReadAliasAfter(selectClause, projection.End) : null; + var orderByNamesAlias = distanceAlias is not null + && orderBy.Trim().Equals(distanceAlias, StringComparison.OrdinalIgnoreCase); + + // When the ORDER BY re-states the call, that call is the one being ordered on; the SELECT + // need not mention the function at all (SELECT id ... ORDER BY vec_distance_*(...)). + (string Function, string Column, string Argument, int End) call; + if (orderCall is { } orderedCall) + { + call = orderedCall; + } + else if (orderByNamesAlias && selectCall is { } projectedCall) + { + call = projectedCall; + } + else + { + return null; + } + + if (!IsSimpleIdentifier(call.Column) + || !VectorQueryOptimizer.CanOptimize(tableName, call.Column, call.Function, limit)) + { + return null; + } + + var queryVector = Unquote(call.Argument); + if (queryVector.Length == 0) + { + return null; + } + + var rows = VectorQueryOptimizer.ExecuteOptimized( + this.tables[tableName], + tableName, + call.Column, + call.Function, + queryVector, + limit, + noEncrypt); + + return ProjectVectorRows(rows, selectClause, distanceAlias, call.Function); + } + + /// + /// Finds the first vec_distance_*(column, vector) call at or after + /// and returns its function name, its column (bare name), its second argument as written, and the + /// index of its closing parenthesis. + /// + /// The text to search. + /// The index to start searching from. + /// The parsed call, or null when there is none. + private static (string Function, string Column, string Argument, int End)? FindVectorDistanceCall(string text, int start) + { + var searchFrom = Math.Min(start, text.Length); + var bestIndex = -1; + string? function = null; + + foreach (var candidate in VectorDistanceFunctions) + { + var index = text.IndexOf(candidate, searchFrom, StringComparison.OrdinalIgnoreCase); + if (index >= 0 && (bestIndex < 0 || index < bestIndex)) + { + bestIndex = index; + function = candidate; + } + } + + if (function is null) + { + return null; + } + + var open = text.IndexOf('(', bestIndex); + if (open < 0) + { + return null; + } + + var close = FindClosingParenthesis(text, open); + if (close < 0) + { + return null; + } + + var arguments = SplitVectorArguments(text[(open + 1)..close]); + if (arguments.Count < 2) + { + return null; + } + + return (function, ExtractBareColumn(arguments[0]), arguments[1], close); + } + + /// + /// Returns the index of the parenthesis matching the one at , tracking + /// nesting and skipping quoted text. + /// + /// The text holding the parentheses. + /// The index of the opening parenthesis. + /// The index of the closing parenthesis, or -1 when unbalanced. + private static int FindClosingParenthesis(string text, int open) + { + var depth = 0; + var inQuote = false; + + for (var i = open; i < text.Length; i++) + { + var c = text[i]; + + if (c == '\'') + { + inQuote = !inQuote; + continue; + } + + if (inQuote) + { + continue; + } + + if (c == '(') + { + depth++; + } + else if (c == ')' && --depth == 0) + { + return i; + } + } + + return -1; + } + + /// + /// Splits the argument list of a function call on its top-level commas, so a vector literal or a + /// nested call inside one argument stays in one piece. Brackets and braces count as nesting too: + /// a bound float[] parameter arrives as an unquoted [1,0,0,0], whose commas are + /// part of the value, and splitting there would leave [1 as the query vector. + /// + /// The text between the parentheses. + /// The trimmed arguments. + private static List SplitVectorArguments(string arguments) + { + var items = new List(); + var current = new System.Text.StringBuilder(); + var nesting = 0; + var inQuote = false; + + foreach (var c in arguments) + { + if (c == '\'') + { + inQuote = !inQuote; + } + + if (!inQuote) + { + if (c is '(' or '[' or '{') + { + nesting++; + } + else if (c is ')' or ']' or '}') + { + if (nesting > 0) + { + nesting--; + } + } + else if (c == ',' && nesting == 0) + { + items.Add(current.ToString().Trim()); + current.Clear(); + continue; + } + } + + current.Append(c); + } + + if (current.Length > 0) + { + items.Add(current.ToString().Trim()); + } + + return items; + } + + /// + /// Reads an alias that follows a parsed call: ... ) AS distance or the bare form + /// ... ) distance. Returns null when the next token is punctuation, an operator, or the + /// end of the clause. + /// + /// The clause the call was parsed from. + /// The index of the call's closing parenthesis. + /// The alias, or null. + private static string? ReadAliasAfter(string text, int callEnd) + { + if (callEnd + 1 >= text.Length) + { + return null; + } + + var rest = text[(callEnd + 1)..].TrimStart(); + + if (rest.StartsWith("AS", StringComparison.OrdinalIgnoreCase) + && rest.Length > 2 + && char.IsWhiteSpace(rest[2])) + { + rest = rest[2..].TrimStart(); + } + + var end = 0; + while (end < rest.Length && (char.IsLetterOrDigit(rest[end]) || rest[end] == '_')) + { + end++; + } + + return end == 0 ? null : rest[..end]; + } + + /// + /// Projects rows returned by the vector index onto the SELECT list, substituting the + /// distance the optimizer injected for the distance expression itself. The scan path + /// around it does not project, so this is what keeps an optimized query's column set identical + /// to the same query without an index. + /// + /// Rows from . + /// The SELECT list. + /// The alias given to the distance expression, if any. + /// The distance function name used by the query. + /// The projected rows. + private static List> ProjectVectorRows( + List> rows, + string selectClause, + string? distanceAlias, + string distanceFunction) + { + var items = SplitVectorArguments(selectClause); + var distanceKey = string.IsNullOrEmpty(distanceAlias) ? "distance" : distanceAlias; + var selectAll = items.Count == 1 && items[0].Trim() == "*"; + + var result = new List>(rows.Count); + foreach (var row in rows) + { + if (selectAll) + { + // `SELECT *` asked for the row, not for the ordering expression. + result.Add(new Dictionary(row, StringComparer.OrdinalIgnoreCase)); + continue; + } + + var projected = new Dictionary(items.Count, StringComparer.OrdinalIgnoreCase); + foreach (var item in items) + { + var (expression, alias) = SplitSelectItem(item); + + if (expression.Contains(distanceFunction, StringComparison.OrdinalIgnoreCase)) + { + projected[alias ?? distanceKey] = row.TryGetValue("distance", out var distance) + ? distance + : DBNull.Value; + continue; + } + + projected[alias ?? ExtractBareColumn(expression)] = FindValue(row, expression) ?? DBNull.Value; + } + + result.Add(projected); + } + + return result; + } + + /// + /// Splits one SELECT item into its expression and its alias, using the same rule the join + /// projection uses (expr AS alias or expr alias). + /// + /// One comma-separated SELECT item. + /// The expression and the alias, if any. + private static (string Expression, string? Alias) SplitSelectItem(string item) + { + var trimmed = item.Trim(); + var match = System.Text.RegularExpressions.Regex.Match( + trimmed, + @"^(.+?)\s+(?:AS\s+)?(\w+)$", + System.Text.RegularExpressions.RegexOptions.IgnoreCase, + TimeSpan.FromSeconds(1)); + + return match.Success + ? (match.Groups[1].Value.Trim(), match.Groups[2].Value.Trim()) + : (trimmed, null); + } + + /// + /// Returns true when the value is a plain column reference (letters, digits, underscore), so a + /// numeric literal or an expression can never be handed to the index registry as a column name. + /// + /// The candidate column name. + /// True when the value is a simple identifier. + private static bool IsSimpleIdentifier(string value) + { + if (value.Length == 0 || !(char.IsLetter(value[0]) || value[0] == '_')) + { + return false; + } + + foreach (var c in value) + { + if (!(char.IsLetterOrDigit(c) || c == '_')) + { + return false; + } + } + + return true; + } + + /// + /// Strips the surrounding quotes from a SQL string literal, leaving a vector literal such as + /// [0.25,0.5,0.75,1] as the text the optimizer's vector reader expects. + /// + /// The literal as written in the statement. + /// The unquoted value. + private static string Unquote(string value) => value.Trim().Trim('\'', '"'); + /// /// Executes COUNT(*) aggregate query with modern patterns. /// βœ… MODERNIZED: Uses pattern matching and null-coalescing. diff --git a/src/SharpCoreDB/SharpCoreDB.csproj b/src/SharpCoreDB/SharpCoreDB.csproj index 3c719d00..59603516 100644 --- a/src/SharpCoreDB/SharpCoreDB.csproj +++ b/src/SharpCoreDB/SharpCoreDB.csproj @@ -2,7 +2,7 @@ net11.0 - preview @@ -37,15 +37,15 @@ SharpCoreDB - 2.1.0 + 2.1.1 2.1.0.0 - 2.1.0.0 + 2.1.1.0 MPCoreDeveloper SharpCoreDB SharpCoreDB A lightweight, encrypted, file-based database engine with SQL support, AES-256-GCM encryption, modern C# features, and production-ready performance for time-tracking, invoicing, and project management applications. Supports Windows, Linux, macOS, Android, iOS, and IoT/embedded devices. Copyright (c) 2026 MPCoreDeveloper - v2.1.0 (2026-10-10): .NET 11 / C# 15 preview release line β€” net11.0-only, native Zstandard compression (quality presets 1/5/19 + frame checksum), Runtime Async, an additive C# 15 API surface (SharpCoreDB.Net11), and the Munarium-inspired DiskANN index + content-verified index artifacts. The net10.0 / C# 14 line is the v2.0 stable packages, now parked on release/v2.0. See docs/net11/UPGRADE.md for details. + v2.1.1 (2026-10-25): patch release with no API changes. A float[] parameter now reaches a VECTOR(n) column as a vector instead of the literal text "System.Single[]", and ORDER BY vec_distance_*() LIMIT k now reaches the vector index instead of a full scan. Previous: v2.1.0 (2026-10-10): .NET 11 / C# 15 preview release line β€” net11.0-only, native Zstandard compression (quality presets 1/5/19 + frame checksum), Runtime Async, an additive C# 15 API surface (SharpCoreDB.Net11), and the Munarium-inspired DiskANN index + content-verified index artifacts. The net10.0 / C# 14 line is the v2.0 stable packages, now parked on release/v2.0. See docs/net11/UPGRADE.md for details. database;embedded;encryption;sql;nosql;time-tracking;invoicing;net11;csharp15;zstd;performance;android;ios;mobile;iot;arm64;x64;distributed;sync MIT https://github.com/MPCoreDeveloper/SharpCoreDB diff --git a/tests/SharpCoreDB.VectorSearch.Tests/SqlVectorQueryTests.cs b/tests/SharpCoreDB.VectorSearch.Tests/SqlVectorQueryTests.cs new file mode 100644 index 00000000..a3adc62a --- /dev/null +++ b/tests/SharpCoreDB.VectorSearch.Tests/SqlVectorQueryTests.cs @@ -0,0 +1,217 @@ +// +// Copyright (c) 2026 MPCoreDeveloper and GitHub Copilot. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// +namespace SharpCoreDB.VectorSearch.Tests; + +using System.Globalization; +using Microsoft.Extensions.DependencyInjection; +using SharpCoreDB.Interfaces; + +/// +/// End-to-end coverage for the planner branch that answers +/// ORDER BY vec_distance_*(column, vector) LIMIT k from a vector index (Phase 5.4). +/// +/// These tests exist because the branch was dead in two independent ways at once: the planner call +/// site was guarded by SqlParser.VectorQueryOptimizer is not null, and that member was an +/// internal static that nothing ever assigned (so CREATE VECTOR INDEX built nothing +/// either), and the method behind the guard had been replaced by a stub returning null. Unit tests +/// over VectorQueryOptimizer passed throughout, because the optimizer itself was fine β€” it +/// was never called. Only a query through Database can tell the difference, which is why +/// these go through AddVectorSupport() and SQL rather than constructing the optimizer. +/// +/// +public sealed class SqlVectorQueryTests : IDisposable +{ + private const string QueryVectorLiteral = "'[1,0,0,0]'"; + + private readonly string _path = Path.Combine(Path.GetTempPath(), $"SCDB_VectorSql_{Guid.NewGuid():N}"); + private readonly ServiceProvider _provider; + private IDatabase? _db; + + /// Registers vector support exactly as a host application would. + public SqlVectorQueryTests() + { + _provider = new ServiceCollection() + .AddSharpCoreDB() + .AddVectorSupport() + .BuildServiceProvider(); + } + + /// + public void Dispose() + { + (_db as IDisposable)?.Dispose(); + _provider.Dispose(); + + try + { + if (Directory.Exists(_path)) + Directory.Delete(_path, true); + } + catch (IOException) + { + // A leaked temp directory must not fail the suite. + } + } + + [Fact] + public void OrderByDistanceAlias_WithIndex_ReturnsNearestRowsProjectedOnTheSelectList() + { + var db = SeededDatabase(); + db.ExecuteSQL("CREATE VECTOR INDEX idx_docs ON docs(embedding) USING FLAT"); + + var rows = Query( + db, + $"SELECT id, body, vec_distance_cosine(embedding, {QueryVectorLiteral}) AS distance " + + "FROM docs ORDER BY distance LIMIT 2"); + + Assert.Equal(new[] { 1L, 3L }, rows.Select(r => Convert.ToInt64(r["id"], CultureInfo.InvariantCulture)).ToArray()); + + // Cosine distance to [1,0,0,0]: id 1 is identical (0.0), id 3 has similarity 0.8 (0.2). + Assert.Equal(0.0f, Convert.ToSingle(rows[0]["distance"], CultureInfo.InvariantCulture), 3); + Assert.Equal(0.2f, Convert.ToSingle(rows[1]["distance"], CultureInfo.InvariantCulture), 3); + + // The projection is the SELECT list, not the whole row: the restored implementation copied + // every column and appended "distance" whatever the query asked for. + Assert.Equal(3, rows[0].Count); + Assert.True(rows[0].ContainsKey("id") && rows[0].ContainsKey("body") && rows[0].ContainsKey("distance")); + } + + [Fact] + public void OrderByDistanceFunction_WithoutDistanceInTheSelectList_IsStillServedFromTheIndex() + { + var db = SeededDatabase(); + db.ExecuteSQL("CREATE VECTOR INDEX idx_docs ON docs(embedding) USING FLAT"); + + var rows = Query( + db, + $"SELECT id FROM docs ORDER BY vec_distance_cosine(embedding, {QueryVectorLiteral}) LIMIT 1"); + + Assert.Single(rows); + Assert.Equal(1L, Convert.ToInt64(rows[0]["id"], CultureInfo.InvariantCulture)); + + // ORDER BY named the function, not an alias of it; the distance was not selected. + Assert.Single(rows[0]); + } + + [Fact] + public void OrderByDistanceAlias_WithBoundVectorParameter_IsServedFromTheIndex() + { + var db = SeededDatabase(); + db.ExecuteSQL("CREATE VECTOR INDEX idx_docs ON docs(embedding) USING FLAT"); + + // A float[] parameter is bound to the bracketed vector literal by ParameterBinder, so the + // planner sees the same text an inline literal would produce. + var rows = db.ExecuteQuery( + "SELECT id, vec_distance_cosine(embedding, @q) AS distance FROM docs ORDER BY distance LIMIT 1", + new Dictionary { ["q"] = new float[] { 1, 0, 0, 0 } }); + + Assert.Single(rows); + Assert.Equal(1L, Convert.ToInt64(rows[0]["id"], CultureInfo.InvariantCulture)); + Assert.True(rows[0].ContainsKey("distance")); + } + + [Fact] + public void OrderByDistanceDescending_IsNotServedFromTheIndex() + { + var db = SeededDatabase(); + db.ExecuteSQL("CREATE VECTOR INDEX idx_docs ON docs(embedding) USING FLAT"); + + var rows = Query( + db, + $"SELECT id, body, vec_distance_cosine(embedding, {QueryVectorLiteral}) AS distance " + + "FROM docs ORDER BY distance DESC LIMIT 2"); + + Assert.Equal(2, rows.Count); + + // A top-k index holds the k nearest rows; the k farthest cannot be derived from it, so the + // query must keep its scan behaviour rather than receive a nearest-k answer labelled as DESC. + // The scan path neither projects nor computes the distance, which is what this asserts. + Assert.DoesNotContain("distance", rows[0].Keys); + Assert.Contains("embedding", rows[0].Keys); + } + + [Fact] + public void OrderByDistanceWithWhereClause_IsNotServedFromTheIndex() + { + var db = SeededDatabase(); + db.ExecuteSQL("CREATE VECTOR INDEX idx_docs ON docs(embedding) USING FLAT"); + + // Applying the predicate after the index chose its k would drop matching rows instead of + // fetching further down the ranking, so a filtered top-k stays on the scan. + var rows = Query( + db, + $"SELECT id, body, vec_distance_cosine(embedding, {QueryVectorLiteral}) AS distance " + + "FROM docs WHERE id > 1 ORDER BY distance LIMIT 2"); + + Assert.Equal(2, rows.Count); + Assert.DoesNotContain("distance", rows[0].Keys); + Assert.Contains("embedding", rows[0].Keys); + } + + [Fact] + public void DropVectorIndex_ReturnsTheQueryToTheScanPath() + { + var db = SeededDatabase(); + db.ExecuteSQL("CREATE VECTOR INDEX idx_docs ON docs(embedding) USING FLAT"); + + var optimized = Query( + db, + $"SELECT id, vec_distance_cosine(embedding, {QueryVectorLiteral}) AS distance " + + "FROM docs ORDER BY distance LIMIT 2"); + Assert.True(optimized[0].ContainsKey("distance")); + + db.ExecuteSQL("DROP VECTOR INDEX idx_docs ON docs"); + + var scanned = Query( + db, + $"SELECT id, vec_distance_cosine(embedding, {QueryVectorLiteral}) AS distance " + + "FROM docs ORDER BY distance LIMIT 2"); + Assert.DoesNotContain("distance", scanned[0].Keys); + } + + [Fact] + public void OrderByDistanceWithoutAnyIndex_FallsBackToTheScan() + { + var db = SeededDatabase(); + + var rows = Query( + db, + $"SELECT id, vec_distance_cosine(embedding, {QueryVectorLiteral}) AS distance " + + "FROM docs ORDER BY distance LIMIT 2"); + + Assert.Equal(2, rows.Count); + Assert.DoesNotContain("distance", rows[0].Keys); + } + + /// + /// Creates a database through the DI factory with four documents whose distances to + /// [1,0,0,0] are distinct enough to identify, and where two rows tie on distance so the + /// index's tie-break (id, ascending) is exercised too. + /// + /// The open database; the caller disposes it. + private IDatabase SeededDatabase() + { + if (_db is not null) + { + return _db; + } + + var factory = _provider.GetRequiredService(); + var db = factory.Create(_path, "pw", isReadOnly: false, config: new DatabaseConfig()); + + db.ExecuteSQL("CREATE TABLE docs (id INTEGER PRIMARY KEY, body TEXT, embedding VECTOR(4))"); + db.ExecuteSQL("INSERT INTO docs (id, body, embedding) VALUES (1, 'nearest', [1,0,0,0])"); + db.ExecuteSQL("INSERT INTO docs (id, body, embedding) VALUES (2, 'orthogonal', [0,1,0,0])"); + db.ExecuteSQL("INSERT INTO docs (id, body, embedding) VALUES (3, 'close', [0.8,0.6,0,0])"); + db.ExecuteSQL("INSERT INTO docs (id, body, embedding) VALUES (4, 'far', [0,0,1,0])"); + + _db = db; + return db; + } + + private static List> Query(IDatabase db, string sql) + => db.ExecuteQuery(sql, new Dictionary()); +} +