@@ -4742,11 +4742,96 @@ func (p *Parser) parseCreateApplicationRoleStatement() (*ast.CreateApplicationRo
47424742 Name : p .parseIdentifier (),
47434743 }
47444744
4745- // Skip rest of statement
4746- p .skipToEndOfStatement ()
4745+ // Optional WITH clause
4746+ if p .curTok .Type == TokenWith {
4747+ p .nextToken ()
4748+ opts , err := p .parseApplicationRoleOptions ()
4749+ if err != nil {
4750+ return nil , err
4751+ }
4752+ stmt .ApplicationRoleOptions = opts
4753+ }
4754+
4755+ // Skip optional semicolon
4756+ if p .curTok .Type == TokenSemicolon {
4757+ p .nextToken ()
4758+ }
4759+
47474760 return stmt , nil
47484761}
47494762
4763+ func (p * Parser ) parseApplicationRoleOptions () ([]* ast.ApplicationRoleOption , error ) {
4764+ var options []* ast.ApplicationRoleOption
4765+
4766+ for {
4767+ optionName := strings .ToUpper (p .curTok .Literal )
4768+ p .nextToken ()
4769+
4770+ // Expect =
4771+ if p .curTok .Type != TokenEquals {
4772+ return nil , fmt .Errorf ("expected = after %s, got %s" , optionName , p .curTok .Literal )
4773+ }
4774+ p .nextToken ()
4775+
4776+ opt := & ast.ApplicationRoleOption {}
4777+
4778+ switch optionName {
4779+ case "PASSWORD" :
4780+ opt .OptionKind = "Password"
4781+ // Parse string literal
4782+ if p .curTok .Type == TokenString {
4783+ val := p .curTok .Literal
4784+ // Strip quotes from string literal
4785+ if len (val ) >= 2 && (val [0 ] == '\'' && val [len (val )- 1 ] == '\'' ) {
4786+ val = val [1 : len (val )- 1 ]
4787+ }
4788+ opt .Value = & ast.IdentifierOrValueExpression {
4789+ Value : val ,
4790+ ValueExpression : & ast.StringLiteral {
4791+ Value : val ,
4792+ LiteralType : "String" ,
4793+ },
4794+ }
4795+ p .nextToken ()
4796+ }
4797+ case "DEFAULT_SCHEMA" :
4798+ opt .OptionKind = "DefaultSchema"
4799+ // Parse identifier
4800+ id := p .parseIdentifier ()
4801+ opt .Value = & ast.IdentifierOrValueExpression {
4802+ Value : id .Value ,
4803+ Identifier : id ,
4804+ }
4805+ case "NAME" :
4806+ opt .OptionKind = "Name"
4807+ id := p .parseIdentifier ()
4808+ opt .Value = & ast.IdentifierOrValueExpression {
4809+ Value : id .Value ,
4810+ Identifier : id ,
4811+ }
4812+ case "LOGIN" :
4813+ opt .OptionKind = "Login"
4814+ id := p .parseIdentifier ()
4815+ opt .Value = & ast.IdentifierOrValueExpression {
4816+ Value : id .Value ,
4817+ Identifier : id ,
4818+ }
4819+ default :
4820+ // Unknown option, skip
4821+ p .nextToken ()
4822+ }
4823+
4824+ options = append (options , opt )
4825+
4826+ if p .curTok .Type != TokenComma {
4827+ break
4828+ }
4829+ p .nextToken () // consume comma
4830+ }
4831+
4832+ return options , nil
4833+ }
4834+
47504835func (p * Parser ) parseCreateFulltextStatement () (ast.Statement , error ) {
47514836 p .nextToken () // consume FULLTEXT
47524837
0 commit comments