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+).
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
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+).