Skip to content

Commit bdb621a

Browse files
committed
Add CREATE EXTERNAL RESOURCE POOL statement support
- Add CreateExternalResourcePoolStatement AST type - Add parsing for CREATE EXTERNAL RESOURCE POOL with parameters - Support MAX_CPU_PERCENT, MAX_MEMORY_PERCENT, MAX_PROCESSES, AFFINITY - Support AFFINITY CPU/NUMANODE with AUTO or range lists - Add JSON marshaling for the new statement type Enables CreateExternalResourcePoolStatementTests130 tests.
1 parent 2c956b4 commit bdb621a

5 files changed

Lines changed: 180 additions & 3 deletions

File tree

ast/resource_pool_statement.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,18 @@ type LiteralRange struct {
4747
To ScalarExpression `json:"To,omitempty"`
4848
}
4949

50+
// CreateExternalResourcePoolStatement represents a CREATE EXTERNAL RESOURCE POOL statement
51+
type CreateExternalResourcePoolStatement struct {
52+
Name *Identifier `json:"Name,omitempty"`
53+
ExternalResourcePoolParameters []*ExternalResourcePoolParameter `json:"ExternalResourcePoolParameters,omitempty"`
54+
}
55+
56+
func (*CreateExternalResourcePoolStatement) node() {}
57+
func (*CreateExternalResourcePoolStatement) statement() {}
58+
5059
// AlterExternalResourcePoolStatement represents an ALTER EXTERNAL RESOURCE POOL statement
5160
type AlterExternalResourcePoolStatement struct {
52-
Name *Identifier `json:"Name,omitempty"`
61+
Name *Identifier `json:"Name,omitempty"`
5362
ExternalResourcePoolParameters []*ExternalResourcePoolParameter `json:"ExternalResourcePoolParameters,omitempty"`
5463
}
5564

parser/marshal.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ func statementToJSON(stmt ast.Statement) jsonNode {
160160
return dropResourcePoolStatementToJSON(s)
161161
case *ast.AlterExternalResourcePoolStatement:
162162
return alterExternalResourcePoolStatementToJSON(s)
163+
case *ast.CreateExternalResourcePoolStatement:
164+
return createExternalResourcePoolStatementToJSON(s)
163165
case *ast.CreateCryptographicProviderStatement:
164166
return createCryptographicProviderStatementToJSON(s)
165167
case *ast.CreateColumnMasterKeyStatement:
@@ -16388,6 +16390,23 @@ func alterExternalResourcePoolStatementToJSON(s *ast.AlterExternalResourcePoolSt
1638816390
return node
1638916391
}
1639016392

16393+
func createExternalResourcePoolStatementToJSON(s *ast.CreateExternalResourcePoolStatement) jsonNode {
16394+
node := jsonNode{
16395+
"$type": "CreateExternalResourcePoolStatement",
16396+
}
16397+
if s.Name != nil {
16398+
node["Name"] = identifierToJSON(s.Name)
16399+
}
16400+
if len(s.ExternalResourcePoolParameters) > 0 {
16401+
params := make([]jsonNode, len(s.ExternalResourcePoolParameters))
16402+
for i, param := range s.ExternalResourcePoolParameters {
16403+
params[i] = externalResourcePoolParameterToJSON(param)
16404+
}
16405+
node["ExternalResourcePoolParameters"] = params
16406+
}
16407+
return node
16408+
}
16409+
1639116410
func externalResourcePoolParameterToJSON(p *ast.ExternalResourcePoolParameter) jsonNode {
1639216411
node := jsonNode{
1639316412
"$type": "ExternalResourcePoolParameter",

parser/parse_statements.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7890,6 +7890,8 @@ func (p *Parser) parseCreateExternalStatement() (ast.Statement, error) {
78907890
return p.parseCreateExternalLanguageStatement()
78917891
case "LIBRARY":
78927892
return p.parseCreateExternalLibraryStatement()
7893+
case "RESOURCE":
7894+
return p.parseCreateExternalResourcePoolStatement()
78937895
}
78947896
return nil, fmt.Errorf("unexpected token after CREATE EXTERNAL: %s", p.curTok.Literal)
78957897
}
@@ -8488,6 +8490,153 @@ func (p *Parser) parseCreateExternalLibraryStatement() (*ast.CreateExternalLibra
84888490
return stmt, nil
84898491
}
84908492

8493+
func (p *Parser) parseCreateExternalResourcePoolStatement() (*ast.CreateExternalResourcePoolStatement, error) {
8494+
// Consume RESOURCE
8495+
p.nextToken()
8496+
8497+
// Expect POOL
8498+
if strings.ToUpper(p.curTok.Literal) != "POOL" {
8499+
return nil, fmt.Errorf("expected POOL after RESOURCE, got %s", p.curTok.Literal)
8500+
}
8501+
p.nextToken()
8502+
8503+
stmt := &ast.CreateExternalResourcePoolStatement{}
8504+
8505+
// Parse pool name
8506+
stmt.Name = p.parseIdentifier()
8507+
8508+
// Check for optional WITH clause
8509+
if p.curTok.Type == TokenWith || strings.ToUpper(p.curTok.Literal) == "WITH" {
8510+
p.nextToken() // consume WITH
8511+
8512+
// Expect (
8513+
if p.curTok.Type != TokenLParen {
8514+
return nil, fmt.Errorf("expected (, got %s", p.curTok.Literal)
8515+
}
8516+
p.nextToken()
8517+
8518+
// Parse parameters
8519+
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
8520+
paramName := strings.ToUpper(p.curTok.Literal)
8521+
p.nextToken()
8522+
8523+
param := &ast.ExternalResourcePoolParameter{}
8524+
8525+
switch paramName {
8526+
case "MAX_CPU_PERCENT":
8527+
param.ParameterType = "MaxCpuPercent"
8528+
if p.curTok.Type == TokenEquals {
8529+
p.nextToken()
8530+
}
8531+
val, err := p.parseScalarExpression()
8532+
if err != nil {
8533+
return nil, err
8534+
}
8535+
param.ParameterValue = val
8536+
case "MAX_MEMORY_PERCENT":
8537+
param.ParameterType = "MaxMemoryPercent"
8538+
if p.curTok.Type == TokenEquals {
8539+
p.nextToken()
8540+
}
8541+
val, err := p.parseScalarExpression()
8542+
if err != nil {
8543+
return nil, err
8544+
}
8545+
param.ParameterValue = val
8546+
case "MAX_PROCESSES":
8547+
param.ParameterType = "MaxProcesses"
8548+
if p.curTok.Type == TokenEquals {
8549+
p.nextToken()
8550+
}
8551+
val, err := p.parseScalarExpression()
8552+
if err != nil {
8553+
return nil, err
8554+
}
8555+
param.ParameterValue = val
8556+
case "AFFINITY":
8557+
param.ParameterType = "Affinity"
8558+
affinitySpec := &ast.ExternalResourcePoolAffinitySpecification{}
8559+
8560+
// Parse CPU or NUMANODE
8561+
affinityType := strings.ToUpper(p.curTok.Literal)
8562+
p.nextToken()
8563+
if affinityType == "CPU" {
8564+
affinitySpec.AffinityType = "Cpu"
8565+
} else if affinityType == "NUMANODE" {
8566+
affinitySpec.AffinityType = "NumaNode"
8567+
}
8568+
8569+
// Expect =
8570+
if p.curTok.Type == TokenEquals {
8571+
p.nextToken()
8572+
}
8573+
8574+
// Check for AUTO or range list
8575+
if strings.ToUpper(p.curTok.Literal) == "AUTO" {
8576+
affinitySpec.IsAuto = true
8577+
p.nextToken()
8578+
} else {
8579+
// Parse range list: (1) or (1 TO 5, 6 TO 7)
8580+
if p.curTok.Type == TokenLParen {
8581+
p.nextToken()
8582+
}
8583+
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
8584+
fromVal, err := p.parseScalarExpression()
8585+
if err != nil {
8586+
return nil, err
8587+
}
8588+
rangeItem := &ast.LiteralRange{From: fromVal}
8589+
8590+
// Check for TO
8591+
if strings.ToUpper(p.curTok.Literal) == "TO" {
8592+
p.nextToken()
8593+
toVal, err := p.parseScalarExpression()
8594+
if err != nil {
8595+
return nil, err
8596+
}
8597+
rangeItem.To = toVal
8598+
}
8599+
8600+
affinitySpec.PoolAffinityRanges = append(affinitySpec.PoolAffinityRanges, rangeItem)
8601+
8602+
// Check for comma
8603+
if p.curTok.Type == TokenComma {
8604+
p.nextToken()
8605+
} else {
8606+
break
8607+
}
8608+
}
8609+
if p.curTok.Type == TokenRParen {
8610+
p.nextToken()
8611+
}
8612+
}
8613+
param.AffinitySpecification = affinitySpec
8614+
}
8615+
8616+
stmt.ExternalResourcePoolParameters = append(stmt.ExternalResourcePoolParameters, param)
8617+
8618+
// Check for comma
8619+
if p.curTok.Type == TokenComma {
8620+
p.nextToken()
8621+
} else {
8622+
break
8623+
}
8624+
}
8625+
8626+
// Consume )
8627+
if p.curTok.Type == TokenRParen {
8628+
p.nextToken()
8629+
}
8630+
}
8631+
8632+
// Skip optional semicolon
8633+
if p.curTok.Type == TokenSemicolon {
8634+
p.nextToken()
8635+
}
8636+
8637+
return stmt, nil
8638+
}
8639+
84918640
func (p *Parser) parseCreateEventSessionStatement() (*ast.CreateEventSessionStatement, error) {
84928641
p.nextToken() // consume EVENT
84938642
if strings.ToUpper(p.curTok.Literal) != "SESSION" {
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)