Skip to content

Commit d8db13f

Browse files
kyleconroyclaude
andcommitted
Add CREATE FULLTEXT INDEX column parsing with LANGUAGE support
- Parse FullTextIndexColumns including TYPE COLUMN and LANGUAGE options - Handle binary/hex literals (0x...) in LANGUAGE clause - Handle integer and string literals in LANGUAGE clause - Change DropFulltextIndexStatement.OnName to TableName to match expected output - Add FullTextIndexColumns marshaling to JSON output Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent d0496a0 commit d8db13f

7 files changed

Lines changed: 88 additions & 12 deletions

File tree

ast/create_simple_statements.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,11 @@ func (s *CreateFulltextCatalogStatement) statement() {}
425425

426426
// CreateFulltextIndexStatement represents a CREATE FULLTEXT INDEX statement.
427427
type CreateFulltextIndexStatement struct {
428-
OnName *SchemaObjectName `json:"OnName,omitempty"`
429-
KeyIndexName *Identifier `json:"KeyIndexName,omitempty"`
430-
CatalogAndFileGroup *FullTextCatalogAndFileGroup `json:"CatalogAndFileGroup,omitempty"`
431-
Options []FullTextIndexOption `json:"Options,omitempty"`
428+
OnName *SchemaObjectName `json:"OnName,omitempty"`
429+
FullTextIndexColumns []*FullTextIndexColumn `json:"FullTextIndexColumns,omitempty"`
430+
KeyIndexName *Identifier `json:"KeyIndexName,omitempty"`
431+
CatalogAndFileGroup *FullTextCatalogAndFileGroup `json:"CatalogAndFileGroup,omitempty"`
432+
Options []FullTextIndexOption `json:"Options,omitempty"`
432433
}
433434

434435
func (s *CreateFulltextIndexStatement) node() {}

ast/fulltext_stoplist_statement.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func (s *DropFullTextCatalogStatement) statement() {}
5151

5252
// DropFulltextIndexStatement represents DROP FULLTEXT INDEX statement
5353
type DropFulltextIndexStatement struct {
54-
OnName *SchemaObjectName `json:"OnName,omitempty"`
54+
TableName *SchemaObjectName `json:"TableName,omitempty"`
5555
}
5656

5757
func (s *DropFulltextIndexStatement) node() {}

parser/marshal.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17512,8 +17512,8 @@ func dropFulltextIndexStatementToJSON(s *ast.DropFulltextIndexStatement) jsonNod
1751217512
node := jsonNode{
1751317513
"$type": "DropFullTextIndexStatement",
1751417514
}
17515-
if s.OnName != nil {
17516-
node["OnName"] = schemaObjectNameToJSON(s.OnName)
17515+
if s.TableName != nil {
17516+
node["TableName"] = schemaObjectNameToJSON(s.TableName)
1751717517
}
1751817518
return node
1751917519
}
@@ -18568,6 +18568,13 @@ func createFulltextIndexStatementToJSON(s *ast.CreateFulltextIndexStatement) jso
1856818568
if s.OnName != nil {
1856918569
node["OnName"] = schemaObjectNameToJSON(s.OnName)
1857018570
}
18571+
if len(s.FullTextIndexColumns) > 0 {
18572+
cols := make([]jsonNode, len(s.FullTextIndexColumns))
18573+
for i, col := range s.FullTextIndexColumns {
18574+
cols[i] = fullTextIndexColumnToJSON(col)
18575+
}
18576+
node["FullTextIndexColumns"] = cols
18577+
}
1857118578
if s.KeyIndexName != nil {
1857218579
node["KeyIndexName"] = identifierToJSON(s.KeyIndexName)
1857318580
}

parser/parse_ddl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func (p *Parser) parseDropFulltextStatement() (ast.Statement, error) {
204204
}
205205
name, _ := p.parseSchemaObjectName()
206206
stmt := &ast.DropFulltextIndexStatement{
207-
OnName: name,
207+
TableName: name,
208208
}
209209
// Skip optional semicolon
210210
if p.curTok.Type == TokenSemicolon {

parser/parse_statements.go

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12796,11 +12796,79 @@ func (p *Parser) parseCreateFulltextStatement() (ast.Statement, error) {
1279612796
OnName: onName,
1279712797
}
1279812798

12799-
// Parse optional (column_list) - skip for now
12799+
// Parse optional (column_list)
1280012800
if p.curTok.Type == TokenLParen {
1280112801
p.nextToken() // consume (
1280212802
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
12803-
p.nextToken()
12803+
col := &ast.FullTextIndexColumn{}
12804+
col.Name = p.parseIdentifier()
12805+
12806+
// Parse optional TYPE COLUMN type_column_name
12807+
if strings.ToUpper(p.curTok.Literal) == "TYPE" {
12808+
p.nextToken() // consume TYPE
12809+
if strings.ToUpper(p.curTok.Literal) == "COLUMN" {
12810+
p.nextToken() // consume COLUMN
12811+
}
12812+
col.TypeColumn = p.parseIdentifier()
12813+
}
12814+
12815+
// Parse optional LANGUAGE language_term
12816+
if p.curTok.Type == TokenLanguage {
12817+
p.nextToken() // consume LANGUAGE
12818+
col.LanguageTerm = &ast.IdentifierOrValueExpression{}
12819+
if p.curTok.Type == TokenString {
12820+
strLit, _ := p.parseStringLiteral()
12821+
col.LanguageTerm.Value = strLit.Value
12822+
col.LanguageTerm.ValueExpression = strLit
12823+
} else if p.curTok.Type == TokenNumber {
12824+
// Check for hex literal (0x...)
12825+
if strings.HasPrefix(strings.ToLower(p.curTok.Literal), "0x") {
12826+
lit := &ast.BinaryLiteral{
12827+
LiteralType: "Binary",
12828+
IsLargeObject: false,
12829+
Value: p.curTok.Literal,
12830+
}
12831+
col.LanguageTerm.Value = p.curTok.Literal
12832+
col.LanguageTerm.ValueExpression = lit
12833+
} else {
12834+
// Parse integer literal directly
12835+
lit := &ast.IntegerLiteral{
12836+
LiteralType: "Integer",
12837+
Value: p.curTok.Literal,
12838+
}
12839+
col.LanguageTerm.Value = p.curTok.Literal
12840+
col.LanguageTerm.ValueExpression = lit
12841+
}
12842+
p.nextToken()
12843+
} else if p.curTok.Type == TokenBinary {
12844+
// Handle binary/hex literal
12845+
lit := &ast.BinaryLiteral{
12846+
LiteralType: "Binary",
12847+
IsLargeObject: false,
12848+
Value: p.curTok.Literal,
12849+
}
12850+
col.LanguageTerm.Value = p.curTok.Literal
12851+
col.LanguageTerm.ValueExpression = lit
12852+
p.nextToken()
12853+
} else {
12854+
col.LanguageTerm.Identifier = p.parseIdentifier()
12855+
col.LanguageTerm.Value = col.LanguageTerm.Identifier.Value
12856+
}
12857+
}
12858+
12859+
// Parse optional STATISTICAL_SEMANTICS
12860+
if strings.ToUpper(p.curTok.Literal) == "STATISTICAL_SEMANTICS" {
12861+
col.StatisticalSemantics = true
12862+
p.nextToken()
12863+
}
12864+
12865+
stmt.FullTextIndexColumns = append(stmt.FullTextIndexColumns, col)
12866+
12867+
if p.curTok.Type == TokenComma {
12868+
p.nextToken() // consume comma
12869+
} else {
12870+
break
12871+
}
1280412872
}
1280512873
if p.curTok.Type == TokenRParen {
1280612874
p.nextToken() // consume )
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)