@@ -160,6 +160,8 @@ func (p *Parser) parseDropStatement() (ast.Statement, error) {
160160 return p .parseDropServiceStatement ()
161161 case "EVENT" :
162162 return p .parseDropEventNotificationStatement ()
163+ case "COLUMN" :
164+ return p .parseDropColumnStatement ()
163165 }
164166
165167 // Handle LOGIN token explicitly
@@ -2275,6 +2277,42 @@ func (p *Parser) parseDropMasterKeyStatement() (*ast.DropMasterKeyStatement, err
22752277 return stmt , nil
22762278}
22772279
2280+ func (p * Parser ) parseDropColumnStatement () (ast.Statement , error ) {
2281+ // Consume COLUMN
2282+ p .nextToken ()
2283+
2284+ keyword := strings .ToUpper (p .curTok .Literal )
2285+ p .nextToken () // consume MASTER or ENCRYPTION
2286+
2287+ if keyword == "MASTER" {
2288+ // DROP COLUMN MASTER KEY
2289+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
2290+ p .nextToken () // consume KEY
2291+ }
2292+ stmt := & ast.DropColumnMasterKeyStatement {
2293+ Name : p .parseIdentifier (),
2294+ }
2295+ if p .curTok .Type == TokenSemicolon {
2296+ p .nextToken ()
2297+ }
2298+ return stmt , nil
2299+ } else if keyword == "ENCRYPTION" {
2300+ // DROP COLUMN ENCRYPTION KEY
2301+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
2302+ p .nextToken () // consume KEY
2303+ }
2304+ stmt := & ast.DropColumnEncryptionKeyStatement {
2305+ Name : p .parseIdentifier (),
2306+ }
2307+ if p .curTok .Type == TokenSemicolon {
2308+ p .nextToken ()
2309+ }
2310+ return stmt , nil
2311+ }
2312+
2313+ return nil , fmt .Errorf ("unexpected token after DROP COLUMN: expected MASTER or ENCRYPTION, got %s" , keyword )
2314+ }
2315+
22782316func (p * Parser ) parseDropXmlSchemaCollectionStatement () (* ast.DropXmlSchemaCollectionStatement , error ) {
22792317 // Consume XML
22802318 p .nextToken ()
@@ -2621,6 +2659,8 @@ func (p *Parser) parseAlterStatement() (ast.Statement, error) {
26212659 return p .parseAlterEventSessionStatement ()
26222660 case "SECURITY" :
26232661 return p .parseAlterSecurityPolicyStatement ()
2662+ case "COLUMN" :
2663+ return p .parseAlterColumnEncryptionKeyStatement ()
26242664 }
26252665 return nil , fmt .Errorf ("unexpected token after ALTER: %s" , p .curTok .Literal )
26262666 default :
@@ -12704,3 +12744,97 @@ func (p *Parser) parseAlterAuthorizationStatement() (*ast.AlterAuthorizationStat
1270412744
1270512745 return stmt , nil
1270612746}
12747+
12748+ func (p * Parser ) parseAlterColumnEncryptionKeyStatement () (ast.Statement , error ) {
12749+ // ALTER COLUMN ENCRYPTION KEY name ADD|DROP VALUE (...)
12750+ // Currently on COLUMN
12751+ p .nextToken () // consume COLUMN
12752+
12753+ if strings .ToUpper (p .curTok .Literal ) != "ENCRYPTION" {
12754+ return nil , fmt .Errorf ("expected ENCRYPTION after COLUMN, got %s" , p .curTok .Literal )
12755+ }
12756+ p .nextToken () // consume ENCRYPTION
12757+
12758+ if strings .ToUpper (p .curTok .Literal ) != "KEY" {
12759+ return nil , fmt .Errorf ("expected KEY after ENCRYPTION, got %s" , p .curTok .Literal )
12760+ }
12761+ p .nextToken () // consume KEY
12762+
12763+ stmt := & ast.AlterColumnEncryptionKeyStatement {}
12764+
12765+ // Parse key name
12766+ stmt .Name = p .parseIdentifier ()
12767+
12768+ // Parse ADD VALUE or DROP VALUE
12769+ keyword := strings .ToUpper (p .curTok .Literal )
12770+ if keyword == "ADD" {
12771+ stmt .AlterType = "Add"
12772+ p .nextToken () // consume ADD
12773+ } else if keyword == "DROP" {
12774+ stmt .AlterType = "Drop"
12775+ p .nextToken () // consume DROP
12776+ } else {
12777+ return nil , fmt .Errorf ("expected ADD or DROP, got %s" , p .curTok .Literal )
12778+ }
12779+
12780+ if strings .ToUpper (p .curTok .Literal ) == "VALUE" {
12781+ p .nextToken () // consume VALUE
12782+ }
12783+
12784+ // Parse the value - enclosed in ( ... )
12785+ if p .curTok .Type == TokenLParen {
12786+ value := & ast.ColumnEncryptionKeyValue {}
12787+ p .nextToken () // consume (
12788+
12789+ // Parse parameters
12790+ for p .curTok .Type != TokenRParen && p .curTok .Type != TokenEOF {
12791+ paramName := strings .ToUpper (p .curTok .Literal )
12792+ p .nextToken () // consume parameter name
12793+
12794+ if p .curTok .Type == TokenEquals {
12795+ p .nextToken () // consume =
12796+ }
12797+
12798+ switch paramName {
12799+ case "COLUMN_MASTER_KEY" :
12800+ value .Parameters = append (value .Parameters , & ast.ColumnMasterKeyNameParameter {
12801+ Name : p .parseIdentifier (),
12802+ ParameterKind : "ColumnMasterKeyName" ,
12803+ })
12804+ case "ALGORITHM" :
12805+ expr , _ := p .parseScalarExpression ()
12806+ value .Parameters = append (value .Parameters , & ast.ColumnEncryptionAlgorithmNameParameter {
12807+ Algorithm : expr ,
12808+ ParameterKind : "EncryptionAlgorithmName" ,
12809+ })
12810+ case "ENCRYPTED_VALUE" :
12811+ expr , _ := p .parseScalarExpression ()
12812+ value .Parameters = append (value .Parameters , & ast.EncryptedValueParameter {
12813+ Value : expr ,
12814+ ParameterKind : "EncryptedValue" ,
12815+ })
12816+ default :
12817+ // Skip unknown parameter
12818+ p .nextToken ()
12819+ }
12820+
12821+ // Skip comma if present
12822+ if p .curTok .Type == TokenComma {
12823+ p .nextToken ()
12824+ }
12825+ }
12826+
12827+ // Consume closing )
12828+ if p .curTok .Type == TokenRParen {
12829+ p .nextToken ()
12830+ }
12831+
12832+ stmt .ColumnEncryptionKeyValues = append (stmt .ColumnEncryptionKeyValues , value )
12833+ }
12834+
12835+ if p .curTok .Type == TokenSemicolon {
12836+ p .nextToken ()
12837+ }
12838+
12839+ return stmt , nil
12840+ }
0 commit comments