Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,13 @@ public enum AlterAvailabilityGroupStatementType
/// Take an action
/// </summary>
Action = 6,
/// <summary>
/// Grant CREATE ANY DATABASE
/// </summary>
GrantCreateAnyDatabase = 7,
/// <summary>
/// Deny CREATE ANY DATABASE
/// </summary>
DenyCreateAnyDatabase = 8,
}
}
4 changes: 4 additions & 0 deletions SqlScriptDom/Parser/TSql/AvailabilityReplicaOptionKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public enum AvailabilityReplicaOptionKind
/// Primary role
/// </summary>
PrimaryRole = 6,
/// <summary>
/// Backup priority
/// </summary>
BackupPriority = 7,

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal class AvailabilityReplicaOptionsHelper : OptionsHelper<AvailabilityRepl
private AvailabilityReplicaOptionsHelper()
{
AddOptionMapping(AvailabilityReplicaOptionKind.ApplyDelay, CodeGenerationSupporter.ApplyDelay);
AddOptionMapping(AvailabilityReplicaOptionKind.BackupPriority, CodeGenerationSupporter.BackupPriority);
AddOptionMapping(AvailabilityReplicaOptionKind.AvailabilityMode, CodeGenerationSupporter.AvailabilityMode);
AddOptionMapping(AvailabilityReplicaOptionKind.EndpointUrl, CodeGenerationSupporter.EndpointUrl);
AddOptionMapping(AvailabilityReplicaOptionKind.SecondaryRole, CodeGenerationSupporter.SecondaryRole);
Expand Down
1 change: 1 addition & 0 deletions SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ internal static class CodeGenerationSupporter
internal const string ApplicationLog = "APPLICATION_LOG";
internal const string Apply = "APPLY";
internal const string ApplyDelay = "APPLY_DELAY";
internal const string BackupPriority = "BACKUP_PRIORITY";
internal const string Assembly = "ASSEMBLY";
internal const string Asymmetric = "ASYMMETRIC";
internal const string AsynchronousCommit = "ASYNCHRONOUS_COMMIT";
Expand Down
4 changes: 4 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql110.g
Original file line number Diff line number Diff line change
Expand Up @@ -7850,6 +7850,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
4 changes: 4 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql120.g
Original file line number Diff line number Diff line change
Expand Up @@ -8011,6 +8011,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
14 changes: 14 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql130.g
Original file line number Diff line number Diff line change
Expand Up @@ -8555,6 +8555,16 @@ alterAvailabilityGroupStatement returns [AlterAvailabilityGroupStatement vResult
alterAvailabilityGroupRemoveReplica[vResult]
| alterAvailabilityGroupSetOption[vResult]
| alterAvailabilityGroupTakeAction[vResult]
| tGrant:Grant Create Any tGrantDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase;
UpdateTokenInfo(vResult, tGrantDatabase);
}
| tDeny:Deny Create Any tDenyDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase;
UpdateTokenInfo(vResult, tDenyDatabase);
}
)
;

Expand Down Expand Up @@ -8920,6 +8930,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
14 changes: 14 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql140.g
Original file line number Diff line number Diff line change
Expand Up @@ -8947,6 +8947,16 @@ alterAvailabilityGroupStatement returns [AlterAvailabilityGroupStatement vResult
alterAvailabilityGroupRemoveReplica[vResult]
| alterAvailabilityGroupSetOption[vResult]
| alterAvailabilityGroupTakeAction[vResult]
| tGrant:Grant Create Any tGrantDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase;
UpdateTokenInfo(vResult, tGrantDatabase);
}
| tDeny:Deny Create Any tDenyDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase;
UpdateTokenInfo(vResult, tDenyDatabase);
}
)
;

Expand Down Expand Up @@ -9312,6 +9322,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
14 changes: 14 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql150.g
Original file line number Diff line number Diff line change
Expand Up @@ -9589,6 +9589,16 @@ alterAvailabilityGroupStatement returns [AlterAvailabilityGroupStatement vResult
alterAvailabilityGroupRemoveReplica[vResult]
| alterAvailabilityGroupSetOption[vResult]
| alterAvailabilityGroupTakeAction[vResult]
| tGrant:Grant Create Any tGrantDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase;
UpdateTokenInfo(vResult, tGrantDatabase);
}
| tDeny:Deny Create Any tDenyDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase;
UpdateTokenInfo(vResult, tDenyDatabase);
}
)
;

Expand Down Expand Up @@ -9954,6 +9964,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
14 changes: 14 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql160.g
Original file line number Diff line number Diff line change
Expand Up @@ -9614,6 +9614,16 @@ alterAvailabilityGroupStatement returns [AlterAvailabilityGroupStatement vResult
alterAvailabilityGroupRemoveReplica[vResult]
| alterAvailabilityGroupSetOption[vResult]
| alterAvailabilityGroupTakeAction[vResult]
| tGrant:Grant Create Any tGrantDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase;
UpdateTokenInfo(vResult, tGrantDatabase);
}
| tDeny:Deny Create Any tDenyDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase;
UpdateTokenInfo(vResult, tDenyDatabase);
}
)
;

Expand Down Expand Up @@ -9979,6 +9989,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
14 changes: 14 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql170.g
Original file line number Diff line number Diff line change
Expand Up @@ -9669,6 +9669,16 @@ alterAvailabilityGroupStatement returns [AlterAvailabilityGroupStatement vResult
alterAvailabilityGroupRemoveReplica[vResult]
| alterAvailabilityGroupSetOption[vResult]
| alterAvailabilityGroupTakeAction[vResult]
| tGrant:Grant Create Any tGrantDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase;
UpdateTokenInfo(vResult, tGrantDatabase);
}
| tDeny:Deny Create Any tDenyDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase;
UpdateTokenInfo(vResult, tDenyDatabase);
}
)
;

Expand Down Expand Up @@ -10034,6 +10044,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
14 changes: 14 additions & 0 deletions SqlScriptDom/Parser/TSql/TSql180.g
Original file line number Diff line number Diff line change
Expand Up @@ -9672,6 +9672,16 @@ alterAvailabilityGroupStatement returns [AlterAvailabilityGroupStatement vResult
alterAvailabilityGroupRemoveReplica[vResult]
| alterAvailabilityGroupSetOption[vResult]
| alterAvailabilityGroupTakeAction[vResult]
| tGrant:Grant Create Any tGrantDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase;
UpdateTokenInfo(vResult, tGrantDatabase);
}
| tDeny:Deny Create Any tDenyDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase;
UpdateTokenInfo(vResult, tDenyDatabase);
}
)
;

Expand Down Expand Up @@ -10037,6 +10047,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
14 changes: 14 additions & 0 deletions SqlScriptDom/Parser/TSql/TSqlFabricDW.g
Original file line number Diff line number Diff line change
Expand Up @@ -9643,6 +9643,16 @@ alterAvailabilityGroupStatement returns [AlterAvailabilityGroupStatement vResult
alterAvailabilityGroupRemoveReplica[vResult]
| alterAvailabilityGroupSetOption[vResult]
| alterAvailabilityGroupTakeAction[vResult]
| tGrant:Grant Create Any tGrantDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase;
UpdateTokenInfo(vResult, tGrantDatabase);
}
| tDeny:Deny Create Any tDenyDatabase:Database
{
vResult.AlterAvailabilityGroupStatementType = AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase;
UpdateTokenInfo(vResult, tDenyDatabase);
}
)
;

Expand Down Expand Up @@ -10008,6 +10018,10 @@ literalReplicaOption returns [LiteralReplicaOption vResult = FragmentFactory.Cre
{
vResult.OptionKind=AvailabilityReplicaOptionKind.SessionTimeout;
}
else if(TryMatch(tOption, CodeGenerationSupporter.BackupPriority))
{
vResult.OptionKind=AvailabilityReplicaOptionKind.BackupPriority;
}
else
{
Match(tOption, CodeGenerationSupporter.ApplyDelay);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ public override void ExplicitVisit(AlterAvailabilityGroupStatement node)
GenerateSpace();
GenerateParenthesisedCommaSeparatedList(node.Options);
break;
case AlterAvailabilityGroupStatementType.GrantCreateAnyDatabase:
GenerateSpaceAndKeyword(TSqlTokenType.Grant);
GenerateSpaceAndKeyword(TSqlTokenType.Create);
GenerateSpaceAndKeyword(TSqlTokenType.Any);
GenerateSpaceAndKeyword(TSqlTokenType.Database);
break;
case AlterAvailabilityGroupStatementType.DenyCreateAnyDatabase:
GenerateSpaceAndKeyword(TSqlTokenType.Deny);
GenerateSpaceAndKeyword(TSqlTokenType.Create);
GenerateSpaceAndKeyword(TSqlTokenType.Any);
GenerateSpaceAndKeyword(TSqlTokenType.Database);
break;
default:
Debug.Assert(false, "Unexepected option encountered");
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ALTER AVAILABILITY GROUP [SalesAG] ADD REPLICA ON 'node1' WITH (BACKUP_PRIORITY = 50);


GO
ALTER AVAILABILITY GROUP [SalesAG] ADD REPLICA ON 'node2' WITH (ENDPOINT_URL = 'TCP://node2:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50);


GO
ALTER AVAILABILITY GROUP [SalesAG] MODIFY REPLICA ON 'node1' WITH (BACKUP_PRIORITY = 100);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ALTER AVAILABILITY GROUP [SalesAG] GRANT CREATE ANY DATABASE;


GO
ALTER AVAILABILITY GROUP [SalesAG] DENY CREATE ANY DATABASE;
1 change: 1 addition & 0 deletions Test/SqlDom/Only110SyntaxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public partial class SqlDomTests
// Note: These filenames are case sensitive, make sure they match the checked-in file exactly
private static readonly ParserTest[] Only110TestInfos = {
new ParserTest110("AlterAvailabilityGroupStatementTests.sql", 24, 12, 12),
new ParserTest110("AlterAvailabilityGroupBackupPriorityTests.sql", 6, 3, 3),
new ParserTest110("AlterSearchPropertyListStatementTests.sql", 4, 4, 4),
new ParserTest110("AlterSelectiveXmlIndexStatementTests.sql", 2, 6, 6),
new ParserTest110("AlterSequenceStatementTests.sql", 2, 6, 6),
Expand Down
3 changes: 2 additions & 1 deletion Test/SqlDom/Only130SyntaxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ public partial class SqlDomTests
new ParserTest130("CreateWorkloadClassifierStatementSqlDwTests.sql", 2, 1, 1, 1, 1),
new ParserTest130("PredictSqlDwTests.sql", 3, 3, 3, 3, 3),
new ParserTest130("CreateEventSessionNotLikePredicate.sql", 2, 1, 1, 1, 1),
new ParserTest130("PersistSamplePercentStatisticsTests130.sql")
new ParserTest130("PersistSamplePercentStatisticsTests130.sql"),
new ParserTest130("AlterAvailabilityGroupCreateAnyDatabaseTests130.sql", 4, 3, 3, 3, 3)
};

[TestMethod]
Expand Down
13 changes: 13 additions & 0 deletions Test/SqlDom/ParserErrorsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ namespace SqlStudio.Tests.UTSqlScriptDom
{
public partial class SqlDomTests
{
/// <summary>
/// Negative test for GitHub issue #222: ALTER AVAILABILITY GROUP ... GRANT/DENY only
/// accepts CREATE ANY DATABASE; any other permission phrase must be rejected.
/// </summary>
[TestMethod]
[Priority(0)]
[SqlStudioTestCategory(Category.UnitTest)]
public void AlterAvailabilityGroupCreateAnyDatabaseNegativeTest()
{
ParserTestUtils.ErrorTest130("ALTER AVAILABILITY GROUP [ag] GRANT CREATE ANY TABLE",
new ParserErrorInfo(47, "SQL46010", "TABLE"));
}

/// <summary>
/// Negative tests for create table with generated always
/// as user id/name start/end columns
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Regression tests for GitHub issue #222: BACKUP_PRIORITY must be accepted as an integer-valued
-- replica option in ADD REPLICA ON / MODIFY REPLICA ON.
ALTER AVAILABILITY GROUP [SalesAG] ADD REPLICA ON 'node1' WITH (BACKUP_PRIORITY = 50)
GO
ALTER AVAILABILITY GROUP [SalesAG] ADD REPLICA ON 'node2' WITH (ENDPOINT_URL = 'TCP://node2:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50)
GO
ALTER AVAILABILITY GROUP [SalesAG] MODIFY REPLICA ON 'node1' WITH (BACKUP_PRIORITY = 100)
GO
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Regression tests for GitHub issue #222: ALTER AVAILABILITY GROUP ... { GRANT | DENY } CREATE ANY DATABASE.
ALTER AVAILABILITY GROUP [SalesAG] GRANT CREATE ANY DATABASE
GO
ALTER AVAILABILITY GROUP [SalesAG] DENY CREATE ANY DATABASE
GO