From 16cb51d52e9f0bdd1297d945bd433a48d619b7b8 Mon Sep 17 00:00:00 2001 From: MPCoreDeveloper Date: Sun, 25 Oct 2026 10:22:03 +0100 Subject: [PATCH 1/3] fix(vector): ORDER BY vec_distance_* reaches the index instead of dying in a dead branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `CREATE VECTOR INDEX` and the `ORDER BY vec_distance_*(col, vector) LIMIT k` planner branch were both permanently inactive, and restoring the deleted method alone would have revived neither. `SqlParser.VectorQueryOptimizer` was an `internal static` that no code in SharpCoreDB ever assigned and no other assembly could assign (the parser is internal), while SharpCoreDB.VectorSearch registers the optimizer with the DI container. So `VectorQueryOptimizer?.BuildIndex(...)` in the DDL path and `VectorQueryOptimizer is not null` in the SELECT path were no-ops in both directions: nothing built an index and nothing looked for one. Wiring: Database.GetSharedSqlParser now resolves IVectorQueryOptimizer from the service provider — the same pattern GRAPH_RAG already used — and attaches it via SetVectorQueryOptimizer; the property is per parser instance instead of static. The second SqlParser construction site (the compiled-query fallback) now goes through GetSharedSqlParser, so falling back cannot produce a parser without the extensions the first site attaches. Restored and repaired: TryExecuteVectorOptimized was replaced by a stub returning null in 997103be, after working in e220461e. The restored code is not a snapshot of it. The old version copied every column and appended a "distance" key whatever the SELECT list said, and did so for DESC and WHERE queries too, so an optimized query and an unoptimized one returned different shapes for the same SQL. Rows are now projected onto the SELECT list (SELECT *, plain columns, aliases, and the distance expression substituted from the key the optimizer injects), ORDER BY may name either the alias or the function, and the two shapes an ascending top-k index cannot answer — DESC and a WHERE clause — fall back to the scan instead of returning a plausible wrong answer. Found while testing: an unquoted vector literal (`[1,0,0,0]`, which is exactly what ParameterBinder produces for a float[] parameter) lost its commas to the argument splitter, leaving "[1" as the query vector. Brackets and braces now count as nesting, so a bound float[] parameter works end to end. Tests: tests/SharpCoreDB.VectorSearch.Tests/SqlVectorQueryTests.cs, seven end-to-end cases through AddVectorSupport() + Database — the only level at which the wiring is observable, which is why the existing VectorQueryOptimizer unit tests stayed green throughout the outage. 255/255 in that project, 2137/2137 in SharpCoreDB.Tests. Known limitation, unchanged: an index is a snapshot of the table at CREATE VECTOR INDEX; rows inserted afterwards are not in it until it is rebuilt. --- .../Database/Core/Database.Core.cs | 1 + .../Database/Execution/Database.Execution.cs | 61 ++- src/SharpCoreDB/Services/SqlParser.Core.cs | 31 +- src/SharpCoreDB/Services/SqlParser.DDL.cs | 4 +- src/SharpCoreDB/Services/SqlParser.DML.cs | 397 +++++++++++++++++- .../SqlVectorQueryTests.cs | 217 ++++++++++ 6 files changed, 683 insertions(+), 28 deletions(-) create mode 100644 tests/SharpCoreDB.VectorSearch.Tests/SqlVectorQueryTests.cs 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/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/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()); +} + From d630af402e1bc6dcf9a9d5f11bff97e1af84cd56 Mon Sep 17 00:00:00 2001 From: MPCoreDeveloper Date: Sun, 25 Oct 2026 11:10:17 +0100 Subject: [PATCH 2/3] Release 2.1.1, closing the Unreleased bucket and shipping the SQL vector fixes 2.1.0 is published and nuget.org versions are immutable, so the next publish has to carry a version that does not exist yet. The Unreleased bucket has also been collecting since the v2.1.0 tag - the coverage job, information_schema, the AOT measurement, the version() fix, the promotion sweep, and the vector read-back fix - so a patch release is the honest cut: no API changes, 27 packages renumbered, the two SQL vector defects fixed (the float[] binder on master, the optimizer wiring in #474). Version bumped in the 28 packable projects under src/ (Version and FileVersion), plus SharpCoreDBVersion in Directory.Packages.props, which is what the samples and providers consume from the published feed - leaving it at 2.1.0 would have pointed them at the release this one supersedes. AssemblyVersion stays 2.1.0.0 on purpose: a patch should not change the assembly identity of the core library. PackageReleaseNotes gained a 2.1.1 line in all 23 packages that declare one. Without it every package would have shipped showing 2.1.0 notes on nuget.org, which is the one place a reader looks for what changed. The EF Core provider's Description also asserted "Compatible with SharpCoreDB 2.1.0". docs/CHANGELOG.md closes [Unreleased] into [2.1.1] - 2026-10-25 with a note on what the release is, and adds the vector-SQL entry (#474) to Fixed, in the evidence-first style the file uses. Stacked on fix/vector-sql-optimizer: merge #474 first, or this release claims a fix it does not contain. The silent failure this avoids: publish-manual.yml pushes with --skip-duplicate, so running it from a tree still declaring 2.1.0 would have gone green and shipped nothing. Verified: Release build 0 errors; pack produces 27 nupkgs, all at 2.1.1, including the six SharpAgent consumes; suites 2137 (16 skipped) / 255 / 116 / 24, all 0 failed. --- Directory.Build.props | 2 +- Directory.Packages.props | 2 +- docs/CHANGELOG.md | 14 +++++++++++--- .../SharpCoreDB.Analytics.csproj | 4 ++-- .../SharpCoreDB.Aspire.Hosting.csproj | 4 ++-- src/SharpCoreDB.CQRS/SharpCoreDB.CQRS.csproj | 4 ++-- .../SharpCoreDB.Client.Protocol.csproj | 4 ++-- src/SharpCoreDB.Client/SharpCoreDB.Client.csproj | 2 +- .../SharpCoreDB.Data.Provider.csproj | 4 ++-- .../SharpCoreDB.Distributed.csproj | 4 ++-- .../SharpCoreDB.EntityFrameworkCore.csproj | 6 +++--- .../SharpCoreDB.EventSourcing.csproj | 4 ++-- .../SharpCoreDB.Extensions.csproj | 4 ++-- .../SharpCoreDB.Functional.Dapper.csproj | 4 ++-- ...arpCoreDB.Functional.EntityFrameworkCore.csproj | 4 ++-- .../SharpCoreDB.Functional.Linq2DB.csproj | 4 ++-- .../SharpCoreDB.Functional.csproj | 4 ++-- .../SharpCoreDB.Graph.Advanced.csproj | 2 +- src/SharpCoreDB.Graph/SharpCoreDB.Graph.csproj | 4 ++-- .../SharpCoreDB.HybridSearch.csproj | 4 ++-- .../SharpCoreDB.Identity.csproj | 2 +- .../SharpCoreDB.Projections.csproj | 4 ++-- .../SharpCoreDB.Provider.Sync.csproj | 2 +- .../SharpCoreDB.Provider.YesSql.csproj | 4 ++-- src/SharpCoreDB.Search/SharpCoreDB.Search.csproj | 4 ++-- .../SharpCoreDB.Serilog.Sinks.csproj | 4 ++-- .../SharpCoreDB.Server.Core.csproj | 4 ++-- .../SharpCoreDB.Server.Protocol.csproj | 4 ++-- src/SharpCoreDB.Server/SharpCoreDB.Server.csproj | 2 +- .../SharpCoreDB.VectorSearch.csproj | 4 ++-- src/SharpCoreDB/SharpCoreDB.csproj | 8 ++++---- 31 files changed, 67 insertions(+), 59 deletions(-) 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 From f828014ecb845c1ae25d98ec2ec72b95b94840a5 Mon Sep 17 00:00:00 2001 From: MPCoreDeveloper Date: Sun, 25 Oct 2026 11:17:09 +0100 Subject: [PATCH 3/3] Update the version pins the published READMEs carry The install snippets inside the NuGet.README.md files name a version, and every one of those files ships inside its nupkg (PackageReadmeFile), so publishing 2.1.1 with them unchanged would have advertised `dotnet add package SharpCoreDB --version 2.1.0` on all 21 package pages - the one line a reader copies. Same pattern in five docs that carry install instructions (analytics, cqrs, graphrag, manual/quickstart, scdb/PRODUCTION_GUIDE); the dated RC.3 record and PROMOTION_TO_MAIN keep their versions, they are history. src/SharpCoreDB/NuGet.README.md also led with "SharpCoreDB 2.1.0" and "What's New in 2.1.0", so the package page would have described the previous release. It now leads with 2.1.1, carries a "What's New in 2.1.1" section for the two vector fixes and the information_schema / coverage work, and keeps the 2.1.0 detail below it. The Graph.Advanced README says "(v2.1.1)" and requires "SharpCoreDB 2.1.1+". Verified by packing the core project and reading the README back out of the nupkg: the first line is "# SharpCoreDB 2.1.1 - Performance-First Database Engine" and the archive is SharpCoreDB.2.1.1.nupkg. --- NuGet.README.md | 12 +++---- docs/analytics/README.md | 2 +- docs/cqrs/README.md | 2 +- docs/graphrag/README.md | 6 ++-- docs/manual/quickstart.md | 2 +- docs/scdb/PRODUCTION_GUIDE.md | 2 +- src/SharpCoreDB.Analytics/NuGet.README.md | 2 +- src/SharpCoreDB.CQRS/NuGet.README.md | 2 +- src/SharpCoreDB.Client/NuGet.README.md | 2 +- src/SharpCoreDB.Data.Provider/NuGet.README.md | 2 +- src/SharpCoreDB.Distributed/NuGet.README.md | 2 +- .../NuGet.README.md | 2 +- src/SharpCoreDB.EventSourcing/NuGet.README.md | 2 +- src/SharpCoreDB.Extensions/NuGet.README.md | 2 +- .../NuGet.README.md | 2 +- src/SharpCoreDB.Graph/NuGet.README.md | 2 +- src/SharpCoreDB.Projections/NuGet.README.md | 2 +- src/SharpCoreDB.Provider.Sync/NuGet.README.md | 2 +- .../NuGet.README.md | 2 +- src/SharpCoreDB.Serilog.Sinks/NuGet.README.md | 2 +- src/SharpCoreDB.Server/NuGet.README.md | 2 +- src/SharpCoreDB.VectorSearch/NuGet.README.md | 2 +- src/SharpCoreDB/NuGet.README.md | 34 +++++++++++++++---- 23 files changed, 56 insertions(+), 36 deletions(-) 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/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.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.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.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.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.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.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.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.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/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.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.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.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.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.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.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/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