Skip to content

Commit 5074d21

Browse files
authored
Add ALTER SERVER CONFIGURATION SET EXTERNAL AUTHENTICATION support (#36)
1 parent c28d1d3 commit 5074d21

File tree

5 files changed

+180
-2
lines changed

5 files changed

+180
-2
lines changed

ast/alter_server_configuration_statement.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,35 @@ type OnOffOptionValue struct {
3939
}
4040

4141
func (o *OnOffOptionValue) node() {}
42+
43+
// AlterServerConfigurationSetExternalAuthenticationStatement represents ALTER SERVER CONFIGURATION SET EXTERNAL AUTHENTICATION statement
44+
type AlterServerConfigurationSetExternalAuthenticationStatement struct {
45+
Options []*AlterServerConfigurationExternalAuthenticationContainerOption
46+
}
47+
48+
func (a *AlterServerConfigurationSetExternalAuthenticationStatement) node() {}
49+
func (a *AlterServerConfigurationSetExternalAuthenticationStatement) statement() {}
50+
51+
// AlterServerConfigurationExternalAuthenticationContainerOption represents the container option for external authentication
52+
type AlterServerConfigurationExternalAuthenticationContainerOption struct {
53+
OptionKind string // "OnOff"
54+
OptionValue *OnOffOptionValue // ON or OFF
55+
Suboptions []*AlterServerConfigurationExternalAuthenticationOption // suboptions inside parentheses
56+
}
57+
58+
func (a *AlterServerConfigurationExternalAuthenticationContainerOption) node() {}
59+
60+
// AlterServerConfigurationExternalAuthenticationOption represents an external authentication suboption
61+
type AlterServerConfigurationExternalAuthenticationOption struct {
62+
OptionKind string // "UseIdentity", "CredentialName"
63+
OptionValue *LiteralOptionValue // optional, for CredentialName
64+
}
65+
66+
func (a *AlterServerConfigurationExternalAuthenticationOption) node() {}
67+
68+
// LiteralOptionValue represents a literal option value
69+
type LiteralOptionValue struct {
70+
Value ScalarExpression
71+
}
72+
73+
func (l *LiteralOptionValue) node() {}

parser/marshal.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ func statementToJSON(stmt ast.Statement) jsonNode {
288288
return alterXmlSchemaCollectionStatementToJSON(s)
289289
case *ast.AlterServerConfigurationSetSoftNumaStatement:
290290
return alterServerConfigurationSetSoftNumaStatementToJSON(s)
291+
case *ast.AlterServerConfigurationSetExternalAuthenticationStatement:
292+
return alterServerConfigurationSetExternalAuthenticationStatementToJSON(s)
291293
case *ast.AlterServerConfigurationStatement:
292294
return alterServerConfigurationStatementToJSON(s)
293295
case *ast.AlterLoginAddDropCredentialStatement:
@@ -3578,6 +3580,59 @@ func onOffOptionValueToJSON(o *ast.OnOffOptionValue) jsonNode {
35783580
}
35793581
}
35803582

3583+
func alterServerConfigurationSetExternalAuthenticationStatementToJSON(s *ast.AlterServerConfigurationSetExternalAuthenticationStatement) jsonNode {
3584+
node := jsonNode{
3585+
"$type": "AlterServerConfigurationSetExternalAuthenticationStatement",
3586+
}
3587+
if len(s.Options) > 0 {
3588+
options := make([]jsonNode, len(s.Options))
3589+
for i, o := range s.Options {
3590+
options[i] = alterServerConfigurationExternalAuthenticationContainerOptionToJSON(o)
3591+
}
3592+
node["Options"] = options
3593+
}
3594+
return node
3595+
}
3596+
3597+
func alterServerConfigurationExternalAuthenticationContainerOptionToJSON(o *ast.AlterServerConfigurationExternalAuthenticationContainerOption) jsonNode {
3598+
node := jsonNode{
3599+
"$type": "AlterServerConfigurationExternalAuthenticationContainerOption",
3600+
}
3601+
if len(o.Suboptions) > 0 {
3602+
suboptions := make([]jsonNode, len(o.Suboptions))
3603+
for i, s := range o.Suboptions {
3604+
suboptions[i] = alterServerConfigurationExternalAuthenticationOptionToJSON(s)
3605+
}
3606+
node["Suboptions"] = suboptions
3607+
}
3608+
node["OptionKind"] = o.OptionKind
3609+
if o.OptionValue != nil {
3610+
node["OptionValue"] = onOffOptionValueToJSON(o.OptionValue)
3611+
}
3612+
return node
3613+
}
3614+
3615+
func alterServerConfigurationExternalAuthenticationOptionToJSON(o *ast.AlterServerConfigurationExternalAuthenticationOption) jsonNode {
3616+
node := jsonNode{
3617+
"$type": "AlterServerConfigurationExternalAuthenticationOption",
3618+
"OptionKind": o.OptionKind,
3619+
}
3620+
if o.OptionValue != nil {
3621+
node["OptionValue"] = literalOptionValueToJSON(o.OptionValue)
3622+
}
3623+
return node
3624+
}
3625+
3626+
func literalOptionValueToJSON(o *ast.LiteralOptionValue) jsonNode {
3627+
node := jsonNode{
3628+
"$type": "LiteralOptionValue",
3629+
}
3630+
if o.Value != nil {
3631+
node["Value"] = scalarExpressionToJSON(o.Value)
3632+
}
3633+
return node
3634+
}
3635+
35813636
func alterServerConfigurationStatementToJSON(s *ast.AlterServerConfigurationStatement) jsonNode {
35823637
node := jsonNode{
35833638
"$type": "AlterServerConfigurationStatement",

parser/parse_ddl.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,6 +1794,8 @@ func (p *Parser) parseAlterServerConfigurationStatement() (ast.Statement, error)
17941794
return p.parseAlterServerConfigurationSetSoftNumaStatement()
17951795
case "PROCESS":
17961796
return p.parseAlterServerConfigurationSetProcessAffinityStatement()
1797+
case "EXTERNAL":
1798+
return p.parseAlterServerConfigurationSetExternalAuthenticationStatement()
17971799
default:
17981800
return nil, fmt.Errorf("unexpected token after SET: %s", p.curTok.Literal)
17991801
}
@@ -1828,6 +1830,95 @@ func (p *Parser) parseAlterServerConfigurationSetSoftNumaStatement() (*ast.Alter
18281830
return stmt, nil
18291831
}
18301832

1833+
func (p *Parser) parseAlterServerConfigurationSetExternalAuthenticationStatement() (*ast.AlterServerConfigurationSetExternalAuthenticationStatement, error) {
1834+
// Consume EXTERNAL
1835+
p.nextToken()
1836+
1837+
// Expect AUTHENTICATION
1838+
if strings.ToUpper(p.curTok.Literal) != "AUTHENTICATION" {
1839+
return nil, fmt.Errorf("expected AUTHENTICATION after EXTERNAL, got %s", p.curTok.Literal)
1840+
}
1841+
p.nextToken()
1842+
1843+
stmt := &ast.AlterServerConfigurationSetExternalAuthenticationStatement{}
1844+
1845+
// Parse ON or OFF
1846+
optionState := strings.ToUpper(p.curTok.Literal)
1847+
if optionState != "ON" && optionState != "OFF" {
1848+
return nil, fmt.Errorf("expected ON or OFF after AUTHENTICATION, got %s", p.curTok.Literal)
1849+
}
1850+
p.nextToken()
1851+
1852+
containerOption := &ast.AlterServerConfigurationExternalAuthenticationContainerOption{
1853+
OptionKind: "OnOff",
1854+
OptionValue: &ast.OnOffOptionValue{
1855+
OptionState: capitalizeFirst(optionState),
1856+
},
1857+
}
1858+
1859+
// Check for suboptions in parentheses (only for ON)
1860+
if optionState == "ON" && p.curTok.Type == TokenLParen {
1861+
p.nextToken() // consume (
1862+
1863+
// Parse suboptions
1864+
for {
1865+
suboption := &ast.AlterServerConfigurationExternalAuthenticationOption{}
1866+
1867+
optionName := strings.ToUpper(p.curTok.Literal)
1868+
switch optionName {
1869+
case "USE_IDENTITY":
1870+
suboption.OptionKind = "UseIdentity"
1871+
p.nextToken()
1872+
case "CREDENTIAL_NAME":
1873+
suboption.OptionKind = "CredentialName"
1874+
p.nextToken()
1875+
1876+
// Expect =
1877+
if p.curTok.Type != TokenEquals {
1878+
return nil, fmt.Errorf("expected = after CREDENTIAL_NAME, got %s", p.curTok.Literal)
1879+
}
1880+
p.nextToken()
1881+
1882+
// Parse string literal
1883+
if p.curTok.Type != TokenString {
1884+
return nil, fmt.Errorf("expected string literal for CREDENTIAL_NAME value, got %s", p.curTok.Literal)
1885+
}
1886+
strLit, err := p.parseStringLiteral()
1887+
if err != nil {
1888+
return nil, err
1889+
}
1890+
suboption.OptionValue = &ast.LiteralOptionValue{
1891+
Value: strLit,
1892+
}
1893+
default:
1894+
return nil, fmt.Errorf("unexpected option in EXTERNAL AUTHENTICATION: %s", p.curTok.Literal)
1895+
}
1896+
1897+
containerOption.Suboptions = append(containerOption.Suboptions, suboption)
1898+
1899+
// Check for comma or closing paren
1900+
if p.curTok.Type == TokenComma {
1901+
p.nextToken()
1902+
continue
1903+
}
1904+
if p.curTok.Type == TokenRParen {
1905+
p.nextToken()
1906+
break
1907+
}
1908+
return nil, fmt.Errorf("expected , or ) in EXTERNAL AUTHENTICATION options, got %s", p.curTok.Literal)
1909+
}
1910+
}
1911+
1912+
stmt.Options = append(stmt.Options, containerOption)
1913+
1914+
// Skip optional semicolon
1915+
if p.curTok.Type == TokenSemicolon {
1916+
p.nextToken()
1917+
}
1918+
1919+
return stmt, nil
1920+
}
1921+
18311922
func (p *Parser) parseAlterServerConfigurationSetProcessAffinityStatement() (*ast.AlterServerConfigurationStatement, error) {
18321923
// Consume PROCESS
18331924
p.nextToken()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}

0 commit comments

Comments
 (0)