Repository navigation
Release 2.1.2 - bound-parameter literal scanner, docs and version bump - #479
Merged
Merged
Conversation
…ound-trips
`ExecuteSQL(sql, parameters)` renders every value back into the statement text (`ParameterBinder`
emits `'it''s'` for `it's`, SQL's doubled-quote convention) and hands the rendered statement to the
ordinary parser, so the formatter and the scanner have to agree about escaping. They did not: the
VALUES scanner dropped the quote of a doubled pair and let a backslash suppress a quote toggle,
which also meant a value ending in a backslash could not be written at all. SharpAgent's
code-evidence index, which writes source text and Windows paths as TEXT values, saw it as rows
rejected with "Mismatched parentheses in VALUES clause" and - the worse half - as a value silently
landing in the neighbouring column (`Invalid VECTOR literal '... iterations)'` on `embedding`).
The rules are now SQL's and SQLite's, written once in `Services/SqlLiteralScanner.cs` and used by
every literal reader on the statement path: the VALUES and `SET` splitters, the
matching-parenthesis scan, all four parameter extractors, the batch INSERT parsers,
`FastSqlLexer.ReadString`, the expression tokenizer, the `WHERE` tokenizer
(`Table.Scanning.EvaluateWhere`, which split on spaces and truncated any quoted value at its first
space) and the wire protocol's `$n` -> `?` translation (hence
`InternalsVisibleTo("SharpCoreDB.Server.Core")`): a doubled quote is one quote and does not close
the literal, and a backslash is data.
`ParseValue` now removes exactly one pair of quotes and collapses the doubling; the old strip loop
removed every edge quote, so a parameter holding `'` stored an empty string and `'it''s'` reached
storage as `it''s`. `UPDATE ... SET col = @v` splits at the first `=` instead of every `=` (a value
containing `=` silently dropped that assignment). A quoted empty literal stores an empty string as
SQLite does, where a trailing `''` used to become NULL. A tuple that still produces more values
than the statement can consume throws before any row is written, naming the table, the tuple index,
both counts and the column list, instead of shifting values into the next column.
Verified red -> green: `ParameterLiteralRoundTripTests` (74 cases) failed 32 of 57 assertions before
the change and passes 74/74 after; `InsertValuesParsingTests` was corrected to SQL semantics
(`'it''s'` -> `it's`, a trailing backslash is data, a trailing `''` is an empty string). Suites:
core 2107 / 0 failed, VectorSearch 255 / 0, EF Core 116 / 0, linq2DB 24 / 0; `SharpCoreDB.CI.slnf`
builds clean. Two latent test bugs surfaced on the way: `EncryptionCoverageTests` and
`WritePathProfilerTests` interpolated `{i * 0.5}` straight into SQL, which renders `0,5` on a
comma-decimal machine and is a four-value tuple - the old parser silently dropped the overflow
value, the new arity check rejects it, so both now format invariantly.
`docs/sharpcoredb-known-issues.md` issue 7 gains a two-file runnable reproduction with the
before/after console output, so the next consumer does not have to take the symptom on trust.
…arameter fix 2.1.1 is published and nuget.org versions are immutable, so the next publish has to carry a version that does not exist yet - and the Unreleased bucket had collected the statement-path literal scanner, a data-correctness fix rather than a performance one: a bound `TEXT` parameter holding an apostrophe, a doubled quote or a backslash was re-scanned as SQL, so the value could land in the neighbouring column, or the statement was rejected with "Mismatched parentheses in VALUES clause". No API changes, so a patch is the honest cut. Version bumped in the 28 packable projects under src/ (`Version`, plus `FileVersion` on the core library), plus `SharpCoreDBVersion` in Directory.Packages.props, which is what the providers and the test projects consume from the published feed. `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.2 line in all 23 packages that declare one, chained in front of the 2.1.1 and 2.1.0 text, and the EF Core provider's `Description` no longer asserts "Compatible with SharpCoreDB 2.1.1". `docs/CHANGELOG.md` closes `[Unreleased]` into `[2.1.2] - 2026-10-26` with a note on what the release is, keeping the fix entry evidence-first. Documentation, because the last two cuts left reader-facing pages naming releases that are superseded: - `src/SharpCoreDB/NuGet.README.md` - the page nuget.org serves - gains a "What's New in 2.1.2" section (symptom, cause, fix, a code sample, the validation numbers), and its title, banner, install snippets and footer move to 2.1.2. The footer still read "Latest Version: 2.1.0". - The 16 per-package `NuGet.README.md` files carried `dotnet add package ... --version 2.1.1`, which is the one line a reader copies off a package page; all now name 2.1.2. - `README.md` (the repository front page) still announced "Current release: v2.1.0" - a release behind - so it gets the 2.1.2 banner, a "What's new in v2.1.2" section, the two-line release table, the quick start and all 30 package snippets at 2.1.2, with 2.1.1 added to "Previous releases". - `src/SharpCoreDB.Server/README.md` pinned `--version 2.1.0-RC.3`, a prerelease that predates 2.1.0, and `docs/Vectors/README.md` pinned 2.1.0; both now 2.1.2. - `docs/PROJECT_STATUS.md` becomes current again: 2.1.2 is the version, and the stale "2.1.0 is prepared on master and not yet tagged or pushed" bullet - false since 2026-10-10 - is replaced by what shipped. - The two historical records (`docs/2.1.0-RC.3_WHAT_CHANGED.md`, `docs/net11/PROMOTION_TO_MAIN.md`) keep their RC.3 snippets on purpose: they describe that cut. Verified: `dotnet msbuild -getProperty:Version` reports 2.1.2 for all 28 packable projects (2.1.2.0 file version, 2.1.0.0 assembly version on the core); `SharpCoreDB.CI.slnf` builds with 0 errors under `/p:UseLocalProjectReferences=true` (required here - 2.1.2 does not exist on nuget.org yet); suites core 2107 / VectorSearch 255 / EF Core 116 / linq2DB 24, all 0 failed. The silent failure this avoids is the one 2.1.1's note recorded: the publish jobs push with `--skip-duplicate`, so a tree still declaring 2.1.1 would have gone green and shipped nothing.
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Release 2.1.2 prepares the first publishable tree for the issue #7 fix.
The fix (
2f23913c)ExecuteSQL(sql, parameters)renders every value back into the statement text and re-parses that text, so the binder and the scanners must agree about escaping. They did not: the VALUES scanner dropped the quote of a doubled pair and let a backslash suppress a quote toggle. A bound TEXT value with an apostrophe or a backslash therefore landed in the neighbouring column, or the statement was rejected with "Mismatched parentheses in VALUES clause".One scanner (
src/SharpCoreDB/Services/SqlLiteralScanner.cs) now owns SQL/SQLite rules and every literal reader on the statement path uses it. Also fixed:ParseValuequote stripping,UPDATE ... SET col = @vsplitting at every=, a quoted''becoming NULL, and a tuple that cannot fit its statement now throws before writing instead of shifting values right.Documentation and version (
1787c15e)SharpCoreDBVersion, and the 23PackageReleaseNotes;AssemblyVersionstays 2.1.0.0.src/SharpCoreDB/NuGet.README.md: new "What's New in 2.1.2" section with a code sample, title/banner/install/footer moved to 2.1.2 (the footer still said 2.1.0).NuGet.README.mdinstall snippets moved to 2.1.2.README.md: 2.1.2 banner + "What's new in v2.1.2", release table, quick start and all 30 snippets at 2.1.2, 2.1.1 added to previous releases. It still announced v2.1.0 as current.src/SharpCoreDB.Server/README.mdpinned--version 2.1.0-RC.3anddocs/Vectors/README.mdpinned 2.1.0; both now 2.1.2.docs/PROJECT_STATUS.md: version/last-updated refreshed; the "2.1.0 is prepared and not yet pushed" bullet (false since 2026-10-10) replaced by what shipped.docs/CHANGELOG.md:[Unreleased]closed into[2.1.2] - 2026-10-26.Verification
dotnet msbuild -getProperty:Version-> 2.1.2 on all 28 packable projects.SharpCoreDB.CI.slnf(see note) builds with 0 errors under/p:UseLocalProjectReferences=true.docs/sharpcoredb-known-issues.mdsection 7 prints the fixed output.Note for the owner
Merging this PR to
masterruns the pack + "Publish to NuGet.org" jobs inci.yml, which is the owner action reserved in AGENTS.md - that is the only remaining step. The branch is otherwise release-ready.