Skip to content

Commit 269492f

Browse files
committed
Add XML_COMPRESSION table option support (partial progress)
- Add XmlCompressionOption and TableXmlCompressionOption types - Add XML_COMPRESSION parsing in CREATE TABLE WITH clause - Add partition ranges support for XML compression Part of work towards CreateTableTests160
1 parent bed1118 commit 269492f

2 files changed

Lines changed: 121 additions & 0 deletions

File tree

ast/xml_compression_option.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ast
2+
3+
// XmlCompressionOption represents an XML compression option
4+
type XmlCompressionOption struct {
5+
IsCompressed string // "On", "Off"
6+
PartitionRanges []*CompressionPartitionRange
7+
OptionKind string // "XmlCompression"
8+
}
9+
10+
func (x *XmlCompressionOption) node() {}
11+
func (x *XmlCompressionOption) tableOption() {}
12+
13+
// TableXmlCompressionOption represents a table-level XML compression option
14+
type TableXmlCompressionOption struct {
15+
XmlCompressionOption *XmlCompressionOption
16+
OptionKind string // "XmlCompression"
17+
}
18+
19+
func (t *TableXmlCompressionOption) node() {}
20+
func (t *TableXmlCompressionOption) tableOption() {}

parser/marshal.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4509,6 +4509,18 @@ func (p *Parser) parseCreateTableStatement() (*ast.CreateTableStatement, error)
45094509
DataCompressionOption: opt,
45104510
OptionKind: "DataCompression",
45114511
})
4512+
} else if optionName == "XML_COMPRESSION" {
4513+
if p.curTok.Type == TokenEquals {
4514+
p.nextToken() // consume =
4515+
}
4516+
opt, err := p.parseXmlCompressionOption()
4517+
if err != nil {
4518+
break
4519+
}
4520+
stmt.Options = append(stmt.Options, &ast.TableXmlCompressionOption{
4521+
XmlCompressionOption: opt,
4522+
OptionKind: "XmlCompression",
4523+
})
45124524
} else if optionName == "MEMORY_OPTIMIZED" {
45134525
if p.curTok.Type == TokenEquals {
45144526
p.nextToken() // consume =
@@ -5382,6 +5394,70 @@ func (p *Parser) parseDataCompressionOption() (*ast.DataCompressionOption, error
53825394
return opt, nil
53835395
}
53845396

5397+
func (p *Parser) parseXmlCompressionOption() (*ast.XmlCompressionOption, error) {
5398+
opt := &ast.XmlCompressionOption{
5399+
OptionKind: "XmlCompression",
5400+
}
5401+
5402+
// Parse ON or OFF
5403+
levelStr := strings.ToUpper(p.curTok.Literal)
5404+
if levelStr == "ON" {
5405+
opt.IsCompressed = "On"
5406+
} else {
5407+
opt.IsCompressed = "Off"
5408+
}
5409+
p.nextToken()
5410+
5411+
// Parse optional ON PARTITIONS clause
5412+
if p.curTok.Type == TokenOn {
5413+
p.nextToken() // consume ON
5414+
if strings.ToUpper(p.curTok.Literal) == "PARTITIONS" {
5415+
p.nextToken() // consume PARTITIONS
5416+
if p.curTok.Type == TokenLParen {
5417+
p.nextToken() // consume (
5418+
// Parse partition ranges
5419+
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
5420+
pr := &ast.CompressionPartitionRange{}
5421+
5422+
// Parse From
5423+
if p.curTok.Type == TokenNumber {
5424+
pr.From = &ast.IntegerLiteral{
5425+
LiteralType: "Integer",
5426+
Value: p.curTok.Literal,
5427+
}
5428+
p.nextToken()
5429+
}
5430+
5431+
// Check for TO
5432+
if strings.ToUpper(p.curTok.Literal) == "TO" {
5433+
p.nextToken() // consume TO
5434+
if p.curTok.Type == TokenNumber {
5435+
pr.To = &ast.IntegerLiteral{
5436+
LiteralType: "Integer",
5437+
Value: p.curTok.Literal,
5438+
}
5439+
p.nextToken()
5440+
}
5441+
}
5442+
5443+
opt.PartitionRanges = append(opt.PartitionRanges, pr)
5444+
5445+
if p.curTok.Type == TokenComma {
5446+
p.nextToken()
5447+
} else {
5448+
break
5449+
}
5450+
}
5451+
if p.curTok.Type == TokenRParen {
5452+
p.nextToken()
5453+
}
5454+
}
5455+
}
5456+
}
5457+
5458+
return opt, nil
5459+
}
5460+
53855461
func (p *Parser) parseColumnDefinition() (*ast.ColumnDefinition, error) {
53865462
col := &ast.ColumnDefinition{}
53875463

@@ -7338,6 +7414,15 @@ func tableOptionToJSON(opt ast.TableOption) jsonNode {
73387414
node["DataCompressionOption"] = dataCompressionOptionToJSON(o.DataCompressionOption)
73397415
}
73407416
return node
7417+
case *ast.TableXmlCompressionOption:
7418+
node := jsonNode{
7419+
"$type": "TableXmlCompressionOption",
7420+
"OptionKind": o.OptionKind,
7421+
}
7422+
if o.XmlCompressionOption != nil {
7423+
node["XmlCompressionOption"] = xmlCompressionOptionToJSON(o.XmlCompressionOption)
7424+
}
7425+
return node
73417426
case *ast.SystemVersioningTableOption:
73427427
return systemVersioningTableOptionToJSON(o)
73437428
case *ast.MemoryOptimizedTableOption:
@@ -7439,6 +7524,22 @@ func dataCompressionOptionToJSON(opt *ast.DataCompressionOption) jsonNode {
74397524
return node
74407525
}
74417526

7527+
func xmlCompressionOptionToJSON(opt *ast.XmlCompressionOption) jsonNode {
7528+
node := jsonNode{
7529+
"$type": "XmlCompressionOption",
7530+
"IsCompressed": opt.IsCompressed,
7531+
"OptionKind": opt.OptionKind,
7532+
}
7533+
if len(opt.PartitionRanges) > 0 {
7534+
ranges := make([]jsonNode, len(opt.PartitionRanges))
7535+
for i, pr := range opt.PartitionRanges {
7536+
ranges[i] = compressionPartitionRangeToJSON(pr)
7537+
}
7538+
node["PartitionRanges"] = ranges
7539+
}
7540+
return node
7541+
}
7542+
74427543
func compressionPartitionRangeToJSON(pr *ast.CompressionPartitionRange) jsonNode {
74437544
node := jsonNode{
74447545
"$type": "CompressionPartitionRange",

0 commit comments

Comments
 (0)