@@ -5759,8 +5759,8 @@ func (p *Parser) parseCreateColumnStoreIndexStatement() (*ast.CreateColumnStoreI
57595759 }
57605760 }
57615761
5762- // Parse optional ORDER clause
5763- if strings .ToUpper (p .curTok .Literal ) == "ORDER" {
5762+ // Parse optional ORDER clause (Azure Synapse/DW syntax - ORDER directly after ON table)
5763+ if p . curTok . Type == TokenOrder || strings .ToUpper (p .curTok .Literal ) == "ORDER" {
57645764 p .nextToken () // consume ORDER
57655765 if p .curTok .Type == TokenLParen {
57665766 p .nextToken () // consume (
@@ -5786,19 +5786,110 @@ func (p *Parser) parseCreateColumnStoreIndexStatement() (*ast.CreateColumnStoreI
57865786 }
57875787 }
57885788
5789- // Skip optional WITH clause for now
5789+ // Parse optional WHERE clause (filtered index)
5790+ if p .curTok .Type == TokenWhere {
5791+ p .nextToken () // consume WHERE
5792+ pred , err := p .parseBooleanExpression ()
5793+ if err != nil {
5794+ return nil , err
5795+ }
5796+ stmt .FilterClause = pred
5797+ }
5798+
5799+ // Parse optional WITH clause
57905800 if p .curTok .Type == TokenWith {
5791- // TODO: parse WITH options
5792- p .nextToken ()
5801+ p .nextToken () // consume WITH
57935802 if p .curTok .Type == TokenLParen {
5794- p .nextToken ()
5795- depth := 1
5796- for depth > 0 && p .curTok .Type != TokenEOF {
5797- if p .curTok .Type == TokenLParen {
5798- depth ++
5799- } else if p .curTok .Type == TokenRParen {
5800- depth --
5803+ p .nextToken () // consume (
5804+ for p .curTok .Type != TokenRParen && p .curTok .Type != TokenEOF {
5805+ if p .curTok .Type == TokenComma {
5806+ p .nextToken ()
5807+ continue
58015808 }
5809+
5810+ optName := strings .ToUpper (p .curTok .Literal )
5811+ switch optName {
5812+ case "COMPRESSION_DELAY" :
5813+ p .nextToken () // consume COMPRESSION_DELAY
5814+ if p .curTok .Type == TokenEquals {
5815+ p .nextToken () // consume =
5816+ }
5817+ expr , err := p .parseScalarExpression ()
5818+ if err != nil {
5819+ return nil , err
5820+ }
5821+ opt := & ast.CompressionDelayIndexOption {
5822+ Expression : expr ,
5823+ TimeUnit : "Unitless" ,
5824+ OptionKind : "CompressionDelay" ,
5825+ }
5826+ // Check for MINUTE/MINUTES
5827+ if strings .ToUpper (p .curTok .Literal ) == "MINUTE" {
5828+ opt .TimeUnit = "Minute"
5829+ p .nextToken ()
5830+ } else if strings .ToUpper (p .curTok .Literal ) == "MINUTES" {
5831+ opt .TimeUnit = "Minutes"
5832+ p .nextToken ()
5833+ }
5834+ stmt .IndexOptions = append (stmt .IndexOptions , opt )
5835+
5836+ case "SORT_IN_TEMPDB" :
5837+ p .nextToken () // consume SORT_IN_TEMPDB
5838+ if p .curTok .Type == TokenEquals {
5839+ p .nextToken () // consume =
5840+ }
5841+ state := "NotSet"
5842+ if p .curTok .Type == TokenOn {
5843+ state = "On"
5844+ p .nextToken ()
5845+ } else if strings .ToUpper (p .curTok .Literal ) == "OFF" {
5846+ state = "Off"
5847+ p .nextToken ()
5848+ }
5849+ stmt .IndexOptions = append (stmt .IndexOptions , & ast.IndexStateOption {
5850+ OptionKind : "SortInTempDB" ,
5851+ OptionState : state ,
5852+ })
5853+
5854+ case "ORDER" :
5855+ p .nextToken () // consume ORDER
5856+ if p .curTok .Type == TokenLParen {
5857+ p .nextToken () // consume (
5858+ orderOpt := & ast.OrderIndexOption {
5859+ OptionKind : "Order" ,
5860+ }
5861+ for p .curTok .Type != TokenRParen && p .curTok .Type != TokenEOF {
5862+ colRef := & ast.ColumnReferenceExpression {
5863+ ColumnType : "Regular" ,
5864+ MultiPartIdentifier : & ast.MultiPartIdentifier {
5865+ Identifiers : []* ast.Identifier {p .parseIdentifier ()},
5866+ },
5867+ }
5868+ colRef .MultiPartIdentifier .Count = len (colRef .MultiPartIdentifier .Identifiers )
5869+ orderOpt .Columns = append (orderOpt .Columns , colRef )
5870+
5871+ if p .curTok .Type == TokenComma {
5872+ p .nextToken ()
5873+ } else {
5874+ break
5875+ }
5876+ }
5877+ if p .curTok .Type == TokenRParen {
5878+ p .nextToken ()
5879+ }
5880+ stmt .IndexOptions = append (stmt .IndexOptions , orderOpt )
5881+ }
5882+
5883+ default :
5884+ // Skip unknown options
5885+ p .nextToken ()
5886+ if p .curTok .Type == TokenEquals {
5887+ p .nextToken ()
5888+ p .nextToken () // skip value
5889+ }
5890+ }
5891+ }
5892+ if p .curTok .Type == TokenRParen {
58025893 p .nextToken ()
58035894 }
58045895 }
@@ -6887,6 +6978,16 @@ func createColumnStoreIndexStatementToJSON(s *ast.CreateColumnStoreIndexStatemen
68876978 }
68886979 node ["Columns" ] = cols
68896980 }
6981+ if s .FilterClause != nil {
6982+ node ["FilterPredicate" ] = booleanExpressionToJSON (s .FilterClause )
6983+ }
6984+ if len (s .IndexOptions ) > 0 {
6985+ opts := make ([]jsonNode , len (s .IndexOptions ))
6986+ for i , opt := range s .IndexOptions {
6987+ opts [i ] = columnStoreIndexOptionToJSON (opt )
6988+ }
6989+ node ["IndexOptions" ] = opts
6990+ }
68906991 if len (s .OrderedColumns ) > 0 {
68916992 cols := make ([]jsonNode , len (s .OrderedColumns ))
68926993 for i , col := range s .OrderedColumns {
@@ -6897,6 +6998,42 @@ func createColumnStoreIndexStatementToJSON(s *ast.CreateColumnStoreIndexStatemen
68976998 return node
68986999}
68997000
7001+ func columnStoreIndexOptionToJSON (opt ast.IndexOption ) jsonNode {
7002+ switch o := opt .(type ) {
7003+ case * ast.CompressionDelayIndexOption :
7004+ node := jsonNode {
7005+ "$type" : "CompressionDelayIndexOption" ,
7006+ "OptionKind" : o .OptionKind ,
7007+ "TimeUnit" : o .TimeUnit ,
7008+ }
7009+ if o .Expression != nil {
7010+ node ["Expression" ] = scalarExpressionToJSON (o .Expression )
7011+ }
7012+ return node
7013+ case * ast.OrderIndexOption :
7014+ node := jsonNode {
7015+ "$type" : "OrderIndexOption" ,
7016+ "OptionKind" : o .OptionKind ,
7017+ }
7018+ if len (o .Columns ) > 0 {
7019+ cols := make ([]jsonNode , len (o .Columns ))
7020+ for i , col := range o .Columns {
7021+ cols [i ] = columnReferenceExpressionToJSON (col )
7022+ }
7023+ node ["Columns" ] = cols
7024+ }
7025+ return node
7026+ case * ast.IndexStateOption :
7027+ return jsonNode {
7028+ "$type" : "IndexStateOption" ,
7029+ "OptionKind" : o .OptionKind ,
7030+ "OptionState" : o .OptionState ,
7031+ }
7032+ default :
7033+ return jsonNode {"$type" : "UnknownIndexOption" }
7034+ }
7035+ }
7036+
69007037func createSpatialIndexStatementToJSON (s * ast.CreateSpatialIndexStatement ) jsonNode {
69017038 node := jsonNode {
69027039 "$type" : "CreateSpatialIndexStatement" ,
0 commit comments