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

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions