diff --git a/SqlScriptDom/Parser/TSql/Ast.xml b/SqlScriptDom/Parser/TSql/Ast.xml
index 24ef837..5c73908 100644
--- a/SqlScriptDom/Parser/TSql/Ast.xml
+++ b/SqlScriptDom/Parser/TSql/Ast.xml
@@ -2529,6 +2529,10 @@
+
+
+
+
diff --git a/SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs b/SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs
index 918e01c..dbca4a1 100644
--- a/SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs
+++ b/SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs
@@ -1,4 +1,4 @@
-//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
@@ -1076,6 +1076,7 @@ internal static class CodeGenerationSupporter
internal const string VirtualDevice = "VIRTUAL_DEVICE";
internal const string VStart = "VSTART";
internal const string WaitAtLowPriority = "WAIT_AT_LOW_PRIORITY";
+ internal const string WaitStatsCaptureMode = "WAIT_STATS_CAPTURE_MODE";
internal const string WebMethod = "WEBMETHOD";
internal const string WellFormedXml = "WELL_FORMED_XML";
internal const string WideChar = "WIDECHAR";
@@ -1263,7 +1264,7 @@ internal static class CodeGenerationSupporter
internal const string Russian = "RUSSIAN";
internal const string Romanian = "ROMANIAN";
internal const string Brazilian = "BRAZILIAN";
- internal const string NorwegianBokmal = "NORWEGIAN (BOKMÅL)";
+ internal const string NorwegianBokmal = "NORWEGIAN (BOKMÃ…L)";
internal const string Dutch = "DUTCH";
internal const string Korean = "KOREAN";
internal const string Japanese = "JAPANESE";
diff --git a/SqlScriptDom/Parser/TSql/QueryStoreOptionKind.cs b/SqlScriptDom/Parser/TSql/QueryStoreOptionKind.cs
index 39d2ed3..6271914 100644
--- a/SqlScriptDom/Parser/TSql/QueryStoreOptionKind.cs
+++ b/SqlScriptDom/Parser/TSql/QueryStoreOptionKind.cs
@@ -21,7 +21,8 @@ public enum QueryStoreOptionKind
Interval_Length_Minutes,
Current_Storage_Size_MB,
Max_Plans_Per_Query,
- Stale_Query_Threshold_Days
+ Stale_Query_Threshold_Days,
+ Wait_Stats_Capture_Mode
}
diff --git a/SqlScriptDom/Parser/TSql/QueryStoreOptionsHelper.cs b/SqlScriptDom/Parser/TSql/QueryStoreOptionsHelper.cs
index 2aca14e..17b194e 100644
--- a/SqlScriptDom/Parser/TSql/QueryStoreOptionsHelper.cs
+++ b/SqlScriptDom/Parser/TSql/QueryStoreOptionsHelper.cs
@@ -26,6 +26,7 @@ private QueryStoreOptionsHelper()
AddOptionMapping(QueryStoreOptionKind.Current_Storage_Size_MB, CodeGenerationSupporter.MaxQdsSize);
AddOptionMapping(QueryStoreOptionKind.Max_Plans_Per_Query, CodeGenerationSupporter.MaxPlansPerQuery);
AddOptionMapping(QueryStoreOptionKind.Stale_Query_Threshold_Days, CodeGenerationSupporter.CleanupPolicy);
+ AddOptionMapping(QueryStoreOptionKind.Wait_Stats_Capture_Mode, CodeGenerationSupporter.WaitStatsCaptureMode, SqlVersionFlags.TSql140AndAbove);
}
internal static readonly QueryStoreOptionsHelper Instance = new QueryStoreOptionsHelper();
diff --git a/SqlScriptDom/Parser/TSql/TSql140.g b/SqlScriptDom/Parser/TSql/TSql140.g
index 08042c5..1311d88 100644
--- a/SqlScriptDom/Parser/TSql/TSql140.g
+++ b/SqlScriptDom/Parser/TSql/TSql140.g
@@ -3144,6 +3144,9 @@ queryStoreOneOption returns [QueryStoreOption vResult = null]
|
{NextTokenMatches(CodeGenerationSupporter.CleanupPolicy)}?
vResult = queryStoreTimeCleanupPolicy
+ |
+ {NextTokenMatches(CodeGenerationSupporter.WaitStatsCaptureMode)}?
+ vResult = queryStoreWaitStatsCaptureOption
;
queryStoreDesiredStateOption returns [QueryStoreDesiredStateOption vResult = FragmentFactory.CreateFragment()]
@@ -3326,6 +3329,30 @@ queryStoreTimeCleanupPolicy returns [QueryStoreTimeCleanupPolicyOption vResult =
}
;
+queryStoreWaitStatsCaptureOption returns [QueryStoreWaitStatsCaptureOption vResult = FragmentFactory.CreateFragment()]
+ : tWaitStatsCaptureMode:Identifier
+ {
+ Match(tWaitStatsCaptureMode, CodeGenerationSupporter.WaitStatsCaptureMode);
+ vResult.OptionKind = QueryStoreOptionKind.Wait_Stats_Capture_Mode;
+ UpdateTokenInfo(vResult, tWaitStatsCaptureMode);
+ }
+ (
+ (EqualsSign tOff:Off
+ {
+ vResult.OptionState = OptionState.Off;
+ UpdateTokenInfo(vResult, tOff);
+ }
+ )
+ |
+ (EqualsSign tOn:On
+ {
+ vResult.OptionState = OptionState.On;
+ UpdateTokenInfo(vResult, tOn);
+ }
+ )
+ )
+ ;
+
automaticTuningDbOption returns [AutomaticTuningDatabaseOption vResult = FragmentFactory.CreateFragment()]
: tAutomaticTuning:Identifier
{
diff --git a/SqlScriptDom/Parser/TSql/TSql150.g b/SqlScriptDom/Parser/TSql/TSql150.g
index d04b752..555902c 100644
--- a/SqlScriptDom/Parser/TSql/TSql150.g
+++ b/SqlScriptDom/Parser/TSql/TSql150.g
@@ -3667,6 +3667,9 @@ queryStoreOneOption returns [QueryStoreOption vResult = null]
|
{NextTokenMatches(CodeGenerationSupporter.CleanupPolicy)}?
vResult = queryStoreTimeCleanupPolicy
+ |
+ {NextTokenMatches(CodeGenerationSupporter.WaitStatsCaptureMode)}?
+ vResult = queryStoreWaitStatsCaptureOption
;
queryStoreDesiredStateOption returns [QueryStoreDesiredStateOption vResult = FragmentFactory.CreateFragment()]
@@ -3894,6 +3897,30 @@ automaticTuningDbOption returns [AutomaticTuningDatabaseOption vResult = Fragmen
)
;
+queryStoreWaitStatsCaptureOption returns [QueryStoreWaitStatsCaptureOption vResult = FragmentFactory.CreateFragment()]
+ : tWaitStatsCaptureMode:Identifier
+ {
+ Match(tWaitStatsCaptureMode, CodeGenerationSupporter.WaitStatsCaptureMode);
+ vResult.OptionKind = QueryStoreOptionKind.Wait_Stats_Capture_Mode;
+ UpdateTokenInfo(vResult, tWaitStatsCaptureMode);
+ }
+ (
+ (EqualsSign tOff:Off
+ {
+ vResult.OptionState = OptionState.Off;
+ UpdateTokenInfo(vResult, tOff);
+ }
+ )
+ |
+ (EqualsSign tOn:On
+ {
+ vResult.OptionState = OptionState.On;
+ UpdateTokenInfo(vResult, tOn);
+ }
+ )
+ )
+ ;
+
automaticTuningOptions [AutomaticTuningDatabaseOption vParent]
{
AutomaticTuningOption vAutomaticTuningOption;
diff --git a/SqlScriptDom/Parser/TSql/TSql160.g b/SqlScriptDom/Parser/TSql/TSql160.g
index ea2694c..913e2a0 100644
--- a/SqlScriptDom/Parser/TSql/TSql160.g
+++ b/SqlScriptDom/Parser/TSql/TSql160.g
@@ -3687,6 +3687,9 @@ queryStoreOneOption returns [QueryStoreOption vResult = null]
|
{NextTokenMatches(CodeGenerationSupporter.CleanupPolicy)}?
vResult = queryStoreTimeCleanupPolicy
+ |
+ {NextTokenMatches(CodeGenerationSupporter.WaitStatsCaptureMode)}?
+ vResult = queryStoreWaitStatsCaptureOption
;
queryStoreDesiredStateOption returns [QueryStoreDesiredStateOption vResult = FragmentFactory.CreateFragment()]
@@ -3869,6 +3872,30 @@ queryStoreTimeCleanupPolicy returns [QueryStoreTimeCleanupPolicyOption vResult =
}
;
+queryStoreWaitStatsCaptureOption returns [QueryStoreWaitStatsCaptureOption vResult = FragmentFactory.CreateFragment()]
+ : tWaitStatsCaptureMode:Identifier
+ {
+ Match(tWaitStatsCaptureMode, CodeGenerationSupporter.WaitStatsCaptureMode);
+ vResult.OptionKind = QueryStoreOptionKind.Wait_Stats_Capture_Mode;
+ UpdateTokenInfo(vResult, tWaitStatsCaptureMode);
+ }
+ (
+ (EqualsSign tOff:Off
+ {
+ vResult.OptionState = OptionState.Off;
+ UpdateTokenInfo(vResult, tOff);
+ }
+ )
+ |
+ (EqualsSign tOn:On
+ {
+ vResult.OptionState = OptionState.On;
+ UpdateTokenInfo(vResult, tOn);
+ }
+ )
+ )
+ ;
+
automaticTuningDbOption returns [AutomaticTuningDatabaseOption vResult = FragmentFactory.CreateFragment()]
: tAutomaticTuning:Identifier
{
diff --git a/SqlScriptDom/Parser/TSql/TSql170.g b/SqlScriptDom/Parser/TSql/TSql170.g
index b6ba097..46794be 100644
--- a/SqlScriptDom/Parser/TSql/TSql170.g
+++ b/SqlScriptDom/Parser/TSql/TSql170.g
@@ -3687,6 +3687,9 @@ queryStoreOneOption returns [QueryStoreOption vResult = null]
|
{NextTokenMatches(CodeGenerationSupporter.CleanupPolicy)}?
vResult = queryStoreTimeCleanupPolicy
+ |
+ {NextTokenMatches(CodeGenerationSupporter.WaitStatsCaptureMode)}?
+ vResult = queryStoreWaitStatsCaptureOption
;
queryStoreDesiredStateOption returns [QueryStoreDesiredStateOption vResult = FragmentFactory.CreateFragment()]
@@ -3869,6 +3872,30 @@ queryStoreTimeCleanupPolicy returns [QueryStoreTimeCleanupPolicyOption vResult =
}
;
+queryStoreWaitStatsCaptureOption returns [QueryStoreWaitStatsCaptureOption vResult = FragmentFactory.CreateFragment()]
+ : tWaitStatsCaptureMode:Identifier
+ {
+ Match(tWaitStatsCaptureMode, CodeGenerationSupporter.WaitStatsCaptureMode);
+ vResult.OptionKind = QueryStoreOptionKind.Wait_Stats_Capture_Mode;
+ UpdateTokenInfo(vResult, tWaitStatsCaptureMode);
+ }
+ (
+ (EqualsSign tOff:Off
+ {
+ vResult.OptionState = OptionState.Off;
+ UpdateTokenInfo(vResult, tOff);
+ }
+ )
+ |
+ (EqualsSign tOn:On
+ {
+ vResult.OptionState = OptionState.On;
+ UpdateTokenInfo(vResult, tOn);
+ }
+ )
+ )
+ ;
+
automaticTuningDbOption returns [AutomaticTuningDatabaseOption vResult = FragmentFactory.CreateFragment()]
: tAutomaticTuning:Identifier
{
diff --git a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.QueryStoreDatabaseOption.cs b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.QueryStoreDatabaseOption.cs
index 5737310..362cd40 100644
--- a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.QueryStoreDatabaseOption.cs
+++ b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.QueryStoreDatabaseOption.cs
@@ -74,5 +74,24 @@ public override void ExplicitVisit(QueryStoreTimeCleanupPolicyOption node)
GenerateNameEqualsValue(CodeGenerationSupporter.StaleQueryThresholdDays, node.StaleQueryThreshold);
GenerateSymbol(TSqlTokenType.RightParenthesis);
}
+
+ public override void ExplicitVisit(QueryStoreWaitStatsCaptureOption node)
+ {
+ System.Diagnostics.Debug.Assert(node.OptionKind == QueryStoreOptionKind.Wait_Stats_Capture_Mode);
+ GenerateIdentifier(CodeGenerationSupporter.WaitStatsCaptureMode);
+ GenerateSpace();
+
+ switch (node.OptionState)
+ {
+ case OptionState.Off:
+ GenerateSymbolAndSpace(TSqlTokenType.EqualsSign);
+ GenerateKeyword(TSqlTokenType.Off);
+ break;
+ case OptionState.On:
+ GenerateSymbolAndSpace(TSqlTokenType.EqualsSign);
+ GenerateKeyword(TSqlTokenType.On);
+ break;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Test/SqlDom/Baselines140/AlterDatabaseOptionsTests140.sql b/Test/SqlDom/Baselines140/AlterDatabaseOptionsTests140.sql
index 85185be..841f2e8 100644
--- a/Test/SqlDom/Baselines140/AlterDatabaseOptionsTests140.sql
+++ b/Test/SqlDom/Baselines140/AlterDatabaseOptionsTests140.sql
@@ -51,3 +51,10 @@ ALTER DATABASE db
ALTER DATABASE db
SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN = OFF);
+
+
+ALTER DATABASE db
+ SET QUERY_STORE (DESIRED_STATE = READ_ONLY, QUERY_CAPTURE_MODE = ALL, SIZE_BASED_CLEANUP_MODE = OFF, INTERVAL_LENGTH_MINUTES = 100, MAX_STORAGE_SIZE_MB = 1000, MAX_PLANS_PER_QUERY = 200, CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 367), WAIT_STATS_CAPTURE_MODE = ON);
+
+ALTER DATABASE db
+ SET QUERY_STORE = ON(DESIRED_STATE = READ_ONLY, QUERY_CAPTURE_MODE = ALL, SIZE_BASED_CLEANUP_MODE = OFF, INTERVAL_LENGTH_MINUTES = 100, MAX_STORAGE_SIZE_MB = 1000, MAX_PLANS_PER_QUERY = 200, CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 367), WAIT_STATS_CAPTURE_MODE = OFF);
\ No newline at end of file
diff --git a/Test/SqlDom/Only140SyntaxTests.cs b/Test/SqlDom/Only140SyntaxTests.cs
index 80a8e89..934222e 100644
--- a/Test/SqlDom/Only140SyntaxTests.cs
+++ b/Test/SqlDom/Only140SyntaxTests.cs
@@ -16,7 +16,7 @@ public partial class SqlDomTests
private static readonly ParserTest[] Only140TestInfos =
{
new ParserTest140("AlterIndexStatementTests140.sql", 2, 20, 20, 20, 20, 20),
- new ParserTest140("AlterDatabaseOptionsTests140.sql", 18, 18, 18, 18, 18, 18),
+ new ParserTest140("AlterDatabaseOptionsTests140.sql", 20, 20, 20, 20, 20, 20),
new ParserTest140("CreateIndexStatementTests140.sql", 18, 14, 14, 14, 14, 14),
new ParserTest140("CreateTableTests140.sql", 17, 15, 15, 15, 15, 11),
new ParserTest140("OptimizerHintsTests140.sql", 6, 6, 6, 6, 6, 0),
diff --git a/Test/SqlDom/TestScripts/AlterDatabaseOptionsTests140.sql b/Test/SqlDom/TestScripts/AlterDatabaseOptionsTests140.sql
index 21b9151..053a71a 100644
--- a/Test/SqlDom/TestScripts/AlterDatabaseOptionsTests140.sql
+++ b/Test/SqlDom/TestScripts/AlterDatabaseOptionsTests140.sql
@@ -17,3 +17,7 @@ ALTER DATABASE db SET AUTOMATIC_TUNING (MAINTAIN_INDEX = DEFAULT);
ALTER DATABASE db SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN = ON, CREATE_INDEX = DEFAULT, MAINTAIN_INDEX = ON, DROP_INDEX = ON);
alter database db set automatic_tuning = auto;
ALtER DataBAsE db SET AUTomaTIC_TUNING (ForCE_LasT_GooD_PLAN = ofF);
+
+-- query_store options for 2017+
+alter database db set query_store (desired_state = read_only, query_capture_mode = all, size_based_cleanup_mode = off, interval_length_minutes = 100, max_storage_size_mb = 1000, max_plans_per_query = 200, cleanup_policy = (stale_query_threshold_days = 367), WAIT_STATS_CAPTURE_MODE = ON);
+alter database db set query_store = on(desired_state = read_only, query_capture_mode = all, size_based_cleanup_mode = off, interval_length_minutes = 100, max_storage_size_mb = 1000, max_plans_per_query = 200, cleanup_policy = (stale_query_threshold_days = 367), WAIT_STATS_CAPTURE_MODE = OFF);