@@ -12767,7 +12767,144 @@ func (p *Parser) parseCreateFulltextStatement() (ast.Statement, error) {
1276712767 stmt := & ast.CreateFulltextIndexStatement {
1276812768 OnName : onName ,
1276912769 }
12770- p .skipToEndOfStatement ()
12770+
12771+ // Parse optional (column_list) - skip for now
12772+ if p .curTok .Type == TokenLParen {
12773+ p .nextToken () // consume (
12774+ for p .curTok .Type != TokenRParen && p .curTok .Type != TokenEOF {
12775+ p .nextToken ()
12776+ }
12777+ if p .curTok .Type == TokenRParen {
12778+ p .nextToken () // consume )
12779+ }
12780+ }
12781+
12782+ // Parse KEY INDEX name
12783+ if strings .ToUpper (p .curTok .Literal ) == "KEY" {
12784+ p .nextToken () // consume KEY
12785+ if strings .ToUpper (p .curTok .Literal ) == "INDEX" {
12786+ p .nextToken () // consume INDEX
12787+ }
12788+ stmt .KeyIndexName = p .parseIdentifier ()
12789+ }
12790+
12791+ // Parse ON clause for catalog/filegroup
12792+ if p .curTok .Type == TokenOn {
12793+ p .nextToken () // consume ON
12794+ stmt .CatalogAndFileGroup = & ast.FullTextCatalogAndFileGroup {}
12795+
12796+ if p .curTok .Type == TokenLParen {
12797+ // (FILEGROUP fg, catalog) or (catalog, FILEGROUP fg) format
12798+ p .nextToken () // consume (
12799+
12800+ // Check first element
12801+ if strings .ToUpper (p .curTok .Literal ) == "FILEGROUP" {
12802+ p .nextToken () // consume FILEGROUP
12803+ stmt .CatalogAndFileGroup .FileGroupName = p .parseIdentifier ()
12804+ stmt .CatalogAndFileGroup .FileGroupIsFirst = true
12805+
12806+ // Check for comma and catalog
12807+ if p .curTok .Type == TokenComma {
12808+ p .nextToken () // consume comma
12809+ stmt .CatalogAndFileGroup .CatalogName = p .parseIdentifier ()
12810+ }
12811+ } else {
12812+ // It's a catalog name first
12813+ stmt .CatalogAndFileGroup .CatalogName = p .parseIdentifier ()
12814+ stmt .CatalogAndFileGroup .FileGroupIsFirst = false
12815+
12816+ // Check for comma and filegroup
12817+ if p .curTok .Type == TokenComma {
12818+ p .nextToken () // consume comma
12819+ if strings .ToUpper (p .curTok .Literal ) == "FILEGROUP" {
12820+ p .nextToken () // consume FILEGROUP
12821+ }
12822+ stmt .CatalogAndFileGroup .FileGroupName = p .parseIdentifier ()
12823+ }
12824+ }
12825+
12826+ if p .curTok .Type == TokenRParen {
12827+ p .nextToken () // consume )
12828+ }
12829+ } else {
12830+ // Just a catalog name without parentheses
12831+ stmt .CatalogAndFileGroup .CatalogName = p .parseIdentifier ()
12832+ stmt .CatalogAndFileGroup .FileGroupIsFirst = false
12833+ }
12834+ }
12835+
12836+ // Parse WITH clause
12837+ if p .curTok .Type == TokenWith {
12838+ p .nextToken () // consume WITH
12839+ noPopulation := false
12840+ for {
12841+ optLit := strings .ToUpper (p .curTok .Literal )
12842+ if optLit == "CHANGE_TRACKING" {
12843+ p .nextToken () // consume CHANGE_TRACKING
12844+ var trackingValue string
12845+ if strings .ToUpper (p .curTok .Literal ) == "MANUAL" {
12846+ trackingValue = "Manual"
12847+ p .nextToken ()
12848+ } else if strings .ToUpper (p .curTok .Literal ) == "AUTO" {
12849+ trackingValue = "Auto"
12850+ p .nextToken ()
12851+ } else if strings .ToUpper (p .curTok .Literal ) == "OFF" {
12852+ trackingValue = "Off"
12853+ p .nextToken ()
12854+ }
12855+ // If we see NO POPULATION after CHANGE_TRACKING OFF, update the value
12856+ if trackingValue == "Off" && noPopulation {
12857+ trackingValue = "OffNoPopulation"
12858+ }
12859+ stmt .Options = append (stmt .Options , & ast.ChangeTrackingFullTextIndexOption {
12860+ Value : trackingValue ,
12861+ OptionKind : "ChangeTracking" ,
12862+ })
12863+ } else if optLit == "STOPLIST" {
12864+ p .nextToken () // consume STOPLIST
12865+ opt := & ast.StopListFullTextIndexOption {
12866+ OptionKind : "StopList" ,
12867+ }
12868+ if strings .ToUpper (p .curTok .Literal ) == "OFF" {
12869+ opt .IsOff = true
12870+ p .nextToken ()
12871+ } else if strings .ToUpper (p .curTok .Literal ) == "SYSTEM" {
12872+ opt .IsOff = false
12873+ opt .StopListName = p .parseIdentifier ()
12874+ } else {
12875+ opt .IsOff = false
12876+ opt .StopListName = p .parseIdentifier ()
12877+ }
12878+ stmt .Options = append (stmt .Options , opt )
12879+ } else if optLit == "NO" {
12880+ p .nextToken () // consume NO
12881+ if strings .ToUpper (p .curTok .Literal ) == "POPULATION" {
12882+ p .nextToken () // consume POPULATION
12883+ noPopulation = true
12884+ // Update CHANGE_TRACKING OFF to OffNoPopulation
12885+ for i , opt := range stmt .Options {
12886+ if ctOpt , ok := opt .(* ast.ChangeTrackingFullTextIndexOption ); ok && ctOpt .Value == "Off" {
12887+ ctOpt .Value = "OffNoPopulation"
12888+ stmt .Options [i ] = ctOpt
12889+ }
12890+ }
12891+ }
12892+ } else {
12893+ break
12894+ }
12895+
12896+ if p .curTok .Type == TokenComma {
12897+ p .nextToken () // consume comma
12898+ } else if p .curTok .Type == TokenSemicolon || p .curTok .Type == TokenEOF {
12899+ break
12900+ }
12901+ }
12902+ }
12903+
12904+ // Skip optional semicolon
12905+ if p .curTok .Type == TokenSemicolon {
12906+ p .nextToken ()
12907+ }
1277112908 return stmt , nil
1277212909 default :
1277312910 // Just create a catalog statement as default
0 commit comments