@@ -2189,6 +2189,8 @@ func (p *Parser) parseAlterStatement() (ast.Statement, error) {
21892189 return p .parseAlterExternalStatement ()
21902190 case TokenView :
21912191 return p .parseAlterViewStatement ()
2192+ case TokenAuthorization :
2193+ return p .parseAlterAuthorizationStatement ()
21922194 case TokenIdent :
21932195 // Handle keywords that are not reserved tokens
21942196 switch strings .ToUpper (p .curTok .Literal ) {
@@ -11744,3 +11746,186 @@ done:
1174411746 }
1174511747 return stmt , nil
1174611748}
11749+
11750+ func (p * Parser ) parseAlterAuthorizationStatement () (* ast.AlterAuthorizationStatement , error ) {
11751+ // Consume AUTHORIZATION
11752+ p .nextToken ()
11753+
11754+ stmt := & ast.AlterAuthorizationStatement {}
11755+
11756+ // Expect ON
11757+ if p .curTok .Type == TokenOn {
11758+ p .nextToken () // consume ON
11759+ }
11760+
11761+ // Parse security target object
11762+ stmt .SecurityTargetObject = & ast.SecurityTargetObject {}
11763+ stmt .SecurityTargetObject .ObjectKind = "NotSpecified"
11764+
11765+ // Parse object kind and ::
11766+ objectKind := strings .ToUpper (p .curTok .Literal )
11767+ switch objectKind {
11768+ case "SERVER" :
11769+ p .nextToken ()
11770+ if strings .ToUpper (p .curTok .Literal ) == "ROLE" {
11771+ p .nextToken ()
11772+ stmt .SecurityTargetObject .ObjectKind = "ServerRole"
11773+ } else {
11774+ stmt .SecurityTargetObject .ObjectKind = "Server"
11775+ }
11776+ case "APPLICATION" :
11777+ p .nextToken ()
11778+ if strings .ToUpper (p .curTok .Literal ) == "ROLE" {
11779+ p .nextToken ()
11780+ }
11781+ stmt .SecurityTargetObject .ObjectKind = "ApplicationRole"
11782+ case "ASYMMETRIC" :
11783+ p .nextToken ()
11784+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
11785+ p .nextToken ()
11786+ }
11787+ stmt .SecurityTargetObject .ObjectKind = "AsymmetricKey"
11788+ case "SYMMETRIC" :
11789+ p .nextToken ()
11790+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
11791+ p .nextToken ()
11792+ }
11793+ stmt .SecurityTargetObject .ObjectKind = "SymmetricKey"
11794+ case "REMOTE" :
11795+ p .nextToken ()
11796+ if strings .ToUpper (p .curTok .Literal ) == "SERVICE" {
11797+ p .nextToken ()
11798+ if strings .ToUpper (p .curTok .Literal ) == "BINDING" {
11799+ p .nextToken ()
11800+ }
11801+ }
11802+ stmt .SecurityTargetObject .ObjectKind = "RemoteServiceBinding"
11803+ case "FULLTEXT" :
11804+ p .nextToken ()
11805+ if strings .ToUpper (p .curTok .Literal ) == "CATALOG" {
11806+ p .nextToken ()
11807+ }
11808+ stmt .SecurityTargetObject .ObjectKind = "FullTextCatalog"
11809+ case "MESSAGE" :
11810+ p .nextToken ()
11811+ if strings .ToUpper (p .curTok .Literal ) == "TYPE" {
11812+ p .nextToken ()
11813+ }
11814+ stmt .SecurityTargetObject .ObjectKind = "MessageType"
11815+ case "XML" :
11816+ p .nextToken ()
11817+ if strings .ToUpper (p .curTok .Literal ) == "SCHEMA" {
11818+ p .nextToken ()
11819+ if strings .ToUpper (p .curTok .Literal ) == "COLLECTION" {
11820+ p .nextToken ()
11821+ }
11822+ }
11823+ stmt .SecurityTargetObject .ObjectKind = "XmlSchemaCollection"
11824+ case "SEARCH" :
11825+ p .nextToken ()
11826+ if strings .ToUpper (p .curTok .Literal ) == "PROPERTY" {
11827+ p .nextToken ()
11828+ if strings .ToUpper (p .curTok .Literal ) == "LIST" {
11829+ p .nextToken ()
11830+ }
11831+ }
11832+ stmt .SecurityTargetObject .ObjectKind = "SearchPropertyList"
11833+ case "AVAILABILITY" :
11834+ p .nextToken ()
11835+ if strings .ToUpper (p .curTok .Literal ) == "GROUP" {
11836+ p .nextToken ()
11837+ }
11838+ stmt .SecurityTargetObject .ObjectKind = "AvailabilityGroup"
11839+ case "TYPE" :
11840+ p .nextToken ()
11841+ stmt .SecurityTargetObject .ObjectKind = "Type"
11842+ case "OBJECT" :
11843+ p .nextToken ()
11844+ stmt .SecurityTargetObject .ObjectKind = "Object"
11845+ case "ASSEMBLY" :
11846+ p .nextToken ()
11847+ stmt .SecurityTargetObject .ObjectKind = "Assembly"
11848+ case "CERTIFICATE" :
11849+ p .nextToken ()
11850+ stmt .SecurityTargetObject .ObjectKind = "Certificate"
11851+ case "CONTRACT" :
11852+ p .nextToken ()
11853+ stmt .SecurityTargetObject .ObjectKind = "Contract"
11854+ case "DATABASE" :
11855+ p .nextToken ()
11856+ stmt .SecurityTargetObject .ObjectKind = "Database"
11857+ case "ENDPOINT" :
11858+ p .nextToken ()
11859+ stmt .SecurityTargetObject .ObjectKind = "Endpoint"
11860+ case "LOGIN" :
11861+ p .nextToken ()
11862+ stmt .SecurityTargetObject .ObjectKind = "Login"
11863+ case "ROLE" :
11864+ p .nextToken ()
11865+ stmt .SecurityTargetObject .ObjectKind = "Role"
11866+ case "ROUTE" :
11867+ p .nextToken ()
11868+ stmt .SecurityTargetObject .ObjectKind = "Route"
11869+ case "SCHEMA" :
11870+ p .nextToken ()
11871+ stmt .SecurityTargetObject .ObjectKind = "Schema"
11872+ case "SERVICE" :
11873+ p .nextToken ()
11874+ stmt .SecurityTargetObject .ObjectKind = "Service"
11875+ case "USER" :
11876+ p .nextToken ()
11877+ stmt .SecurityTargetObject .ObjectKind = "User"
11878+ }
11879+
11880+ // Parse :: if present
11881+ if p .curTok .Type == TokenColonColon {
11882+ p .nextToken ()
11883+ }
11884+
11885+ // Parse object name as multi-part identifier
11886+ if p .curTok .Type == TokenDot || p .curTok .Type == TokenIdent || p .curTok .Type == TokenLBracket {
11887+ stmt .SecurityTargetObject .ObjectName = & ast.SecurityTargetObjectName {}
11888+ multiPart := & ast.MultiPartIdentifier {}
11889+ for {
11890+ if p .curTok .Type == TokenDot {
11891+ multiPart .Identifiers = append (multiPart .Identifiers , & ast.Identifier {
11892+ Value : "" ,
11893+ QuoteType : "NotQuoted" ,
11894+ })
11895+ } else {
11896+ id := p .parseIdentifier ()
11897+ multiPart .Identifiers = append (multiPart .Identifiers , id )
11898+ }
11899+ if p .curTok .Type == TokenDot {
11900+ p .nextToken ()
11901+ } else {
11902+ break
11903+ }
11904+ }
11905+ multiPart .Count = len (multiPart .Identifiers )
11906+ stmt .SecurityTargetObject .ObjectName .MultiPartIdentifier = multiPart
11907+ }
11908+
11909+ // Expect TO
11910+ if p .curTok .Type == TokenTo {
11911+ p .nextToken ()
11912+ }
11913+
11914+ // Check for SCHEMA OWNER or principal name
11915+ if strings .ToUpper (p .curTok .Literal ) == "SCHEMA" {
11916+ p .nextToken () // consume SCHEMA
11917+ if strings .ToUpper (p .curTok .Literal ) == "OWNER" {
11918+ p .nextToken () // consume OWNER
11919+ }
11920+ stmt .ToSchemaOwner = true
11921+ } else {
11922+ // Parse principal name
11923+ stmt .PrincipalName = p .parseIdentifier ()
11924+ }
11925+
11926+ if p .curTok .Type == TokenSemicolon {
11927+ p .nextToken ()
11928+ }
11929+
11930+ return stmt , nil
11931+ }
0 commit comments