Skip to content

UPDATE STATISTICS ... WITH PERSIST_SAMPLE_PERCENT = ON fails to parse on all TSqlParser versions (80–180) #205

@aazami12

Description

@aazami12

Summary

The PERSIST_SAMPLE_PERCENT = { ON | OFF } clause of UPDATE STATISTICS (and CREATE STATISTICS) is documented and supported by SQL Server 2016 (13.x) SP1 CU4 and later, plus Azure SQL Database / Managed Instance, but every TSqlNNNParser in Microsoft.SqlServer.TransactSql.ScriptDom rejects it with Incorrect syntax near 'ON'. (or 'OFF'). This means valid production T-SQL fails parsing, including scripts that target the SQL versions where the syntax was introduced.

Reference: https://learn.microsoft.com/sql/t-sql/statements/update-statistics-transact-sql#persist_sample_percent--on--off-

Repro

using Microsoft.SqlServer.TransactSql.ScriptDom;
using System.IO;

var parser = new TSql160Parser(true);
using var reader = new StringReader(
"UPDATE STATISTICS dbo.MyTable WITH FULLSCAN, PERSIST_SAMPLE_PERCENT = ON;");
parser.Parse(reader, out var errors);
foreach (var e in errors)
System.Console.WriteLine($"{e.Message} @ line {e.Line}, col {e.Column}");

Output:
Incorrect syntax near 'ON'. @ line 1, col 71

Affected versions

Reproduced against Microsoft.SqlServer.TransactSql.ScriptDom 180.18.1 (file version 18.0.18.1, .NET Framework 4.7.2 / .NET 8 lib both behave identically). The same error occurs on every parser version exposed by the package:

┌────────────────────────────────────────────────┬─────────────────────────────┐
│ Parser │ Result │
├────────────────────────────────────────────────┼─────────────────────────────┤
│ TSql80Parser … TSql180Parser (all 11 versions) │ Incorrect syntax near 'ON'. │
└────────────────────────────────────────────────┴─────────────────────────────┘

Variants tested (all fail)

UPDATE STATISTICS dbo.T WITH FULLSCAN, PERSIST_SAMPLE_PERCENT = ON; -- FAIL
UPDATE STATISTICS dbo.T WITH FULLSCAN, PERSIST_SAMPLE_PERCENT = OFF; -- FAIL
UPDATE STATISTICS dbo.T WITH PERSIST_SAMPLE_PERCENT = ON; -- FAIL
UPDATE STATISTICS dbo.T WITH PERSIST_SAMPLE_PERCENT = ON, FULLSCAN; -- FAIL
UPDATE STATISTICS dbo.T WITH SAMPLE 50 PERCENT, PERSIST_SAMPLE_PERCENT = ON; -- FAIL

Sanity-check (passes — confirms the parser otherwise handles UPDATE STATISTICS WITH ...):

UPDATE STATISTICS dbo.T WITH FULLSCAN; -- OK
UPDATE STATISTICS dbo.T WITH FULLSCAN, NORECOMPUTE; -- OK

Expected behavior

TSql130Parser (SQL Server 2016, the minimum SP1-CU4 version where the option became available) and every later parser should accept the PERSIST_SAMPLE_PERCENT = { ON | OFF } option in any valid combination and ordering with the other WITH options of UPDATE
STATISTICS and CREATE STATISTICS. The same applies to the Sql{NNN}ScriptGenerator round-trip, once the parser accepts the AST, the generator should emit it.

Actual behavior

All parsers from TSql80Parser through TSql180Parser raise Incorrect syntax near 'ON'/'OFF' at the = value token of PERSIST_SAMPLE_PERCENT, suggesting the option is missing entirely from the grammar (not just gated by parser version).

Environment

  • Microsoft.SqlServer.TransactSql.ScriptDom 180.18.1 (latest on NuGet at time of report)
  • Reproduced on .NET Framework 4.7.2 (also reproduces on .NET 8 build of the package)
  • Windows 11 24H2

Impact

Anyone using ScriptDom to lint, format, refactor, or validate production deployment scripts that include the PERSIST_SAMPLE_PERCENT option (which is recommended best practice on large tables to keep custom sampling rates across auto-stats updates) will get a hard
parse failure.

Suggested fix

Add PERSIST_SAMPLE_PERCENT = { ON | OFF } to the <update_stats_stream_option> and <create_stats_stream_option> rules in the TSqlParser grammar, gated by the appropriate SQL Server version (SQL 2016 SP1 CU4 / 130+).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions