@@ -282,6 +282,10 @@ func statementToJSON(stmt ast.Statement) jsonNode {
282282 return alterSchemaStatementToJSON (s )
283283 case * ast.AlterRoleStatement :
284284 return alterRoleStatementToJSON (s )
285+ case * ast.CreateServerRoleStatement :
286+ return createServerRoleStatementToJSON (s )
287+ case * ast.AlterServerRoleStatement :
288+ return alterServerRoleStatementToJSON (s )
285289 case * ast.AlterRemoteServiceBindingStatement :
286290 return alterRemoteServiceBindingStatementToJSON (s )
287291 case * ast.AlterXmlSchemaCollectionStatement :
@@ -2655,11 +2659,13 @@ func (p *Parser) parseGrantStatement() (*ast.GrantStatement, error) {
26552659
26562660 // Parse permission(s)
26572661 perm := & ast.Permission {}
2658- for p .curTok .Type != TokenTo && p .curTok .Type != TokenEOF {
2662+ for p .curTok .Type != TokenTo && p .curTok .Type != TokenOn && p . curTok . Type != TokenEOF {
26592663 if p .curTok .Type == TokenIdent || p .curTok .Type == TokenCreate ||
26602664 p .curTok .Type == TokenProcedure || p .curTok .Type == TokenView ||
26612665 p .curTok .Type == TokenSelect || p .curTok .Type == TokenInsert ||
2662- p .curTok .Type == TokenUpdate || p .curTok .Type == TokenDelete {
2666+ p .curTok .Type == TokenUpdate || p .curTok .Type == TokenDelete ||
2667+ p .curTok .Type == TokenAlter || p .curTok .Type == TokenExecute ||
2668+ p .curTok .Type == TokenDrop {
26632669 perm .Identifiers = append (perm .Identifiers , & ast.Identifier {
26642670 Value : p .curTok .Literal ,
26652671 QuoteType : "NotQuoted" ,
@@ -2677,6 +2683,150 @@ func (p *Parser) parseGrantStatement() (*ast.GrantStatement, error) {
26772683 stmt .Permissions = append (stmt .Permissions , perm )
26782684 }
26792685
2686+ // Check for ON clause (SecurityTargetObject)
2687+ if p .curTok .Type == TokenOn {
2688+ p .nextToken () // consume ON
2689+
2690+ stmt .SecurityTargetObject = & ast.SecurityTargetObject {}
2691+ stmt .SecurityTargetObject .ObjectKind = "NotSpecified"
2692+
2693+ // Parse object kind and ::
2694+ // Object kinds can be: SERVER ROLE, APPLICATION ROLE, ASYMMETRIC KEY, SYMMETRIC KEY, etc.
2695+ objectKind := strings .ToUpper (p .curTok .Literal )
2696+ switch objectKind {
2697+ case "SERVER" :
2698+ p .nextToken () // consume SERVER
2699+ if strings .ToUpper (p .curTok .Literal ) == "ROLE" {
2700+ p .nextToken () // consume ROLE
2701+ stmt .SecurityTargetObject .ObjectKind = "ServerRole"
2702+ } else {
2703+ stmt .SecurityTargetObject .ObjectKind = "Server"
2704+ }
2705+ case "APPLICATION" :
2706+ p .nextToken () // consume APPLICATION
2707+ if strings .ToUpper (p .curTok .Literal ) == "ROLE" {
2708+ p .nextToken () // consume ROLE
2709+ }
2710+ stmt .SecurityTargetObject .ObjectKind = "ApplicationRole"
2711+ case "ASYMMETRIC" :
2712+ p .nextToken () // consume ASYMMETRIC
2713+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
2714+ p .nextToken () // consume KEY
2715+ }
2716+ stmt .SecurityTargetObject .ObjectKind = "AsymmetricKey"
2717+ case "SYMMETRIC" :
2718+ p .nextToken () // consume SYMMETRIC
2719+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
2720+ p .nextToken () // consume KEY
2721+ }
2722+ stmt .SecurityTargetObject .ObjectKind = "SymmetricKey"
2723+ case "REMOTE" :
2724+ p .nextToken () // consume REMOTE
2725+ if strings .ToUpper (p .curTok .Literal ) == "SERVICE" {
2726+ p .nextToken () // consume SERVICE
2727+ if strings .ToUpper (p .curTok .Literal ) == "BINDING" {
2728+ p .nextToken () // consume BINDING
2729+ }
2730+ }
2731+ stmt .SecurityTargetObject .ObjectKind = "RemoteServiceBinding"
2732+ case "FULLTEXT" :
2733+ p .nextToken () // consume FULLTEXT
2734+ if strings .ToUpper (p .curTok .Literal ) == "CATALOG" {
2735+ p .nextToken () // consume CATALOG
2736+ }
2737+ stmt .SecurityTargetObject .ObjectKind = "FullTextCatalog"
2738+ case "MESSAGE" :
2739+ p .nextToken () // consume MESSAGE
2740+ if strings .ToUpper (p .curTok .Literal ) == "TYPE" {
2741+ p .nextToken () // consume TYPE
2742+ }
2743+ stmt .SecurityTargetObject .ObjectKind = "MessageType"
2744+ case "XML" :
2745+ p .nextToken () // consume XML
2746+ if strings .ToUpper (p .curTok .Literal ) == "SCHEMA" {
2747+ p .nextToken () // consume SCHEMA
2748+ if strings .ToUpper (p .curTok .Literal ) == "COLLECTION" {
2749+ p .nextToken () // consume COLLECTION
2750+ }
2751+ }
2752+ stmt .SecurityTargetObject .ObjectKind = "XmlSchemaCollection"
2753+ case "SEARCH" :
2754+ p .nextToken () // consume SEARCH
2755+ if strings .ToUpper (p .curTok .Literal ) == "PROPERTY" {
2756+ p .nextToken () // consume PROPERTY
2757+ if strings .ToUpper (p .curTok .Literal ) == "LIST" {
2758+ p .nextToken () // consume LIST
2759+ }
2760+ }
2761+ stmt .SecurityTargetObject .ObjectKind = "SearchPropertyList"
2762+ case "AVAILABILITY" :
2763+ p .nextToken () // consume AVAILABILITY
2764+ if strings .ToUpper (p .curTok .Literal ) == "GROUP" {
2765+ p .nextToken () // consume GROUP
2766+ }
2767+ stmt .SecurityTargetObject .ObjectKind = "AvailabilityGroup"
2768+ case "TYPE" :
2769+ p .nextToken ()
2770+ stmt .SecurityTargetObject .ObjectKind = "Type"
2771+ case "OBJECT" :
2772+ p .nextToken ()
2773+ stmt .SecurityTargetObject .ObjectKind = "Object"
2774+ case "ASSEMBLY" :
2775+ p .nextToken ()
2776+ stmt .SecurityTargetObject .ObjectKind = "Assembly"
2777+ case "CERTIFICATE" :
2778+ p .nextToken ()
2779+ stmt .SecurityTargetObject .ObjectKind = "Certificate"
2780+ case "CONTRACT" :
2781+ p .nextToken ()
2782+ stmt .SecurityTargetObject .ObjectKind = "Contract"
2783+ case "DATABASE" :
2784+ p .nextToken ()
2785+ stmt .SecurityTargetObject .ObjectKind = "Database"
2786+ case "ENDPOINT" :
2787+ p .nextToken ()
2788+ stmt .SecurityTargetObject .ObjectKind = "Endpoint"
2789+ case "LOGIN" :
2790+ p .nextToken ()
2791+ stmt .SecurityTargetObject .ObjectKind = "Login"
2792+ case "ROLE" :
2793+ p .nextToken ()
2794+ stmt .SecurityTargetObject .ObjectKind = "Role"
2795+ case "ROUTE" :
2796+ p .nextToken ()
2797+ stmt .SecurityTargetObject .ObjectKind = "Route"
2798+ case "SCHEMA" :
2799+ p .nextToken ()
2800+ stmt .SecurityTargetObject .ObjectKind = "Schema"
2801+ case "SERVICE" :
2802+ p .nextToken ()
2803+ stmt .SecurityTargetObject .ObjectKind = "Service"
2804+ case "USER" :
2805+ p .nextToken ()
2806+ stmt .SecurityTargetObject .ObjectKind = "User"
2807+ }
2808+
2809+ // Expect ::
2810+ if p .curTok .Type == TokenColonColon {
2811+ p .nextToken () // consume ::
2812+
2813+ // Parse object name as multi-part identifier
2814+ stmt .SecurityTargetObject .ObjectName = & ast.SecurityTargetObjectName {}
2815+ multiPart := & ast.MultiPartIdentifier {}
2816+ for {
2817+ id := p .parseIdentifier ()
2818+ multiPart .Identifiers = append (multiPart .Identifiers , id )
2819+ if p .curTok .Type == TokenDot {
2820+ p .nextToken () // consume .
2821+ } else {
2822+ break
2823+ }
2824+ }
2825+ multiPart .Count = len (multiPart .Identifiers )
2826+ stmt .SecurityTargetObject .ObjectName .MultiPartIdentifier = multiPart
2827+ }
2828+ }
2829+
26802830 // Expect TO
26812831 if p .curTok .Type == TokenTo {
26822832 p .nextToken ()
@@ -2965,6 +3115,9 @@ func grantStatementToJSON(s *ast.GrantStatement) jsonNode {
29653115 }
29663116 node ["Permissions" ] = perms
29673117 }
3118+ if s .SecurityTargetObject != nil {
3119+ node ["SecurityTargetObject" ] = securityTargetObjectToJSON (s .SecurityTargetObject )
3120+ }
29683121 if len (s .Principals ) > 0 {
29693122 principals := make ([]jsonNode , len (s .Principals ))
29703123 for i , p := range s .Principals {
@@ -2975,6 +3128,27 @@ func grantStatementToJSON(s *ast.GrantStatement) jsonNode {
29753128 return node
29763129}
29773130
3131+ func securityTargetObjectToJSON (s * ast.SecurityTargetObject ) jsonNode {
3132+ node := jsonNode {
3133+ "$type" : "SecurityTargetObject" ,
3134+ "ObjectKind" : s .ObjectKind ,
3135+ }
3136+ if s .ObjectName != nil {
3137+ node ["ObjectName" ] = securityTargetObjectNameToJSON (s .ObjectName )
3138+ }
3139+ return node
3140+ }
3141+
3142+ func securityTargetObjectNameToJSON (s * ast.SecurityTargetObjectName ) jsonNode {
3143+ node := jsonNode {
3144+ "$type" : "SecurityTargetObjectName" ,
3145+ }
3146+ if s .MultiPartIdentifier != nil {
3147+ node ["MultiPartIdentifier" ] = multiPartIdentifierToJSON (s .MultiPartIdentifier )
3148+ }
3149+ return node
3150+ }
3151+
29783152func permissionToJSON (p * ast.Permission ) jsonNode {
29793153 node := jsonNode {
29803154 "$type" : "Permission" ,
@@ -3578,6 +3752,32 @@ func alterRoleActionToJSON(a ast.AlterRoleAction) jsonNode {
35783752 }
35793753}
35803754
3755+ func createServerRoleStatementToJSON (s * ast.CreateServerRoleStatement ) jsonNode {
3756+ node := jsonNode {
3757+ "$type" : "CreateServerRoleStatement" ,
3758+ }
3759+ if s .Owner != nil {
3760+ node ["Owner" ] = identifierToJSON (s .Owner )
3761+ }
3762+ if s .Name != nil {
3763+ node ["Name" ] = identifierToJSON (s .Name )
3764+ }
3765+ return node
3766+ }
3767+
3768+ func alterServerRoleStatementToJSON (s * ast.AlterServerRoleStatement ) jsonNode {
3769+ node := jsonNode {
3770+ "$type" : "AlterServerRoleStatement" ,
3771+ }
3772+ if s .Action != nil {
3773+ node ["Action" ] = alterRoleActionToJSON (s .Action )
3774+ }
3775+ if s .Name != nil {
3776+ node ["Name" ] = identifierToJSON (s .Name )
3777+ }
3778+ return node
3779+ }
3780+
35813781func alterRemoteServiceBindingStatementToJSON (s * ast.AlterRemoteServiceBindingStatement ) jsonNode {
35823782 node := jsonNode {
35833783 "$type" : "AlterRemoteServiceBindingStatement" ,
0 commit comments