Skip to content

Commit 66f9ed5

Browse files
committed
Add SPARSE/FILESTREAM column storage options parsing
- Add ColumnStorageOptions struct to AST with IsFileStream and SparseOption - Add StorageOptions field to ColumnDefinition - Parse SPARSE, FILESTREAM, COLUMN_SET FOR ALL_SPARSE_COLUMNS in column definitions - Also parse ROWGUIDCOL, HIDDEN, MASKED column attributes - Add columnStorageOptionsToJSON for marshalling Enables 2 tests: ColumnDefinitionTests100, Baselines100_ColumnDefinitionTests100
1 parent 4fcb35e commit 66f9ed5

4 files changed

Lines changed: 76 additions & 2 deletions

File tree

ast/create_table_statement.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,19 @@ type ColumnDefinition struct {
4949
IsHidden bool
5050
IsMasked bool
5151
Nullable *NullableConstraintDefinition
52+
StorageOptions *ColumnStorageOptions
5253
}
5354

5455
func (c *ColumnDefinition) node() {}
5556

57+
// ColumnStorageOptions represents storage options for a column (SPARSE, FILESTREAM)
58+
type ColumnStorageOptions struct {
59+
IsFileStream bool // true if FILESTREAM specified
60+
SparseOption string // "None", "Sparse", "ColumnSetForAllSparseColumns"
61+
}
62+
63+
func (c *ColumnStorageOptions) node() {}
64+
5665
// DataTypeReference is an interface for data type references
5766
type DataTypeReference interface {
5867
Node

parser/marshal.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3570,6 +3570,56 @@ func (p *Parser) parseColumnDefinition() (*ast.ColumnDefinition, error) {
35703570
indexDef.Name = p.parseIdentifier()
35713571
}
35723572
col.Index = indexDef
3573+
} else if upperLit == "SPARSE" {
3574+
p.nextToken() // consume SPARSE
3575+
if col.StorageOptions == nil {
3576+
col.StorageOptions = &ast.ColumnStorageOptions{}
3577+
}
3578+
col.StorageOptions.SparseOption = "Sparse"
3579+
} else if upperLit == "FILESTREAM" {
3580+
p.nextToken() // consume FILESTREAM
3581+
if col.StorageOptions == nil {
3582+
col.StorageOptions = &ast.ColumnStorageOptions{}
3583+
}
3584+
col.StorageOptions.IsFileStream = true
3585+
} else if upperLit == "COLUMN_SET" {
3586+
p.nextToken() // consume COLUMN_SET
3587+
// Expect FOR ALL_SPARSE_COLUMNS
3588+
if strings.ToUpper(p.curTok.Literal) == "FOR" {
3589+
p.nextToken() // consume FOR
3590+
if strings.ToUpper(p.curTok.Literal) == "ALL_SPARSE_COLUMNS" {
3591+
p.nextToken() // consume ALL_SPARSE_COLUMNS
3592+
if col.StorageOptions == nil {
3593+
col.StorageOptions = &ast.ColumnStorageOptions{}
3594+
}
3595+
col.StorageOptions.SparseOption = "ColumnSetForAllSparseColumns"
3596+
}
3597+
}
3598+
} else if upperLit == "ROWGUIDCOL" {
3599+
p.nextToken() // consume ROWGUIDCOL
3600+
col.IsRowGuidCol = true
3601+
} else if upperLit == "HIDDEN" {
3602+
p.nextToken() // consume HIDDEN
3603+
col.IsHidden = true
3604+
} else if upperLit == "MASKED" {
3605+
p.nextToken() // consume MASKED
3606+
col.IsMasked = true
3607+
// Skip optional WITH clause
3608+
if strings.ToUpper(p.curTok.Literal) == "WITH" {
3609+
p.nextToken()
3610+
if p.curTok.Type == TokenLParen {
3611+
depth := 1
3612+
p.nextToken()
3613+
for depth > 0 && p.curTok.Type != TokenEOF {
3614+
if p.curTok.Type == TokenLParen {
3615+
depth++
3616+
} else if p.curTok.Type == TokenRParen {
3617+
depth--
3618+
}
3619+
p.nextToken()
3620+
}
3621+
}
3622+
}
35733623
} else {
35743624
break
35753625
}
@@ -4847,6 +4897,9 @@ func columnDefinitionToJSON(c *ast.ColumnDefinition) jsonNode {
48474897
"IsMasked": c.IsMasked,
48484898
"ColumnIdentifier": identifierToJSON(c.ColumnIdentifier),
48494899
}
4900+
if c.StorageOptions != nil {
4901+
node["StorageOptions"] = columnStorageOptionsToJSON(c.StorageOptions)
4902+
}
48504903
if c.ComputedColumnExpression != nil {
48514904
node["ComputedColumnExpression"] = scalarExpressionToJSON(c.ComputedColumnExpression)
48524905
}
@@ -4875,6 +4928,18 @@ func columnDefinitionToJSON(c *ast.ColumnDefinition) jsonNode {
48754928
return node
48764929
}
48774930

4931+
func columnStorageOptionsToJSON(o *ast.ColumnStorageOptions) jsonNode {
4932+
sparseOption := o.SparseOption
4933+
if sparseOption == "" {
4934+
sparseOption = "None"
4935+
}
4936+
return jsonNode{
4937+
"$type": "ColumnStorageOptions",
4938+
"IsFileStream": o.IsFileStream,
4939+
"SparseOption": sparseOption,
4940+
}
4941+
}
4942+
48784943
func defaultConstraintToJSON(d *ast.DefaultConstraintDefinition) jsonNode {
48794944
node := jsonNode{
48804945
"$type": "DefaultConstraintDefinition",
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)