From 4c7f290f7de599a85a3a1cdef75530e80248fb5d Mon Sep 17 00:00:00 2001 From: Sai Avishkar Sreerama Date: Fri, 6 Sep 2024 14:11:36 +0000 Subject: [PATCH 1/9] Merged PR 1450917: Adding CTAS support to the 160Parser This change adds the ability to parse the CTAS statement which has the "Create Table TblName AS Select" format. So far we support "Create Table tableName With(Distribution) AS Select...) syntax only. This change fixes the syntax error at Select and allows the DW users to run the sql queries with the syntax. ---- #### AI description (iteration 1) #### PR Classification New feature: Adding support for CTAS (Create Table As Select) statements in the 160Parser. #### PR Summary This pull request introduces support for parsing CTAS statements in the TSql160Parser and includes corresponding unit tests. - Added `CreateCTASParser160Test` method in `Test/SqlDom/TSqlParserTest.cs` to validate CTAS statement parsing. - Updated `TSql160.g` to handle `As` keyword for CTAS statements. - Minor import addition in `Test/SqlDom/PhaseOneParserTest.cs`. --- SqlScriptDom/Parser/TSql/TSql160.g | 5 +++ Test/SqlDom/PhaseOneParserTest.cs | 2 + Test/SqlDom/TSqlParserTest.cs | 60 ++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/SqlScriptDom/Parser/TSql/TSql160.g b/SqlScriptDom/Parser/TSql/TSql160.g index 11f82a2..97d634c 100644 --- a/SqlScriptDom/Parser/TSql/TSql160.g +++ b/SqlScriptDom/Parser/TSql/TSql160.g @@ -26510,6 +26510,11 @@ createTableStatement returns [CreateTableStatement vResult = this.FragmentFactor } UpdateTokenInfo(vResult, tFileTableOrGraphEdge); } + | + As + { + vResult.SelectStatement = selectStatement(SubDmlFlags.None); + } ) // Default is not used as a keyword after on or textimage_on (even though it is a keyword) diff --git a/Test/SqlDom/PhaseOneParserTest.cs b/Test/SqlDom/PhaseOneParserTest.cs index 6bddbb6..7e4aeee 100644 --- a/Test/SqlDom/PhaseOneParserTest.cs +++ b/Test/SqlDom/PhaseOneParserTest.cs @@ -4,9 +4,11 @@ // //------------------------------------------------------------------------------ +using System.Collections.Generic; using System.IO; using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json.Linq; using SqlStudio.Tests.AssemblyTools.TestCategory; namespace SqlStudio.Tests.UTSqlScriptDom diff --git a/Test/SqlDom/TSqlParserTest.cs b/Test/SqlDom/TSqlParserTest.cs index 57ec709..5d947db 100644 --- a/Test/SqlDom/TSqlParserTest.cs +++ b/Test/SqlDom/TSqlParserTest.cs @@ -533,6 +533,66 @@ COPY INTO #Test Console.WriteLine($"Error {error.Number} Message {error.Message}"); } Assert.AreEqual(0, errors.Count); + } + + /// + /// This test validates the generation of table and stored procedure that contains CTAS statements + /// + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void CreateCTASParser160Test() + { + TSql160Parser parser = new TSql160Parser(true); + StringReader reader = new StringReader(@" + -- CTAS + CREATE TABLE TestTable AS + SELECT customername, contactname + FROM customers + GO; + + -- CTAS in stored procedure - 'create table As Select *' + CREATE PROCEDURE test_proc_withCreateSelect + AS + BEGIN + CREATE TABLE Test1 + AS + SELECT * FROM Test + END + GO; + + -- CTAS in stored procedure - 'create table With( ) As Select' + CREATE PROCEDURE test_proc_withCreateWith + AS + BEGIN + CREATE TABLE [dbo].[ReplicateToHash_ID] + WITH(DISTRIBUTION = Hash(id)) + AS SELECT ID FROM [dbo].[REPLICATE_TEST_UPDATE] + END + GO; + + -- CTAS in stored procedure - 'create table as Select columnsNames' + CREATE PROCEDURE test_proc_withSelectColumns + AS + BEGIN + CREATE TABLE Test1 + AS + SELECT Id AS ID, + person AS Person + FROM Test + END + GO;"); + + var fragments = parser.Parse(reader, out IList errors); + + Assert.IsTrue(errors.Count == 0); + Assert.AreEqual(4, ((TSqlScript)fragments).Batches.Count); + foreach(TSqlBatch batch in ((TSqlScript)fragments).Batches) + { + TSqlStatement statement = batch.Statements[0]; + Assert.IsNotNull(statement); + Assert.IsTrue(statement is CreateTableStatement || statement is CreateProcedureStatement); + } } void VerifyTokenTypesAndOffsets(IList tokens, TSqlTokenType[] tokenTypes, int[] zeroBasedTokenOffsets, int offsetShift) From 1d4b9711670bce7730a94bf27231d25501cec996 Mon Sep 17 00:00:00 2001 From: Sai Avishkar Sreerama Date: Fri, 6 Sep 2024 19:42:58 +0000 Subject: [PATCH 2/9] Merged PR 1451812: Adds release notes to 191.9142.1 Adds release notes to 191.9142.1, adds the CTAS support to 160 Parser and SDK update ---- #### AI description (iteration 1) #### PR Classification Documentation #### PR Summary This pull request adds release notes for version 161.9142.1. - `release-notes/161.91/161.9142.1.md`: Introduces release notes detailing target platform support, updated dependencies, new features, fixed issues, and known issues. --- release-notes/161.91/161.9142.1.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 release-notes/161.91/161.9142.1.md diff --git a/release-notes/161.91/161.9142.1.md b/release-notes/161.91/161.9142.1.md new file mode 100644 index 0000000..eee84cc --- /dev/null +++ b/release-notes/161.91/161.9142.1.md @@ -0,0 +1,27 @@ +# Release Notes + +## Microsoft.SqlServer.TransactSql.ScriptDom 161.9142.1 +This update brings the below changes over the previous release: + +### Target Platform Support + +* .NET Framework 4.6.2 (Windows x86, Windows x64) +* .NET 6 (Windows x86, Windows x64, Linux, macOS) +* .NET Standard 2.0+ (Windows x86, Windows x64, Linux, macOS) + +### Dependencies +* Updates.NET SDK to latest patch version 6.0.425 + +#### .NET Framework +#### .NET Core +#### .NET Standard + +### New Features + + +### Fixed +* Adds support for CTAS syntax to 160 TSqlParser + +### Changes + +### Known Issues From 9530bebdda0fad6a592697beca411197774b7ee4 Mon Sep 17 00:00:00 2001 From: "Abhishek Kumar (MDD)" Date: Wed, 25 Sep 2024 21:34:00 +0000 Subject: [PATCH 3/9] Merged PR 1464510: Added tests for vector functions Added tests for below vector functions: 1. VECTOR_DISTANCE 2. VECTOR_NORM 3. VECTOR_NORMALIZE --- .../Baselines160/VectorFunctionTests160.sql | 15 +++++++++++++++ Test/SqlDom/Only160SyntaxTests.cs | 1 + .../TestScripts/VectorFunctionTests160.sql | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 Test/SqlDom/Baselines160/VectorFunctionTests160.sql create mode 100644 Test/SqlDom/TestScripts/VectorFunctionTests160.sql diff --git a/Test/SqlDom/Baselines160/VectorFunctionTests160.sql b/Test/SqlDom/Baselines160/VectorFunctionTests160.sql new file mode 100644 index 0000000..8f53253 --- /dev/null +++ b/Test/SqlDom/Baselines160/VectorFunctionTests160.sql @@ -0,0 +1,15 @@ +DECLARE @v1 AS VECTOR (4), @v2 AS VECTOR (4); +SET @v2 = CAST ('[0.1, 0.1, 0.1,0.2]' AS VECTOR (4)); +SET @v1 = CONVERT (VECTOR (4), '[0.1, 0.2, 0.1, 0.2]'); + +SELECT VECTOR_DISTANCE('cosine', @v1, @v2); +SELECT VECTOR_DISTANCE('euclidean', @v1, @v2); +SELECT VECTOR_DISTANCE('dot', @v1, @v2); +SELECT VECTOR_DISTANCE('dot', @v1, NULL); +SELECT ROUND(VECTOR_DISTANCE('cosine', @v1, @v2), 16); + +SELECT VECTOR_NORM(@v1, 'norm1'); +SELECT VECTOR_NORM(@v1, 'norm2'); + +SELECT VECTOR_NORMALIZE(@v1, 'norm1') AS normalized_vector; +SELECT VECTOR_NORMALIZE(@v1, 'norm2') AS normalized_vector; diff --git a/Test/SqlDom/Only160SyntaxTests.cs b/Test/SqlDom/Only160SyntaxTests.cs index a52b8e6..e0545b3 100644 --- a/Test/SqlDom/Only160SyntaxTests.cs +++ b/Test/SqlDom/Only160SyntaxTests.cs @@ -46,6 +46,7 @@ public partial class SqlDomTests new ParserTest160("InlineIndexColumnWithINCLUDEtest.sql", nErrors80: 3, nErrors90: 3, nErrors100: 3, nErrors110: 3, nErrors120: 2, nErrors130: 2, nErrors140: 2, nErrors150: 2), new ParserTest160("MaterializedViewTests160.sql", nErrors80: 6, nErrors90: 3, nErrors100: 3, nErrors110: 3, nErrors120: 3, nErrors130: 0, nErrors140: 0, nErrors150: 0), new ParserTest160("NotEnforcedConstraintTests160.sql", nErrors80: 3, nErrors90: 1, nErrors100: 1, nErrors110: 1, nErrors120: 1, nErrors130: 1, nErrors140: 1, nErrors150: 1), + new ParserTest160("VectorFunctionTests160.sql", nErrors80: 0, nErrors90: 0, nErrors100: 0, nErrors110: 0, nErrors120: 0, nErrors130: 0, nErrors140: 0, nErrors150: 0), }; private static readonly ParserTest[] SqlAzure160_TestInfos = diff --git a/Test/SqlDom/TestScripts/VectorFunctionTests160.sql b/Test/SqlDom/TestScripts/VectorFunctionTests160.sql new file mode 100644 index 0000000..d11a906 --- /dev/null +++ b/Test/SqlDom/TestScripts/VectorFunctionTests160.sql @@ -0,0 +1,18 @@ +DECLARE @v1 vector ( 4 ), @v2 vector(4) +SET @v2 = CAST('[0.1, 0.1, 0.1,0.2]' as vector(4)) +SET @v1 = CONVERT(vector( 4 ), '[0.1, 0.2, 0.1, 0.2]') + +-- VECTOR_DISTANCE +SELECT VECTOR_DISTANCE('cosine', @v1, @v2); +SELECT VECTOR_DISTANCE('euclidean', @v1, @v2); +SELECT VECTOR_DISTANCE('dot', @v1, @v2); +SELECT VECTOR_DISTANCE('dot', @v1, NULL); +SELECT ROUND(VECTOR_DISTANCE('cosine',@v1,@v2),16) + +-- VECTOR_NORM +SELECT VECTOR_NORM(@v1, 'norm1'); +SELECT VECTOR_NORM(@v1, 'norm2'); + +-- VECTOR_NORMALIZE +SELECT VECTOR_NORMALIZE(@v1, 'norm1') AS normalized_vector; +SELECT VECTOR_NORMALIZE(@v1, 'norm2') AS normalized_vector; From c7163d2b25278808115abf799b02a441ca881bd4 Mon Sep 17 00:00:00 2001 From: "Abhishek Kumar (MDD)" Date: Wed, 9 Oct 2024 16:43:41 +0000 Subject: [PATCH 4/9] Merged PR 1472202: Parser tests for VECTORPROPERTY Metadata function Updated vector function test script to include VECTORPROPERTY Metadata function --- Test/SqlDom/Baselines160/VectorFunctionTests160.sql | 3 +++ Test/SqlDom/TestScripts/VectorFunctionTests160.sql | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/Test/SqlDom/Baselines160/VectorFunctionTests160.sql b/Test/SqlDom/Baselines160/VectorFunctionTests160.sql index 8f53253..f23ad25 100644 --- a/Test/SqlDom/Baselines160/VectorFunctionTests160.sql +++ b/Test/SqlDom/Baselines160/VectorFunctionTests160.sql @@ -13,3 +13,6 @@ SELECT VECTOR_NORM(@v1, 'norm2'); SELECT VECTOR_NORMALIZE(@v1, 'norm1') AS normalized_vector; SELECT VECTOR_NORMALIZE(@v1, 'norm2') AS normalized_vector; + +SELECT VECTORPROPERTY(@v1, 'Dimensions'); +SELECT VECTORPROPERTY(@v1, 'BaseType'); diff --git a/Test/SqlDom/TestScripts/VectorFunctionTests160.sql b/Test/SqlDom/TestScripts/VectorFunctionTests160.sql index d11a906..abc2719 100644 --- a/Test/SqlDom/TestScripts/VectorFunctionTests160.sql +++ b/Test/SqlDom/TestScripts/VectorFunctionTests160.sql @@ -16,3 +16,7 @@ SELECT VECTOR_NORM(@v1, 'norm2'); -- VECTOR_NORMALIZE SELECT VECTOR_NORMALIZE(@v1, 'norm1') AS normalized_vector; SELECT VECTOR_NORMALIZE(@v1, 'norm2') AS normalized_vector; + +-- VECTORPROPERTY Metadata function +SELECT VECTORPROPERTY(@v1, 'Dimensions'); +SELECT VECTORPROPERTY(@v1, 'BaseType'); From de53fc2f384517faef8a9767354d404cdc76e422 Mon Sep 17 00:00:00 2001 From: MerlinBot Date: Sat, 12 Oct 2024 13:00:40 +0000 Subject: [PATCH 5/9] [Security] Update .NET SDK to latest patch version --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 8b11616..ac22e7f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0.425", + "version": "6.0.427", "rollForward": "latestMajor" }, "msbuild-sdks": { From 408722c1b962974a77281bafcc98bed3438d1719 Mon Sep 17 00:00:00 2001 From: MerlinBot Date: Tue, 26 Nov 2024 21:42:17 +0000 Subject: [PATCH 6/9] Merged PR 1489440: Policy as Code configuration of Approver Count on Official Branches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Introducing Policy-as-Code, powered by 1ES’ Policy Aware Engineering System (PAES)! With [Policy-as-Code](https://aka.ms/1esPaaC), repository owners can configure Azure DevOps (ADO) branch policies directly in the source code, eliminating the need for manual per-branch configuration. Policy-as-Code is the easiest way to manage branch policies efficiently! This Pull Request (PR) contains policy configuration settings that will be applied to the entire repository. Learn more about this approver count policy [here](https://aka.ms/1esPaaCAC). --- ### Actions Required - **What is in this PR and why should I complete it?** - This PR contains a suggested initialization of peer review policy settings specific to your repository. - By adopting Policy-as-Code, you ensure that branch policies are version-controlled and consistently applied across your repository. This practice enhances collaboration, compliance, and reduces manual configuration efforts. - [OneBranch is rolling out pipeline-time validation on all its official pipelines](https://aka.ms/obprv). - **What do I need to do?** - Review the targeted leaf branches in the .yml file created for you. You may remove any branches where collaboration is not expected. [Most leaf branches shouldn't be using official pipelines](https://aka.ms/OBPRValidation). ### Best Practices on Policy-as-Code - **Is branch policy required? Do I need to complete this PR?** - Branch policies are required on default branches (like `main`, `master`, `default`, `release*`), but these are configured at the service level through a different mechanism ([learn more](https://aka.ms/1esPaaCCY22)). The policies in this PR are specific to your repository. - **What if we are already using branch policies? How do conflicts work?** - Policies can still be customized using the ADO UI. **Your existing branch policies will remain unchanged**. In case of conflicts, the **most restrictive** policy settings will take precedence, ensuring compliance is maintained. - **Who created this PR?** - This PR was generated by OneBranch to facilitate the adoption of Policy-as-Code. The Policy-as-Code tooling is a product of the 1ES team. - **Who do I contact for additional support?** - For more information, visit the [PAES Wiki](https://aka.ms/1esPaaC). To learn more about OneBranch compliance enforcement efforts, click [here](https://aka.ms/obprv). If you have questions or need assistance related to PAES and Policy-as-Code, please email [PolicyServiceHelp@microsoft.com](mailto:PolicyServiceHelp@microsoft.com). --- By reviewing and completing this PR, you'll be taking a significant step toward streamlined policy management and improved compliance within your development workflow. Thank you for your attention to this important initiative! --- .azuredevops/policies/approvercountpolicy.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .azuredevops/policies/approvercountpolicy.yml diff --git a/.azuredevops/policies/approvercountpolicy.yml b/.azuredevops/policies/approvercountpolicy.yml new file mode 100644 index 0000000..6be04b6 --- /dev/null +++ b/.azuredevops/policies/approvercountpolicy.yml @@ -0,0 +1,19 @@ +name: approver_count +description: Approver count policy for msdata/SQLToolsAndLibraries/ScriptDOM repository +resource: repository +where: +configuration: + approverCountPolicySettings: + isBlocking: true + requireMinimumApproverCount: 1 + creatorVoteCounts: false + allowDownvotes: false + sourcePushOptions: + resetOnSourcePush: false + requireVoteOnLastIteration: true + requireVoteOnEachIteration: false + resetRejectionsOnSourcePush: false + blockLastPusherVote: true + branchNames: + - refs/heads/main + displayName: msdata/SQLToolsAndLibraries/ScriptDOM Approver Count Policy From c35245a35c07c3a58d6930fcdd1967d487ddb67e Mon Sep 17 00:00:00 2001 From: Leila Lali Date: Thu, 5 Dec 2024 23:36:09 +0000 Subject: [PATCH 7/9] Merged PR 1528877: Merging 170 branch to main New feature This pull request adds support for the vector type in ScriptDOM and includes tests to verify the TSQL script for creating tables with vector column types. - Added `TSql170Parser.cs` to implement the T-SQL 17.0 parser. - Added `Sql170ScriptGeneratorVisitor.cs` to handle script generation for T-SQL 17.0. - Added `TSql170ParserBaseInternal.cs` to provide base internal parsing logic for T-SQL 17.0. - Added `Sql170ScriptGenerator.cs` to create a script generator for T-SQL 17.0. Related work items: #3355520 --- SqlScriptDom/GenerateFiles.props | 1 + .../Parser/TSql/OnOffSimpleDbOptionsHelper.cs | 4 + SqlScriptDom/Parser/TSql/OptionsHelper.cs | 2 + SqlScriptDom/Parser/TSql/SqlVersionFlags.cs | 20 +- SqlScriptDom/Parser/TSql/TSql170.g | 34253 ++++++++++++++++ SqlScriptDom/Parser/TSql/TSql170Parser.cs | 268 + .../Parser/TSql/TSql170ParserBaseInternal.cs | 50 + SqlScriptDom/Parser/TSql/TSqlParser.cs | 2 + .../Sql170ScriptGeneratorVisitor.cs | 252 + .../SqlServer/Sql170ScriptGenerator.cs | 42 + .../ScriptDom/SqlServer/SqlVersion.cs | 5 + Test/SqlDom/CommonSyntaxTests.cs | 13 + Test/SqlDom/GraphDbRegressionTests.cs | 6 +- Test/SqlDom/ParserTest.cs | 23 +- Test/SqlDom/TSqlParserTest.cs | 3 +- Test/SqlDom/TestUtilities.cs | 19 +- Test/SqlDom/UTSqlScriptDom.csproj | 1 + 17 files changed, 34948 insertions(+), 16 deletions(-) create mode 100644 SqlScriptDom/Parser/TSql/TSql170.g create mode 100644 SqlScriptDom/Parser/TSql/TSql170Parser.cs create mode 100644 SqlScriptDom/Parser/TSql/TSql170ParserBaseInternal.cs create mode 100644 SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/Sql170ScriptGeneratorVisitor.cs create mode 100644 SqlScriptDom/ScriptDom/SqlServer/Sql170ScriptGenerator.cs diff --git a/SqlScriptDom/GenerateFiles.props b/SqlScriptDom/GenerateFiles.props index 61e0aed..1571a61 100644 --- a/SqlScriptDom/GenerateFiles.props +++ b/SqlScriptDom/GenerateFiles.props @@ -11,6 +11,7 @@ + diff --git a/SqlScriptDom/Parser/TSql/OnOffSimpleDbOptionsHelper.cs b/SqlScriptDom/Parser/TSql/OnOffSimpleDbOptionsHelper.cs index dc45e3b..696b6cf 100644 --- a/SqlScriptDom/Parser/TSql/OnOffSimpleDbOptionsHelper.cs +++ b/SqlScriptDom/Parser/TSql/OnOffSimpleDbOptionsHelper.cs @@ -62,6 +62,10 @@ private OnOffSimpleDbOptionsHelper() // 160 options AddOptionMapping(DatabaseOptionKind.Ledger, CodeGenerationSupporter.Ledger, SqlVersionFlags.TSql160AndAbove); + + // 170 options + // TODO: add any new 170 options here + } internal static readonly OnOffSimpleDbOptionsHelper Instance = new OnOffSimpleDbOptionsHelper(); diff --git a/SqlScriptDom/Parser/TSql/OptionsHelper.cs b/SqlScriptDom/Parser/TSql/OptionsHelper.cs index a2b7127..642b9f4 100644 --- a/SqlScriptDom/Parser/TSql/OptionsHelper.cs +++ b/SqlScriptDom/Parser/TSql/OptionsHelper.cs @@ -126,6 +126,8 @@ internal SqlVersionFlags MapSqlVersionToSqlVersionFlags(SqlVersion sqlVersion) return SqlVersionFlags.TSql150; case SqlVersion.Sql160: return SqlVersionFlags.TSql160; + case SqlVersion.Sql170: + return SqlVersionFlags.TSql170; default: throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SqlScriptGeneratorResource.UnknownEnumValue, sqlVersion, "SqlVersion"), "sqlVersion"); } diff --git a/SqlScriptDom/Parser/TSql/SqlVersionFlags.cs b/SqlScriptDom/Parser/TSql/SqlVersionFlags.cs index 2bc3317..6be3e78 100644 --- a/SqlScriptDom/Parser/TSql/SqlVersionFlags.cs +++ b/SqlScriptDom/Parser/TSql/SqlVersionFlags.cs @@ -23,21 +23,23 @@ internal enum SqlVersionFlags TSql140 = 0x40, TSql150 = 0x80, TSql160 = 0x100, + TSql170 = 0x200, - TSqlAll = TSql80 | TSql90 | TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160, - TSql90AndAbove = TSql90 | TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160, - TSql100AndAbove = TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160, - TSql110AndAbove = TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160, - TSql120AndAbove = TSql120 | TSql130 | TSql140 | TSql150 | TSql160, - TSql130AndAbove = TSql130 | TSql140 | TSql150 | TSql160, - TSql140AndAbove = TSql140 | TSql150 | TSql160, - TSql150AndAbove = TSql150 | TSql160, - TSql160AndAbove = TSql160, + TSqlAll = TSql80 | TSql90 | TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160 | TSql170, + TSql90AndAbove = TSql90 | TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160 | TSql170, + TSql100AndAbove = TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160 | TSql170, + TSql110AndAbove = TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160 | TSql170, + TSql120AndAbove = TSql120 | TSql130 | TSql140 | TSql150 | TSql160 | TSql170, + TSql130AndAbove = TSql130 | TSql140 | TSql150 | TSql160 | TSql170, + TSql140AndAbove = TSql140 | TSql150 | TSql160 | TSql170, + TSql150AndAbove = TSql150 | TSql160 | TSql170, + TSql160AndAbove = TSql160 | TSql170, TSqlUnder110 = TSql80 | TSql90 | TSql100, TSqlUnder120 = TSql80 | TSql90 | TSql100 | TSql110, TSqlUnder130 = TSql80 | TSql90 | TSql100 | TSql110 | TSql120, TSqlUnder140 = TSql80 | TSql90 | TSql100 | TSql110 | TSql120 | TSql130, TSqlUnder150 = TSql80 | TSql90 | TSql100 | TSql110 | TSql120 | TSql130 | TSql140, TSqlUnder160 = TSql80 | TSql90 | TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150, + TSqlUnder170 = TSql80 | TSql90 | TSql100 | TSql110 | TSql120 | TSql130 | TSql140 | TSql150 | TSql160, } } \ No newline at end of file diff --git a/SqlScriptDom/Parser/TSql/TSql170.g b/SqlScriptDom/Parser/TSql/TSql170.g new file mode 100644 index 0000000..b6ba097 --- /dev/null +++ b/SqlScriptDom/Parser/TSql/TSql170.g @@ -0,0 +1,34253 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ + +// sacaglar: Handling position information for ASTs +// The properties and AddX (X is the type of the parameter, e.g., AddStatement) +// update the position information of the AST. In the rare case when +// we are setting a bool, int, or string etc. we have to call UpdateTokenInfo +// with the token (because we are not passing the property a token, we are just +// passing a bool, int etc. +// Also for token that we don't track of like Comma, Semicolon etc. we have to +// call the same function. Alternatively the properties(StartOffset, FragmentLength) +// on Fragment.cs can be used for this purpose. + +options { + language = "CSharp"; + namespace = "Microsoft.SqlServer.TransactSql.ScriptDom"; +} + +{ + using System.Diagnostics; + using System.Globalization; + using System.Collections.Generic; +} + +class TSql170ParserInternal extends Parser("TSql170ParserBaseInternal"); +options { + k = 2; + defaultErrorHandler=false; + classHeaderPrefix = "internal partial"; + importVocab = TSql; +} + +{ + public TSql170ParserInternal(bool initialQuotedIdentifiersOn) + : base(initialQuotedIdentifiersOn) + { + initialize(); + } +} + +// Figure out a way to refactor exception handling +entryPointChildObjectName returns [ChildObjectName vResult = null] + : + vResult=childObjectNameWithThreePrefixes + EOF + ; + +entryPointSchemaObjectName returns [SchemaObjectName vResult = null] + : + vResult=schemaObjectFourPartName + EOF + ; + +entryPointScalarDataType returns [DataTypeReference vResult = null] + : + vResult = scalarDataType + EOF + ; + +entryPointExpression returns [ScalarExpression vResult = null] + : + vResult = expression + EOF + ; + +entryPointBooleanExpression returns [BooleanExpression vResult = null] + : + vResult = booleanExpression + EOF + ; + +entryPointStatementList returns [StatementList vResult = null] +{ + bool vParseErrorOccurred = false; +} + : + vResult = statementList[ref vParseErrorOccurred] + { + if (vParseErrorOccurred) + vResult = null; + } + EOF + ; + +entryPointSubqueryExpressionWithOptionalCTE returns [SelectStatement vResult = null] +{ + SelectFunctionReturnType vRetType; +} + : + vRetType = functionReturnClauseRelational + { + vResult = vRetType.SelectStatement; + } + EOF + ; + +entryPointIPv4Address returns [IPv4 vResult = null] + : + vResult = ipAddressV4 + EOF + ; + +entryPointConstantOrIdentifier returns [TSqlFragment vResult = null] + : + vResult = possibleNegativeConstantOrIdentifier + EOF + ; + +entryPointConstantOrIdentifierWithDefault returns [TSqlFragment vResult = null] + : + vResult = possibleNegativeConstantOrIdentifierWithDefault + EOF + ; + +script returns [TSqlScript vResult = this.FragmentFactory.CreateFragment()] +{ + TSqlBatch vCurrentBatch; + + // Script always includes all of the tokens... + if (vResult.ScriptTokenStream != null && vResult.ScriptTokenStream.Count > 0) + { + vResult.UpdateTokenInfo(0,vResult.ScriptTokenStream.Count-1); + } +} + : vCurrentBatch = batch + { + if (vCurrentBatch != null) + AddAndUpdateTokenInfo(vResult, vResult.Batches, vCurrentBatch); + } + ( + Go + { + ResetQuotedIdentifiersSettingToInitial(); + ThrowPartialAstIfPhaseOne(null); + } + vCurrentBatch = batch + { + if (vCurrentBatch != null) + AddAndUpdateTokenInfo(vResult, vResult.Batches, vCurrentBatch); + } + + )* + + tEof:EOF + { + UpdateTokenInfo(vResult,tEof); + } + ; + +// TODO, sacaglar: Tracking issue, bug# 584772 +batch returns [TSqlBatch vResult = null] +{ + TSqlStatement vStatement; +} + : (tSemi:Semicolon)* + ( + ( + Create (((Or Alter)? ( Proc | Procedure | Trigger | View | Function)) | ( Default | Rule | Schema | {NextTokenMatches(CodeGenerationSupporter.Federation)}? | {NextTokenMatches(CodeGenerationSupporter.Materialized)}? )) + | + Alter ( Proc | Procedure | Trigger | View | Function | {NextTokenMatches(CodeGenerationSupporter.Federation)}? | {NextTokenMatches(CodeGenerationSupporter.Materialized)}? ) + | + Use {NextTokenMatches(CodeGenerationSupporter.Federation) && LA(2) == Identifier}? + )=> + ( + vStatement=lastStatementOptSemi + { + if (vStatement != null) + { + if (vResult == null) + { + vResult = this.FragmentFactory.CreateFragment(); + } + AddAndUpdateTokenInfo(vResult, vResult.Statements, vStatement); + } + } + ) + | + (vStatement = optSimpleExecute + { + if (vStatement != null) // Can be empty + { + ThrowPartialAstIfPhaseOne(vStatement); + + if (vResult == null) + vResult = this.FragmentFactory.CreateFragment(); + + AddAndUpdateTokenInfo(vResult, vResult.Statements, vStatement); + } + } + (vStatement=statementOptSemi + { + if (vStatement != null) // statement can be null if there was a parse error. + { + if (vResult == null) + vResult = this.FragmentFactory.CreateFragment(); + + AddAndUpdateTokenInfo(vResult, vResult.Statements, vStatement); + } + } + )* + ) + ) + ; + exception + catch[TSqlParseErrorException exception] + { + if (!exception.DoNotLog) + { + AddParseError(exception.ParseError); + } + RecoverAtBatchLevel(); + } + catch[antlr.NoViableAltException exception] + { + ParseError error = GetFaultTolerantUnexpectedTokenError( + exception.token, exception, _tokenSource.LastToken.Offset); + AddParseError(error); + RecoverAtBatchLevel(); + } + catch[antlr.MismatchedTokenException exception] + { + ParseError error = GetFaultTolerantUnexpectedTokenError( + exception.token, exception, _tokenSource.LastToken.Offset); + AddParseError(error); + RecoverAtBatchLevel(); + } + catch[antlr.RecognitionException] + { + ParseError error = GetUnexpectedTokenError(); + AddParseError(error); + RecoverAtBatchLevel(); + } + catch[antlr.TokenStreamRecognitionException exception] + { + // This exception should be handled when we are creating TSqlTokenStream... + ParseError error = ProcessTokenStreamRecognitionException(exception, _tokenSource.LastToken.Offset); + AddParseError(error); + RecoverAtBatchLevel(); + } + catch[antlr.ANTLRException exception] + { + CreateInternalError("batch", exception); + } + +statementOptSemi returns [TSqlStatement vResult = null] + : vResult=statement optSemicolons[vResult] + ; + +lastStatementOptSemi returns [TSqlStatement vResult = null] + : vResult=lastStatement optSemicolons[vResult] + ; + +optSemicolons[TSqlStatement vParent] +{ + int nSemicolons = 0; +} + : ( + // Greedy behavior is good enough, we ignore the semicolons + options {greedy = true; } : + tSemi:Semicolon + { + ++nSemicolons; + if (vParent != null) // vResult can be null if there was a parse error. + UpdateTokenInfo(vParent,tSemi); + } + )* + ; + + +///////////////////////////////////////////////// +// Copy Command +///////////////////////////////////////////////// +copyStatement returns [CopyStatement vResult = FragmentFactory.CreateFragment()] +{ + SchemaObjectName vTo; + StringLiteral vFrom; +} + : + tCopy:Identifier + { + Match(tCopy, CodeGenerationSupporter.CopyCommand); + } + tInto: Into + vTo = schemaObjectThreePartName + { + UpdateTokenInfo(vResult,tCopy); + vResult.Into = vTo; + } + (copyColumnList[vResult])? + From vFrom = nonEmptyString /* No need to verify null as it's already nonempty */ + { + ExternalFileOption.CheckXMLValidity(vFrom, CodeGenerationSupporter.From); + AddAndUpdateTokenInfo(vResult, vResult.From, vFrom); + } + (Comma vFrom = nonEmptyString + { + ExternalFileOption.CheckXMLValidity(vFrom, CodeGenerationSupporter.From); + AddAndUpdateTokenInfo(vResult, vResult.From, vFrom); + } + )* + (copyWithClause[vResult])? + (optimizerHints[vResult, vResult.OptimizerHints])? +; + +copyColumnList [CopyStatement vParent] +{ + CopyOption copyOption = FragmentFactory.CreateFragment(); + ListTypeCopyOption vColumnOptions = FragmentFactory.CreateFragment();; + CopyColumnOption vColumnOption; + Int32 columnCount = 0; +} +: + tLParen: LeftParenthesis + { + copyOption.Kind = CopyOptionKind.ColumnOptions; + } + vColumnOption = copyColumnOption[ref columnCount, tLParen] + { + AddAndUpdateTokenInfo(vColumnOptions, vColumnOptions.Options, vColumnOption); + } + (Comma vColumnOption = copyColumnOption[ref columnCount, tLParen] + { + AddAndUpdateTokenInfo(vColumnOptions, vColumnOptions.Options, vColumnOption); + } + )* + tRParen:RightParenthesis + { + UpdateTokenInfo(vParent,tRParen); + copyOption.Value = vColumnOptions; + AddAndUpdateTokenInfo(vParent, vParent.Options, copyOption); + } +; + +copyColumnOption [ref Int32 columnCount, IToken tToken] returns [CopyColumnOption vResult = FragmentFactory.CreateFragment()] +{ + Identifier vColumnName; + ScalarExpression vDefaultColumnValue = null; + bool vDefaultSpecified = false; + IntegerLiteral vFieldNumber = null; +} + : + vColumnName = identifier + { + CheckAndIncrementColumnCount(ref columnCount, tToken); + } + (tDefault:Default vDefaultColumnValue = defaultValueLiteral + { + vDefaultSpecified = true; + })? + (vFieldNumber = integer)? + { + CopyListOptionsHelper.Instance.AssignCopyColumnOptions(vResult, vColumnName, vDefaultColumnValue, vDefaultSpecified, vFieldNumber, columnCount); + } +; + +copyWithClause [CopyStatement vParent] +{ + CopyOption vOption; + Int32 encountered = 0; +} + : With LeftParenthesis vOption = copyOption[ref encountered] + { + AddAndUpdateTokenInfo(vParent, vParent.Options, vOption); + } + (Comma vOption = copyOption[ref encountered] + { + AddAndUpdateTokenInfo(vParent, vParent.Options, vOption); + } + )* + tRParen:RightParenthesis + { + UpdateTokenInfo(vParent,tRParen); + } +; + +copyOption [ref Int32 encountered] returns [CopyOption vResult = FragmentFactory.CreateFragment()] +{ + CopyStatementOptionBase vValue = null; +} + : + ( + tOption:Identifier + { + vResult.Kind = CopyIdentifierOrValueOptionsHelper.Instance.ParseOption(tOption); + CheckCopyOptionDuplication(ref encountered, vResult.Kind, tOption); + } + | tIdentityInsert:IdentityInsert + { + vResult.Kind = CopyOptionKind.Identity_Insert; + CheckCopyOptionDuplication(ref encountered, vResult.Kind, tIdentityInsert); + } + | tCredential:Credential + { + vResult.Kind = CopyOptionKind.Credential; + CheckCopyOptionDuplication(ref encountered, vResult.Kind, tCredential); + } + ) + EqualsSign + ( + vValue = singleValueTypeCopyOption + { + CopyIdentifierOrValueOptionsHelper.Instance.AssignValueToCopyOption(vResult, (SingleValueTypeCopyOption) vValue); + } + | + vValue = copyCredentialOption + { + if ((vResult.Kind != CopyOptionKind.Credential || vResult.Kind != CopyOptionKind.ErrorFileCredential) && + CopyIdentifierOrValueOptionsHelper.Instance.ValidateCopyCredential((CopyCredentialOption)vValue)) + { + vResult.Value = (CopyCredentialOption) vValue; + } + else + { + ThrowIncorrectSyntaxErrorException(vValue); + } + } + ) +; + +singleValueTypeCopyOption returns [SingleValueTypeCopyOption vResult = FragmentFactory.CreateFragment()] +{ + Identifier vValue; + Literal vLiteral; +} + : + vValue=identifier + { + vResult.SingleValue = IdentifierOrValueExpression(vValue); + } + | vLiteral = integer + { + vResult.SingleValue = IdentifierOrValueExpression(vLiteral); + } + | vLiteral = stringLiteral + { + vResult.SingleValue = IdentifierOrValueExpression(vLiteral); + } +; + +copyCredentialOption returns [CopyCredentialOption vResult = FragmentFactory.CreateFragment()] +{ + StringLiteral vIdentityValue; + StringLiteral vSecretValue; +} + : + LeftParenthesis + Identity EqualsSign vIdentityValue = stringLiteral + { + vResult.Identity = vIdentityValue; + } + (Comma tSecret:Identifier EqualsSign vSecretValue = stringLiteral + { + Match(tSecret, CodeGenerationSupporter.Secret); + CopyIdentifierOrValueOptionsHelper.Instance.ValidateSecret(vSecretValue); + vResult.Secret = (StringLiteral) vSecretValue; + })? + RightParenthesis +; + + +///////////////////////////////////////////////// +// Rename table statement +///////////////////////////////////////////////// + +/* Syntax: +RENAME OBJECT [::] [Database].[Schema].OldTable TO NewTable +*/ + +renameEntityStatement returns [RenameEntityStatement vResult = this.FragmentFactory.CreateFragment()] +{ + SchemaObjectName vSchemaObjectName; + Identifier vRenamedEntityType; + Identifier vNewName; +} + :tRename:Identifier vRenamedEntityType = securityStatementPermission + { + Match(tRename, CodeGenerationSupporter.Rename); + vResult.RenameEntityType = ParseSecurityObjectKind(vRenamedEntityType); + if(!(vResult.RenameEntityType == SecurityObjectKind.Object)) + { + // RenameEntityStatement::Translate() throws an unexpected exception if the entity type is not + // "object". Since other object kinds are not supported in this statement, we throw + // a syntax error. + throw GetUnexpectedTokenErrorException(vRenamedEntityType); + } + } + + ( + DoubleColon + { + vResult.SeparatorType = SeparatorType.DoubleColon; + } + )? + + vSchemaObjectName = schemaObjectThreePartName + { + vResult.OldName = vSchemaObjectName; + } + To + ( + vNewName = identifier + { + vResult.NewName = vNewName; + } + ) + + { + UpdateTokenInfo(vResult, tRename); + } + ; + +///////////////////////////////////////////////// +// CREATE TABLE AS SELECT STATEMENT +///////////////////////////////////////////////// + +ctasCreateTableStatement [CreateTableStatement vParent] +{ + SelectStatement vSelectStatement; +} + : + (columnNameList[vParent, vParent.CtasColumns])? + ( + options {greedy = true; } : + withTableOptions[vParent] + ) + As + vSelectStatement = selectStatement[SubDmlFlags.None] + { + vParent.SelectStatement = vSelectStatement; + } + { + CheckCtasStatementHasDistributionOption(vParent); + } + ; + +///////////////////////////////////////////////// +// CREATE EXTERNAL TABLE AS SELECT STATEMENT +///////////////////////////////////////////////// +ctasCreateExternalTableStatement [CreateExternalTableStatement vParent] +{ + SelectStatement vSelectStatement; +} + : + ( + options { greedy = true; } : + withExternalTableOptions[vParent] + ) + As + vSelectStatement = selectStatement[SubDmlFlags.None] + { + vParent.SelectStatement = vSelectStatement; + } + { + CheckExternalTableCtasStatementHasNotRejectedRowLocationOption(vParent); + } + ; + +// This rule conflicts with identifierStatements (both can start with Identifier) +// We should update predicates here and in identifierStatements at the same time +optSimpleExecute returns [ExecuteStatement vResult = null] +{ + ExecutableProcedureReference vExecProc; + ExecuteSpecification vExecuteSpecification; +} + : {!NextTokenMatches(CodeGenerationSupporter.Disable) && !NextTokenMatches(CodeGenerationSupporter.Enable) && + !NextTokenMatches(CodeGenerationSupporter.Move) && !NextTokenMatches(CodeGenerationSupporter.Get) && + !NextTokenMatches(CodeGenerationSupporter.Receive) && !NextTokenMatches(CodeGenerationSupporter.Send) && + !NextTokenMatches(CodeGenerationSupporter.Throw) && !NextTokenMatches(CodeGenerationSupporter.Rename)}? + (vExecProc = execProc + { + vResult = FragmentFactory.CreateFragment(); + vExecuteSpecification = FragmentFactory.CreateFragment(); + vExecuteSpecification.ExecutableEntity = vExecProc; + vResult.ExecuteSpecification=vExecuteSpecification; + } + optSemicolons[vResult] + ) + | /* empty */ + ; + +statement returns [TSqlStatement vResult = null] +{ + // The next tokens offset is cached to help error + // recovery, so when error occurs if the next token is + // Create or Alter, and its offset is the same as + // vNextTokenOffset that means, this rule already + // tried to parsed and failed, so we should skip over. + // The case where it works is: + // select * from create table t1(c1 int) + int nextTokenLine = LT(1).getLine(); + int nextTokenColumn = LT(1).getColumn(); +} + : vResult=createTableStatement + | vResult=alterTableStatement + | vResult=createIndexStatement + | vResult=copyStatement + | vResult=declareStatements + | vResult=setStatements + | vResult=beginStatements + | vResult=breakStatement + | vResult=continueStatement + | vResult=ifStatement + | vResult=whileStatement + | vResult=labelStatement + | vResult=backupStatements + | vResult=restoreStatements + | vResult=gotoStatement + | vResult=saveTransactionStatement + | vResult=rollbackTransactionStatement + | vResult=commitTransactionStatement + | vResult=createStatisticsStatement + | vResult=updateStatisticsStatement + | vResult=alterDatabaseStatements + | vResult=executeStatement + | vResult=withCommonTableExpressionsAndXmlNamespacesStatements + | vResult=raiseErrorStatement + | vResult=alter2005Statements + | vResult=create2005Statements + | vResult=createDatabaseStatements + | vResult=addStatements + | vResult=identifierStatements + | vResult=printStatement + | vResult=waitForStatement + | vResult=readTextStatement + | vResult=updateTextStatement + | vResult=writeTextStatement + | vResult=lineNoStatement + | vResult=useStatement + | vResult=killStatements + | vResult=bulkInsertStatement + | vResult=insertBulkStatement + | vResult=checkpointStatement + | vResult=reconfigureStatement + | vResult=shutdownStatement + | vResult=setUserStatement + | vResult=truncateTableStatement + | vResult=grantStatement90 + | vResult=denyStatement90 + | vResult=revokeStatement90 + | vResult=returnStatement + | vResult=openStatements + | vResult=closeStatements + | vResult=deallocateCursorStatement + | vResult=fetchCursorStatement + | vResult=dropStatements + | vResult=dbccStatement + | vResult=revertStatement + | vResult=executeAsStatement + | vResult=endConversationStatement + ; + exception + catch[TSqlParseErrorException exception] + { + if (!exception.DoNotLog) + { + AddParseError(exception.ParseError); + } + RecoverAtStatementLevel(nextTokenLine, nextTokenColumn); + } + catch[antlr.NoViableAltException exception] + { + ParseError error = GetFaultTolerantUnexpectedTokenError( + exception.token, exception, _tokenSource.LastToken.Offset); + AddParseError(error); + RecoverAtStatementLevel(nextTokenLine, nextTokenColumn); + } + catch[antlr.MismatchedTokenException exception] + { + ParseError error = GetFaultTolerantUnexpectedTokenError( + exception.token, exception, _tokenSource.LastToken.Offset); + AddParseError(error); + RecoverAtStatementLevel(nextTokenLine, nextTokenColumn); + } + catch[antlr.RecognitionException] + { + ParseError error = GetUnexpectedTokenError(); + AddParseError(error); + RecoverAtStatementLevel(nextTokenLine, nextTokenColumn); + } + catch[antlr.TokenStreamRecognitionException exception] + { + // This exception should be handled when we are creating TSqlTokenStream... + ParseError error = ProcessTokenStreamRecognitionException(exception, _tokenSource.LastToken.Offset); + AddParseError(error); + RecoverAtStatementLevel(nextTokenLine, nextTokenColumn); + } + catch[antlr.ANTLRException exception] + { + CreateInternalError("statement", exception); + } + +withCommonTableExpressionsAndXmlNamespacesStatements returns [StatementWithCtesAndXmlNamespaces vResult = null] +{ + WithCtesAndXmlNamespaces vWithCommonTableExpressionsAndXmlNamespaces = null; +} + : + ( + vWithCommonTableExpressionsAndXmlNamespaces=withCommonTableExpressionsAndXmlNamespaces + )? + ( + vResult=select[SubDmlFlags.SelectNotForInsert] + { + // check for invalid combination of CHANGE_TRACKING_CONTEXT and Select statement + if ((vWithCommonTableExpressionsAndXmlNamespaces != null) && (vWithCommonTableExpressionsAndXmlNamespaces.ChangeTrackingContext != null)) + ThrowParseErrorException("SQL46072", vWithCommonTableExpressionsAndXmlNamespaces.ChangeTrackingContext, TSqlParserResource.SQL46072Message); + } + | + vResult=deleteStatement[SubDmlFlags.None] + | + vResult=insertStatement[SubDmlFlags.None] + | + vResult=updateStatement[SubDmlFlags.None] + | + vResult=mergeStatement[SubDmlFlags.None] + ) + { + vResult.WithCtesAndXmlNamespaces = vWithCommonTableExpressionsAndXmlNamespaces; + } + ; + +lastStatement returns [TSqlStatement vResult = null] + : vResult=createProcedureStatement + | vResult=alterProcedureStatement + | vResult=createTriggerStatement + | vResult=alterTriggerStatement + | vResult=createDefaultStatement + | vResult=createRuleStatement + | vResult=createViewStatement + | vResult=alterViewStatement + | vResult=createFunctionStatement + | vResult=alterFunctionStatement + | vResult=createSchemaStatement + | vResult=createIdentifierStatement + | vResult=alterIdentifierStatement + | vResult=useFederationStatement + | vResult=createOrAlterStatements + ; + +createIdentifierStatement returns [TSqlStatement vResult] + : tCreate:Create + ( + {NextTokenMatches(CodeGenerationSupporter.Materialized)}? + vResult=createMaterializedViewStatement + | + {NextTokenMatches(CodeGenerationSupporter.Federation)}? + vResult=createFederationStatement + ) + { + UpdateTokenInfo(vResult,tCreate); + } + ; + +alterIdentifierStatement returns [TSqlStatement vResult] + : tAlter:Alter + ( + {NextTokenMatches(CodeGenerationSupporter.Materialized)}? + vResult=alterMaterializedViewStatement + | + {NextTokenMatches(CodeGenerationSupporter.Federation)}? + vResult=alterFederationStatement + ) + { + UpdateTokenInfo(vResult,tAlter); + } + ; + +createOrAlterStatements returns [TSqlStatement vResult] + : tCreate:Create Or Alter + ( + vResult = createOrAlterFunctionStatement + | vResult = createOrAlterProcedureStatement + | vResult = createOrAlterTriggerStatement + | vResult = createOrAlterViewStatement + ) + { + UpdateTokenInfo(vResult,tCreate); + } + ; + +// This rule conflicts with optSimpleExecute (both can start with Identifier) +// We should update predicates here and in optSimpleExecute at the same time +identifierStatements returns [TSqlStatement vResult] + : {NextTokenMatches(CodeGenerationSupporter.Disable)}? + vResult=disableTriggerStatement + | {NextTokenMatches(CodeGenerationSupporter.Enable)}? + vResult=enableTriggerStatement + | {NextTokenMatches(CodeGenerationSupporter.Move)}? + vResult = moveConversationStatement + | {NextTokenMatches(CodeGenerationSupporter.Get)}? + vResult = getConversationGroupStatement + | {NextTokenMatches(CodeGenerationSupporter.Receive)}? + vResult = receiveStatement + | {NextTokenMatches(CodeGenerationSupporter.Send)}? + vResult = sendStatement + | {NextTokenMatches(CodeGenerationSupporter.Throw)}? + vResult = throwStatement + | {NextTokenMatches(CodeGenerationSupporter.Rename)}? + vResult = renameEntityStatement + ; + + +disableTriggerStatement returns [EnableDisableTriggerStatement vResult = this.FragmentFactory.CreateFragment()] + : + tDisable:Identifier + { + Match(tDisable, CodeGenerationSupporter.Disable); + UpdateTokenInfo(vResult,tDisable); + vResult.TriggerEnforcement = TriggerEnforcement.Disable; + } + enableDisableTriggerBody[vResult] + ; + +enableTriggerStatement returns [EnableDisableTriggerStatement vResult = this.FragmentFactory.CreateFragment()] + : + tEnable:Identifier + { + Match(tEnable, CodeGenerationSupporter.Enable); + UpdateTokenInfo(vResult,tEnable); + vResult.TriggerEnforcement = TriggerEnforcement.Enable; + } + enableDisableTriggerBody[vResult] + ; + +enableDisableTriggerBody[EnableDisableTriggerStatement vParent] +{ + SchemaObjectName vSchemaObjectName; + TriggerObject vTriggerObject; +} + : + Trigger + ( + vSchemaObjectName=schemaObjectThreePartName + { + AddAndUpdateTokenInfo(vParent, vParent.TriggerNames,vSchemaObjectName); + } + ( + Comma vSchemaObjectName=schemaObjectThreePartName + { + AddAndUpdateTokenInfo(vParent, vParent.TriggerNames,vSchemaObjectName); + } + )* + | + All + { + vParent.All = true; + } + ) + On vTriggerObject=triggerObject + { + vParent.TriggerObject = vTriggerObject; + } + ; + +create2005Statements returns [TSqlStatement vResult = null] + : tCreate:Create + ( + {NextTokenMatches(CodeGenerationSupporter.Aggregate)}? + vResult=createAggregateStatement + | + {NextTokenMatches(CodeGenerationSupporter.Application)}? + vResult=createApplicationRoleStatement + | + {NextTokenMatches(CodeGenerationSupporter.Assembly)}? + vResult=createAssemblyStatement + | + {NextTokenMatches(CodeGenerationSupporter.Asymmetric)}? + vResult=createAsymmetricKeyStatement + | + {NextTokenMatches(CodeGenerationSupporter.Availability)}? + vResult=createAvailabilityGroupStatement + | + {NextTokenMatches(CodeGenerationSupporter.Broker)}? + vResult=createBrokerPriorityStatement + | + {NextTokenMatches(CodeGenerationSupporter.Certificate)}? + vResult=createCertificateStatement + | + {NextTokenMatches(CodeGenerationSupporter.Column)}? + vResult=createColumnStatements + | + {NextTokenMatches(CodeGenerationSupporter.ColumnStore)}? + vResult=createColumnStoreIndexStatement[null, null] + | + {NextTokenMatches(CodeGenerationSupporter.Contract)}? + vResult=createContractStatement + | + {NextTokenMatches(CodeGenerationSupporter.Credential)}? + vResult=createCredentialStatement + | + {NextTokenMatches(CodeGenerationSupporter.Cryptographic)}? + vResult=createCryptographicProviderStatement + | + {NextTokenMatches(CodeGenerationSupporter.Endpoint)}? + vResult=createEndpointStatement + | + {NextTokenMatches(CodeGenerationSupporter.Event)}? + vResult=createEventStatement // NOTIFICATION or SESSION + | + {NextTokenMatches(CodeGenerationSupporter.External)}? + vResult=createExternalStatements // EXTERNAL DATA SOURCE, FILE FORMAT, STREAM, TABLE, RESOURCE POOL, LIBRARY, LANGUAGE + | + {NextTokenMatches(CodeGenerationSupporter.Fulltext)}? + vResult=createFulltextStatement // Index or CATALOG + | + vResult=createPrimaryXmlIndexStatement + | + {NextTokenMatches(CodeGenerationSupporter.Selective)}? + vResult=createSelectiveXmlIndexStatement + | + {NextTokenMatches(CodeGenerationSupporter.Xml)}? + vResult=createXmlStatements // Index or Schema + | + {NextTokenMatches(CodeGenerationSupporter.Login)}? + vResult=createLoginStatement + | + {NextTokenMatches(CodeGenerationSupporter.Message)}? + vResult=createMessageTypeStatement + | + {NextTokenMatches(CodeGenerationSupporter.Master)}? + vResult=createMasterKeyStatement + | + {NextTokenMatches(CodeGenerationSupporter.Partition)}? + vResult=createPartitionStatement // SCHEME or Function + | + {NextTokenMatches(CodeGenerationSupporter.Queue)}? + vResult=createQueueStatement + | + {NextTokenMatches(CodeGenerationSupporter.Remote)}? + vResult=createRemoteServiceBindingStatement + | + {NextTokenMatches(CodeGenerationSupporter.Resource)}? + vResult=createResourcePoolStatement + | + {NextTokenMatches(CodeGenerationSupporter.Role)}? + vResult=createRoleStatement + | + {NextTokenMatches(CodeGenerationSupporter.Route)}? + vResult=createRouteStatement + | + {NextTokenMatches(CodeGenerationSupporter.Search)}? + vResult=createSearchPropertyListStatement + | + {NextTokenMatches(CodeGenerationSupporter.Service)}? + vResult=createServiceStatement + | + {NextTokenMatches(CodeGenerationSupporter.Spatial)}? + vResult=createSpatialIndexStatement + | + {NextTokenMatches(CodeGenerationSupporter.Symmetric)}? + vResult=createSymmetricKeyStatement + | + {NextTokenMatches(CodeGenerationSupporter.Synonym)}? + vResult=createSynonymStatement + | + {NextTokenMatches(CodeGenerationSupporter.Type)}? + vResult=createTypeStatement + | + {NextTokenMatches(CodeGenerationSupporter.Server)}? + vResult=createServerStatements //AUDIT or ROLE + | + {NextTokenMatches(CodeGenerationSupporter.Workload)}? + vResult=createWorkloadStatements + | + {NextTokenMatches(CodeGenerationSupporter.Sequence)}? + vResult=createSequenceStatement + | + {NextTokenMatches(CodeGenerationSupporter.Security)}? + vResult=createSecurityPolicyStatement + | + vResult=createUserStatement + ) + { + UpdateTokenInfo(vResult,tCreate); + ThrowPartialAstIfPhaseOne(vResult); + } + ; + exception + catch[PhaseOnePartialAstException exception] + { + UpdateTokenInfo(exception.Statement, tCreate); + throw; + } + +createAggregateStatement returns [CreateAggregateStatement vResult = FragmentFactory.CreateFragment()] +{ + SchemaObjectName vSchemaObjectName; + ProcedureParameter vParameter; + AssemblyName vAssemblyName; + DataTypeReference vDataType; +} + : tAggregate:Identifier vSchemaObjectName=schemaObjectThreePartName + { + Match(tAggregate, CodeGenerationSupporter.Aggregate); + CheckTwoPartNameForSchemaObjectName(vSchemaObjectName, CodeGenerationSupporter.Aggregate); + vResult.Name = vSchemaObjectName; + ThrowPartialAstIfPhaseOne(vResult); + } + LeftParenthesis vParameter = aggregateParameter + { + AddAndUpdateTokenInfo(vResult, vResult.Parameters, vParameter); + } + (Comma vParameter = aggregateParameter + { + AddAndUpdateTokenInfo(vResult, vResult.Parameters, vParameter); + } + )* + RightParenthesis + tReturns:Identifier vDataType = scalarDataType + { + Match(tReturns,CodeGenerationSupporter.Returns); + vResult.ReturnType = vDataType; + } + External vAssemblyName = assemblyName + { + vResult.AssemblyName = vAssemblyName; + } + ; + +aggregateParameter returns [ProcedureParameter vResult = FragmentFactory.CreateFragment()] +{ + Identifier vParamName; + DataTypeReference vDataType; + NullableConstraintDefinition vNullableConstraintDefinition; +} + : vParamName = identifierVariable (As)? vDataType = scalarDataType + { + vResult.VariableName = vParamName; + vResult.DataType = vDataType; + } + ( + vNullableConstraintDefinition = nullableConstraint + { + vResult.Nullable=vNullableConstraintDefinition; + } + )? + ; + +createApplicationRoleStatement returns [CreateApplicationRoleStatement vResult = this.FragmentFactory.CreateFragment()] + : + applicationRoleStatement[vResult, true] + ; + +createAssemblyStatement returns [CreateAssemblyStatement vResult = this.FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; + AssemblyOption vOption; +} + : tAssembly:Identifier vIdentifier=identifier + { + Match(tAssembly, CodeGenerationSupporter.Assembly); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + From expressionList[vResult, vResult.Parameters] + ( + // Greedy due to conflict with withCommonTableExpressionsAndXmlNamespaces + options {greedy = true; } : + With tPermissionSet:Identifier EqualsSign + vOption=assemblyPermissionSetOption[tPermissionSet] + { + AddAndUpdateTokenInfo(vResult, vResult.Options, vOption); + } + )? + ; + +createExternalLibraryStatement returns [CreateExternalLibraryStatement vResult = this.FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; + ExternalLibraryFileOption vFileOption; + StringLiteral vLanguage; +} + : tLibrary:Identifier vIdentifier=identifier + { + Match(tLibrary, CodeGenerationSupporter.Library); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + From vFileOption=createExternalLibraryFileOption + { + vResult.ExternalLibraryFiles.Add(vFileOption); + } + (Comma vFileOption = createExternalLibraryFileOption + { + vResult.ExternalLibraryFiles.Add(vFileOption); + } + )* + With LeftParenthesis tLanguage:Identifier EqualsSign vLanguage=nonEmptyString + { + Match(tLanguage, CodeGenerationSupporter.Language); + vResult.Language = vLanguage; + } + RightParenthesis + ; + +alterExternalLibraryStatement returns [AlterExternalLibraryStatement vResult = this.FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; + ExternalLibraryFileOption vFileOption; + StringLiteral vLanguage; +} + : tLibrary:Identifier vIdentifier=identifier + { + Match(tLibrary, CodeGenerationSupporter.Library); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + Set vFileOption=alterExternalLibraryFileOption + { + vResult.ExternalLibraryFiles.Add(vFileOption); + } + With LeftParenthesis tLanguage:Identifier EqualsSign vLanguage=nonEmptyString + { + Match(tLanguage, CodeGenerationSupporter.Language); + vResult.Language = vLanguage; + } + RightParenthesis + ; + +dropExternalLibraryStatement returns [DropExternalLibraryStatement vResult = this.FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; +} + : tLibrary:Identifier vIdentifier=identifier + { + Match(tLibrary, CodeGenerationSupporter.Library); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + ; + +binaryOrString returns [ValueExpression vResult] + : + vResult=binary + | + vResult=stringLiteral + ; + +createExternalLibraryFileOption returns [ExternalLibraryFileOption vResult = FragmentFactory.CreateFragment()] +{ + ScalarExpression vContent; + Identifier vPlatform; +} + : LeftParenthesis tContent:Identifier EqualsSign vContent=binaryOrString + { + Match(tContent, CodeGenerationSupporter.Content); + vResult.Content = vContent; + } + (Comma tPlatform:Identifier EqualsSign vPlatform=identifier + { + Match(tPlatform, CodeGenerationSupporter.Platform); + vResult.Platform = vPlatform; + } + )* + RightParenthesis + ; + +alterExternalLibraryFileOption returns [ExternalLibraryFileOption vResult = FragmentFactory.CreateFragment()] +{ + ScalarExpression vContent; + Identifier vPlatform; +} + : LeftParenthesis tContent:Identifier EqualsSign vContent=binaryOrString + { + Match(tContent, CodeGenerationSupporter.Content); + vResult.Content = vContent; + } + (Comma tPlatform:Identifier EqualsSign vPlatform=identifier + { + Match(tPlatform, CodeGenerationSupporter.Platform); + vResult.Platform = vPlatform; + } + )* + RightParenthesis + ; + +createExternalLanguageStatement returns [CreateExternalLanguageStatement vResult = this.FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; + ExternalLanguageFileOption vFileOption; +} + : tLanguage:Identifier vIdentifier=identifier + { + Match(tLanguage, CodeGenerationSupporter.Language); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + From vFileOption=externalLanguageFileOption + { + vResult.ExternalLanguageFiles.Add(vFileOption); + } + (Comma vFileOption = externalLanguageFileOption + { + vResult.ExternalLanguageFiles.Add(vFileOption); + } + )* + ; + +externalLanguageFileOption returns [ExternalLanguageFileOption vResult = FragmentFactory.CreateFragment()] +{ + ScalarExpression vContent; + StringLiteral vFileName; + Identifier vPlatform; + StringLiteral vParameters; + StringLiteral vEnvironmentVariables; +} + : LeftParenthesis tContent:Identifier EqualsSign vContent=binaryOrString + { + Match(tContent, CodeGenerationSupporter.Content); + vResult.Content = vContent; + } + Comma tFileName:Identifier EqualsSign vFileName=nonEmptyString + { + Match(tFileName, CodeGenerationSupporter.File_Name); + vResult.FileName = vFileName; + } + ( + tComma:Comma + ( + {NextTokenMatches(CodeGenerationSupporter.Platform)}? + ( + tPlatform:Identifier EqualsSign vPlatform=identifier + { + Match(tPlatform, CodeGenerationSupporter.Platform); + vResult.Platform = vPlatform; + } + ) + | + {NextTokenMatches(CodeGenerationSupporter.Parameters)}? + ( + tParameters:Identifier EqualsSign vParameters=nonEmptyString + { + Match(tParameters, CodeGenerationSupporter.Parameters); + vResult.Parameters = vParameters; + } + ) + | + {NextTokenMatches(CodeGenerationSupporter.EnvironmentVariables)}? + ( + tEnvironmentVariables:Identifier EqualsSign vEnvironmentVariables=nonEmptyString + { + Match(tEnvironmentVariables, CodeGenerationSupporter.EnvironmentVariables); + vResult.EnvironmentVariables = vEnvironmentVariables; + } + ) + ) + )* + + RightParenthesis + ; + +alterExternalLanguageStatement returns [AlterExternalLanguageStatement vResult = this.FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; + ExternalLanguageFileOption vFileOption; + Identifier vPlatform; +} + : tLanguage:Identifier vIdentifier=identifier + { + Match(tLanguage, CodeGenerationSupporter.Language); + vResult.Name = vIdentifier; + vResult.Operation=new Identifier(); + ThrowPartialAstIfPhaseOne(vResult); + } + ( + authorizationOpt[vResult] + ( + {NextTokenMatches(CodeGenerationSupporter.Set)}? + ( + Set vFileOption=externalLanguageFileOption + { + vResult.ExternalLanguageFiles.Add(vFileOption); + vResult.Operation.Value = CodeGenerationSupporter.Set; + } + ) + | + {NextTokenMatches(CodeGenerationSupporter.Add)}? + ( + Add vFileOption=externalLanguageFileOption + { + vResult.ExternalLanguageFiles.Add(vFileOption); + vResult.Operation.Value = CodeGenerationSupporter.Add; + } + ) + | + {NextTokenMatches(CodeGenerationSupporter.Remove)}? + ( + tRemove:Identifier tPlatform:Identifier vPlatform=identifier + { + Match(tRemove, CodeGenerationSupporter.Remove); + vResult.Platform = vPlatform; + vResult.Operation.Value = CodeGenerationSupporter.Remove; + } + ) + ) + ) + + ; + +dropExternalLanguageStatement returns [DropExternalLanguageStatement vResult = this.FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; +} + : tLanguage:Identifier vIdentifier=identifier + { + Match(tLanguage, CodeGenerationSupporter.Language); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + ; + +createAsymmetricKeyStatement returns [CreateAsymmetricKeyStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; + Literal vPassword; +} + : tAsymmetric:Identifier Key vIdentifier=identifier + { + Match(tAsymmetric, CodeGenerationSupporter.Asymmetric); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + createAsymmetricKeyParams[vResult] + ( + // Greedy due to linear approximation introduced after the rule securityStatementPermission + options {greedy = true; } : + vPassword = encryptClause + { + vResult.Password = vPassword; + } + )? + ; + +createAsymmetricKeyParams[CreateAsymmetricKeyStatement vParent] +{ + EncryptionSource vSource; +} + : From vSource = asymKeySource + { + vParent.KeySource=vSource; + } + | With asymKeySpec[vParent] + ; + +asymKeySource returns [EncryptionSource vResult] + : + vResult = fileEncryptionSource + | {NextTokenMatches(CodeGenerationSupporter.Assembly)}? + vResult = assemblyEncryptionSource + | vResult = providerEncryptionSource + ; + +assemblyEncryptionSource returns [AssemblyEncryptionSource vResult=FragmentFactory.CreateFragment()] +{ + Identifier vAssembly; +} + : tAssembly:Identifier vAssembly = identifier + { + Match(tAssembly, CodeGenerationSupporter.Assembly); + vResult.Assembly = vAssembly; + } + ; + +providerEncryptionSource returns [ProviderEncryptionSource vResult = FragmentFactory.CreateFragment()] +{ + Identifier vProviderName; +} + : tProvider:Identifier vProviderName = identifier + { + Match(tProvider, CodeGenerationSupporter.Provider); + vResult.Name = vProviderName; + } + providerKeySourceOptions[vResult.KeyOptions, vResult] + ; + +fileEncryptionSource returns [FileEncryptionSource vResult = FragmentFactory.CreateFragment()] +{ + Literal vFile; +} + : (tExecutable:Identifier + { + Match(tExecutable, CodeGenerationSupporter.Executable); + vResult.IsExecutable = true; + } + )? + File EqualsSign vFile = stringLiteral + { + vResult.File = vFile; + } + ; + +asymKeySpec [CreateAsymmetricKeyStatement vParent] + : tAlgorithm:Identifier EqualsSign tRealAlg:Identifier + { + Match(tAlgorithm,CodeGenerationSupporter.Algorithm); + vParent.EncryptionAlgorithm = EncryptionAlgorithmsHelper.Instance.ParseOption(tRealAlg); + UpdateTokenInfo(vParent,tRealAlg); + } + ; + +createCertificateStatement returns [CreateCertificateStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; +} + : tCertificate:Identifier vIdentifier=identifier + { + Match(tCertificate, CodeGenerationSupporter.Certificate); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + createCertificateParams[vResult] + ( + // Greedy due to linear approximation introduced after the rule securityStatementPermission + options {greedy = true; } : + createCertificateActivityFlag[vResult] + )? + ; + +createCertificateParams [CreateCertificateStatement vParent] +{ + Literal vPassword; + CertificateOption vOption; + CertificateOptionKinds encounteredOptions = CertificateOptionKinds.None; +} + : From certificateSource[vParent] + | ( + (vPassword = encryptClause + { + vParent.EncryptionPassword = vPassword; + } + )? + With vOption = certificateOption[encounteredOptions] + { + encounteredOptions = encounteredOptions | vOption.Kind; + AddAndUpdateTokenInfo(vParent, vParent.CertificateOptions,vOption); + } + (Comma vOption = certificateOption[encounteredOptions] + { + encounteredOptions = encounteredOptions | vOption.Kind; + AddAndUpdateTokenInfo(vParent, vParent.CertificateOptions,vOption); + } + )* + ) + ; + +createCertificateActivityFlag [CertificateStatementBase vParent] +{ + OptionState vOptionState; +} + : tActive:Identifier For tBeginDialog:Identifier EqualsSign vOptionState = optionOnOff[vParent] + { + Match(tActive,CodeGenerationSupporter.Active); + Match(tBeginDialog,CodeGenerationSupporter.BeginDialog); + vParent.ActiveForBeginDialog = vOptionState; + } + ; + +certificateOption [CertificateOptionKinds encountered]returns [CertificateOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vValue; +} + : tOption:Identifier EqualsSign vValue = stringLiteral + { + vResult.Kind = CertificateOptionKindsHelper.Instance.ParseOption(tOption); + vResult.Value = vValue; + CheckCertificateOptionDupication(encountered,vResult.Kind,tOption); + } + ; + +certificateSource [CreateCertificateStatement vParent] +{ + EncryptionSource vCertificateSource; +} + : + ( + vCertificateSource=fileEncryptionSource + ( + // Greedy due to conflict with withCommonTableExpressionsAndXmlNamespaces + options {greedy = true; } : + With privateKeySpec[vParent] + )? + | + vCertificateSource = assemblyEncryptionSource + ) + { + vParent.CertificateSource = vCertificateSource; + } + ; + +encryptClause returns [Literal vResult] + : tEncryption:Identifier By tPassword:Identifier EqualsSign vResult = stringLiteral + { + Match(tEncryption,CodeGenerationSupporter.Encryption); + Match(tPassword,CodeGenerationSupporter.Password); + } + ; + +privateKeySpec [CertificateStatementBase vParent] + : tPrivate:Identifier Key LeftParenthesis certificatePrivateKeySpec[vParent] (Comma certificatePrivateKeySpec[vParent])* tRParen:RightParenthesis + { + Match(tPrivate,CodeGenerationSupporter.Private); + UpdateTokenInfo(vParent,tRParen); + } + ; + +certificatePrivateKeySpec [CertificateStatementBase vParent] +{ + Literal vFilePath; +} + : passwordChangeOption[vParent] + | tFile:File EqualsSign vFilePath = stringLiteral + { + if (vParent.PrivateKeyPath != null) + throw GetUnexpectedTokenErrorException(tFile); + else + vParent.PrivateKeyPath = vFilePath; + } + ; + +passwordChangeOption [IPasswordChangeOption vParent] +{ + Literal vPassword; +} + : tEncryptionDecryption:Identifier By tPassword:Identifier EqualsSign vPassword = stringLiteral + { + if (TryMatch(tEncryptionDecryption,CodeGenerationSupporter.Encryption)) + { + if (vParent.EncryptionPassword != null) + throw GetUnexpectedTokenErrorException(tEncryptionDecryption); + else + vParent.EncryptionPassword = vPassword; + } + else + { + Match(tEncryptionDecryption,CodeGenerationSupporter.Decryption); + if (vParent.DecryptionPassword != null) + throw GetUnexpectedTokenErrorException(tEncryptionDecryption); + else + vParent.DecryptionPassword = vPassword; + } + } + ; + + +createContractStatement returns [CreateContractStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; + ContractMessage vMessage; +} + : tContract:Identifier vIdentifier=identifier + { + Match(tContract, CodeGenerationSupporter.Contract); + vResult.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vResult); + } + authorizationOpt[vResult] + LeftParenthesis vMessage = contractMessage + { + AddAndUpdateTokenInfo(vResult, vResult.Messages,vMessage); + } + (Comma vMessage = contractMessage + { + AddAndUpdateTokenInfo(vResult, vResult.Messages,vMessage); + } + )* + tRParen:RightParenthesis + { + UpdateTokenInfo(vResult,tRParen); + } + ; + +contractMessage returns [ContractMessage vResult = FragmentFactory.CreateFragment()] +{ + Identifier vMessageName; +} + : vMessageName = identifier tSent:Identifier By + { + Match(tSent,CodeGenerationSupporter.Sent); + vResult.Name = vMessageName; + } + ( tAny:Any + { + vResult.SentBy = MessageSender.Any; + UpdateTokenInfo(vResult,tAny); + } + | tInitiatorTarget:Identifier + { + if (TryMatch(tInitiatorTarget,CodeGenerationSupporter.Initiator)) + vResult.SentBy = MessageSender.Initiator; + else + { + Match(tInitiatorTarget,CodeGenerationSupporter.Target); + vResult.SentBy = MessageSender.Target; + } + UpdateTokenInfo(vResult,tInitiatorTarget); + } + ) + ; + +createDatabaseScopedCredentialStatement returns [CreateCredentialStatement vResult = FragmentFactory.CreateFragment()] + : tScoped:Identifier + { + Match(tScoped, CodeGenerationSupporter.Scoped); + vResult.IsDatabaseScoped = true; + } + + credentialStatementBody[vResult] + + ; + +createCredentialStatement returns [CreateCredentialStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vCryptographicProviderName; + vResult.IsDatabaseScoped = false; +} + : credentialStatementBody[vResult] + ( + For tCryptographic:Identifier tProvider:Identifier vCryptographicProviderName=identifier + { + Match(tCryptographic, CodeGenerationSupporter.Cryptographic); + Match(tProvider, CodeGenerationSupporter.Provider); + vResult.CryptographicProviderName = vCryptographicProviderName; + } + )? + ; + +credentialStatementBody [CredentialStatement vParent] +{ + Identifier vIdentifier; + Literal vLiteral; +} + : tCredential:Identifier vIdentifier=identifier + { + Match(tCredential, CodeGenerationSupporter.Credential); + vParent.Name = vIdentifier; + ThrowPartialAstIfPhaseOne(vParent); + } + With Identity EqualsSign vLiteral = stringLiteral + { + vParent.Identity = vLiteral; + } + (Comma tSecret:Identifier EqualsSign vLiteral = stringLiteral + { + Match(tSecret,CodeGenerationSupporter.Secret); + vParent.Secret = vLiteral; + } + )? + ; + +createServerStatements returns [TSqlStatement vResult] + : tServer:Identifier + { + Match(tServer, CodeGenerationSupporter.Server); + } + ( + {NextTokenMatches(CodeGenerationSupporter.Audit)}? + vResult=createServerAuditStatements + | + {NextTokenMatches(CodeGenerationSupporter.Role)}? + vResult=createServerRoleStatement + ) + ; + +createServerAuditStatements returns [TSqlStatement vResult] + : tAudit:Identifier + { + Match(tAudit, CodeGenerationSupporter.Audit); + } + ( + vResult = createServerAuditSpecificationStatement + | + vResult = createServerAuditStatement + ) + ; + +createServerAuditStatement returns [CreateServerAuditStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vAuditName; + AuditTarget vTarget; + BooleanExpression vFilterPredicate; +} + : vAuditName = identifier + { + vResult.AuditName = vAuditName; + ThrowPartialAstIfPhaseOne(vResult); + } + vTarget = auditTargetClause[true] + { + vResult.AuditTarget = vTarget; + } + ( // Greedy due to conflict with withCommonTableExpressionsAndXmlNamespaces + options {greedy = true; } : + auditCreateWithClause[vResult] + )? + ( + Where vFilterPredicate=eventBooleanExpression + { + vResult.PredicateExpression = vFilterPredicate; + } + )? + ; + +auditTargetClause [bool pathRequired] returns [AuditTarget vResult = FragmentFactory.CreateFragment()] +{ + AuditTargetOption vOption; + bool pathOptionEncountered = false; +} + : tTo:To + { + UpdateTokenInfo(vResult,tTo); + } + ( + ( + tFile:File LeftParenthesis vOption = auditFileOption + { + vResult.TargetKind = AuditTargetKind.File; + AddAndUpdateTokenInfo(vResult, vResult.TargetOptions, vOption); + + pathOptionEncountered |= (vOption.OptionKind==AuditTargetOptionKind.FilePath); + } + ( + Comma vOption = auditFileOption + { + AddAndUpdateTokenInfo(vResult, vResult.TargetOptions, vOption); + + pathOptionEncountered |= vOption.OptionKind==AuditTargetOptionKind.FilePath; + } + )* + | + tUrl:Identifier LeftParenthesis vOption = auditUrlOption + { + Match(tUrl, CodeGenerationSupporter.Url); + vResult.TargetKind = AuditTargetKind.Url; + AddAndUpdateTokenInfo(vResult, vResult.TargetOptions, vOption); + + pathOptionEncountered |= (vOption.OptionKind==AuditTargetOptionKind.Path); + } + ( + Comma vOption = auditUrlOption + { + AddAndUpdateTokenInfo(vResult, vResult.TargetOptions, vOption); + + pathOptionEncountered |= vOption.OptionKind==AuditTargetOptionKind.Path; + } + )? + ) + tRParen:RightParenthesis + { + UpdateTokenInfo(vResult,tRParen); + if (pathRequired && !pathOptionEncountered) + { + if(tFile != null) + { + ThrowParseErrorException("SQL46056", tFile, TSqlParserResource.SQL46056Message); + } + else + { + ThrowParseErrorException("SQL46126", tUrl, TSqlParserResource.SQL46126Message); + } + } + } + | + tApplicationLogSecurityLogExternalMonitor:Identifier + { + if (TryMatch(tApplicationLogSecurityLogExternalMonitor, CodeGenerationSupporter.ApplicationLog)) + { + vResult.TargetKind = AuditTargetKind.ApplicationLog; + } + else if (TryMatch(tApplicationLogSecurityLogExternalMonitor, CodeGenerationSupporter.SecurityLog)) + { + vResult.TargetKind = AuditTargetKind.SecurityLog; + } + else + { + Match(tApplicationLogSecurityLogExternalMonitor, CodeGenerationSupporter.ExternalMonitor); + vResult.TargetKind = AuditTargetKind.ExternalMonitor; + } + UpdateTokenInfo(vResult,tApplicationLogSecurityLogExternalMonitor); + } + ) + ; + +// Corresponds to audit_file_option_element in SQL yacc grammar +auditFileOption returns [AuditTargetOption vResult = null] + : + {NextTokenMatches(CodeGenerationSupporter.MaxSize)}? + vResult = maxSizeAuditFileOption + | + {NextTokenMatches(CodeGenerationSupporter.MaxRolloverFiles)}? + vResult = maxRolloverFilesAuditFileOption + | + {NextTokenMatches(CodeGenerationSupporter.ReserveDiskSpace)}? + vResult = reserveDiskSpaceAuditFileOption + | + {NextTokenMatches(CodeGenerationSupporter.MaxFiles)}? + vResult = maxFilesAuditFileOption + | + vResult = pathAuditFileOption + ; + +auditUrlOption returns [AuditTargetOption vResult = null] + : + {NextTokenMatches(CodeGenerationSupporter.RetentionDays)}? + vResult = retentionDaysAuditUrlOption + | + vResult = pathAuditFileOption + ; + +maxSizeAuditFileOption returns [MaxSizeAuditTargetOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vSize; +} + : tOption:Identifier EqualsSign + { + Match(tOption, CodeGenerationSupporter.MaxSize); + vResult.OptionKind=AuditTargetOptionKind.MaxSize; + UpdateTokenInfo(vResult, tOption); + } + ( + vSize = integer tUnit:Identifier + { + vResult.Size = vSize; + + if (TryMatch(tUnit, CodeGenerationSupporter.GB)) + { + vResult.Unit = MemoryUnit.GB; + ThrowIfTooLargeAuditFileSize(vSize, 10); + } + else if (TryMatch(tUnit, CodeGenerationSupporter.TB)) + { + vResult.Unit = MemoryUnit.TB; + ThrowIfTooLargeAuditFileSize(vSize, 20); + } + else + { + Match(tUnit, CodeGenerationSupporter.MB); + vResult.Unit = MemoryUnit.MB; + ThrowIfTooLargeAuditFileSize(vSize, 0); + } + + UpdateTokenInfo(vResult, tUnit); + } + | + tUnlimited:Identifier + { + Match(tUnlimited, CodeGenerationSupporter.Unlimited); + vResult.IsUnlimited = true; + vResult.Size = null; + vResult.Unit = MemoryUnit.Unspecified; + } + ) + ; + +retentionDaysAuditUrlOption returns [RetentionDaysAuditTargetOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vDays; +} + : tRetentionDays:Identifier EqualsSign + { + Match(tRetentionDays, CodeGenerationSupporter.RetentionDays); + vResult.OptionKind=AuditTargetOptionKind.RetentionDays; + UpdateTokenInfo(vResult, tRetentionDays); + } + ( + vDays = integer + { + vResult.Days = vDays; + } + ) + ; + +maxRolloverFilesAuditFileOption returns [MaxRolloverFilesAuditTargetOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vValue; +} + : tOption:Identifier EqualsSign + { + Match(tOption, CodeGenerationSupporter.MaxRolloverFiles); + vResult.OptionKind=AuditTargetOptionKind.MaxRolloverFiles; + UpdateTokenInfo(vResult, tOption); + } + ( + vValue = integer + { + vResult.Value = vValue; + } + | + tUnlimited:Identifier + { + Match(tUnlimited, CodeGenerationSupporter.Unlimited); + vResult.IsUnlimited = true; + UpdateTokenInfo(vResult, tUnlimited); + } + ) + ; + +maxFilesAuditFileOption returns [LiteralAuditTargetOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vValue; +} + : tOption:Identifier EqualsSign vValue = integer + { + Match(tOption, CodeGenerationSupporter.MaxFiles); + vResult.OptionKind=AuditTargetOptionKind.MaxFiles; + UpdateTokenInfo(vResult, tOption); + vResult.Value = vValue; + } + ; + +reserveDiskSpaceAuditFileOption returns [OnOffAuditTargetOption vResult = FragmentFactory.CreateFragment()] +{ + OptionState vValue; +} + : tOption:Identifier EqualsSign vValue = optionOnOff[vResult] + { + Match(tOption, CodeGenerationSupporter.ReserveDiskSpace); + vResult.OptionKind=AuditTargetOptionKind.ReserveDiskSpace; + UpdateTokenInfo(vResult, tOption); + vResult.Value = vValue; + } + ; + +pathAuditFileOption returns [LiteralAuditTargetOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vValue; +} + : tOption:Identifier EqualsSign vValue = stringLiteral + { + if(TryMatch(tOption, CodeGenerationSupporter.FilePath)) + { + vResult.OptionKind=AuditTargetOptionKind.FilePath; + } + else + { + Match(tOption, CodeGenerationSupporter.Path); + vResult.OptionKind=AuditTargetOptionKind.Path; + } + UpdateTokenInfo(vResult, tOption); + vResult.Value = vValue; + } + ; + +auditCreateWithClause [ServerAuditStatement vParent] +{ + AuditOption vOption; +} + : With LeftParenthesis vOption = auditCreateOption + { + AddAndUpdateTokenInfo(vParent, vParent.Options, vOption); + } + (Comma vOption = auditCreateOption + { + AddAndUpdateTokenInfo(vParent, vParent.Options, vOption); + } + )* + tRParen:RightParenthesis + { + UpdateTokenInfo(vParent, tRParen); + } + ; + +auditWithClause [ServerAuditStatement vParent] +{ + AuditOption vOption; +} + : With LeftParenthesis vOption = auditOption + { + AddAndUpdateTokenInfo(vParent, vParent.Options, vOption); + } + (Comma vOption = auditOption + { + AddAndUpdateTokenInfo(vParent, vParent.Options, vOption); + } + )* + tRParen:RightParenthesis + { + UpdateTokenInfo(vParent, tRParen); + } + ; + +// Corresponds to audit_create_option_element in SQL yacc +auditCreateOption returns [AuditOption vResult] + : + tOption:Identifier EqualsSign + ( + vResult = queueDelayAuditOption[tOption] + | + vResult = onFailureAuditOption[tOption] + | + vResult = auditGuidAuditOption[tOption] + | + vResult = operatorAuditOption[tOption] + ) + ; + +// Corresponds to audit_option_element in SQL yacc +auditOption returns [AuditOption vResult] + : + tOption:Identifier EqualsSign + ( + vResult = queueDelayAuditOption[tOption] + | + vResult = onFailureAuditOption[tOption] + | + {TryMatch(tOption, CodeGenerationSupporter.OperatorAudit)}? + vResult = operatorAuditOption[tOption] + | + {TryMatch(tOption, CodeGenerationSupporter.State)}? + vResult = stateAuditOption[tOption] + ) + ; + +queueDelayAuditOption [IToken tOption] returns [QueueDelayAuditOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vValue; +} + : vValue = integer + { + Match(tOption, CodeGenerationSupporter.QueueDelay); + vResult.OptionKind=AuditOptionKind.QueueDelay; + UpdateTokenInfo(vResult,tOption); + vResult.Delay = vValue; + } + ; + +onFailureAuditOption [IToken tOption] returns [OnFailureAuditOption vResult = FragmentFactory.CreateFragment()] + : + { + Match(tOption, CodeGenerationSupporter.OnFailure); + UpdateTokenInfo(vResult,tOption); + vResult.OptionKind=AuditOptionKind.OnFailure; + } + ( + tContinue:Continue + { + UpdateTokenInfo(vResult,tContinue); + vResult.OnFailureAction = AuditFailureActionType.Continue; + } + | + tShutdown:Shutdown + { + UpdateTokenInfo(vResult,tShutdown); + vResult.OnFailureAction = AuditFailureActionType.Shutdown; + } + | + tIdentifier:Identifier + { + Match(tIdentifier, CodeGenerationSupporter.FailOperation); + UpdateTokenInfo(vResult, tIdentifier); + vResult.OnFailureAction = AuditFailureActionType.FailOperation; + } + ) + ; + +auditGuidAuditOption [IToken tOption] returns [AuditGuidAuditOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vValue; +} + : vValue = stringLiteral + { + Match(tOption, CodeGenerationSupporter.AuditGuid); + ThrowIfWrongGuidFormat(vValue); + vResult.OptionKind=AuditOptionKind.AuditGuid; + UpdateTokenInfo(vResult,tOption); + vResult.Guid = vValue; + } + ; + +operatorAuditOption [IToken tOption] returns [OperatorAuditOption vResult = FragmentFactory.CreateFragment()] +{ + OptionState vValue; +} + : vValue = optionOnOff[vResult] + { + Match(tOption, CodeGenerationSupporter.OperatorAudit); + vResult.OptionKind=AuditOptionKind.OperatorAudit; + UpdateTokenInfo(vResult,tOption); + vResult.Value = vValue; + } + ; + +stateAuditOption [IToken tOption] returns [StateAuditOption vResult = FragmentFactory.CreateFragment()] +{ + OptionState vValue; +} + : vValue = optionOnOff[vResult] + { + Match(tOption, CodeGenerationSupporter.State); + vResult.OptionKind=AuditOptionKind.State; + UpdateTokenInfo(vResult,tOption); + vResult.Value = vValue; + } + ; + +createServerAuditSpecificationStatement returns [CreateServerAuditSpecificationStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vAuditSpecName; + AuditSpecificationPart vPart; +} + : tSpecification:Identifier vAuditSpecName = identifier + { + Match(tSpecification, CodeGenerationSupporter.Specification); + vResult.SpecificationName = vAuditSpecName; + ThrowPartialAstIfPhaseOne(vResult); + } + auditSpecificationForClause[vResult] + ( // Conflicts with Add SIGNATURE (but it actually shouldn't, k=2 should be enough) + (Add LeftParenthesis) => + vPart = createAuditSpecificationDetail + { + AddAndUpdateTokenInfo(vResult, vResult.Parts, vPart); + } + (Comma vPart = createAuditSpecificationDetail + { + AddAndUpdateTokenInfo(vResult, vResult.Parts, vPart); + } + )* + )? + auditSpecificationStateOpt[vResult] + ; + +alterServerStatements returns [TSqlStatement vResult] + : + tServer:Identifier + { + Match(tServer, CodeGenerationSupporter.Server); + } + ( + {NextTokenMatches(CodeGenerationSupporter.Audit)}? + vResult = alterServerAuditStatements + | + {NextTokenMatches(CodeGenerationSupporter.Configuration)}? + vResult = alterServerConfigurationStatement + | + {NextTokenMatches(CodeGenerationSupporter.Role)}? + vResult = alterServerRoleStatement + ) + ; + +alterServerAuditStatements returns [TSqlStatement vResult] + : tAudit:Identifier + { + Match(tAudit, CodeGenerationSupporter.Audit); + } + ( + {NextTokenMatches(CodeGenerationSupporter.Specification)}? + vResult = alterServerAuditSpecificationStatement + | + vResult = alterServerAuditStatement + ) + ; + +alterServerAuditSpecificationStatement returns [AlterServerAuditSpecificationStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vAuditSpecName; + AuditSpecificationPart vPart; +} + : tSpecification:Identifier vAuditSpecName = identifier + { + Match(tSpecification, CodeGenerationSupporter.Specification); + vResult.SpecificationName = vAuditSpecName; + ThrowPartialAstIfPhaseOne(vResult); + } + (auditSpecificationForClause[vResult])? + ( // Conflicts with Add SIGNATURE and Drop statements + ((Add|Drop) LeftParenthesis) => + vPart = auditSpecificationDetail + { + AddAndUpdateTokenInfo(vResult, vResult.Parts, vPart); + } + (Comma vPart = auditSpecificationDetail + { + AddAndUpdateTokenInfo(vResult, vResult.Parts, vPart); + } + )* + )? + auditSpecificationStateOpt[vResult] + ; + +alterServerAuditStatement returns [AlterServerAuditStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vAuditName; + Identifier vNewName; + AuditTarget vTarget = null; + BooleanExpression vFilterPredicate = null; +} + : vAuditName = identifier + { + vResult.AuditName = vAuditName; + ThrowPartialAstIfPhaseOne(vResult); + } + ( + {NextTokenMatches(CodeGenerationSupporter.Modify)}? + tModify:Identifier tName:Identifier EqualsSign vNewName = identifier + { + Match(tModify, CodeGenerationSupporter.Modify); + Match(tName, CodeGenerationSupporter.Name); + vResult.NewName = vNewName; + } + | + ( + vTarget = auditTargetClause[false] + { + vResult.AuditTarget = vTarget; + } + )? + ( // Greedy due to conflict with withCommonTableExpressionsAndXmlNamespaces + options {greedy = true; } : + auditWithClause[vResult] + )? + ( + Where vFilterPredicate=eventBooleanExpression + { + vResult.PredicateExpression = vFilterPredicate; + } + )? + { + if(vTarget == null && (vResult.Options == null || vResult.Options.Count == 0) && vFilterPredicate == null) + { + ThrowIncorrectSyntaxErrorException(vAuditName); + } + } + | + tRemove:Identifier tWhere:Where + { + Match(tRemove, CodeGenerationSupporter.Remove); + UpdateTokenInfo(vResult, tWhere); + vResult.RemoveWhere=true; + } + ) + ; + +alterServerConfigurationStatement returns [TSqlStatement vResult] + : + tConfiguration:Identifier Set + { + Match(tConfiguration, CodeGenerationSupporter.Configuration); + } + ( + {NextTokenMatches(CodeGenerationSupporter.Process)}? + vResult = alterServerConfigurationSetProcessAffinityStatement + | + {NextTokenMatches(CodeGenerationSupporter.Buffer)}? + vResult = alterServerConfigurationSetBufferPoolExtensionStatement + | + {NextTokenMatches(CodeGenerationSupporter.Diagnostics)}? + vResult = alterServerConfigurationSetDiagnosticsLogStatement + | + {NextTokenMatches(CodeGenerationSupporter.Failover)}? + vResult = alterServerConfigurationSetFailoverClusterPropertyStatement + | + {NextTokenMatches(CodeGenerationSupporter.Hadr)}? + vResult = alterServerConfigurationSetHadrClusterStatement + | + {NextTokenMatches(CodeGenerationSupporter.SoftNuma)}? + vResult = alterServerConfigurationSetSoftNumaStatement + | + {NextTokenMatches(CodeGenerationSupporter.External)}? + vResult = alterServerConfigurationSetExternalAuthenticationStatement + ) + ; + + +alterServerConfigurationSetExternalAuthenticationStatement returns [AlterServerConfigurationSetExternalAuthenticationStatement vResult = FragmentFactory.CreateFragment()] +{ + AlterServerConfigurationExternalAuthenticationOption vOption; +} + : tExternal:External tAuthentication:Identifier + { + Match(tExternal, CodeGenerationSupporter.External); + Match(tAuthentication, CodeGenerationSupporter.Authentication); + } + vOption=alterServerConfigurationExternalAuthenticationContainerOption + { + AddAndUpdateTokenInfo(vResult, vResult.Options, vOption); + } + ; + +alterServerConfigurationExternalAuthenticationContainerOption returns [AlterServerConfigurationExternalAuthenticationContainerOption vResult = FragmentFactory.CreateFragment()] +{ + OnOffOptionValue vOptionValue; + AlterServerConfigurationExternalAuthenticationOption vAlterServerConfigurationExternalAuthenticationOption; +} + : vOptionValue=onOffOptionValue + { + vResult.OptionValue = vOptionValue; + vResult.OptionKind = AlterServerConfigurationExternalAuthenticationOptionKind.OnOff; + } + ( + { + // Additional options are only allowed when external authentication is set to ON + if (vOptionValue.OptionState != OptionState.On) + ThrowIncorrectSyntaxErrorException(vOptionValue); + } + LeftParenthesis + (vAlterServerConfigurationExternalAuthenticationOption=alterServerConfigurationExternalAuthenticationOption + { + AddAndUpdateTokenInfo(vResult, vResult.Suboptions, vAlterServerConfigurationExternalAuthenticationOption); + }) + RightParenthesis + | + { + // Empty rule: setting external authorization to OFF is the only allowed + if (vOptionValue.OptionState != OptionState.Off) + ThrowIncorrectSyntaxErrorException(vOptionValue); + } + ) + ; + +alterServerConfigurationExternalAuthenticationOption returns [AlterServerConfigurationExternalAuthenticationOption vResult] + : {NextTokenMatches(CodeGenerationSupporter.UseIdentity)}? + vResult = alterServerConfigurationExternalAuthenticationUseIdentityOption + | + {NextTokenMatches(CodeGenerationSupporter.CredentialName)}? + vResult = alterServerConfigurationExternalAuthenticationCredentialNameOption + ; + +alterServerConfigurationExternalAuthenticationCredentialNameOption returns [AlterServerConfigurationExternalAuthenticationOption vResult = FragmentFactory.CreateFragment()] +{ + LiteralOptionValue vCredentialName; +} + : tCredentialName:Identifier EqualsSign vCredentialName=stringLiteralOptionValue + { + Match(tCredentialName, CodeGenerationSupporter.CredentialName); + vResult.OptionKind = AlterServerConfigurationExternalAuthenticationOptionHelper.Instance.ParseOption(tCredentialName); + vResult.OptionValue = vCredentialName; + } + ; + +alterServerConfigurationExternalAuthenticationUseIdentityOption returns [AlterServerConfigurationExternalAuthenticationOption vResult = FragmentFactory.CreateFragment()] +{ +} + : tUseIdentity:Identifier + { + Match(tUseIdentity, CodeGenerationSupporter.UseIdentity); + vResult.OptionKind = AlterServerConfigurationExternalAuthenticationOptionHelper.Instance.ParseOption(tUseIdentity); + } + ; + +alterServerConfigurationSetSoftNumaStatement returns [AlterServerConfigurationSetSoftNumaStatement vResult = FragmentFactory.CreateFragment()] +{ + AlterServerConfigurationSoftNumaOption vOption; +} + : tSoftNuma:Identifier + { + Match(tSoftNuma, CodeGenerationSupporter.SoftNuma); + } + vOption=alterServerConfigurationSoftNumaOption + { + AddAndUpdateTokenInfo(vResult, vResult.Options, vOption); + } + ; + +alterServerConfigurationSoftNumaOption returns [AlterServerConfigurationSoftNumaOption vResult = FragmentFactory.CreateFragment()] +{ + OnOffOptionValue vOptionValue; +} + : vOptionValue=onOffOptionValue + { + vResult.OptionKind = AlterServerConfigurationSoftNumaOptionKind.OnOff; + vResult.OptionValue = vOptionValue; + } + + ; + +alterServerConfigurationSetBufferPoolExtensionStatement returns [AlterServerConfigurationSetBufferPoolExtensionStatement vResult = FragmentFactory.CreateFragment()] +{ + AlterServerConfigurationBufferPoolExtensionOption vOption; +} + : tBuffer:Identifier tPool:Identifier tExtension:Identifier + { + Match(tBuffer, CodeGenerationSupporter.Buffer); + Match(tPool, CodeGenerationSupporter.Pool); + Match(tExtension, CodeGenerationSupporter.Extension); + } + vOption=alterServerConfigurationBufferPoolExtensionContainerOption + { + AddAndUpdateTokenInfo(vResult, vResult.Options, vOption); + } + ; + +alterServerConfigurationBufferPoolExtensionContainerOption returns [AlterServerConfigurationBufferPoolExtensionContainerOption vResult = FragmentFactory.CreateFragment()] +{ + OnOffOptionValue vOptionValue; + AlterServerConfigurationBufferPoolExtensionOption vFileNameSuboption; + AlterServerConfigurationBufferPoolExtensionOption vSizeSuboption; +} + : vOptionValue=onOffOptionValue + { + vResult.OptionValue = vOptionValue; + vResult.OptionKind = AlterServerConfigurationBufferPoolExtensionOptionKind.OnOff; + } + ( + { + // Additional options are only allowed when buffer pool extension is set to ON + if (vOptionValue.OptionState != OptionState.On) + ThrowIncorrectSyntaxErrorException(vOptionValue); + } + tLParen:LeftParenthesis vFileNameSuboption=alterServerConfigurationBufferPoolExtensionFileNameOption + { + UpdateTokenInfo(vResult, tLParen); + AddAndUpdateTokenInfo(vResult, vResult.Suboptions, vFileNameSuboption); + } + tComma:Comma vSizeSuboption=alterServerConfigurationBufferPoolExtensionSizeOption tRParen:RightParenthesis + { + AddAndUpdateTokenInfo(vResult, vResult.Suboptions, vSizeSuboption); + UpdateTokenInfo(vResult, tRParen); + } + | + { + // Empty rule: setting buffer pool extension to OFF is the only allowed + if (vOptionValue.OptionState != OptionState.Off) + ThrowIncorrectSyntaxErrorException(vOptionValue); + } + ) + ; + +alterServerConfigurationBufferPoolExtensionFileNameOption returns [AlterServerConfigurationBufferPoolExtensionOption vResult = FragmentFactory.CreateFragment()] +{ + LiteralOptionValue vFileName; +} + : tFileName:Identifier EqualsSign vFileName=stringLiteralOptionValue + { + Match(tFileName, CodeGenerationSupporter.FileName); + vResult.OptionKind = AlterServerConfigurationBufferPoolExtensionOptionHelper.Instance.ParseOption(tFileName); + vResult.OptionValue = vFileName; + } + ; + +alterServerConfigurationBufferPoolExtensionSizeOption returns [AlterServerConfigurationBufferPoolExtensionSizeOption vResult = FragmentFactory.CreateFragment()] +{ + LiteralOptionValue vSize; + MemoryUnit vMemUnit; +} + : tSize:Identifier EqualsSign vSize=integerLiteralOptionValue vMemUnit=memUnit[vResult] + { + Match(tSize, CodeGenerationSupporter.Size); + + if (vMemUnit != MemoryUnit.KB && vMemUnit != MemoryUnit.MB && vMemUnit != MemoryUnit.GB) + ThrowIncorrectSyntaxErrorException(vSize); + + vResult.OptionKind = AlterServerConfigurationBufferPoolExtensionOptionHelper.Instance.ParseOption(tSize); + vResult.OptionValue = vSize; + vResult.SizeUnit = vMemUnit; + } + ; + +alterServerConfigurationSetDiagnosticsLogStatement returns [AlterServerConfigurationSetDiagnosticsLogStatement vResult = FragmentFactory.CreateFragment()] +{ + AlterServerConfigurationDiagnosticsLogOption vOption; +} + : tDiagnostics:Identifier tLog:Identifier + { + Match(tDiagnostics, CodeGenerationSupporter.Diagnostics); + Match(tLog, CodeGenerationSupporter.Log); + } + vOption=alterServerConfigurationDiagnosticsLogOption + { + AddAndUpdateTokenInfo(vResult, vResult.Options, vOption); + } + ; + +alterServerConfigurationDiagnosticsLogOption returns [AlterServerConfigurationDiagnosticsLogOption vResult = FragmentFactory.CreateFragment()] +{ + OptionValue vOptionValue; +} + : vOptionValue=onOffOptionValue + { + vResult.OptionKind = AlterServerConfigurationDiagnosticsLogOptionKind.OnOff; + vResult.OptionValue = vOptionValue; + } + | + {NextTokenMatches(CodeGenerationSupporter.MaxUnderscoreSize)}? + vResult=alterServerConfigurationDiagnosticsLogMaxSizeOption + | + tLogOption:Identifier EqualsSign + { + vResult.OptionKind = AlterServerConfigurationDiagnosticsLogOptionHelper.Instance.ParseOption(tLogOption); + } + ( + {vResult.OptionKind == AlterServerConfigurationDiagnosticsLogOptionKind.Path}? + vOptionValue=stringOrDefaultLiteralOptionValue + { + vResult.OptionValue = vOptionValue; + } + | + {vResult.OptionKind == AlterServerConfigurationDiagnosticsLogOptionKind.MaxFiles}? + vOptionValue=integerOrDefaultLiteralOptionValue + { + vResult.OptionValue = vOptionValue; + } + ) + ; + +alterServerConfigurationDiagnosticsLogMaxSizeOption returns [AlterServerConfigurationDiagnosticsLogMaxSizeOption vResult = FragmentFactory.CreateFragment()] +{ + OptionValue vOptionValue; +} + : tMaxSize:Identifier EqualsSign + { + vResult.OptionKind = AlterServerConfigurationDiagnosticsLogOptionHelper.Instance.ParseOption(tMaxSize); + if (vResult.OptionKind != AlterServerConfigurationDiagnosticsLogOptionKind.MaxSize) + ThrowIncorrectSyntaxErrorException(tMaxSize); + } + ( + vOptionValue=integerLiteralOptionValue tMB:Identifier + { + Match(tMB, CodeGenerationSupporter.MB); + vResult.OptionValue = vOptionValue; + vResult.SizeUnit = MemoryUnit.MB; + UpdateTokenInfo(vResult, tMB); + } + | + vOptionValue=defaultLiteralOptionValue + { + vResult.OptionValue = vOptionValue; + } + ) + ; + +alterServerConfigurationSetFailoverClusterPropertyStatement returns [AlterServerConfigurationSetFailoverClusterPropertyStatement vResult = FragmentFactory.CreateFragment()] +{ + AlterServerConfigurationFailoverClusterPropertyOption vOption; +} + : tFailover:Identifier tCluster:Identifier tProperty:Identifier + { + Match(tFailover, CodeGenerationSupporter.Failover); + Match(tCluster, CodeGenerationSupporter.Cluster); + Match(tProperty, CodeGenerationSupporter.Property); + } + vOption=alterServerConfigurationFailoverClusterPropertyOption + { + AddAndUpdateTokenInfo(vResult, vResult.Options, vOption); + } + ; + +alterServerConfigurationFailoverClusterPropertyOption returns [AlterServerConfigurationFailoverClusterPropertyOption vResult = FragmentFactory.CreateFragment()] +{ + OptionValue vOptionValue; +} + : tProperty:Identifier EqualsSign + { + vResult.OptionKind = AlterServerConfigurationFailoverClusterPropertyOptionHelper.Instance.ParseOption(tProperty); + } + ( + {vResult.OptionKind == AlterServerConfigurationFailoverClusterPropertyOptionKind.SqlDumperDumpFlags}? + vOptionValue=binaryOrDefaultLiteralOptionValue + { + vResult.OptionValue = vOptionValue; + } + | + {vResult.OptionKind == AlterServerConfigurationFailoverClusterPropertyOptionKind.SqlDumperDumpPath}? + vOptionValue=stringOrDefaultLiteralOptionValue + { + vResult.OptionValue = vOptionValue; + } + | + vOptionValue=integerOrDefaultLiteralOptionValue + { + vResult.OptionValue = vOptionValue; + } + ) + ; + +alterServerConfigurationSetHadrClusterStatement returns [AlterServerConfigurationSetHadrClusterStatement vResult = FragmentFactory.CreateFragment()] +{ + AlterServerConfigurationHadrClusterOption vOption; +} + : tHadr:Identifier tCluster:Identifier + { + Match(tHadr, CodeGenerationSupporter.Hadr); + Match(tCluster, CodeGenerationSupporter.Cluster); + } + vOption=alterServerConfigurationHadrClusterOption + { + AddAndUpdateTokenInfo(vResult, vResult.Options, vOption); + } + ; + +alterServerConfigurationHadrClusterOption returns [AlterServerConfigurationHadrClusterOption vResult = FragmentFactory.CreateFragment()] +{ + OptionValue vOptionValue; +} + : tOptionKind:Identifier EqualsSign + { + vResult.OptionKind = AlterServerConfigurationHadrClusterOptionHelper.Instance.ParseOption(tOptionKind); + } + ( + vOptionValue=stringLiteralOptionValue + { + vResult.OptionValue = vOptionValue; + } + | + tLocal:Identifier + { + Match(tLocal, CodeGenerationSupporter.Local); + vResult.IsLocal = true; + UpdateTokenInfo(vResult, tLocal); + } + ) + ; + +alterServerConfigurationSetProcessAffinityStatement returns [AlterServerConfigurationStatement vResult = FragmentFactory.CreateFragment()] + : tProcess:Identifier tAffinity:Identifier + { + Match(tProcess, CodeGenerationSupporter.Process); + Match(tAffinity, CodeGenerationSupporter.Affinity); + } + tCpuOrNumanode:Identifier EqualsSign + ( + affinityRangeList[vResult] + { + if (TryMatch(tCpuOrNumanode, CodeGenerationSupporter.Cpu)) + { + vResult.ProcessAffinity = ProcessAffinityType.Cpu; + } + else + { + Match(tCpuOrNumanode, CodeGenerationSupporter.NumaNode); + vResult.ProcessAffinity = ProcessAffinityType.NumaNode; + } + } + | + tAuto:Identifier + { + // AUTO implies CPU affinity + Match(tCpuOrNumanode, CodeGenerationSupporter.Cpu); + Match(tAuto, CodeGenerationSupporter.Auto); + + vResult.ProcessAffinity = ProcessAffinityType.CpuAuto; + + UpdateTokenInfo(vResult, tAuto); + } + ) + ; + +affinityRangeList [AlterServerConfigurationStatement vParent] +{ + ProcessAffinityRange vAffinityRange; +} + : vAffinityRange = affinityRange + { + AddAndUpdateTokenInfo(vParent, vParent.ProcessAffinityRanges, vAffinityRange); + } + (Comma vAffinityRange = affinityRange + { + AddAndUpdateTokenInfo(vParent, vParent.ProcessAffinityRanges, vAffinityRange); + } + )* + ; + +affinityRange returns [ProcessAffinityRange vResult = FragmentFactory.CreateFragment()] +{ + Literal vBoundary; +} + : vBoundary = integer + { + vResult.From = vBoundary; + } + (To vBoundary = integer + { + vResult.To = vBoundary; + } + )? + ; + +////////////////////////////////////////////////////////////////////// +// Alter Database +////////////////////////////////////////////////////////////////////// +alterDatabaseStatements returns [TSqlStatement vResult = null] + : tAlter:Alter Database + ( + // Conflicts with alterDatabase alternative below + {NextTokenMatches(CodeGenerationSupporter.Audit) && NextTokenMatches(CodeGenerationSupporter.Specification, 2)}? + vResult = alterDatabaseAuditSpecification[tAlter] + | + {NextTokenMatches(CodeGenerationSupporter.Scoped) && NextTokenMatches(CodeGenerationSupporter.Credential, 2)}? + vResult = alterDatabaseScopedCredentialStatement[tAlter] + | + {NextTokenMatches(CodeGenerationSupporter.Scoped) && NextTokenMatches(CodeGenerationSupporter.Configuration, 2)}? + vResult = alterDatabaseScopedConfigurationStatement[tAlter] + | + vResult = alterDatabase[tAlter] + | + vResult = alterDatabaseEncryptionKey[tAlter] + ) + ; + +alterDatabaseScopedConfigurationStatement[IToken tAlter] returns [AlterDatabaseScopedConfigurationStatement vResult] +{ + bool vSecondary = false; +} + : + tScoped:Identifier tConfiguration:Identifier + { + Match(tScoped, CodeGenerationSupporter.Scoped); + Match(tConfiguration, CodeGenerationSupporter.Configuration); + } + (For tSecondary:Identifier + { + vSecondary = true; + } + )? + ( + vResult = alterDatabaseScopedConfigSet[vSecondary] + | + vResult = alterDatabaseScopedConfigClear + ) + { + if (vSecondary) + { + vResult.Secondary = true; + UpdateTokenInfo(vResult,tSecondary); + } + UpdateTokenInfo(vResult,tAlter); + } + ; + +alterDatabaseScopedConfigClear returns [AlterDatabaseScopedConfigurationClearStatement vResult = FragmentFactory.CreateFragment()] +{ + DatabaseConfigurationClearOption vOption; +} + : + tClear:Identifier + { + Match(tClear, CodeGenerationSupporter.Clear); + UpdateTokenInfo(vResult, tClear); + } + vOption = databaseConfigurationClearOption + { + vResult.Option = vOption; + } + ; + +databaseConfigurationClearOption returns [DatabaseConfigurationClearOption vResult = FragmentFactory.CreateFragment()] +{ + BinaryLiteral vLiteral; +} + : + tOption:Identifier + { + vResult.OptionKind = DatabaseConfigClearOptionKindHelper.Instance.ParseOption(tOption, SqlVersionFlags.TSql170); + UpdateTokenInfo(vResult, tOption); + } + ( + vLiteral = binary + { + vResult.PlanHandle = vLiteral; + } + )? + ; + +alterDatabaseScopedConfigSet[bool forSecondary] returns [AlterDatabaseScopedConfigurationSetStatement vResult = FragmentFactory.CreateFragment()] +{ + DatabaseConfigurationSetOption vOption; +} + : + Set + ( + {NextTokenMatches(CodeGenerationSupporter.MaxDop)}? + vOption = alterDatabaseScopedMaxDopOption[forSecondary] + | + {NextTokenMatches(CodeGenerationSupporter.QueryOptimizerHotFixes) || NextTokenMatches(CodeGenerationSupporter.ParameterSniffing) || + NextTokenMatches(CodeGenerationSupporter.LegacyCardinalityEstimation)}? + vOption = alterDatabaseScopedOnOffPrimaryOption[forSecondary] + | + vOption = alterDatabaseScopedGenericOption[forSecondary] + ) + { + vResult.Option = vOption; + } + ; + +alterDatabaseScopedMaxDopOption[bool forSecondary] returns [MaxDopConfigurationOption vResult = FragmentFactory.CreateFragment()] +{ + Literal vValue; +} + : + tMaxDop:Identifier EqualsSign + { + vResult.OptionKind = DatabaseConfigSetOptionKindHelper.Instance.ParseOption(tMaxDop, SqlVersionFlags.TSql170); + UpdateTokenInfo(vResult, tMaxDop); + } + ( + vValue = integer + { + vResult.Value = vValue; + } + | + {NextTokenMatches(CodeGenerationSupporter.Primary)}? + tPrimary:Primary + { + if (!forSecondary) + { + ThrowParseErrorException("SQL46115", vResult, TSqlParserResource.SQL46115Message); + } + vResult.Primary = true; + UpdateTokenInfo(vResult, tPrimary); + } + ) + ; + +alterDatabaseScopedOnOffPrimaryOption[bool forSecondary] returns [OnOffPrimaryConfigurationOption vResult = FragmentFactory.CreateFragment()] +{ + DatabaseConfigurationOptionState vOptionState; +} + : + tOption:Identifier + { + vResult.OptionKind = DatabaseConfigSetOptionKindHelper.Instance.ParseOption(tOption, SqlVersionFlags.TSql170); + UpdateTokenInfo(vResult, tOption); + } + EqualsSign + ( + vOptionState = databaseConfigurationOptionOnOffPrimary[vResult] + { + if(!forSecondary && vOptionState == DatabaseConfigurationOptionState.Primary) + { + ThrowParseErrorException("SQL46115", vResult, TSqlParserResource.SQL46115Message); + } + } + ) + { + vResult.OptionState = vOptionState; + } + ; + +alterDatabaseScopedGenericOption[bool forSecondary] returns [GenericConfigurationOption vResult = FragmentFactory.CreateFragment()] +{ + Identifier vOptionName; + Identifier vValueOnOff; + IdentifierOrScalarExpression vValue; + IToken token = LT(1); +} + : + vOptionName = identifier + { + vResult.GenericOptionKind = vOptionName; + } + EqualsSign + ( + {NextTokenMatches(CodeGenerationSupporter.Primary)}? + tPrimary:Primary + { + vValue = CreateIdentifierOrScalarExpressionFromIdentifier(CreateIdentifierFromToken(tPrimary)); + UpdateTokenInfo(vValue, token); + if (!forSecondary) + { + ThrowParseErrorException("SQL46115", vValue, TSqlParserResource.SQL46115Message); + } + vResult.GenericOptionState = vValue; + } + | + vValue = stringOrSignedIntegerOrIdentifier + { + vResult.GenericOptionState = vValue; + } + | + vValueOnOff = onOff + { + vResult.GenericOptionState = CreateIdentifierOrScalarExpressionFromIdentifier(vValueOnOff);; + } + ) + ; + +alterDatabase [IToken tAlter] returns [AlterDatabaseStatement vResult = null] +{ + Identifier vIdentifier = null; + bool vUseCurrent = false; +} + : ( + vIdentifier=identifier + | + vIdentifier=sqlCommandIdentifier + | + tCurrent:Current + { + vUseCurrent=true; + } + ) + ( vResult = alterDbAdd + | {NextTokenMatches(CodeGenerationSupporter.Remove)}? + vResult = alterDbRemove + | {NextTokenMatches(CodeGenerationSupporter.Modify)}? + vResult = alterDbModify + | vResult = alterDbSet + | vResult = alterDbCollate + | vResult = alterDbRebuild // Undocumented - for PSS only + ) + { + if(vUseCurrent) + { + vResult.UseCurrent = true; + UpdateTokenInfo(vResult,tCurrent); + } + else + { + vResult.DatabaseName = vIdentifier; + } + UpdateTokenInfo(vResult,tAlter); + ThrowPartialAstIfPhaseOne(vResult); + } + ; + exception + catch[PhaseOnePartialAstException exception] + { + UpdateTokenInfo(exception.Statement,tAlter); + (exception.Statement as AlterDatabaseStatement).DatabaseName = vIdentifier; + throw; + } + +alterDbCollate returns [AlterDatabaseCollateStatement vResult = FragmentFactory.CreateFragment()] + : collation[vResult] + ; + +alterDbRebuild returns [AlterDatabaseRebuildLogStatement vResult = FragmentFactory.CreateFragment()] +{ + FileDeclaration vFileDeclaration; +} + : tRebuild:Identifier tLog:Identifier + { + Match(tRebuild, CodeGenerationSupporter.Rebuild); + Match(tLog, CodeGenerationSupporter.Log); + UpdateTokenInfo(vResult,tLog); + ThrowPartialAstIfPhaseOne(vResult); + } + (On vFileDeclaration = fileDecl[false] + { + vResult.FileDeclaration = vFileDeclaration; + } + )? + ; + +alterDbAdd returns [AlterDatabaseStatement vResult = null] + : Add + ( + vResult = alterDbAddFile + | + vResult = alterDbAddFilegroup + ) + ; + +// Add File / Add LOG File +alterDbAddFile returns [AlterDatabaseAddFileStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; +} + : (tLog:Identifier + { + Match(tLog,CodeGenerationSupporter.Log); + vResult.IsLog = true; + } + )? + File + { + ThrowPartialAstIfPhaseOne(vResult); + } + fileDeclBodyList[vResult, vResult.FileDeclarations] + (vIdentifier = toFilegroup + { + vResult.FileGroup = vIdentifier; + } + )? + ; + +// Add FILEGROUP +alterDbAddFilegroup returns [AlterDatabaseAddFileGroupStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier; +} + : tFilegroup:Identifier vIdentifier=identifier + { + Match(tFilegroup, CodeGenerationSupporter.Filegroup); + vResult.FileGroup = vIdentifier; + } + (Contains tFileStreamOrMemoryOptimizedData:Identifier + { + if (TryMatch(tFileStreamOrMemoryOptimizedData, CodeGenerationSupporter.FileStream)) + { + vResult.ContainsFileStream = true;; + } + else + { + Match(tFileStreamOrMemoryOptimizedData, CodeGenerationSupporter.MemoryOptimizedData); + vResult.ContainsMemoryOptimizedData = true; + } + UpdateTokenInfo(vResult, tFileStreamOrMemoryOptimizedData); + } + )? + ; + +alterDbRemove returns [AlterDatabaseStatement vResult = null] +{ + Identifier vIdentifier; +} + : tRemove:Identifier + { + Match(tRemove,CodeGenerationSupporter.Remove); + } + (File vIdentifier = identifier + { + AlterDatabaseRemoveFileStatement removeFile = FragmentFactory.CreateFragment(); + removeFile.File = vIdentifier; + vResult = removeFile; + } + | + tFileGroup:Identifier vIdentifier = identifier + { + // REMOVE FILEGROUP + Match(tFileGroup,CodeGenerationSupporter.Filegroup); + AlterDatabaseRemoveFileGroupStatement vRemoveFilegroup = FragmentFactory.CreateFragment(); + vRemoveFilegroup.FileGroup = vIdentifier; + vResult = vRemoveFilegroup; + } + ) + ; + +alterDbModify returns [AlterDatabaseStatement vResult = null] +{ + Identifier vIdentifier; +} + : tModify:Identifier + { + Match(tModify,CodeGenerationSupporter.Modify); + } + ( + {NextTokenMatches(CodeGenerationSupporter.Name)}? + (tName:Identifier EqualsSign vIdentifier = identifier + { + // MODIFY NAME = + Match(tName,CodeGenerationSupporter.Name); + AlterDatabaseModifyNameStatement modifyDbName = FragmentFactory.CreateFragment(); + modifyDbName.NewDatabaseName = vIdentifier; + vResult = modifyDbName; + } + ) + | + (tFileGroup2:Identifier + { + Match(tFileGroup2,CodeGenerationSupporter.Filegroup); + } + vResult = alterDbModifyFilegroup + ) + | vResult = alterDbModifyFile + | vResult = alterDbModifyAzureOptions + ) + ; + +alterDbModifyAzureOptions returns [AlterDatabaseSetStatement vResult = FragmentFactory.CreateFragment()] + : + azureOptions[vResult, vResult.Options] + ; + +// MODIFY File syntax +alterDbModifyFile returns [AlterDatabaseModifyFileStatement vResult = FragmentFactory.CreateFragment()] +{ + FileDeclaration vFileDecl; +} + : File + { + ThrowPartialAstIfPhaseOne(vResult); + } + vFileDecl = fileDecl[true] + { + vResult.FileDeclaration = vFileDecl; + } + ; + +alterDbModifyFilegroup returns [AlterDatabaseModifyFileGroupStatement vResult = FragmentFactory.CreateFragment()] +{ + Identifier vIdentifier, vIdentifier2; + AlterDatabaseTermination vTermination; +} + : vIdentifier = identifier + { + vResult.FileGroup = vIdentifier; + } + ( + (tName2:Identifier EqualsSign vIdentifier2 = identifier + { + // MODIFY FILEGROUP NAME = + Match(tName2,CodeGenerationSupporter.Name); + vResult.NewFileGroupName = vIdentifier2; + ThrowPartialAstIfPhaseOne(vResult); + } + ) + | tDefault:Default + { + // MODIFY FILEGROUP Default + vResult.MakeDefault = true; + UpdateTokenInfo(vResult,tDefault); + } + | + (tUpdatabilityOption:Identifier + { + // MODIFY FILEGROUP