Skip to content

Commit ec37dc5

Browse files
committed
Version identity now centralizes in the internal static ReferenceBuild class.
1 parent 4abfbb3 commit ec37dc5

7 files changed

Lines changed: 107 additions & 32 deletions

File tree

SqlServerSimulator/Network/TdsSession.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,12 @@ private void WriteLoginResponse(TdsTokenWriter writer, int packetSize)
330330
writer.WriteErrorOrInfo(Tds.TokenInfo, 5703, 1, 0, "Changed language setting to us_english.", "SIMULATED", "", 1);
331331
var serverCollation = TdsCollationCodec.For(Collation.Get(simulation.ServerCollationName));
332332
writer.WriteEnvChangeSqlCollation(serverCollation.Info, serverCollation.SortId);
333-
writer.WriteLoginAck(Tds.Version74, "Microsoft SQL Server", 17, 0, 4065);
333+
writer.WriteLoginAck(
334+
Tds.Version74,
335+
"Microsoft SQL Server",
336+
checked((byte)ReferenceBuild.Version.Major),
337+
checked((byte)ReferenceBuild.Version.Minor),
338+
checked((ushort)ReferenceBuild.Version.Build));
334339
writer.WriteEnvChange(Tds.EnvPacketSize, packetSize.ToString(System.Globalization.CultureInfo.InvariantCulture), Tds.DefaultPacketSize.ToString(System.Globalization.CultureInfo.InvariantCulture));
335340
writer.WriteDone(Tds.DoneFinal, 0);
336341
}
@@ -806,9 +811,17 @@ private static byte[] BuildPreloginResponse(bool includeFedAuth, bool marsReques
806811
var dataStart = (optionCount * 5) + 1;
807812
var data = new List<(byte Token, byte[] Value)>
808813
{
809-
// VERSION = major, minor, build (big-endian u16), subbuild (u16).
810-
// Build 4065 = 0x0FE1; mirrors the SQL Server 2025 reference build.
811-
(Tds.PreloginVersion, [17, 0, 0x0F, 0xE1, 0, 0]),
814+
// VERSION = major, minor, build (big-endian u16), subbuild (u16,
815+
// zero like real's prelogin); values derive from ReferenceBuild.
816+
(Tds.PreloginVersion,
817+
[
818+
checked((byte)ReferenceBuild.Version.Major),
819+
checked((byte)ReferenceBuild.Version.Minor),
820+
(byte)(ReferenceBuild.Version.Build >> 8),
821+
(byte)(ReferenceBuild.Version.Build & 0xFF),
822+
0,
823+
0,
824+
]),
812825
(Tds.PreloginEncryption, [Tds.EncryptRequired]),
813826
(Tds.PreloginInstance, [0]),
814827
(Tds.PreloginThreadId, []),

SqlServerSimulator/Parser/Expressions/ServerProperty.cs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ public override SqlValue Run(RuntimeContext runtime)
3838
/// <summary>
3939
/// Resolves one property to its inner value; a NULL result (a null-valued
4040
/// property, or an unrecognized name via the default arm) becomes the NULL
41-
/// <c>sql_variant</c> in <see cref="Run"/>. The version-identity constants
42-
/// mirror the SQL Server 2025 reference build the simulator emulates
43-
/// (17.0.4065.4, RTM-CU7 / KB5096981); a real build number is what lets
44-
/// SSMS's per-build client feature gates proceed.
41+
/// <c>sql_variant</c> in <see cref="Run"/>. The version identity derives
42+
/// from <see cref="ReferenceBuild"/>.
4543
/// </summary>
4644
private static SqlValue Produce(string name, RuntimeContext runtime)
4745
{
@@ -85,17 +83,17 @@ private static SqlValue Produce(string name, RuntimeContext runtime)
8583
// Must be non-NULL — Activity Monitor casts it like the NetBIOS
8684
// name above.
8785
"PROCESSID" => SqlValue.FromInt32(Environment.ProcessId),
88-
"PRODUCTBUILD" => SqlValue.FromNVarchar("4065"),
86+
"PRODUCTBUILD" => SqlValue.FromNVarchar(ReferenceBuild.ProductBuild),
8987
// Real SQL Server reports NULL for ProductBuildType on a CU build
9088
// (it's non-null only for GDR/OD servicing branches).
9189
"PRODUCTBUILDTYPE" => SqlValue.Null(SqlType.NVarchar),
9290
"PRODUCTLEVEL" => SqlValue.FromNVarchar("RTM"),
93-
"PRODUCTMAJORVERSION" => SqlValue.FromNVarchar("17"),
94-
"PRODUCTMINORVERSION" => SqlValue.FromNVarchar("0"),
95-
"PRODUCTUPDATELEVEL" => SqlValue.FromNVarchar("CU7"),
96-
"PRODUCTUPDATEREFERENCE" => SqlValue.FromNVarchar("KB5096981"),
97-
"PRODUCTVERSION" => SqlValue.FromNVarchar("17.0.4065.4"),
98-
"RESOURCEVERSION" => SqlValue.FromNVarchar("17.00.4065"),
91+
"PRODUCTMAJORVERSION" => SqlValue.FromNVarchar(ReferenceBuild.ProductMajorVersion),
92+
"PRODUCTMINORVERSION" => SqlValue.FromNVarchar(ReferenceBuild.ProductMinorVersion),
93+
"PRODUCTUPDATELEVEL" => SqlValue.FromNVarchar(ReferenceBuild.UpdateLevel),
94+
"PRODUCTUPDATEREFERENCE" => SqlValue.FromNVarchar(ReferenceBuild.UpdateReference),
95+
"PRODUCTVERSION" => SqlValue.FromNVarchar(ReferenceBuild.ProductVersion),
96+
"RESOURCEVERSION" => SqlValue.FromNVarchar(ReferenceBuild.MajorMinorBuild),
9997
"SERVERNAME" => SqlValue.FromNVarchar("SIMULATED"),
10098
"SQLCHARSET" => SqlValue.FromByte(1),
10199
"SQLCHARSETNAME" => SqlValue.FromNVarchar("iso_1"),

SqlServerSimulator/Parser/Expressions/Value.cs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,10 @@ public Value(DoubleAtPrefixedString doubleAtPrefixedString)
3131
switch (doubleAtPrefixedString.Parse())
3232
{
3333
case AtAtKeyword.Version:
34-
// Mirrors the real SQL Server 2025 @@VERSION banner's multi-line
35-
// shape and reference build (17.0.4065.4), with the simulator's
36-
// own identity standing in for the host-OS line.
37-
this.Constant = SqlValue.FromNVarchar(
38-
"Microsoft SQL Server 2025 (RTM-CU7) (KB5096981) - 17.0.4065.4 (X64) \n" +
39-
"\tJul 8 2026 23:26:08 \n" +
40-
"\tCopyright (C) 2025 Microsoft Corporation\n" +
41-
"\tDeveloper Edition (64-bit) on SQL Server Simulator");
34+
this.Constant = SqlValue.FromNVarchar(ReferenceBuild.Banner);
4235
return;
4336
case AtAtKeyword.MicrosoftVersion:
44-
// (major << 24) | (minor << 16) | build, self-consistent with
45-
// SERVERPROPERTY('ProductVersion') = "17.0.4065.4":
46-
// (17 << 24) | 4065 = 285216737 (0x11000FE1). Matches the real
47-
// reference instance's @@MICROSOFTVERSION.
48-
this.Constant = SqlValue.FromInt32((17 << 24) | 4065);
37+
this.Constant = SqlValue.FromInt32(ReferenceBuild.MicrosoftVersion);
4938
return;
5039
case AtAtKeyword.MaxPrecision:
5140
this.Constant = SqlValue.FromByte(38);
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System.Globalization;
2+
3+
namespace SqlServerSimulator;
4+
5+
/// <summary>
6+
/// Single source of truth for the SQL Server reference build the simulator
7+
/// emulates. Every version-bearing surface derives from here — the
8+
/// <c>SERVERPROPERTY</c> version family, <c>@@VERSION</c> /
9+
/// <c>@@MICROSOFTVERSION</c>, <c>xp_msver</c>,
10+
/// <c>SimulatedDbConnection.ServerVersion</c>, and the TDS LOGINACK /
11+
/// prelogin VERSION bytes — so a reference-build refresh is a one-file bump.
12+
/// The graduated tests pin the derived literals independently
13+
/// (<c>ServerPropertyTests</c>, <c>XpMsverTests</c>), so a typo here fails
14+
/// the suite rather than propagating silently.
15+
/// </summary>
16+
internal static class ReferenceBuild
17+
{
18+
/// <summary>
19+
/// SQL Server 2025 RTM-CU7 — the live reference instance behavior probes
20+
/// run against. SSMS gates report viewers and Activity Monitor on
21+
/// per-build client feature checks, so a real build number is
22+
/// load-bearing, not cosmetic.
23+
/// </summary>
24+
public static readonly Version Version = new(17, 0, 4065, 4);
25+
26+
/// <summary>Servicing level paired with <see cref="Version"/> (<c>SERVERPROPERTY('ProductUpdateLevel')</c>).</summary>
27+
public const string UpdateLevel = "CU7";
28+
29+
/// <summary>Servicing KB paired with <see cref="Version"/> (<c>SERVERPROPERTY('ProductUpdateReference')</c>).</summary>
30+
public const string UpdateReference = "KB5096981";
31+
32+
/// <summary>"17.0.4065.4" — <c>SERVERPROPERTY('ProductVersion')</c> and the <c>xp_msver</c> ProductVersion row.</summary>
33+
public static readonly string ProductVersion = Version.ToString();
34+
35+
/// <summary>"17" — <c>SERVERPROPERTY('ProductMajorVersion')</c>.</summary>
36+
public static readonly string ProductMajorVersion = Version.Major.ToString(CultureInfo.InvariantCulture);
37+
38+
/// <summary>"0" — <c>SERVERPROPERTY('ProductMinorVersion')</c>.</summary>
39+
public static readonly string ProductMinorVersion = Version.Minor.ToString(CultureInfo.InvariantCulture);
40+
41+
/// <summary>"4065" — <c>SERVERPROPERTY('ProductBuild')</c>.</summary>
42+
public static readonly string ProductBuild = Version.Build.ToString(CultureInfo.InvariantCulture);
43+
44+
/// <summary>
45+
/// "17.00.4065" (two-digit minor) — <c>SERVERPROPERTY('ResourceVersion')</c>,
46+
/// and the string real SqlClient computes from the LOGINACK version bytes,
47+
/// which <c>SimulatedDbConnection.ServerVersion</c> mirrors in-process.
48+
/// </summary>
49+
public static readonly string MajorMinorBuild = string.Create(CultureInfo.InvariantCulture, $"{Version.Major}.{Version.Minor:00}.{Version.Build}");
50+
51+
/// <summary>
52+
/// <c>@@MICROSOFTVERSION</c>: <c>(major &lt;&lt; 24) | (minor &lt;&lt; 16) | build</c>
53+
/// = 285216737 (0x11000FE1), matching the reference instance.
54+
/// </summary>
55+
public static readonly int MicrosoftVersion = (Version.Major << 24) | (Version.Minor << 16) | Version.Build;
56+
57+
/// <summary>
58+
/// The <c>@@VERSION</c> banner: real's multi-line shape and build-date
59+
/// line, with the simulator's own identity standing in for the host-OS
60+
/// line.
61+
/// </summary>
62+
public static readonly string Banner =
63+
$"Microsoft SQL Server 2025 (RTM-{UpdateLevel}) ({UpdateReference}) - {ProductVersion} (X64) \n" +
64+
"\tJul 8 2026 23:26:08 \n" +
65+
"\tCopyright (C) 2025 Microsoft Corporation\n" +
66+
"\tDeveloper Edition (64-bit) on SQL Server Simulator";
67+
68+
/// <summary>
69+
/// The <c>xp_msver</c> FileVersion row. The encoding (product year,
70+
/// zero-padded major ×10, zero-padded revision, servicing-branch tag,
71+
/// build-date stamp) is the reference binary's literal file-version
72+
/// resource — not derivable, so bump it together with <see cref="Version"/>.
73+
/// </summary>
74+
public const string FileVersion = "2025.0170.4065.04 ((sql2025_rtm_qfe-cu7).260709-0512)";
75+
}

SqlServerSimulator/SimulatedDbConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ public override string ConnectionString
543543
public override string DataSource => DataSourceName;
544544

545545
/// <inheritdoc/>
546-
public override string ServerVersion => "17.00.4065";
546+
public override string ServerVersion => ReferenceBuild.MajorMinorBuild;
547547

548548
private ConnectionState state;
549549

SqlServerSimulator/Simulation/Simulation.XpMsver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ private static SqlValue[][] BuildXpMsverRows() =>
9292
// ProductVersion Internal_Value packs the major version as
9393
// (major << 16) — 17 << 16 = 1114112 — matching real xp_msver.
9494
XpMsverRow(1, "ProductName", null, "Microsoft SQL Server"),
95-
XpMsverRow(2, "ProductVersion", 17 << 16, "17.0.4065.4"),
95+
XpMsverRow(2, "ProductVersion", ReferenceBuild.Version.Major << 16, ReferenceBuild.ProductVersion),
9696
XpMsverRow(3, "Language", null, "English"),
9797
XpMsverRow(4, "Platform", null, "NT x64"),
9898
XpMsverRow(5, "Comments", null, "SQL"),
9999
XpMsverRow(6, "CompanyName", null, "Microsoft Corporation"),
100100
XpMsverRow(7, "FileDescription", null, "SQL Server Windows NT - 64 Bit"),
101-
XpMsverRow(8, "FileVersion", null, "2025.0170.4065.04 ((sql2025_rtm_qfe-cu7).260709-0512)"),
101+
XpMsverRow(8, "FileVersion", null, ReferenceBuild.FileVersion),
102102
XpMsverRow(9, "InternalName", null, "SQLSERVR"),
103103
XpMsverRow(10, "LegalCopyright", null, "Microsoft. All rights reserved."),
104104
XpMsverRow(11, "LegalTrademarks", null, "Microsoft SQL Server is a registered trademark of Microsoft Corporation."),

docs/claude/scalars.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ Constants whose values don't carry real session/server identity in the simulator
204204
- **`@@TEXTSIZE`** — -1 (matches SQL Server's documented default).
205205
- **`@@OPTIONS`** — 5432 (composite of ANSI/ARITHABORT/QUOTED_IDENTIFIER/CONCAT_NULL_YIELDS_NULL flags matching the simulator's defaults).
206206
- **`@@VERSION`** — a multi-line banner mirroring the real SQL Server 2025 `@@VERSION` shape (`Microsoft SQL Server 2025 (RTM-CU7) (KB5096981) - 17.0.4065.4 (X64)` / build-date line / copyright / edition line), with the simulator's own identity (`Developer Edition (64-bit) on SQL Server Simulator`) standing in for real's host-OS line.
207-
- **`@@MICROSOFTVERSION`** — int `285216737` (`0x11000FE1`), the `(major << 24) | (minor << 16) | build` packing of version `17.0.4065.4` (`(17 << 24) | 4065`), self-consistent with `SERVERPROPERTY('ProductVersion')` = `"17.0.4065.4"` and the real reference instance's value. **Version-identity decision**: every version-bearing surface (`SERVERPROPERTY` family, `@@VERSION`, `@@MICROSOFTVERSION`, `xp_msver`, the TDS LOGINACK/prelogin build) reports the SQL Server 2025 reference build **17.0.4065.4** (RTM-CU7 / KB5096981) the simulator emulates. The prior build-0 identity was changed because SSMS's Activity Monitor and report viewer gate on a per-build client feature check that stops immediately on build 0.
207+
- **`@@MICROSOFTVERSION`** — int `285216737` (`0x11000FE1`), the `(major << 24) | (minor << 16) | build` packing of version `17.0.4065.4` (`(17 << 24) | 4065`), self-consistent with `SERVERPROPERTY('ProductVersion')` = `"17.0.4065.4"` and the real reference instance's value. **Version-identity decision**: every version-bearing surface (`SERVERPROPERTY` family, `@@VERSION`, `@@MICROSOFTVERSION`, `xp_msver`, the TDS LOGINACK/prelogin build, `SimulatedDbConnection.ServerVersion`) reports the SQL Server 2025 reference build **17.0.4065.4** (RTM-CU7 / KB5096981) the simulator emulates; the single source of truth is the internal static `ReferenceBuild` class (root of `SqlServerSimulator/`), which holds the `Version` plus the non-derivable CU / KB / banner / xp_msver-FileVersion constants — bump there on a reference refresh, and the graduated tests' pinned literals catch any typo. The prior build-0 identity was changed because SSMS's Activity Monitor and report viewer gate on a per-build client feature check that stops immediately on build 0.
208208
- **`@@REMSERVER`** — NULL (deprecated in SQL Server proper too).
209209

210210
Server-instance metadata accessed via **`SERVERPROPERTY(name)`** — see [`catalog-views.md`](catalog-views.md).

0 commit comments

Comments
 (0)