@@ -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+
18311922func (p * Parser ) parseAlterServerConfigurationSetProcessAffinityStatement () (* ast.AlterServerConfigurationStatement , error ) {
18321923 // Consume PROCESS
18331924 p .nextToken ()
0 commit comments