Skip to content

Release 2.1.2 - bound-parameter literal scanner, docs and version bump - #479

Merged
MPCoreDeveloper merged 2 commits into
masterfrom
release/2.1.2
Oct 26, 2026
Merged

MPCoreDeveloper merged 2 commits into
masterfrom
release/2.1.2

Conversation

@MPCoreDeveloper

Copy link
Copy Markdown
Owner

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: ParseValue quote stripping, UPDATE ... SET col = @v splitting 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)

  • Version 2.1.2 in the 28 packable projects, SharpCoreDBVersion, and the 23 PackageReleaseNotes; AssemblyVersion stays 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).
  • 16 per-package NuGet.README.md install 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.md pinned --version 2.1.0-RC.3 and docs/Vectors/README.md pinned 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.
  • Suites: core 2107 / 0 failed, VectorSearch 255 / 0, EF Core 116 / 0, linq2DB 24 / 0.
  • Repro in docs/sharpcoredb-known-issues.md section 7 prints the fixed output.
  • SharpAgent: 144 indexing tests green against this build, no code change needed.

Note for the owner

Merging this PR to master runs the pack + "Publish to NuGet.org" jobs in ci.yml, which is the owner action reserved in AGENTS.md - that is the only remaining step. The branch is otherwise release-ready.

…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.
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
5.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@MPCoreDeveloper
MPCoreDeveloper merged commit c9dc162 into master Oct 26, 2026
15 of 16 checks passed
@MPCoreDeveloper
MPCoreDeveloper deleted the release/2.1.2 branch October 26, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant