@@ -6772,11 +6772,149 @@ func (p *Parser) parseCreateSymmetricKeyStatement() (*ast.CreateSymmetricKeyStat
67726772 Name : p .parseIdentifier (),
67736773 }
67746774
6775+ // Check for FROM PROVIDER clause
6776+ if p .curTok .Type == TokenFrom && strings .ToUpper (p .peekTok .Literal ) == "PROVIDER" {
6777+ p .nextToken () // consume FROM
6778+ p .nextToken () // consume PROVIDER
6779+ stmt .Provider = p .parseIdentifier ()
6780+ }
6781+
6782+ // Check for WITH clause (key options)
6783+ if p .curTok .Type == TokenWith {
6784+ p .nextToken () // consume WITH
6785+ keyOpts , err := p .parseSymmetricKeyOptions ()
6786+ if err != nil {
6787+ return nil , err
6788+ }
6789+ stmt .KeyOptions = keyOpts
6790+ }
6791+
6792+ // Check for ENCRYPTION BY clause
6793+ if strings .ToUpper (p .curTok .Literal ) == "ENCRYPTION" {
6794+ p .nextToken () // consume ENCRYPTION
6795+ if strings .ToUpper (p .curTok .Literal ) == "BY" {
6796+ p .nextToken () // consume BY
6797+ }
6798+ mechanisms , err := p .parseCryptoMechanisms ()
6799+ if err != nil {
6800+ return nil , err
6801+ }
6802+ stmt .EncryptingMechanisms = mechanisms
6803+ }
6804+
67756805 // Skip rest of statement
67766806 p .skipToEndOfStatement ()
67776807 return stmt , nil
67786808}
67796809
6810+ func (p * Parser ) parseSymmetricKeyOptions () ([]ast.KeyOption , error ) {
6811+ var options []ast.KeyOption
6812+
6813+ for {
6814+ optName := strings .ToUpper (p .curTok .Literal )
6815+ switch optName {
6816+ case "PROVIDER_KEY_NAME" :
6817+ p .nextToken () // consume PROVIDER_KEY_NAME
6818+ if p .curTok .Type == TokenEquals {
6819+ p .nextToken () // consume =
6820+ }
6821+ keyName , _ := p .parseScalarExpression ()
6822+ opt := & ast.ProviderKeyNameKeyOption {
6823+ KeyName : keyName ,
6824+ OptionKind : "ProviderKeyName" ,
6825+ }
6826+ options = append (options , opt )
6827+
6828+ case "ALGORITHM" :
6829+ p .nextToken () // consume ALGORITHM
6830+ if p .curTok .Type == TokenEquals {
6831+ p .nextToken () // consume =
6832+ }
6833+ algo := strings .ToUpper (p .curTok .Literal )
6834+ p .nextToken () // consume algorithm name
6835+ opt := & ast.AlgorithmKeyOption {
6836+ Algorithm : algo ,
6837+ OptionKind : "Algorithm" ,
6838+ }
6839+ options = append (options , opt )
6840+
6841+ case "CREATION_DISPOSITION" :
6842+ p .nextToken () // consume CREATION_DISPOSITION
6843+ if p .curTok .Type == TokenEquals {
6844+ p .nextToken () // consume =
6845+ }
6846+ disposition := strings .ToUpper (p .curTok .Literal )
6847+ p .nextToken () // consume CREATE_NEW or OPEN_EXISTING
6848+ opt := & ast.CreationDispositionKeyOption {
6849+ IsCreateNew : disposition == "CREATE_NEW" ,
6850+ OptionKind : "CreationDisposition" ,
6851+ }
6852+ options = append (options , opt )
6853+
6854+ default :
6855+ return options , nil
6856+ }
6857+
6858+ if p .curTok .Type == TokenComma {
6859+ p .nextToken () // consume ,
6860+ } else {
6861+ break
6862+ }
6863+ }
6864+
6865+ return options , nil
6866+ }
6867+
6868+ func (p * Parser ) parseCryptoMechanisms () ([]* ast.CryptoMechanism , error ) {
6869+ var mechanisms []* ast.CryptoMechanism
6870+
6871+ for {
6872+ mechanism := & ast.CryptoMechanism {}
6873+ upperLit := strings .ToUpper (p .curTok .Literal )
6874+
6875+ switch upperLit {
6876+ case "CERTIFICATE" :
6877+ p .nextToken () // consume CERTIFICATE
6878+ mechanism .CryptoMechanismType = "Certificate"
6879+ mechanism .Identifier = p .parseIdentifier ()
6880+ case "SYMMETRIC" :
6881+ p .nextToken () // consume SYMMETRIC
6882+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
6883+ p .nextToken () // consume KEY
6884+ }
6885+ mechanism .CryptoMechanismType = "SymmetricKey"
6886+ mechanism .Identifier = p .parseIdentifier ()
6887+ case "ASYMMETRIC" :
6888+ p .nextToken () // consume ASYMMETRIC
6889+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
6890+ p .nextToken () // consume KEY
6891+ }
6892+ mechanism .CryptoMechanismType = "AsymmetricKey"
6893+ mechanism .Identifier = p .parseIdentifier ()
6894+ case "PASSWORD" :
6895+ p .nextToken () // consume PASSWORD
6896+ if p .curTok .Type == TokenEquals {
6897+ p .nextToken () // consume =
6898+ }
6899+ mechanism .CryptoMechanismType = "Password"
6900+ // Password should be a string literal
6901+ mechanism .PasswordOrSignature , _ = p .parseScalarExpression ()
6902+ default :
6903+ return mechanisms , nil
6904+ }
6905+
6906+ mechanisms = append (mechanisms , mechanism )
6907+
6908+ if p .curTok .Type == TokenComma {
6909+ p .nextToken () // consume ,
6910+ } else {
6911+ break
6912+ }
6913+ }
6914+
6915+ return mechanisms , nil
6916+ }
6917+
67806918func (p * Parser ) parseCreateCertificateStatement () (* ast.CreateCertificateStatement , error ) {
67816919 p .nextToken () // consume CERTIFICATE
67826920
0 commit comments